Browse Source

提交

groupmealweb
gwbvipvip 9 months ago
parent
commit
e05e7a7e9c
100 changed files with 3453 additions and 524 deletions
  1. +0
    -1
      dist/2255.a25b6bb8.async.js
  2. +0
    -1
      dist/3059.b3e40214.async.js
  3. +0
    -3
      dist/3537.6923ec17.async.js
  4. +0
    -417
      dist/3667.a51bb1c9.async.js
  5. +0
    -1
      dist/5977.8c6992c5.chunk.css
  6. +0
    -27
      dist/6486.837492aa.async.js
  7. +0
    -1
      dist/7973.006892df.async.js
  8. +0
    -1
      dist/8151.e344b23c.async.js
  9. +0
    -1
      dist/8328.688c2ff1.chunk.css
  10. +0
    -1
      dist/8790.67a4f36e.async.js
  11. +0
    -27
      dist/9215.80966678.async.js
  12. +0
    -1
      dist/9396.3fe14a67.async.js
  13. +0
    -2
      dist/9669.75110ec8.async.js
  14. +0
    -1
      dist/CNAME
  15. BIN
     
  16. BIN
     
  17. BIN
     
  18. BIN
     
  19. BIN
     
  20. +0
    -1
      dist/logo.svg
  21. +0
    -1
      dist/p__404.7bdbd081.async.js
  22. +0
    -1
      dist/p__404.b74445fb.chunk.css
  23. +0
    -2
      dist/p__Welcome.a394acf9.chunk.css
  24. +0
    -1
      dist/p__applet__basicconfiguration.914f173e.chunk.css
  25. +0
    -1
      dist/p__applet__paytemplate.b77cf64e.chunk.css
  26. +0
    -1
      dist/p__company__account.d466ea36.async.js
  27. +0
    -1
      dist/p__company__account.f6838307.chunk.css
  28. +0
    -1
      dist/p__database__basic__batching.5b012b67.chunk.css
  29. +0
    -1
      dist/p__database__goods__goodsInfo.67f6136b.chunk.css
  30. +0
    -1
      dist/p__database__goods__goodsInfo.76140e4f.async.js
  31. +0
    -1
      dist/p__database__goods__goodsattribute.326bd497.async.js
  32. +0
    -1
      dist/p__database__goods__goodstypemanage.af758cbf.async.js
  33. +0
    -1
      dist/p__database__goods__goodstypemanage.f6838307.chunk.css
  34. +0
    -1
      dist/p__database__goods__newgoods.5acfdb51.async.js
  35. +0
    -1
      dist/p__database__goods__newgoods.f3ef09c5.chunk.css
  36. +0
    -1
      dist/p__device__deviceInfo.64ee08bc.async.js
  37. +0
    -1
      dist/p__device__deviceVesion.009937ac.async.js
  38. +0
    -1
      dist/p__device__deviceVesion.63cc2960.chunk.css
  39. +0
    -1
      dist/p__device__product.ca8be7d4.async.js
  40. +0
    -1
      dist/p__order__orderflow.f6838307.chunk.css
  41. +0
    -1
      dist/p__org__orgamange.2a1ec583.async.js
  42. +0
    -1
      dist/p__org__orgamange.5d1001bb.chunk.css
  43. +0
    -1
      dist/p__org__roles.1f1ff1a5.async.js
  44. +0
    -1
      dist/p__org__users.742ace03.async.js
  45. +0
    -1
      dist/p__push__batchingpush.f6838307.chunk.css
  46. +0
    -1
      dist/p__push__bompush.1840c32b.async.js
  47. +0
    -1
      dist/p__push__goodspush.f6838307.chunk.css
  48. +0
    -1
      dist/p__push__technologypush.f6838307.chunk.css
  49. +0
    -1
      dist/p__sys__dictionary__dicttype.23fb8d43.async.js
  50. +0
    -1
      dist/p__sys__dictionary__dicttype.f6838307.chunk.css
  51. +0
    -5
      dist/pro_icon.svg
  52. +0
    -1
      dist/t__plugin-layout__Layout.e1129705.chunk.css
  53. +0
    -1
      dist/umi.2d7db433.css
  54. +21
    -0
      src/.umi-production/core/history.ts
  55. +8
    -0
      src/.umi-production/core/plugin.ts
  56. +362
    -0
      src/.umi-production/core/pluginConfig.d.ts
  57. +40
    -0
      src/.umi-production/core/pluginRegister.ts
  58. +4
    -0
      src/.umi-production/core/polyfill.ts
  59. +395
    -0
      src/.umi-production/core/routes.ts
  60. +12
    -0
      src/.umi-production/core/umiExports.ts
  61. +40
    -0
      src/.umi-production/plugin-access/AccessProvider.ts
  62. +33
    -0
      src/.umi-production/plugin-access/access.tsx
  63. +9
    -0
      src/.umi-production/plugin-access/context.ts
  64. +7
    -0
      src/.umi-production/plugin-access/rootContainer.ts
  65. +80
    -0
      src/.umi-production/plugin-access/runtimeUtil.ts
  66. +51
    -0
      src/.umi-production/plugin-antd-icon-config/app.ts
  67. +14
    -0
      src/.umi-production/plugin-antd-icon/icons.ts
  68. +3
    -0
      src/.umi-production/plugin-helmet/exports.ts
  69. +37
    -0
      src/.umi-production/plugin-initial-state/Provider.tsx
  70. +7
    -0
      src/.umi-production/plugin-initial-state/exports.ts
  71. +63
    -0
      src/.umi-production/plugin-initial-state/models/initialState.ts
  72. +13
    -0
      src/.umi-production/plugin-initial-state/runtime.tsx
  73. +53
    -0
      src/.umi-production/plugin-layout/Layout.tsx
  74. +12
    -0
      src/.umi-production/plugin-layout/icons.ts
  75. +56
    -0
      src/.umi-production/plugin-layout/layout/component/Exception/index.tsx
  76. +91
    -0
      src/.umi-production/plugin-layout/layout/component/logo.tsx
  77. +7
    -0
      src/.umi-production/plugin-layout/layout/layout/blankLayout.tsx
  78. +37
    -0
      src/.umi-production/plugin-layout/layout/layout/getLayoutRenderConfig.ts
  79. +135
    -0
      src/.umi-production/plugin-layout/layout/layout/index.tsx
  80. +59
    -0
      src/.umi-production/plugin-layout/layout/layout/style.less
  81. +13
    -0
      src/.umi-production/plugin-layout/layout/layoutExports.ts
  82. +3
    -0
      src/.umi-production/plugin-layout/layout/types/index.d.ts
  83. +89
    -0
      src/.umi-production/plugin-layout/layout/types/interface.d.ts
  84. +38
    -0
      src/.umi-production/plugin-layout/layout/utils/copySrcFiles.ts
  85. +152
    -0
      src/.umi-production/plugin-layout/layout/utils/getLayoutContent.tsx
  86. +14
    -0
      src/.umi-production/plugin-layout/layoutExports.ts
  87. +72
    -0
      src/.umi-production/plugin-layout/renderRightContent.tsx
  88. +56
    -0
      src/.umi-production/plugin-layout/runtime.tsx
  89. +473
    -0
      src/.umi-production/plugin-locale/SelectLang.tsx
  90. +60
    -0
      src/.umi-production/plugin-locale/locale.tsx
  91. +277
    -0
      src/.umi-production/plugin-locale/localeExports.ts
  92. +10
    -0
      src/.umi-production/plugin-locale/runtime.tsx
  93. +39
    -0
      src/.umi-production/plugin-model/Provider.tsx
  94. +4
    -0
      src/.umi-production/plugin-model/helpers/constant.tsx
  95. +19
    -0
      src/.umi-production/plugin-model/helpers/dispatcher.tsx
  96. +83
    -0
      src/.umi-production/plugin-model/helpers/executor.tsx
  97. +12
    -0
      src/.umi-production/plugin-model/runtime.tsx
  98. +71
    -0
      src/.umi-production/plugin-model/useModel.tsx
  99. +41
    -0
      src/.umi-production/plugin-openapi/openapi.tsx
  100. +278
    -0
      src/.umi-production/plugin-request/request.ts

+ 0
- 1
dist/2255.a25b6bb8.async.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/3059.b3e40214.async.js
File diff suppressed because it is too large
View File


+ 0
- 3
dist/3537.6923ec17.async.js
File diff suppressed because it is too large
View File


+ 0
- 417
dist/3667.a51bb1c9.async.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/5977.8c6992c5.chunk.css
File diff suppressed because it is too large
View File


+ 0
- 27
dist/6486.837492aa.async.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/7973.006892df.async.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/8151.e344b23c.async.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/8328.688c2ff1.chunk.css
File diff suppressed because it is too large
View File


+ 0
- 1
dist/8790.67a4f36e.async.js
File diff suppressed because it is too large
View File


+ 0
- 27
dist/9215.80966678.async.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/9396.3fe14a67.async.js
File diff suppressed because it is too large
View File


+ 0
- 2
dist/9669.75110ec8.async.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/CNAME View File

@@ -1 +0,0 @@
preview.pro.ant.design

BIN
View File


BIN
View File


BIN
View File


BIN
View File


BIN
View File


+ 0
- 1
dist/logo.svg
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__404.7bdbd081.async.js View File

@@ -1 +0,0 @@
(self.webpackChunkant_design_pro=self.webpackChunkant_design_pro||[]).push([[2571],{7594:function(u,_,t){"use strict";t.r(_);var P=t(57106),s=t(6129),d=t(57663),E=t(71577),e=t(67294),a=t(48971),n=t(85893),o=function(){return(0,n.jsx)(s.ZP,{status:"404",title:"404",subTitle:"Sorry, the page you visited does not exist.",extra:(0,n.jsx)(E.Z,{type:"primary",onClick:function(){return a.m8.push("/")},children:"Back Home"})})};_.default=o}}]);

+ 0
- 1
dist/p__404.b74445fb.chunk.css View File

@@ -1 +0,0 @@
.ant-result{padding:48px 32px}.ant-result-success .ant-result-icon>.anticon{color:#52c41a}.ant-result-error .ant-result-icon>.anticon{color:#ff4d4f}.ant-result-info .ant-result-icon>.anticon{color:#fa541c}.ant-result-warning .ant-result-icon>.anticon{color:#faad14}.ant-result-image{width:250px;height:295px;margin:auto}.ant-result-icon{margin-bottom:24px;text-align:center}.ant-result-icon>.anticon{font-size:72px}.ant-result-title{color:rgba(0,0,0,.85);font-size:24px;line-height:1.8;text-align:center}.ant-result-subtitle{color:rgba(0,0,0,.45);font-size:14px;line-height:1.6;text-align:center}.ant-result-extra{margin:24px 0 0;text-align:center}.ant-result-extra>*{margin-right:8px}.ant-result-extra>:last-child{margin-right:0}.ant-result-content{margin-top:24px;padding:24px 40px;background-color:#fafafa}.ant-result-rtl{direction:rtl}.ant-result-rtl .ant-result-extra>*{margin-right:0;margin-left:8px}.ant-result-rtl .ant-result-extra>:last-child{margin-left:0}

+ 0
- 2
dist/p__Welcome.a394acf9.chunk.css
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__applet__basicconfiguration.914f173e.chunk.css
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__applet__paytemplate.b77cf64e.chunk.css
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__company__account.d466ea36.async.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__company__account.f6838307.chunk.css
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__database__basic__batching.5b012b67.chunk.css
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__database__goods__goodsInfo.67f6136b.chunk.css
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__database__goods__goodsInfo.76140e4f.async.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__database__goods__goodsattribute.326bd497.async.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__database__goods__goodstypemanage.af758cbf.async.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__database__goods__goodstypemanage.f6838307.chunk.css
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__database__goods__newgoods.5acfdb51.async.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__database__goods__newgoods.f3ef09c5.chunk.css View File

@@ -1 +0,0 @@
.ant-pro-descriptions .ant-descriptions-view{overflow:visible!important;overflow:initial!important}

+ 0
- 1
dist/p__device__deviceInfo.64ee08bc.async.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__device__deviceVesion.009937ac.async.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__device__deviceVesion.63cc2960.chunk.css
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__device__product.ca8be7d4.async.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__order__orderflow.f6838307.chunk.css
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__org__orgamange.2a1ec583.async.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__org__orgamange.5d1001bb.chunk.css
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__org__roles.1f1ff1a5.async.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__org__users.742ace03.async.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__push__batchingpush.f6838307.chunk.css
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__push__bompush.1840c32b.async.js View File

@@ -1 +0,0 @@
(self.webpackChunkant_design_pro=self.webpackChunkant_design_pro||[]).push([[961],{67971:function(){}}]);

+ 0
- 1
dist/p__push__goodspush.f6838307.chunk.css
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__push__technologypush.f6838307.chunk.css
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__sys__dictionary__dicttype.23fb8d43.async.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/p__sys__dictionary__dicttype.f6838307.chunk.css
File diff suppressed because it is too large
View File


+ 0
- 5
dist/pro_icon.svg View File

@@ -1,5 +0,0 @@
<svg width="42" height="42" xmlns="http://www.w3.org/2000/svg">
<g>
<path fill="#070707" d="m6.717392,13.773912l5.6,0c2.8,0 4.7,1.9 4.7,4.7c0,2.8 -2,4.7 -4.9,4.7l-2.5,0l0,4.3l-2.9,0l0,-13.7zm2.9,2.2l0,4.9l1.9,0c1.6,0 2.6,-0.9 2.6,-2.4c0,-1.6 -0.9,-2.4 -2.6,-2.4l-1.9,0l0,-0.1zm8.9,11.5l2.7,0l0,-5.7c0,-1.4 0.8,-2.3 2.2,-2.3c0.4,0 0.8,0.1 1,0.2l0,-2.4c-0.2,-0.1 -0.5,-0.1 -0.8,-0.1c-1.2,0 -2.1,0.7 -2.4,2l-0.1,0l0,-1.9l-2.7,0l0,10.2l0.1,0zm11.7,0.1c-3.1,0 -5,-2 -5,-5.3c0,-3.3 2,-5.3 5,-5.3s5,2 5,5.3c0,3.4 -1.9,5.3 -5,5.3zm0,-2.1c1.4,0 2.2,-1.1 2.2,-3.2c0,-2 -0.8,-3.2 -2.2,-3.2c-1.4,0 -2.2,1.2 -2.2,3.2c0,2.1 0.8,3.2 2.2,3.2z" class="st0" id="Ant-Design-Pro"/>
</g>
</svg>

+ 0
- 1
dist/t__plugin-layout__Layout.e1129705.chunk.css
File diff suppressed because it is too large
View File


+ 0
- 1
dist/umi.2d7db433.css
File diff suppressed because it is too large
View File


+ 21
- 0
src/.umi-production/core/history.ts View File

@@ -0,0 +1,21 @@
// @ts-nocheck
import { createBrowserHistory, History } from 'D:/Work/BPA.SAAS.Web/node_modules/umi/node_modules/@umijs/runtime';

let options = {
"basename": "/"
};
if ((<any>window).routerBase) {
options.basename = (<any>window).routerBase;
}

// remove initial history because of ssr
let history: History = process.env.__IS_SERVER ? null : createBrowserHistory(options);
export const createHistory = (hotReload = false) => {
if (!hotReload) {
history = createBrowserHistory(options);
}

return history;
};

export { history };

+ 8
- 0
src/.umi-production/core/plugin.ts View File

@@ -0,0 +1,8 @@
// @ts-nocheck
import { Plugin } from 'D:/Work/BPA.SAAS.Web/node_modules/umi/node_modules/@umijs/runtime';

const plugin = new Plugin({
validKeys: ['modifyClientRenderOpts','patchRoutes','rootContainer','render','onRouteChange','__mfsu','getInitialState','initialStateConfig','locale','layout','layoutActionRef','request',],
});

export { plugin };

+ 362
- 0
src/.umi-production/core/pluginConfig.d.ts View File

@@ -0,0 +1,362 @@
// Created by Umi Plugin

export interface IConfigFromPlugins {
"404"?: boolean
routes?: {
/**
* Any valid URL path
*/
path?: string
/**
* A React component to render only when the location matches.
*/
component?: (string | (() => any))
wrappers?: string[]
/**
* navigate to a new location
*/
redirect?: string
/**
* When true, the active class/style will only be applied if the location is matched exactly.
*/
exact?: boolean
routes?: any[]
[k: string]: any
}[]
history?: {
type?: ("browser" | "hash" | "memory")
options?: {

}
}
polyfill?: {
imports?: string[]
}
alias?: {

}
analyze?: {
analyzerMode?: ("server" | "static" | "disabled")
analyzerHost?: string
analyzerPort?: any
openAnalyzer?: boolean
generateStatsFile?: boolean
statsFilename?: string
logLevel?: ("info" | "warn" | "error" | "silent")
defaultSizes?: ("stat" | "parsed" | "gzip")
[k: string]: any
}
/**
* postcss autoprefixer, default flexbox: no-2009
*/
autoprefixer?: {

}
base?: string
chainWebpack?: (() => any)
chunks?: string[]
/**
* more css-loader options see https://webpack.js.org/loaders/css-loader/#options
*/
cssLoader?: {
url?: (boolean | (() => any))
import?: (boolean | (() => any))
modules?: (boolean | string | {

})
sourceMap?: boolean
importLoaders?: number
onlyLocals?: boolean
esModule?: boolean
localsConvention?: ("asIs" | "camelCase" | "camelCaseOnly" | "dashes" | "dashesOnly")
}
cssModulesTypescriptLoader?: {
mode?: ("emit" | "verify")
}
cssnano?: {

}
copy?: any[]
define?: {

}
devScripts?: {

}
/**
* devServer configs
*/
devServer?: {
/**
* devServer port, default 8000
*/
port?: number
host?: string
https?: ({
key?: string
cert?: string
http2?: boolean
[k: string]: any
} | boolean)
headers?: {

}
writeToDisk?: (boolean | (() => any))
[k: string]: any
}
devtool?: string
/**
* Code splitting for performance optimization
*/
dynamicImport?: {
/**
* loading the component before loaded
*/
loading?: string
}
/**
* Code splitting for import statement syntax
*/
dynamicImportSyntax?: {

}
exportStatic?: {
htmlSuffix?: boolean
dynamicRoot?: boolean
supportWin?: boolean
/**
* extra render paths only enable in ssr
*/
extraRoutePaths?: (() => any)
}
externals?: ({

} | string | (() => any))
extraBabelIncludes?: any[]
extraBabelPlugins?: any[]
extraBabelPresets?: any[]
extraPostCSSPlugins?: any[]
/**
* fork-ts-checker-webpack-plugin options see https://github.com/TypeStrong/fork-ts-checker-webpack-plugin#options
*/
forkTSChecker?: {
async?: boolean
typescript?: (boolean | {

})
eslint?: {

}
issue?: {

}
formatter?: (string | {

})
logger?: {

}
[k: string]: any
}
fastRefresh?: {

}
hash?: boolean
ignoreMomentLocale?: boolean
inlineLimit?: number
lessLoader?: {

}
manifest?: {
fileName?: string
publicPath?: ""
basePath?: string
writeToFileEmit?: boolean
}
/**
* open mfsu feature
*/
mfsu?: {
development?: {
output?: string
}
production?: {
output?: string
}
mfName?: string
exportAllMembers?: {

}
chunks?: string[]
ignoreNodeBuiltInModules?: boolean
}
mountElementId?: ""
mpa?: {

}
nodeModulesTransform?: {
type?: ("all" | "none")
exclude?: string[]
}
outputPath?: ""
plugins?: string[]
postcssLoader?: {

}
presets?: string[]
proxy?: {

}
publicPath?: string
runtimePublicPath?: boolean
ssr?: {
/**
* force execing Page getInitialProps functions
*/
forceInitial?: boolean
/**
* remove window.g_initialProps in html
*/
removeWindowInitialProps?: boolean
/**
* disable serve-side render in umi dev mode.
*/
devServerRender?: boolean
mode?: ("stream" | "string")
/**
* static markup in static site
*/
staticMarkup?: boolean
}
singular?: boolean
styleLoader?: {

}
targets?: {

}
terserOptions?: {

}
theme?: {

}
runtimeHistory?: {

}
webpack5?: {
lazyCompilation?: {
entries?: boolean
imports?: boolean
test?: any
}
}
workerLoader?: {

}
favicon?: string
headScripts?: any[]
links?: any[]
metas?: any[]
scripts?: any[]
styles?: any[]
title?: string
mock?: {
exclude?: string[]
}
ProBlockOption?: string
themeConfig?: {

}
logo?: (string | boolean)
mode?: any
description?: string
locales?: string[][]
resolve?: {

}
menus?: {

}
navs?: (any[] | {

})
algolia?: {
appId?: string
apiKey?: string
indexName?: string
debug?: boolean
}
sitemap?: {
hostname?: string
excludes?: string[]
}
apiParser?: {

}
antd?: {
dark?: boolean
compact?: boolean
mobile?: boolean
disableBabelPluginImport?: boolean
config?: {

}
}
dva?: {
disableModelsReExport?: boolean
/**
* lazy load dva model avoiding the import modules from umi undefined
*/
lazyLoad?: boolean
extraModels?: string[]
hmr?: boolean
immer?: (boolean | {

})
skipModelValidate?: boolean
}
locale?: {
default?: string
useLocalStorage?: boolean
baseNavigator?: boolean
title?: boolean
antd?: boolean
baseSeparator?: string
}
layout?: {

}
request?: {
dataField?: ""
}
block?: number
esbuild?: {
target?: (string | string[])
format?: ("iife" | "cjs" | "esm")
}
openAPI?: ({
requestLibPath?: string
schemaPath?: string
mock?: boolean
projectName?: string
apiPrefix?: (string | (() => any))
namespace?: string
hook?: {
customFunctionName?: (() => any)
customClassName?: (() => any)
}
}[] | {
requestLibPath?: string
schemaPath?: string
mock?: boolean
projectName?: string
apiPrefix?: (string | (() => any))
namespace?: string
hook?: {
customFunctionName?: (() => any)
customClassName?: (() => any)
}
})
[k: string]: any
}

+ 40
- 0
src/.umi-production/core/pluginRegister.ts View File

@@ -0,0 +1,40 @@
// @ts-nocheck
import { plugin } from './plugin';
import * as Plugin_0 from '../../app.jsx';
import * as Plugin_1 from '@@/plugin-antd-icon-config/app.ts';
import * as Plugin_2 from 'D:/Work/BPA.SAAS.Web/src/.umi-production/plugin-access/rootContainer.ts';
import * as Plugin_3 from '../plugin-initial-state/runtime';
import * as Plugin_4 from 'D:/Work/BPA.SAAS.Web/src/.umi-production/plugin-locale/runtime.tsx';
import * as Plugin_5 from '@@/plugin-layout/runtime.tsx';
import * as Plugin_6 from '../plugin-model/runtime';

plugin.register({
apply: Plugin_0,
path: '../../app.jsx',
});
plugin.register({
apply: Plugin_1,
path: '@@/plugin-antd-icon-config/app.ts',
});
plugin.register({
apply: Plugin_2,
path: 'D:/Work/BPA.SAAS.Web/src/.umi-production/plugin-access/rootContainer.ts',
});
plugin.register({
apply: Plugin_3,
path: '../plugin-initial-state/runtime',
});
plugin.register({
apply: Plugin_4,
path: 'D:/Work/BPA.SAAS.Web/src/.umi-production/plugin-locale/runtime.tsx',
});
plugin.register({
apply: Plugin_5,
path: '@@/plugin-layout/runtime.tsx',
});
plugin.register({
apply: Plugin_6,
path: '../plugin-model/runtime',
});

export const __mfsu = 1;

+ 4
- 0
src/.umi-production/core/polyfill.ts View File

@@ -0,0 +1,4 @@
// @ts-nocheck
import 'core-js';
import 'regenerator-runtime/runtime';
export {};

+ 395
- 0
src/.umi-production/core/routes.ts View File

@@ -0,0 +1,395 @@
// @ts-nocheck
import React from 'react';
import { ApplyPluginsType, dynamic } from 'D:/Work/BPA.SAAS.Web/node_modules/umi/node_modules/@umijs/runtime';
import * as umiExports from './umiExports';
import { plugin } from './plugin';
import LoadingComponent from '@ant-design/pro-layout/es/PageLoading';

export function getRoutes() {
const routes = [
{
"path": "/",
"component": dynamic({ loader: () => import(/* webpackChunkName: 't__plugin-layout__Layout' */'D:/Work/BPA.SAAS.Web/src/.umi-production/plugin-layout/Layout.tsx'), loading: LoadingComponent}),
"routes": [
{
"path": "/user",
"layout": false,
"routes": [
{
"name": "系统登录",
"path": "/user/login",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__user__login' */'D:/Work/BPA.SAAS.Web/src/pages/user/login'), loading: LoadingComponent}),
"access": "k1",
"exact": true
}
]
},
{
"name": "系统管理",
"icon": "SettingOutlined",
"path": "/sys",
"routes": [
{
"name": "系统菜单",
"icon": "smile",
"path": "/sys/menus",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__sys__menus' */'D:/Work/BPA.SAAS.Web/src/pages/sys/menus'), loading: LoadingComponent}),
"access": "k6",
"exact": true
},
{
"name": "字典类型",
"icon": "smile",
"path": "/sys/dictionary/dicttype",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__sys__dictionary__dicttype' */'D:/Work/BPA.SAAS.Web/src/pages/sys/dictionary/dicttype'), loading: LoadingComponent}),
"access": "k6",
"exact": true
}
]
},
{
"name": "加盟商管理",
"icon": "SettingOutlined",
"path": "/company",
"routes": [
{
"name": "账号管理",
"icon": "smile",
"path": "/company/account",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__company__account' */'D:/Work/BPA.SAAS.Web/src/pages/company/account'), loading: LoadingComponent}),
"access": "k2",
"exact": true
}
]
},
{
"name": "组织管理",
"icon": "SettingOutlined",
"path": "/org",
"routes": [
{
"name": "机构管理",
"icon": "smile",
"path": "/org/orgamange",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__org__orgamange' */'D:/Work/BPA.SAAS.Web/src/pages/org/orgamange'), loading: LoadingComponent}),
"access": "k2",
"exact": true
},
{
"name": "角色管理",
"icon": "smile",
"path": "/org/roles",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__org__roles' */'D:/Work/BPA.SAAS.Web/src/pages/org/roles'), loading: LoadingComponent}),
"access": "k5",
"exact": true
},
{
"name": "用户账号管理",
"icon": "smile",
"path": "/org/users",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__org__users' */'D:/Work/BPA.SAAS.Web/src/pages/org/users'), loading: LoadingComponent}),
"access": "k5",
"exact": true
}
]
},
{
"name": "元数据管理",
"icon": "DropboxSquareFilled",
"path": "/database",
"routes": [
{
"name": "物料管理",
"icon": "smile",
"path": "/database/basic/batching",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__database__basic__batching' */'D:/Work/BPA.SAAS.Web/src/pages/database/basic/batching'), loading: LoadingComponent}),
"access": "k7",
"exact": true
},
{
"name": "商品管理",
"icon": "smile",
"path": "/database",
"routes": [
{
"name": "商品类型",
"icon": "smile",
"path": "/database/goods/goodstypemanage",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__database__goods__goodstypemanage' */'D:/Work/BPA.SAAS.Web/src/pages/database/goods/goodstypemanage'), loading: LoadingComponent}),
"access": "k7",
"exact": true
},
{
"name": "商品多属性",
"icon": "smile",
"path": "/database/goods/goodsattribute",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__database__goods__goodsattribute' */'D:/Work/BPA.SAAS.Web/src/pages/database/goods/goodsattribute'), loading: LoadingComponent}),
"access": "k7",
"exact": true
},
{
"name": "商品基础信息",
"icon": "smile",
"path": "/database/goods/newgoods",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__database__goods__newgoods' */'D:/Work/BPA.SAAS.Web/src/pages/database/goods/newgoods'), loading: LoadingComponent}),
"access": "k7",
"exact": true
},
{
"name": "添加商品基础信息",
"icon": "smile",
"path": "/database/goods/goodsInfo",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__database__goods__goodsInfo' */'D:/Work/BPA.SAAS.Web/src/pages/database/goods/goodsInfo'), loading: LoadingComponent}),
"access": "k7",
"exact": true
}
]
}
]
},
{
"name": "设备管理",
"icon": "BankFilled",
"path": "/device",
"routes": [
{
"name": "产品管理",
"icon": "smile",
"path": "/device/product",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__device__product' */'D:/Work/BPA.SAAS.Web/src/pages/device/product'), loading: LoadingComponent}),
"access": "k12",
"exact": true
},
{
"name": "设备信息",
"icon": "smile",
"path": "/device/deviceInfo",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__device__deviceInfo' */'D:/Work/BPA.SAAS.Web/src/pages/device/deviceInfo'), loading: LoadingComponent}),
"access": "k14",
"exact": true
},
{
"name": "版本管理",
"icon": "smile",
"path": "/device/deviceVesion",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__device__deviceVesion' */'D:/Work/BPA.SAAS.Web/src/pages/device/deviceVesion'), loading: LoadingComponent}),
"access": "k14",
"exact": true
},
{
"name": "产品功能",
"icon": "smile",
"path": "/device/productmanage",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__device__productmanage' */'D:/Work/BPA.SAAS.Web/src/pages/device/productmanage'), loading: LoadingComponent}),
"access": "k14",
"exact": true
}
]
},
{
"name": "设备数据下发",
"icon": "BankFilled",
"path": "/push",
"routes": [
{
"name": "商品数据下发",
"icon": "smile",
"path": "/push/goodspush",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__push__goodspush' */'D:/Work/BPA.SAAS.Web/src/pages/push/goodspush'), loading: LoadingComponent}),
"access": "k12",
"exact": true
},
{
"name": "工艺数据下发",
"icon": "smile",
"path": "/push/technologypush",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__push__technologypush' */'D:/Work/BPA.SAAS.Web/src/pages/push/technologypush'), loading: LoadingComponent}),
"access": "k14",
"exact": true
},
{
"name": "物料数据下发",
"icon": "smile",
"path": "/push/batchingpush",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__push__batchingpush' */'D:/Work/BPA.SAAS.Web/src/pages/push/batchingpush'), loading: LoadingComponent}),
"access": "k14",
"exact": true
},
{
"name": "配方数据下发",
"icon": "smile",
"path": "/push/bompush",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__push__bompush' */'D:/Work/BPA.SAAS.Web/src/pages/push/bompush'), loading: LoadingComponent}),
"access": "k14",
"exact": true
}
]
},
{
"path": "/shop",
"icon": "SettingOutlined",
"name": "门店管理",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__shop' */'D:/Work/BPA.SAAS.Web/src/pages/shop'), loading: LoadingComponent}),
"exact": true
},
{
"name": "小程序管理",
"icon": "BankFilled",
"path": "/applet",
"routes": [
{
"name": "页面管理",
"icon": "smile",
"path": "/applet/paytemplate",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__applet__paytemplate' */'D:/Work/BPA.SAAS.Web/src/pages/applet/paytemplate'), loading: LoadingComponent}),
"exact": true
},
{
"name": "素材管理",
"icon": "smile",
"path": "/applet/basicconfiguration",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__applet__basicconfiguration' */'D:/Work/BPA.SAAS.Web/src/pages/applet/basicconfiguration'), loading: LoadingComponent}),
"exact": true
},
{
"name": "小程序基础配置",
"icon": "smile",
"path": "/applet/appidmanager",
"routes": [
{
"name": "支付配置",
"icon": "smile",
"path": "/applet/appidmanager/payment",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__applet__appidmanager__payment' */'D:/Work/BPA.SAAS.Web/src/pages/applet/appidmanager/payment'), loading: LoadingComponent}),
"exact": true
},
{
"name": "APPID",
"icon": "smile",
"path": "/applet/appidmanager/appid",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__applet__appidmanager__appid' */'D:/Work/BPA.SAAS.Web/src/pages/applet/appidmanager/appid'), loading: LoadingComponent}),
"exact": true
}
]
}
]
},
{
"name": "门店管理",
"icon": "BankFilled",
"path": "/shopmanage",
"routes": [
{
"name": "员工管理",
"icon": "smile",
"path": "/shopmanage/storeStaff",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__shopmanage__storeStaff' */'D:/Work/BPA.SAAS.Web/src/pages/shopmanage/storeStaff'), loading: LoadingComponent}),
"exact": true
},
{
"name": "打印机模板",
"icon": "smile",
"path": "/shopmanage/printerTemplate",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__shopmanage__printerTemplate' */'D:/Work/BPA.SAAS.Web/src/pages/shopmanage/printerTemplate'), loading: LoadingComponent}),
"exact": true
},
{
"name": "店铺小票打印机",
"icon": "smile",
"path": "/shopmanage/Printer",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__shopmanage__Printer' */'D:/Work/BPA.SAAS.Web/src/pages/shopmanage/Printer'), loading: LoadingComponent}),
"exact": true
},
{
"name": "店铺桌面码",
"icon": "smile",
"path": "/shopmanage/storeDesktopNumber",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__shopmanage__storeDesktopNumber' */'D:/Work/BPA.SAAS.Web/src/pages/shopmanage/storeDesktopNumber'), loading: LoadingComponent}),
"exact": true
},
{
"name": "店铺广告",
"icon": "smile",
"path": "/shopmanage/storeAdvertisement",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__shopmanage__storeAdvertisement' */'D:/Work/BPA.SAAS.Web/src/pages/shopmanage/storeAdvertisement'), loading: LoadingComponent}),
"exact": true
},
{
"name": "店铺菜谱",
"icon": "smile",
"path": "/shopmanage/storeGoodsInfo",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__shopmanage__storeGoodsInfo' */'D:/Work/BPA.SAAS.Web/src/pages/shopmanage/storeGoodsInfo'), loading: LoadingComponent}),
"exact": true
},
{
"name": "加购商品",
"icon": "smile",
"hideInMenu": true,
"path": "/shopmanage/storeAddGoodsInfo",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__shopmanage__storeAddGoodsInfo' */'D:/Work/BPA.SAAS.Web/src/pages/shopmanage/storeAddGoodsInfo'), loading: LoadingComponent}),
"exact": true
}
]
},
{
"name": "订单管理",
"icon": "BankFilled",
"path": "/order",
"routes": [
{
"name": "订单流水",
"icon": "smile",
"path": "/order/orderflow",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__order__orderflow' */'D:/Work/BPA.SAAS.Web/src/pages/order/orderflow'), loading: LoadingComponent}),
"exact": true
},
{
"name": "第三方订单",
"icon": "smile",
"path": "/order/thirdOrder",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__order__thirdOrder' */'D:/Work/BPA.SAAS.Web/src/pages/order/thirdOrder'), loading: LoadingComponent}),
"exact": true
},
{
"name": "授权管理",
"icon": "smile",
"path": "/order/thirdAuthorize",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__order__thirdAuthorize' */'D:/Work/BPA.SAAS.Web/src/pages/order/thirdAuthorize'), loading: LoadingComponent}),
"exact": true
}
]
},
{
"path": "/index.html",
"redirect": "/welcome",
"exact": true
},
{
"path": "/",
"redirect": "/welcome",
"exact": true
},
{
"path": "/welcome",
"name": "welcome",
"icon": "smile",
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__Welcome' */'D:/Work/BPA.SAAS.Web/src/pages/Welcome'), loading: LoadingComponent}),
"exact": true
},
{
"component": dynamic({ loader: () => import(/* webpackChunkName: 'p__404' */'D:/Work/BPA.SAAS.Web/src/pages/404'), loading: LoadingComponent}),
"exact": true
}
]
}
];

// allow user to extend routes
plugin.applyPlugins({
key: 'patchRoutes',
type: ApplyPluginsType.event,
args: { routes },
});

return routes;
}

+ 12
- 0
src/.umi-production/core/umiExports.ts View File

@@ -0,0 +1,12 @@
// @ts-nocheck
export { history } from './history';
export { plugin } from './plugin';
export * from '../plugin-access/access';
export * from '../plugin-initial-state/exports';
export * from '../plugin-locale/localeExports';
export * from '../plugin-locale/SelectLang';
export * from '../plugin-layout/layoutExports';
export * from '../plugin-model/useModel';
export * from '../plugin-request/request';
export * from '../plugin-helmet/exports';
export * from '../preset-ui/UmiUIFlag';

+ 40
- 0
src/.umi-production/plugin-access/AccessProvider.ts View File

@@ -0,0 +1,40 @@
// @ts-nocheck
import React, { useMemo } from 'react';
import { IRoute } from 'umi';
import { useModel } from '../core/umiExports';
import accessFactory from '../../access';
import AccessContext, { AccessInstance } from './context';
import { traverseModifyRoutes } from './runtimeUtil';

type Routes = IRoute[];

interface Props {
routes: Routes;
children: React.ReactNode;
}

const AccessProvider: React.FC<Props> = props => {
if (typeof useModel !== 'function') {
throw new Error('[plugin-access]: useModel is not a function, @umijs/plugin-initial-state is needed.')
}

const { children } = props;
const { initialState } = useModel('@@initialState');

const access: AccessInstance = useMemo(() => accessFactory(initialState as any), [initialState]);

if (process.env.NODE_ENV === 'development' && (access === undefined || access === null)) {
console.warn('[plugin-access]: the access instance created by access.ts(js) is nullish, maybe you need check it.');
}

return React.createElement(
AccessContext.Provider,
{ value: access },
React.cloneElement(children, {
...children.props,
routes:traverseModifyRoutes(props.routes, access)
}),
);
};

export default AccessProvider;

+ 33
- 0
src/.umi-production/plugin-access/access.tsx View File

@@ -0,0 +1,33 @@
// @ts-nocheck
import React, { useContext } from 'react';
import AccessContext, { AccessInstance as AccessInstanceType } from './context';
import { traverseModifyRoutes } from './runtimeUtil';

export { traverseModifyRoutes };

export type AccessInstance = AccessInstanceType;

export const useAccess = () => {
const access = useContext(AccessContext);

return access;
};

export interface AccessProps {
accessible: boolean;
fallback?: React.ReactNode;
}

export const Access: React.FC<AccessProps> = props => {
const { accessible, fallback, children } = props;

if (process.env.NODE_ENV === 'development' && typeof accessible === 'function') {
console.warn(
'[plugin-access]: provided "accessible" prop is a function named "' +
(accessible as Function).name +
'" instead of a boolean, maybe you need check it.',
);
}

return <>{accessible ? children : fallback}</>;
};

+ 9
- 0
src/.umi-production/plugin-access/context.ts View File

@@ -0,0 +1,9 @@
// @ts-nocheck
import React from 'react';
import accessFactory from '@/access';

export type AccessInstance = ReturnType<typeof accessFactory>;

const AccessContext = React.createContext<AccessInstance>(null!);

export default AccessContext;

+ 7
- 0
src/.umi-production/plugin-access/rootContainer.ts View File

@@ -0,0 +1,7 @@
// @ts-nocheck
import React from 'react';
import AccessProvider from './AccessProvider';

export function rootContainer(container: React.ReactNode, { routes }) {
return React.createElement(AccessProvider, { routes }, container);
}

+ 80
- 0
src/.umi-production/plugin-access/runtimeUtil.ts View File

@@ -0,0 +1,80 @@
// @ts-nocheck
import { IRoute } from 'umi';

type ChildrenList = IRoute[];

const oldChildrenPropsName = 'routes';
export function traverseModifyRoutes(childrenList: ChildrenList, access: any): ChildrenList {
const resultChildrenList: ChildrenList = []
.concat(childrenList as any)
.map((resultRoute: IRoute) => {
const childList = resultRoute.children || resultRoute[oldChildrenPropsName];
if (childList && childList?.length) {
return {
...resultRoute,
children: childList?.map((route: any) => ({ ...route })),
// return new route to routes.
[oldChildrenPropsName]: childList?.map((route: any) => ({ ...route })),
};
}
return resultRoute;
});
return resultChildrenList.map((currentRoute) => {
let currentRouteAccessible =
typeof currentRoute.unaccessible === 'boolean' ? !currentRoute.unaccessible : true;

// 判断路由是否有权限的具体代码
if (currentRoute && currentRoute.access) {
if (typeof currentRoute.access !== 'string') {
throw new Error(
'[plugin-access]: "access" field set in "' +
currentRoute.path +
'" route should be a string.',
);
}
const accessProp = access[currentRoute.access];
// 如果是方法需要执行以下
if (typeof accessProp === 'function') {
currentRouteAccessible = accessProp(currentRoute);
} else if (typeof accessProp === 'boolean') {
// 不是方法就直接 copy
currentRouteAccessible = accessProp;
}
currentRoute.unaccessible = !currentRouteAccessible;
}
const childList = currentRoute.children || currentRoute[oldChildrenPropsName];
// 筛选子路由
if (childList && Array.isArray(childList) && childList.length) {
if (!Array.isArray(childList)) {
return currentRoute;
}
// 父亲没权限,理论上每个孩子都没权限
// 可能有打平 的事情发生,所以都执行一下
childList.forEach((childRoute) => {
childRoute.unaccessible = !currentRouteAccessible;
});
const finallyChildList = traverseModifyRoutes(childList, access);
// 如果每个子节点都没有权限,那么自己也属于没有权限
const isAllChildChildrenUnaccessible =
Array.isArray(finallyChildList) && finallyChildList.every((route) => route.unaccessible);
if (!currentRoute.unaccessible && isAllChildChildrenUnaccessible) {
currentRoute.unaccessible = true;
}
if (finallyChildList && finallyChildList?.length > 0) {
return {
...currentRoute,
children: finallyChildList,
[oldChildrenPropsName]: finallyChildList,
};
}
delete currentRoute.routes;
delete currentRoute.children;
}
return currentRoute;
});
}

+ 51
- 0
src/.umi-production/plugin-antd-icon-config/app.ts View File

@@ -0,0 +1,51 @@
// @ts-nocheck
import React from 'react';
import allIcons from '@@/plugin-antd-icon/icons';

export interface MenuDataItem {
children?: MenuDataItem[];
routes?: MenuDataItem[];
hideChildrenInMenu?: boolean;
hideInMenu?: boolean;
icon?: string;
locale?: string;
name?: string;
key?: string;
path?: string;
[key: string]: any;
}
function toHump(name: string) {
return name.replace(/\-(\w)/g, function (all, letter) {
return letter.toUpperCase();
});
}

function formatter(data: MenuDataItem[]): MenuDataItem[] {
if (!Array.isArray(data)) {
return data;
}
(data || []).forEach((item = { path: '/' }) => {
if (item.icon) {
const { icon } = item;
const v4IconName = toHump(icon.replace(icon[0], icon[0].toUpperCase()));
const NewIcon = allIcons[icon] || allIcons[`${v4IconName}Outlined`];
if (NewIcon) {
try {
item.icon = React.createElement(NewIcon);
} catch (error) {
console.log(error);
}
}
}
if (item.routes || item.children) {
const children = formatter(item.routes || item.children);
// Reduce memory usage
item.children = children;
}
});
return data;
}

export function patchRoutes({ routes }) {
formatter(routes);
}

+ 14
- 0
src/.umi-production/plugin-antd-icon/icons.ts View File

@@ -0,0 +1,14 @@
// @ts-nocheck

import SettingOutlined from '@ant-design/icons/SettingOutlined';
import SmileOutlined from '@ant-design/icons/SmileOutlined';
import DropboxSquareFilled from '@ant-design/icons/DropboxSquareFilled';
import BankFilled from '@ant-design/icons/BankFilled'

export default {
SettingOutlined,
SmileOutlined,
DropboxSquareFilled,
BankFilled
}

+ 3
- 0
src/.umi-production/plugin-helmet/exports.ts View File

@@ -0,0 +1,3 @@
// @ts-nocheck
// @ts-ignore
export { Helmet } from 'D:/Work/BPA.SAAS.Web/node_modules/react-helmet';

+ 37
- 0
src/.umi-production/plugin-initial-state/Provider.tsx View File

@@ -0,0 +1,37 @@
// @ts-nocheck

import React, { useRef, useEffect } from "react";
import { plugin } from "../core/umiExports";
import { ApplyPluginsType } from 'umi';
import { useModel } from "../plugin-model/useModel";
if (typeof useModel !== "function") {
throw new Error(
"[plugin-initial-state]: useModel is not a function, @umijs/plugin-model is required."
);
}

interface Props {
children: React.ReactNode;
}
export default (props: Props) => {
const { children } = props;
const appLoaded = useRef(false);
// 获取用户的配置,暂时只支持 loading
const useRuntimeConfig =
plugin.applyPlugins({
key: "initialStateConfig",
type: ApplyPluginsType.modify,
initialValue: {},
}) || {};
const { loading = false } = useModel("@@initialState") || {};
useEffect(() => {
if (!loading) {
appLoaded.current = true;
}
}, [loading]);
// initial state loading 时,阻塞渲染
if (loading && !appLoaded.current) {
return useRuntimeConfig.loading || null;
}
return children;
};

+ 7
- 0
src/.umi-production/plugin-initial-state/exports.ts View File

@@ -0,0 +1,7 @@
// @ts-nocheck

// @ts-ignore
import { InitialState as InitialStateType } from '../plugin-initial-state\models\initialState';

export type InitialState = InitialStateType;
export const __PLUGIN_INITIAL_STATE = 1;

+ 63
- 0
src/.umi-production/plugin-initial-state/models/initialState.ts View File

@@ -0,0 +1,63 @@
// @ts-nocheck
// @ts-nocheck
import { useState, useEffect, useCallback } from 'react';
import { Models } from '../../plugin-model/useModel';
import * as app from '../../../app';

const sleep = (delay: number) => new Promise((resolve) => setTimeout(resolve, delay||0));

export type InitialState = Models<'@@initialState'>;

async function getInitialState() {
return await app.getInitialState();
}

type ThenArg<T> = T extends Promise<infer U> ? U : T;

const initState = {
initialState: undefined as ThenArg<ReturnType<typeof getInitialState>> | undefined,
loading: true,
error: undefined as Error | undefined,
};

type InitialStateType = ThenArg<ReturnType<typeof getInitialState>> | undefined;

type InitialStateTypeFn = (
initialState: InitialStateType,
) => ThenArg<ReturnType<typeof getInitialState>> | undefined;

export default () => {
const [state, setState] = useState(initState);

const refresh = useCallback(async () => {
setState((s) => ({ ...s, loading: true, error: undefined }));
try {
const asyncFunc = () => new Promise<InitialStateType>((res) => res(getInitialState()));
const ret = await asyncFunc();
setState((s) => ({ ...s, initialState: ret, loading: false }));
} catch (e) {
setState((s) => ({ ...s, error: e, loading: false }));
}
await sleep(10)
}, []);

const setInitialState = useCallback(async (initialState: InitialStateType | InitialStateTypeFn) => {
setState((s) => {
if (typeof initialState === 'function') {
return { ...s, initialState: initialState(s.initialState), loading: false };
}
return { ...s, initialState, loading: false };
});
await sleep(10)
}, []);

useEffect(() => {
refresh();
}, []);

return {
...state,
refresh,
setInitialState,
};
};

+ 13
- 0
src/.umi-production/plugin-initial-state/runtime.tsx View File

@@ -0,0 +1,13 @@
// @ts-nocheck
import React from 'react';
import Provider from './Provider';

export function rootContainer(container: React.ReactNode) {
return React.createElement(
// 这里的 plugin-initial-state 不能从 constant 里取,里面有 path 依赖
// 但 webpack-5 没有 node 补丁(包括 path)
Provider,
null,
container,
);
}

+ 53
- 0
src/.umi-production/plugin-layout/Layout.tsx View File

@@ -0,0 +1,53 @@
// @ts-nocheck
import React, { useState, useEffect } from "react";
import { ApplyPluginsType, useModel , useIntl, traverseModifyRoutes, useAccess } from "umi";
import { plugin } from "../core/umiExports";
import LayoutComponent from './layout/layout/index.tsx';

export default props => {
const [runtimeConfig, setRuntimeConfig] = useState(null);

const initialInfo = (useModel && useModel("@@initialState")) || {
initialState: undefined,
loading: false,
setInitialState: null
}; // plugin-initial-state 未开启

const access = useAccess?.();

useEffect(() => {
const useRuntimeConfig =
plugin.applyPlugins({
key: "layout",
type: ApplyPluginsType.modify,
initialValue: {
...initialInfo,
traverseModifyRoutes: (menuData) => {return traverseModifyRoutes?.(menuData, access);},
},
}) || {};
if (useRuntimeConfig instanceof Promise) {
useRuntimeConfig.then((config) => {
setRuntimeConfig(config);
});
return;
}
setRuntimeConfig(useRuntimeConfig);
}, [initialInfo?.initialState, access]);

const userConfig = {
...{'name':'ant-design-pro','theme':'PRO','locale':false,'showBreadcrumb':true,'siderWidth':208,'navTheme':'dark','primaryColor':'#FA541C','layout':'side','contentWidth':'Fluid','fixedHeader':false,'fixSiderbar':true,'colorWeak':false,'title':'黑菠萝智慧门店','pwa':false,'logo':'/logo.svg','iconfontUrl':''},
...runtimeConfig || {}
};

const { formatMessage } = useIntl();

if(!runtimeConfig){
return null
}

return React.createElement(LayoutComponent, {
userConfig,
formatMessage,
...props
});
};

+ 12
- 0
src/.umi-production/plugin-layout/icons.ts View File

@@ -0,0 +1,12 @@
// @ts-nocheck

import SettingOutlined from '@ant-design/icons/es/icons/SettingOutlined';
import SmileOutlined from '@ant-design/icons/es/icons/SmileOutlined';
import DropboxSquareFilled from '@ant-design/icons/es/icons/DropboxSquareFilled';
import BankFilled from '@ant-design/icons/es/icons/BankFilled'
export default {
SettingOutlined,
SmileOutlined,
DropboxSquareFilled,
BankFilled
}

+ 56
- 0
src/.umi-production/plugin-layout/layout/component/Exception/index.tsx View File

@@ -0,0 +1,56 @@
import React from 'react';
import { Result, Button } from 'antd';
import { history } from 'umi';
import { IRouteLayoutConfig } from '../../types/interface.d';

function backToHome() {
history.push('/');
}

const Exception404 = () => (
<Result
status="404"
title="404"
subTitle="抱歉,你访问的页面不存在"
extra={
<Button type="primary" onClick={backToHome}>
返回首页
</Button>
}
/>
);

const Exception403 = () => (
<Result
status="403"
title="403"
subTitle="抱歉,你无权访问该页面"
extra={
<Button type="primary" onClick={backToHome}>
返回首页
</Button>
}
/>
);

const WithExceptionOpChildren: React.FC<{
currentPathConfig?: IRouteLayoutConfig;
children: any;
noFound: React.ReactNode;
unAccessible: React.ReactNode;
}> = (props) => {
const { children, currentPathConfig } = props;
// 404 现在应该很少会发生
if (!currentPathConfig) {
return props.noFound || <Exception404 />;
}
/**
* 这里是没有权限的意思
*/
if (currentPathConfig.unAccessible || currentPathConfig.unaccessible) {
return props.unAccessible || <Exception403 />;
}
return children;
};

export { Exception404, Exception403, WithExceptionOpChildren };

+ 91
- 0
src/.umi-production/plugin-layout/layout/component/logo.tsx View File

@@ -0,0 +1,91 @@
import React from 'react';

const LogoIcon: React.FC = () => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 200 200"
>
<defs>
<linearGradient
id="linearGradient-1"
x1="62.102%"
x2="108.197%"
y1="0%"
y2="37.864%"
>
<stop offset="0%" stopColor="#4285EB"></stop>
<stop offset="100%" stopColor="#2EC7FF"></stop>
</linearGradient>
<linearGradient
id="linearGradient-2"
x1="69.644%"
x2="54.043%"
y1="0%"
y2="108.457%"
>
<stop offset="0%" stopColor="#29CDFF"></stop>
<stop offset="37.86%" stopColor="#148EFF"></stop>
<stop offset="100%" stopColor="#0A60FF"></stop>
</linearGradient>
<linearGradient
id="linearGradient-3"
x1="69.691%"
x2="16.723%"
y1="-12.974%"
y2="117.391%"
>
<stop offset="0%" stopColor="#FA816E"></stop>
<stop offset="41.473%" stopColor="#F74A5C"></stop>
<stop offset="100%" stopColor="#F51D2C"></stop>
</linearGradient>
<linearGradient
id="linearGradient-4"
x1="68.128%"
x2="30.44%"
y1="-35.691%"
y2="114.943%"
>
<stop offset="0%" stopColor="#FA8E7D"></stop>
<stop offset="51.264%" stopColor="#F74A5C"></stop>
<stop offset="100%" stopColor="#F51D2C"></stop>
</linearGradient>
</defs>
<g fill="none" fillRule="evenodd" stroke="none" strokeWidth="1">
<g transform="translate(-20 -20)">
<g transform="translate(20 20)">
<g>
<g fillRule="nonzero">
<g>
<path
fill="url(#linearGradient-1)"
d="M91.588 4.177L4.18 91.513a11.981 11.981 0 000 16.974l87.408 87.336a12.005 12.005 0 0016.989 0l36.648-36.618c4.209-4.205 4.209-11.023 0-15.228-4.208-4.205-11.031-4.205-15.24 0l-27.783 27.76c-1.17 1.169-2.945 1.169-4.114 0l-69.802-69.744c-1.17-1.169-1.17-2.942 0-4.11l69.802-69.745c1.17-1.169 2.944-1.169 4.114 0l27.783 27.76c4.209 4.205 11.032 4.205 15.24 0 4.209-4.205 4.209-11.022 0-15.227L108.581 4.056c-4.719-4.594-12.312-4.557-16.993.12z"
></path>
<path
fill="url(#linearGradient-2)"
d="M91.588 4.177L4.18 91.513a11.981 11.981 0 000 16.974l87.408 87.336a12.005 12.005 0 0016.989 0l36.648-36.618c4.209-4.205 4.209-11.023 0-15.228-4.208-4.205-11.031-4.205-15.24 0l-27.783 27.76c-1.17 1.169-2.945 1.169-4.114 0l-69.802-69.744c-1.17-1.169-1.17-2.942 0-4.11l69.802-69.745c2.912-2.51 7.664-7.596 14.642-8.786 5.186-.883 10.855 1.062 17.009 5.837L108.58 4.056c-4.719-4.594-12.312-4.557-16.993.12z"
></path>
</g>
<path
fill="url(#linearGradient-3)"
d="M153.686 135.855c4.208 4.205 11.031 4.205 15.24 0l27.034-27.012c4.7-4.696 4.7-12.28 0-16.974l-27.27-27.15c-4.218-4.2-11.043-4.195-15.254.013-4.209 4.205-4.209 11.022 0 15.227l18.418 18.403c1.17 1.169 1.17 2.943 0 4.111l-18.168 18.154c-4.209 4.205-4.209 11.023 0 15.228z"
></path>
</g>
<ellipse
cx="100.519"
cy="100.437"
fill="url(#linearGradient-4)"
rx="23.6"
ry="23.581"
></ellipse>
</g>
</g>
</g>
</g>
</svg>
);
};

export default LogoIcon;

+ 7
- 0
src/.umi-production/plugin-layout/layout/layout/blankLayout.tsx View File

@@ -0,0 +1,7 @@
export default ({ children }: { children: any }) => {
console.error(
'@umijs/plugin-layout 需要安装 @ant-design/pro-layout 才可运行',
);
console.error('https://prolayout.ant.design/');
return children;
};

+ 37
- 0
src/.umi-production/plugin-layout/layout/layout/getLayoutRenderConfig.ts View File

@@ -0,0 +1,37 @@
const getLayoutRenderConfig = (currentPathConfig: {
layout:
| {
hideMenu: boolean;
hideNav: boolean;
hideFooter: boolean;
}
| false;
hideFooter: boolean;
}) => {
const layoutRender: any = {};

if (currentPathConfig?.hideFooter) {
layoutRender.footerRender = false;
}

if (currentPathConfig?.layout == false) {
layoutRender.pure = true;
return layoutRender;
}

if (currentPathConfig?.layout?.hideMenu) {
layoutRender.menuRender = false;
}

if (currentPathConfig?.layout?.hideFooter) {
layoutRender.footerRender = false;
}

if (currentPathConfig?.layout?.hideNav) {
layoutRender.headerRender = false;
}

return layoutRender;
};

export default getLayoutRenderConfig;

+ 135
- 0
src/.umi-production/plugin-layout/layout/layout/index.tsx View File

@@ -0,0 +1,135 @@
import React, { useState,useMemo } from 'react';
// @ts-ignore
import { Link, useModel, history, traverseModifyRoutes, useAccess } from 'umi';
import ProLayout, {
BasicLayoutProps,
} from "@ant-design/pro-layout";
import './style.less';
// @ts-ignore
import renderRightContent from '@@/plugin-layout/renderRightContent';
import { WithExceptionOpChildren } from '../component/Exception';
import { getMatchMenu, MenuDataItem, transformRoute } from '@umijs/route-utils';
// @ts-ignore
import logo from '../component/logo';
import getLayoutRenderConfig from './getLayoutRenderConfig';

const BasicLayout = (props: any) => {
const { children, userConfig = {}, location, route, ...restProps } = props;
const initialInfo = (useModel && useModel('@@initialState')) || {
initialState: undefined,
loading: false,
setInitialState: null,
};

// plugin-initial-state 未开启
const { initialState, loading, setInitialState } = initialInfo;

const currentPathConfig = useMemo(() => {
const { menuData } = transformRoute(
props?.route?.routes || [],
undefined,
undefined,
true,
);
// 动态路由匹配
const currentPathConfig = getMatchMenu(location.pathname, menuData).pop();
return currentPathConfig || {};
},[location?.pathname, props?.route?.routes]);

// layout 是否渲染相关
const layoutRestProps: BasicLayoutProps & {
rightContentRender?:
| false
| ((
props: BasicLayoutProps,
dom: React.ReactNode,
config: any,
) => React.ReactNode);
} = {
itemRender: (route) => <Link to={route.path}>{route.breadcrumbName}</Link>,
...userConfig,
...restProps,
...getLayoutRenderConfig(currentPathConfig as any ||{}),
};

const access = useAccess?.();

return (
<ProLayout
route={route}
location={location}
title={userConfig?.name || userConfig?.title}
navTheme="dark"
siderWidth={256}
onMenuHeaderClick={(e) => {
e.stopPropagation();
e.preventDefault();
history.push('/');
}}
menu={ { locale: userConfig.locale } }
// 支持了一个 patchMenus,其实应该用 menuDataRender
menuDataRender={
userConfig.patchMenus
? (menuData) => userConfig?.patchMenus(menuData, initialInfo)
: undefined
}
formatMessage={userConfig?.formatMessage}
logo={logo}
menuItemRender={(menuItemProps, defaultDom) => {
if (menuItemProps.isUrl) {
return defaultDom;
}
if (menuItemProps.path && location.pathname !== menuItemProps.path) {
return (
<Link to={menuItemProps.path} target={menuItemProps.target}>
{defaultDom}
</Link>
);
}
return defaultDom;
}}
disableContentMargin
fixSiderbar
fixedHeader
postMenuData={
traverseModifyRoutes
? (menuData) => traverseModifyRoutes?.(menuData, access)
: undefined
}
{...layoutRestProps}
rightContentRender={
// === false 应该关闭这个功能
layoutRestProps?.rightContentRender !== false &&
((layoutProps) => {
const dom = renderRightContent?.(
userConfig,
loading,
initialState,
setInitialState,
);
if (layoutRestProps.rightContentRender) {
return layoutRestProps.rightContentRender(layoutProps, dom, {
userConfig,
loading,
initialState,
setInitialState,
});
}
return dom;
})
}
>
<WithExceptionOpChildren
noFound={userConfig?.noFound}
unAccessible={userConfig?.unAccessible}
currentPathConfig={currentPathConfig}
>
{userConfig.childrenRender
? userConfig.childrenRender(children, props)
: children}
</WithExceptionOpChildren>
</ProLayout>
);
};

export default BasicLayout;

+ 59
- 0
src/.umi-production/plugin-layout/layout/layout/style.less View File

@@ -0,0 +1,59 @@
@import '~antd/es/style/themes/default.less';

@pro-header-hover-bg: rgba(0, 0, 0, 0.025);

@media screen and (max-width: @screen-xs) {
// 在小屏幕的时候可以有更好的体验
.umi-plugin-layout-container {
width: 100% !important;
}
.umi-plugin-layout-container > * {
border-radius: 0 !important;
}
}

.umi-plugin-layout-menu {
:global(.anticon) {
margin-right: 8px;
}
:global(.ant-dropdown-menu-item) {
min-width: 160px;
}
}

.umi-plugin-layout-right {
display: flex;
float: right;
height: 100%;
margin-left: auto;
overflow: hidden;
.umi-plugin-layout-action {
display: flex;
align-items: center;
height: 100%;
padding: 0 12px;
cursor: pointer;
transition: all 0.3s;
> i {
color: @text-color;
vertical-align: middle;
}
&:hover {
background: @pro-header-hover-bg;
}
&:global(.opened) {
background: @pro-header-hover-bg;
}
}

.umi-plugin-layout-search {
padding: 0 12px;
&:hover {
background: transparent;
}
}
}

.umi-plugin-layout-name {
margin-left: 8px;
}

+ 13
- 0
src/.umi-production/plugin-layout/layout/layoutExports.ts View File

@@ -0,0 +1,13 @@
import { BasicLayoutProps } from '@ant-design/pro-layout';
import { Models } from '@@/plugin-model/useModel';

export type RunTimeLayoutConfig = (
initData: Models<'@@initialState'>,
) => BasicLayoutProps & {
childrenRender?: (dom: JSX.Element, props: BasicLayoutProps) => React.ReactNode,
unAccessible?: JSX.Element,
noFound?: JSX.Element,
};

// avoid `export *` error
export default {};

+ 3
- 0
src/.umi-production/plugin-layout/layout/types/index.d.ts View File

@@ -0,0 +1,3 @@
declare module '*.less';

export * from './interface';

+ 89
- 0
src/.umi-production/plugin-layout/layout/types/interface.d.ts View File

@@ -0,0 +1,89 @@
import { IRoute } from 'umi';

interface Error {
componentStack?: string;
error?: string;
[key: string]: any;
}

/**
* 插件编译时配置
*/
export interface LayoutConfig {
name?: string;
logo?: string;
theme?: string;
locale?: any; // same with locale plugin
showBreadcrumb?: boolean; // TODO 面包屑功能暂不支持
layoutComponent?: Record<string, string>; // 自定义主题
}

/**
* 插件运行时配置
*/
export interface ILayoutRuntimeConfig {
/** 导航用户退出的逻辑 默认不做处理 */
logout?: (initialState: any) => void;

// TODO IMPORT initinfo type from init plugin
/** 自定义导航头右上角 ,有默认 UI, 接受 initialState & 修改 initialState 的方法 */
rightRender?: (
initialState: any,
setInitialState: any,
runtimeLayout: ILayoutRuntimeConfig,
) => React.ReactNode;

errorBoundary?: {
/** 发生错误后的回调(可做一些错误日志上报,打点等) */
onError?: (error: Error, info: any) => void;
/** 发生错误后展示的组件,接受 error */
ErrorComponent?: (error: Error) => React.ReactElement<any>;
};
}

export interface IRouteMenuConfig {
/** 当前菜单名 */
name: string;
/** antd 的 icon name 和 url */
icon?: string;
/** 在菜单中隐藏他的子项 */
hideChildren?: boolean;
/** 默认为false 在菜单中只隐藏此项,子项往上提,仍旧展示 */
flatMenu?: boolean;
[key: string]: any;
}

export interface IRouteLayoutConfig {
/** 默认 false */
hideMenu?: boolean;
/** 默认 false */
hideNav?: boolean;
/** 默认 false */
hideFooter?: boolean;
[key: string]: any;
}

/**
* 路由配置
*/
export interface IBestAFSRoute extends IRoute {
/** 权限:https://yuque.antfin-inc.com/bigfish/best_afs/nxuhgb */
access?: string;

/** 当前页面的面包屑是否隐藏 */
showBreadcrumb?: boolean;

/** 默认为 false,在菜单中隐藏此项包括子项 */
menu?: false | IRouteMenuConfig;

/** 默认为 true ,是否显示 Layout */
layout?: boolean | IRouteLayoutConfig;
}

export interface TechMenuItem {
title: string | React.ReactNode;
icon: string;
link: string | React.ReactNode;
children?: TechMenuItem[];
externalLink: boolean;
}

+ 38
- 0
src/.umi-production/plugin-layout/layout/utils/copySrcFiles.ts View File

@@ -0,0 +1,38 @@
import { utils } from 'umi';
import { join } from 'path';
import { readFileSync, copyFileSync, statSync, writeFileSync } from 'fs';

export default ({
cwd,
absTmpPath,
config,
}: {
cwd: string;
absTmpPath: string;
config: object;
}) => {
const files = utils.glob.sync('**/*', {
cwd,
});
const base = join(absTmpPath, 'plugin-layout', 'layout');
utils.mkdirp.sync(base);
files.forEach(async (file) => {
if (['index.ts', 'runtime.tsx.tpl'].includes(file)) return;
const source = join(cwd, file);
const target = join(base, file);
if (statSync(source).isDirectory()) {
utils.mkdirp.sync(target);
} else {
if (target.endsWith('.tpl')) {
const sourceContent = readFileSync(source, 'utf-8');
await writeFileSync(
target.replace(/\.tpl$/, ''),
utils.Mustache.render(sourceContent, config),
'utf-8',
);
} else {
await copyFileSync(source, target);
}
}
});
};

+ 152
- 0
src/.umi-production/plugin-layout/layout/utils/getLayoutContent.tsx View File

@@ -0,0 +1,152 @@
import { LayoutConfig } from '../types/interface.d';

export default (
userConfig: LayoutConfig,
path: string,
formatMessage: boolean,
hasAccess: boolean,
) => `import React, { useState, useEffect } from "react";
import { ApplyPluginsType, useModel ${
// 没有 formatMessage 就不打开国际化
formatMessage ? `, useIntl` : ''
}${hasAccess ? ', traverseModifyRoutes, useAccess' : ''} } from "umi";
import { plugin } from "../core/umiExports";
import LayoutComponent from '${path}';

export default props => {
const [runtimeConfig, setRuntimeConfig] = useState(null);

const initialInfo = (useModel && useModel("@@initialState")) || {
initialState: undefined,
loading: false,
setInitialState: null
}; // plugin-initial-state 未开启

${hasAccess ? 'const access = useAccess?.();' : ''}

useEffect(() => {
const useRuntimeConfig =
plugin.applyPlugins({
key: "layout",
type: ApplyPluginsType.modify,
initialValue: {
...initialInfo,
${
hasAccess
? 'traverseModifyRoutes: (menuData) => {return traverseModifyRoutes?.(menuData, access);},'
: ''
}
},
}) || {};
if (useRuntimeConfig instanceof Promise) {
useRuntimeConfig.then((config) => {
setRuntimeConfig(config);
});
return;
}
setRuntimeConfig(useRuntimeConfig);
}, [initialInfo?.initialState, ${hasAccess ? 'access' : ''}]);

const userConfig = {
...${JSON.stringify(userConfig).replace(/"/g, "'")},
...runtimeConfig || {}
};

${formatMessage ? 'const { formatMessage } = useIntl();' : ''}

if(!runtimeConfig){
return null
}

return React.createElement(LayoutComponent, {
userConfig,
${formatMessage ? 'formatMessage,' : ''}
...props
});
};
`;

const genRenderRightContent = (props: {
locale: boolean;
initialState: boolean;
}) => {
if (!props.initialState) {
return `export default function renderRightContent() {
return null;
}
`;
}
return `import React from 'react';
import { Avatar, Dropdown, Menu, Spin } from 'antd';
${props.locale ? "import { SelectLang } from 'umi';" : ''}
import { LogoutOutlined } from '@ant-design/icons';
import { ILayoutRuntimeConfig } from '../types/interface.d';

export default function renderRightContent(
runtimeLayout: ILayoutRuntimeConfig,
loading: boolean,
initialState: any,
setInitialState: any,
) {
if (runtimeLayout.rightRender) {
return runtimeLayout.rightRender(
initialState,
setInitialState,
runtimeLayout,
);
}

const menu = (
<Menu className="umi-plugin-layout-menu">
<Menu.Item
key="logout"
onClick={() =>
runtimeLayout.logout && runtimeLayout?.logout(initialState)
}
>
<LogoutOutlined />
退出登录
</Menu.Item>
</Menu>
);

const avatar = (
<span className="umi-plugin-layout-action">
<Avatar
size="small"
className="umi-plugin-layout-avatar"
src={
initialState?.avatar ||
'https://gw.alipayobjects.com/zos/antfincdn/XAosXuNZyF/BiazfanxmamNRoxxVxka.png'
}
alt="avatar"
/>
<span className="umi-plugin-layout-name">{initialState?.name}</span>
</span>
);

if (loading) {
return (
<div className="umi-plugin-layout-right">
<Spin size="small" style={{ marginLeft: 8, marginRight: 8 }} />
</div>
);
}

return (
<div className="umi-plugin-layout-right anticon">
{runtimeLayout.logout ? (
<Dropdown overlay={menu} overlayClassName="umi-plugin-layout-container">
{avatar}
</Dropdown>
) : (
avatar
)}
${props.locale ? '{SelectLang && <SelectLang />}' : ''}
</div>
);
}
`;
};

export { genRenderRightContent };

+ 14
- 0
src/.umi-production/plugin-layout/layoutExports.ts View File

@@ -0,0 +1,14 @@
// @ts-nocheck
import { BasicLayoutProps } from '@ant-design/pro-layout';
import { Models } from '@@/plugin-model/useModel';

export type RunTimeLayoutConfig = (
initData: Models<'@@initialState'>,
) => BasicLayoutProps & {
childrenRender?: (dom: JSX.Element, props: BasicLayoutProps) => React.ReactNode,
unAccessible?: JSX.Element,
noFound?: JSX.Element,
};

// avoid `export *` error
export default {};

+ 72
- 0
src/.umi-production/plugin-layout/renderRightContent.tsx View File

@@ -0,0 +1,72 @@
// @ts-nocheck
import React from 'react';
import { Avatar, Dropdown, Menu, Spin } from 'antd';
import { SelectLang } from 'umi';
import { LogoutOutlined } from '@ant-design/icons';
import { ILayoutRuntimeConfig } from '../types/interface.d';

export default function renderRightContent(
runtimeLayout: ILayoutRuntimeConfig,
loading: boolean,
initialState: any,
setInitialState: any,
) {
if (runtimeLayout.rightRender) {
return runtimeLayout.rightRender(
initialState,
setInitialState,
runtimeLayout,
);
}

const menu = (
<Menu className="umi-plugin-layout-menu">
<Menu.Item
key="logout"
onClick={() =>
runtimeLayout.logout && runtimeLayout?.logout(initialState)
}
>
<LogoutOutlined />
退出登录
</Menu.Item>
</Menu>
);

const avatar = (
<span className="umi-plugin-layout-action">
<Avatar
size="small"
className="umi-plugin-layout-avatar"
src={
initialState?.avatar ||
'https://gw.alipayobjects.com/zos/antfincdn/XAosXuNZyF/BiazfanxmamNRoxxVxka.png'
}
alt="avatar"
/>
<span className="umi-plugin-layout-name">{initialState?.name}</span>
</span>
);

if (loading) {
return (
<div className="umi-plugin-layout-right">
<Spin size="small" style={{ marginLeft: 8, marginRight: 8 }} />
</div>
);
}

return (
<div className="umi-plugin-layout-right anticon">
{runtimeLayout.logout ? (
<Dropdown overlay={menu} overlayClassName="umi-plugin-layout-container">
{avatar}
</Dropdown>
) : (
avatar
)}
{SelectLang && <SelectLang />}
</div>
);
}

+ 56
- 0
src/.umi-production/plugin-layout/runtime.tsx View File

@@ -0,0 +1,56 @@
// @ts-nocheck
import React from 'react';
// @ts-ignore
import allIcons from './icons';

export interface MenuDataItem {
children?: MenuDataItem[];
routes?: MenuDataItem[];
hideChildrenInMenu?: boolean;
hideInMenu?: boolean;
icon?: string;
locale?: string;
name?: string;
key?: string;
path?: string;
[key: string]: any;
}
function toHump(name: string) {
return name.replace(/\-(\w)/g, function(all, letter) {
return letter.toUpperCase();
});
}

function formatter(data: MenuDataItem[]): MenuDataItem[] {
if (!Array.isArray(data)) {
return data;
}
(data || []).forEach((item = { path: '/' }) => {
// 兼容旧的写法 menu:{icon:""}
const icon = item.icon ? item.icon : item.menu ? item.menu.icon : '';
if (icon && typeof icon === "string") {
const v4IconName = toHump(icon.replace(icon[0], icon[0].toUpperCase()));
const NewIcon = allIcons[icon] || allIcons[`${v4IconName}Outlined`];
if (NewIcon) {
try {
if (item.icon)
item.icon = React.createElement(NewIcon);
if (item.menu)
item.menu.icon = React.createElement(NewIcon);
} catch (error) {
console.log(error);
}
}
}
if (item.routes || item.children) {
const children = formatter(item.routes || item.children);
// Reduce memory usage
item.children = children;
}
});
return data;
}

export function patchRoutes({ routes }) {
formatter(routes);
}

+ 473
- 0
src/.umi-production/plugin-locale/SelectLang.tsx View File

@@ -0,0 +1,473 @@
// @ts-nocheck
import React,{ useState } from 'react';
import { Menu, Dropdown } from 'antd';
import { ClickParam } from 'antd/es/menu';
import { DropDownProps } from 'antd/es/dropdown';
import { getLocale, getAllLocales, setLocale } from './localeExports';

export interface HeaderDropdownProps extends DropDownProps {
overlayClassName?: string;
placement?:
| 'bottomLeft'
| 'bottomRight'
| 'topLeft'
| 'topCenter'
| 'topRight'
| 'bottomCenter';
}

const HeaderDropdown: React.FC<HeaderDropdownProps> = ({
overlayClassName: cls,
...restProps
}) => (
<Dropdown
overlayClassName={cls}
{...restProps}
/>
);

interface LocalData {
lang: string,
label?: string,
icon?: string,
title?: string,
}

interface SelectLangProps {
globalIconClassName?: string;
postLocalesData?: (locales: LocalData[]) => LocalData[];
onItemClick?: (params: ClickParam) => void;
className?: string;
reload?: boolean;
icon?: React.ReactNode;
}

const transformArrayToObject = (allLangUIConfig:LocalData[])=>{
return allLangUIConfig.reduce((obj, item) => {
if(!item.lang){
return obj;
}

return {
...obj,
[item.lang]: item,
};
}, {});
}

const defaultLangUConfigMap = {
'ar-EG': {
lang: 'ar-EG',
label: 'العربية',
icon: '🇪🇬',
title: 'لغة'
},
'az-AZ': {
lang: 'az-AZ',
label: 'Azərbaycan dili',
icon: '🇦🇿',
title: 'Dil'
},
'bg-BG': {
lang: 'bg-BG',
label: 'Български език',
icon: '🇧🇬',
title: 'език'
},
'bn-BD': {
lang: 'bn-BD',
label: 'বাংলা',
icon: '🇧🇩',
title: 'ভাষা'
},
'ca-ES': {
lang: 'ca-ES',
label: 'Catalá',
icon: '🇨🇦',
title: 'llengua'
},
'cs-CZ': {
lang: 'cs-CZ',
label: 'Čeština',
icon: '🇨🇿',
title: 'Jazyk'
},
'da-DK': {
lang: 'da-DK',
label: 'Dansk',
icon: '🇩🇰',
title: 'Sprog'
},
'de-DE': {
lang: 'de-DE',
label: 'Deutsch',
icon: '🇩🇪',
title: 'Sprache'
},
'el-GR': {
lang: 'el-GR',
label: 'Ελληνικά',
icon: '🇬🇷',
title: 'Γλώσσα'
},
'en-GB': {
lang: 'en-GB',
label: 'English',
icon: '🇬🇧',
title: 'Language'
},
'en-US': {
lang: 'en-US',
label: 'English',
icon: '🇺🇸',
title: 'Language'
},
'es-ES': {
lang: 'es-ES',
label: 'Español',
icon: '🇪🇸',
title: 'Idioma'
},
'et-EE': {
lang: 'et-EE',
label: 'Eesti',
icon: '🇪🇪',
title: 'Keel'
},
'fa-IR': {
lang: 'fa-IR',
label: 'فارسی',
icon: '🇮🇷',
title: 'زبان'
},
'fi-FI': {
lang: 'fi-FI',
label: 'Suomi',
icon: '🇫🇮',
title: 'Kieli'
},
'fr-BE': {
lang: 'fr-BE',
label: 'Français',
icon: '🇧🇪',
title: 'Langue'
},
'fr-FR': {
lang: 'fr-FR',
label: 'Français',
icon: '🇫🇷',
title: 'Langue'
},
'ga-IE': {
lang: 'ga-IE',
label: 'Gaeilge',
icon: '🇮🇪',
title: 'Teanga'
},
'he-IL': {
lang: 'he-IL',
label: 'עברית',
icon: '🇮🇱',
title: 'שפה'
},
'hi-IN': {
lang: 'hi-IN',
label: 'हिन्दी, हिंदी',
icon: '🇮🇳',
title: 'भाषा: हिन्दी'
},
'hr-HR': {
lang: 'hr-HR',
label: 'Hrvatski jezik',
icon: '🇭🇷',
title: 'Jezik'
},
'hu-HU': {
lang: 'hu-HU',
label: 'Magyar',
icon: '🇭🇺',
title: 'Nyelv'
},
'hy-AM': {
lang: 'hu-HU',
label: 'Հայերեն',
icon: '🇦🇲',
title: 'Լեզու'
},
'id-ID': {
lang: 'id-ID',
label: 'Bahasa Indonesia',
icon: '🇮🇩',
title: 'Bahasa'
},
'it-IT': {
lang: 'it-IT',
label: 'Italiano',
icon: '🇮🇹',
title: 'Linguaggio'
},
'is-IS': {
lang: 'is-IS',
label: 'Íslenska',
icon: '🇮🇸',
title: 'Tungumál'
},
'ja-JP': {
lang: 'ja-JP',
label: '日本語',
icon: '🇯🇵',
title: '言語'
},
'ku-IQ': {
lang: 'ku-IQ',
label: 'کوردی',
icon: '🇮🇶',
title: 'Ziman'
},
'kn-IN': {
lang: 'zh-TW',
label: 'ಕನ್ನಡ',
icon: '🇮🇳',
title: 'ಭಾಷೆ'
},
'ko-KR': {
lang: 'ko-KR',
label: '한국어',
icon: '🇰🇷',
title: '언어'
},
'lv-LV': {
lang: 'lv-LV',
label: 'Latviešu valoda',
icon: '🇱🇮',
title: 'Kalba'
},
'mk-MK': {
lang: 'mk-MK',
label: 'македонски јазик',
icon: '🇲🇰',
title: 'Јазик'
},
'mn-MN': {
lang: 'mn-MN',
label: 'Монгол хэл',
icon: '🇲🇳',
title: 'Хэл'
},
'ms-MY': {
lang: 'ms-MY',
label: 'بهاس ملايو‎',
icon: '🇲🇾',
title: 'Bahasa'
},
'nb-NO': {
lang: 'nb-NO',
label: 'Norsk',
icon: '🇳🇴',
title: 'Språk'
},
'ne-NP': {
lang: 'ne-NP',
label: 'नेपाली',
icon: '🇳🇵',
title: 'भाषा'
},
'nl-BE': {
lang: 'nl-BE',
label: 'Vlaams',
icon: '🇧🇪',
title: 'Taal'
},
'nl-NL': {
lang: 'nl-NL',
label: 'Vlaams',
icon: '🇳🇱',
title: 'Taal'
},
'pl-PL': {
lang: 'pl-PL',
label: 'Polski',
icon: '🇵🇱',
title: 'Język'
},
'pt-BR': {
lang: 'pt-BR',
label: 'Português',
icon: '🇧🇷',
title: 'Idiomas'
},
'pt-PT': {
lang: 'pt-PT',
label: 'Português',
icon: '🇵🇹',
title: 'Idiomas'
},
'ro-RO': {
lang: 'ro-RO',
label: 'Română',
icon: '🇷🇴',
title: 'Limba'
},
'ru-RU': {
lang: 'ru-RU',
label: 'Русский',
icon: '🇷🇺',
title: 'язык'
},
'sk-SK': {
lang: 'sk-SK',
label: 'Slovenčina',
icon: '🇸🇰',
title: 'Jazyk'
},
'sr-RS': {
lang: 'sr-RS',
label: 'српски језик',
icon: '🇸🇷',
title: 'Језик'
},
'sl-SI': {
lang: 'sl-SI',
label: 'Slovenščina',
icon: '🇸🇱',
title: 'Jezik'
},
'sv-SE': {
lang: 'sv-SE',
label: 'Svenska',
icon: '🇸🇪',
title: 'Språk'
},
'ta-IN': {
lang: 'ta-IN',
label: 'தமிழ்',
icon: '🇮🇳',
title: 'மொழி'
},
'th-TH': {
lang: 'th-TH',
label: 'ไทย',
icon: '🇹🇭',
title: 'ภาษา'
},
'tr-TR': {
lang: 'tr-TR',
label: 'Türkçe',
icon: '🇹🇷',
title: 'Dil'
},
'uk-UA': {
lang: 'uk-UA',
label: 'Українська',
icon: '🇺🇰',
title: 'Мова'
},
'vi-VN': {
lang: 'vi-VN',
label: 'Tiếng Việt',
icon: '🇻🇳',
title: 'Ngôn ngữ'
},
'zh-CN': {
lang: 'zh-CN',
label: '简体中文',
icon: '🇨🇳',
title: '语言'
},
'zh-TW': {
lang: 'zh-TW',
label: '繁體中文',
icon: '🇭🇰',
title: '語言'
}
};

export const SelectLang: React.FC<SelectLangProps> = (props) => {
const {
globalIconClassName,
postLocalesData,
onItemClick,
icon,
style,
reload,
...restProps
} = props;
const [selectedLang, setSelectedLang] = useState(() => getLocale());

const changeLang = ({ key }: ClickParam): void => {
setLocale(key, reload);
setSelectedLang(getLocale())
};


const defaultLangUConfig = getAllLocales().map(
(key) =>
defaultLangUConfigMap[key] || {
lang: key,
label: key,
icon: "🌐",
title: key,
}
);

const allLangUIConfig =
postLocalesData?.(defaultLangUConfig) || defaultLangUConfig;
const handleClick = onItemClick
? (params: ClickParam) => onItemClick(params)
: changeLang;

const menuItemStyle = { minWidth: "160px" };
const menuItemIconStyle = { marginRight: "8px" };
const langMenu = (
<Menu selectedKeys={[selectedLang]} onClick={handleClick}>
{allLangUIConfig.map((localeObj) => {
return (
<Menu.Item key={localeObj.lang || localeObj.key} style={menuItemStyle}>
<span role="img" aria-label={localeObj?.label || "en-US"} style={menuItemIconStyle}>
{localeObj?.icon || "🌐"}
</span>
{localeObj?.label || "en-US"}
</Menu.Item>
);
})}
</Menu>
);

const inlineStyle = {
cursor: "pointer",
padding: "12px",
display: "inline-flex",
alignItems: "center",
justifyContent: "center",
fontSize: 18,
verticalAlign: "middle",
...style,
};

return (
<HeaderDropdown overlay={langMenu} placement="bottomRight" {...restProps}>
<span className={globalIconClassName} style={inlineStyle}>
<i className="anticon" title={allLangUIConfig[selectedLang]?.title}>
{ icon ?
icon : (
<svg
viewBox="0 0 24 24"
focusable="false"
width="1em"
height="1em"
fill="currentColor"
aria-hidden="true"
>
<path d="M0 0h24v24H0z" fill="none" />
<path
d="M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z "
className="css-c4d79v"
/>
</svg>
)}
</i>
</span>
</HeaderDropdown>
);
return <></>
};

+ 60
- 0
src/.umi-production/plugin-locale/locale.tsx View File

@@ -0,0 +1,60 @@
// @ts-nocheck
import React from 'react';
import EventEmitter from 'events';
import { ConfigProvider } from 'antd';

import moment from 'moment';
import 'moment/locale/zh-cn';
import 'moment/locale/zh-tw';
import { RawIntlProvider, getLocale, getDirection , setIntl, getIntl, localeInfo } from './localeExports';


// @ts-ignore
export const event = new EventEmitter();
event.setMaxListeners(5);
export const LANG_CHANGE_EVENT = Symbol('LANG_CHANGE');

export function _onCreate() {
const locale = getLocale();
if (moment?.locale) {
moment.locale(localeInfo[locale]?.momentLocale || '');
}
setIntl(locale);
}

const useIsomorphicLayoutEffect =
typeof window !== 'undefined' &&
typeof window.document !== 'undefined' &&
typeof window.document.createElement !== 'undefined'
? React.useLayoutEffect
: React.useEffect

export const _LocaleContainer = (props:any) => {
const [locale, setLocale] = React.useState(() => getLocale());
const [intl, setContainerIntl] = React.useState(() => getIntl(locale, true));

const handleLangChange = (locale:string) => {
if (moment?.locale) {
moment.locale(localeInfo[locale]?.momentLocale || 'en');
}
setLocale(locale);
setContainerIntl(getIntl(locale));
};

useIsomorphicLayoutEffect(() => {
event.on(LANG_CHANGE_EVENT, handleLangChange);
return () => {
event.off(LANG_CHANGE_EVENT, handleLangChange);
};
}, []);

const defaultAntdLocale = {
}
const direction = getDirection();

return (
<ConfigProvider direction={direction} locale={localeInfo[locale]?.antd || defaultAntdLocale}>
<RawIntlProvider value={intl}>{props.children}</RawIntlProvider>
</ConfigProvider>
)
};

+ 277
- 0
src/.umi-production/plugin-locale/localeExports.ts View File

@@ -0,0 +1,277 @@
// @ts-nocheck
import {
createIntl,
IntlShape,
MessageDescriptor,
} from 'D:/Work/BPA.SAAS.Web/node_modules/react-intl';
import { ApplyPluginsType } from 'umi';
import { event, LANG_CHANGE_EVENT } from './locale';
// @ts-ignore
import warning from 'D:/Work/BPA.SAAS.Web/node_modules/@umijs/plugin-locale/node_modules/warning/warning.js';

import { plugin } from '../core/plugin';

export {
createIntl,
};
export {
FormattedDate,
FormattedDateParts,
FormattedDisplayName,
FormattedHTMLMessage,
FormattedList,
FormattedMessage,
FormattedNumber,
FormattedNumberParts,
FormattedPlural,
FormattedRelativeTime,
FormattedTime,
FormattedTimeParts,
IntlContext,
IntlProvider,
RawIntlProvider,
createIntlCache,
defineMessages,
injectIntl,
useIntl,
} from 'D:/Work/BPA.SAAS.Web/node_modules/react-intl';

let g_intl: IntlShape;

const useLocalStorage = true;

import enUS0 from 'antd/es/locale/en_US';
import lang_enUS0 from "D:/Work/BPA.SAAS.Web/src/locales/en-US.js";
import zhCN0 from 'antd/es/locale/zh_CN';
import lang_zhCN0 from "D:/Work/BPA.SAAS.Web/src/locales/zh-CN.js";
import zhTW0 from 'antd/es/locale/zh_TW';
import lang_zhTW0 from "D:/Work/BPA.SAAS.Web/src/locales/zh-TW.js";

export const localeInfo: {[key: string]: any} = {
'en-US': {
messages: {
...lang_enUS0,
},
locale: 'en-US',
antd: {
...enUS0,
},
momentLocale: '',
},
'zh-CN': {
messages: {
...lang_zhCN0,
},
locale: 'zh-CN',
antd: {
...zhCN0,
},
momentLocale: 'zh-cn',
},
'zh-TW': {
messages: {
...lang_zhTW0,
},
locale: 'zh-TW',
antd: {
...zhTW0,
},
momentLocale: 'zh-tw',
},
};

/**
* 增加一个新的国际化语言
* @param name 语言的 key
* @param messages 对应的枚举对象
* @param extraLocale momentLocale, antd 国际化
*/
export const addLocale = (
name: string,
messages: Object,
extraLocales: {
momentLocale:string;
antd:string
},
) => {
if (!name) {
return;
}
// 可以合并
const mergeMessages = localeInfo[name]?.messages
? Object.assign({}, localeInfo[name].messages, messages)
: messages;


const { momentLocale, antd } = extraLocales || {};
const locale = name.split('-')?.join('-')
localeInfo[name] = {
messages: mergeMessages,
locale,
momentLocale: momentLocale,
antd,
};
// 如果这是的 name 和当前的locale 相同需要重新设置一下,不然更新不了
if (locale === getLocale()) {
event.emit(LANG_CHANGE_EVENT, locale);
}
};

/**
* 获取当前的 intl 对象,可以在 node 中使用
* @param locale 需要切换的语言类型
* @param changeIntl 是否不使用 g_intl
* @returns IntlShape
*/
export const getIntl = (locale?: string, changeIntl?: boolean) => {
// 如果全局的 g_intl 存在,且不是 setIntl 调用
if (g_intl && !changeIntl && !locale) {
return g_intl;
}
// 如果存在于 localeInfo 中
if (locale&&localeInfo[locale]) {
return createIntl(localeInfo[locale]);
}
// 不存在需要一个报错提醒
warning(
!locale||!!localeInfo[locale],
`The current popular language does not exist, please check the locales folder!`,
);
// 使用 zh-CN
if (localeInfo["zh-CN"]) return createIntl(localeInfo["zh-CN"]);

// 如果还没有,返回一个空的
return createIntl({
locale: "zh-CN",
messages: {},
});
};

/**
* 切换全局的 intl 的设置
* @param locale 语言的key
*/
export const setIntl = (locale: string) => {
g_intl = getIntl(locale, true);
};

/**
* 获取当前选择的语言
* @returns string
*/
export const getLocale = () => {
const runtimeLocale = plugin.applyPlugins({
key: 'locale',
type: ApplyPluginsType.modify,
initialValue: {},
});
// runtime getLocale for user define
if (typeof runtimeLocale?.getLocale === 'function') {
return runtimeLocale.getLocale();
}
// please clear localStorage if you change the baseSeparator config
// because changing will break the app
const lang =
navigator.cookieEnabled && typeof localStorage !== 'undefined' && useLocalStorage
? window.localStorage.getItem('umi_locale')
: '';
// support baseNavigator, default true
let browserLang;
const isNavigatorLanguageValid =
typeof navigator !== 'undefined' && typeof navigator.language === 'string';
browserLang = isNavigatorLanguageValid
? navigator.language.split('-').join('-')
: '';
return lang || browserLang || "zh-CN";
};


/**
* 获取当前选择的方向
* @returns string
*/
export const getDirection = () => {
const lang = getLocale();
// array with all prefixs for rtl langueges ex: ar-EG , he-IL
const rtlLangs = ['he', 'ar', 'fa', 'ku']
const direction = rtlLangs.filter(lng => lang.startsWith(lng)).length ? 'rtl' : 'ltr';
return direction;
};

/**
* 切换语言
* @param lang 语言的 key
* @param realReload 是否刷新页面,默认刷新
* @returns string
*/
export const setLocale = (lang: string, realReload: boolean = true) => {
const runtimeLocale = plugin.applyPlugins({
key: 'locale',
type: ApplyPluginsType.modify,
initialValue: {},
});

const updater = () => {
if (getLocale() !== lang) {
if (navigator.cookieEnabled && typeof window.localStorage !== 'undefined' && useLocalStorage) {
window.localStorage.setItem('umi_locale', lang || '');
}
setIntl(lang);
if (realReload) {
window.location.reload();
} else {
event.emit(LANG_CHANGE_EVENT, lang);
// chrome 不支持这个事件。所以人肉触发一下
if (window.dispatchEvent) {
const event = new Event('languagechange');
window.dispatchEvent(event);
}
}
}
}

if (typeof runtimeLocale?.setLocale === 'function') {
runtimeLocale.setLocale({
lang,
realReload,
updater: updater,
});
return;
}

updater();
};

let firstWaring = true;

/**
* intl.formatMessage 的语法糖
* @deprecated 使用此 api 会造成切换语言的时候无法自动刷新,请使用 useIntl 或 injectIntl
* @param descriptor { id : string, defaultMessage : string }
* @param values { [key:string] : string }
* @returns string
*/
export const formatMessage: IntlShape['formatMessage'] = (
descriptor: MessageDescriptor,
values: any,
) => {
if (firstWaring) {
warning(
false,
`Using this API will cause automatic refresh when switching languages, please use useIntl or injectIntl.

使用此 api 会造成切换语言的时候无法自动刷新,请使用 useIntl 或 injectIntl。

http://j.mp/37Fkd5Q
`,
);
firstWaring = false;
}
return g_intl.formatMessage(descriptor, values);
};

/**
* 获取语言列表
* @returns string[]
*/
export const getAllLocales = () => Object.keys(localeInfo);

+ 10
- 0
src/.umi-production/plugin-locale/runtime.tsx View File

@@ -0,0 +1,10 @@
// @ts-nocheck
import React from 'react';
// @ts-ignore
import { _LocaleContainer } from './locale';
import { getIntl, getLocale } from './localeExports';

export function rootContainer(container: Element) {
return React.createElement(_LocaleContainer, null, container);
}


+ 39
- 0
src/.umi-production/plugin-model/Provider.tsx View File

@@ -0,0 +1,39 @@
// @ts-nocheck
import React from 'react';
import initialState from 'D:/Work/BPA.SAAS.Web/src/.umi-production/plugin-initial-state/models/initialState';

// @ts-ignore
import Dispatcher from './helpers/dispatcher';
// @ts-ignore
import Executor from './helpers/executor';
// @ts-ignore
import { UmiContext } from './helpers/constant';

export const models = { '@@initialState': initialState, };

export type Model<T extends keyof typeof models> = {
[key in keyof typeof models]: ReturnType<typeof models[T]>;
};

export type Models<T extends keyof typeof models> = Model<T>[T]

const dispatcher = new Dispatcher!();
const Exe = Executor!;

export default ({ children }: { children: React.ReactNode }) => {

return (
<UmiContext.Provider value={dispatcher}>
{
Object.entries(models).map(pair => (
<Exe key={pair[0]} namespace={pair[0]} hook={pair[1] as any} onUpdate={(val: any) => {
const [ns] = pair as [keyof typeof models, any];
dispatcher.data[ns] = val;
dispatcher.update(ns);
}} />
))
}
{children}
</UmiContext.Provider>
)
}

+ 4
- 0
src/.umi-production/plugin-model/helpers/constant.tsx View File

@@ -0,0 +1,4 @@
// @ts-nocheck
import React from 'react';

export const UmiContext = React.createContext({});

+ 19
- 0
src/.umi-production/plugin-model/helpers/dispatcher.tsx View File

@@ -0,0 +1,19 @@
// @ts-nocheck
export default class Dispatcher {
callbacks = {};

data = {};

update = (namespace: string) => {
(this.callbacks[namespace] || []).forEach(
(callback: (val: any) => void) => {
try {
const data = this.data[namespace];
callback(data);
} catch (e) {
callback(undefined);
}
},
);
};
}

+ 83
- 0
src/.umi-production/plugin-model/helpers/executor.tsx View File

@@ -0,0 +1,83 @@
// @ts-nocheck
import React, { useEffect, useRef, useMemo } from 'react';

interface ExecutorProps {
hook: () => any;
onUpdate: (val: any) => void;
namespace: string;
}

export default (props: ExecutorProps) => {
const { hook, onUpdate, namespace } = props;

const updateRef = useRef(onUpdate);
updateRef.current = onUpdate;
const initialLoad = useRef(false);

let data: any;
try {
data = hook();
if (
process.env.NODE_ENV === 'development' &&
typeof document !== 'undefined'
) {
try {
let count = Object.keys(
((window as any)._umi_useModel_dev_tool_log || {})[namespace] || {},
).length;
(window as any)._umi_useModel_dev_tool = Object.assign(
(window as any)._umi_useModel_dev_tool || {},
{
[namespace]: data,
},
);
(window as any)._umi_useModel_dev_tool_log = Object.assign(
(window as any)._umi_useModel_dev_tool_log || {},
{
[namespace]: Object.assign(
((window as any)._umi_useModel_dev_tool_log || {})[namespace] ||
{},
{
[count]: data,
},
),
},
);
window.dispatchEvent(
new CustomEvent('_umi_useModel_update', {
detail: {
namespace,
time: Date.now(),
data,
index: count,
},
}),
);
} catch (e) {
// dev tool 记录失败、可能是低版本浏览器,忽略
}
}
} catch (e) {
console.error(
`plugin-model: Invoking '${namespace || 'unknown'}' model failed:`,
e,
);
}

// 首次执行时立刻返回初始值
useMemo(() => {
updateRef.current(data);
initialLoad.current = false;
}, []);

// React 16.13 后 update 函数用 useEffect 包裹
useEffect(() => {
if (initialLoad.current) {
updateRef.current(data);
} else {
initialLoad.current = true;
}
});

return <></>;
};

+ 12
- 0
src/.umi-production/plugin-model/runtime.tsx View File

@@ -0,0 +1,12 @@
// @ts-nocheck
/* eslint-disable import/no-dynamic-require */
import React from 'react';
import Provider from './Provider';

export function rootContainer(container: React.ReactNode) {
return React.createElement(
Provider,
null,
container,
);
}

+ 71
- 0
src/.umi-production/plugin-model/useModel.tsx View File

@@ -0,0 +1,71 @@
// @ts-nocheck
import { useState, useEffect, useContext, useRef } from 'react';
// @ts-ignore
import isEqual from 'D:/Work/BPA.SAAS.Web/node_modules/@umijs/plugin-model/node_modules/fast-deep-equal/index.js';
// @ts-ignore
import { UmiContext } from './helpers/constant';
import { Model, models } from './Provider';

export type Models<T extends keyof typeof models> = Model<T>[T]

export function useModel<T extends keyof Model<T>>(model: T): Model<T>[T]
export function useModel<T extends keyof Model<T>, U>(model: T, selector: (model: Model<T>[T]) => U): U

export function useModel<T extends keyof Model<T>, U>(
namespace: T,
updater?: (model: Model<T>[T]) => U
) : typeof updater extends undefined ? Model<T>[T] : ReturnType<NonNullable<typeof updater>>{

type RetState = typeof updater extends undefined ? Model<T>[T] : ReturnType<NonNullable<typeof updater>>
const dispatcher = useContext<any>(UmiContext);
const updaterRef = useRef(updater);
updaterRef.current = updater;
const [state, setState] = useState<RetState>(
() => updaterRef.current ? updaterRef.current(dispatcher.data![namespace]) : dispatcher.data![namespace]
);
const stateRef = useRef<any>(state);
stateRef.current = state;

const isMount = useRef(false);
useEffect(() => {
isMount.current = true;
return () => {
isMount.current = false;
}
}, [])

useEffect(() => {
const handler = (e: any) => {
if(!isMount.current) {
// 如果 handler 执行过程中,组件被卸载了,则强制更新全局 data
setTimeout(() => {
dispatcher.data![namespace] = e;
dispatcher.update(namespace);
});
} else {
if(updater && updaterRef.current){
const currentState = updaterRef.current(e);
const previousState = stateRef.current
if(!isEqual(currentState, previousState)){
setState(currentState);
}
} else {
setState(e);
}
}
}
try {
dispatcher.callbacks![namespace]!.add(handler);
dispatcher.update(namespace);
} catch (e) {
dispatcher.callbacks![namespace] = new Set();
dispatcher.callbacks![namespace]!.add(handler);
dispatcher.update(namespace);
}
return () => {
dispatcher.callbacks![namespace]!.delete(handler);
}
}, [namespace]);

return state;
};

+ 41
- 0
src/.umi-production/plugin-openapi/openapi.tsx View File

@@ -0,0 +1,41 @@
// @ts-nocheck

// This file is generated by Umi automatically
// DO NOT CHANGE IT MANUALLY!
import { useEffect, useState } from 'react';
import { SwaggerUIBundle } from 'swagger-ui-dist';
import 'swagger-ui-dist/swagger-ui.css';

const App = () => {
const [value, setValue] = useState("openapi" );

useEffect(() => {
SwaggerUIBundle({
url: `/umi-plugins_${value}.json`,
dom_id: '#swagger-ui',
});
}, [value]);
return (
<div
style={{
padding: 24,
}}
>
<select
style={{
position: "fixed",
right: "16px",
top: "8px",
}}
onChange={(e) => setValue(e.target.value)}
>
<option value="openapi">openapi</option>
<option value="swagger">swagger</option>
</select>
<div id="swagger-ui" />
</div>
);
};

export default App;

+ 278
- 0
src/.umi-production/plugin-request/request.ts View File

@@ -0,0 +1,278 @@
// @ts-nocheck
/**
* Base on https://github.com/umijs/D:/Work/BPA.SAAS.Web/node_modules/umi-request
*/
import {
extend,
Context,
RequestOptionsInit,
OnionMiddleware,
RequestOptionsWithoutResponse,
RequestMethod,
RequestOptionsWithResponse,
RequestResponse,
RequestInterceptor,
ResponseInterceptor,
} from 'D:/Work/BPA.SAAS.Web/node_modules/umi-request';
// @ts-ignore

import { ApplyPluginsType } from 'umi';
import { history, plugin } from '../core/umiExports';
// decoupling with antd UI library, you can using `alias` modify the ui methods
// @ts-ignore
import { message, notification } from '@umijs/plugin-request/lib/ui';
import useUmiRequest, { UseRequestProvider } from 'D:/Work/BPA.SAAS.Web/node_modules/@ahooksjs/use-request';
import {
BaseOptions,
BasePaginatedOptions,
BaseResult,
CombineService,
LoadMoreFormatReturn,
LoadMoreOptions,
LoadMoreOptionsWithFormat,
LoadMoreParams,
LoadMoreResult,
OptionsWithFormat,
PaginatedFormatReturn,
PaginatedOptionsWithFormat,
PaginatedParams,
PaginatedResult,
} from 'D:/Work/BPA.SAAS.Web/node_modules/@ahooksjs/use-request/lib/types';

type ResultWithData<T = any> = { data?: T; [key: string]: any };

function useRequest<
R = any,
P extends any[] = any,
U = any,
UU extends U = any,
>(
service: CombineService<R, P>,
options: OptionsWithFormat<R, P, U, UU>,
): BaseResult<U, P>;
function useRequest<R extends ResultWithData = any, P extends any[] = any>(
service: CombineService<R, P>,
options?: BaseOptions<R['data'], P>,
): BaseResult<R['data'], P>;
function useRequest<R extends LoadMoreFormatReturn = any, RR = any>(
service: CombineService<RR, LoadMoreParams<R>>,
options: LoadMoreOptionsWithFormat<R, RR>,
): LoadMoreResult<R>;
function useRequest<
R extends ResultWithData<LoadMoreFormatReturn | any> = any,
RR extends R = any,
>(
service: CombineService<R, LoadMoreParams<R['data']>>,
options: LoadMoreOptions<RR['data']>,
): LoadMoreResult<R['data']>;

function useRequest<R = any, Item = any, U extends Item = any>(
service: CombineService<R, PaginatedParams>,
options: PaginatedOptionsWithFormat<R, Item, U>,
): PaginatedResult<Item>;
function useRequest<Item = any, U extends Item = any>(
service: CombineService<
ResultWithData<PaginatedFormatReturn<Item>>,
PaginatedParams
>,
options: BasePaginatedOptions<U>,
): PaginatedResult<Item>;
function useRequest(service: any, options: any = {}) {
return useUmiRequest(service, {
formatResult: result => result?.data,
requestMethod: (requestOptions: any) => {
if (typeof requestOptions === 'string') {
return request(requestOptions);
}
if (typeof requestOptions === 'object') {
const { url, ...rest } = requestOptions;
return request(url, rest);
}
throw new Error('request options error');
},
...options,
});
}

export interface RequestConfig extends RequestOptionsInit {
errorConfig?: {
errorPage?: string;
adaptor?: (resData: any, ctx: Context) => ErrorInfoStructure;
};
middlewares?: OnionMiddleware[];
requestInterceptors?: RequestInterceptor[];
responseInterceptors?: ResponseInterceptor[];
}

export enum ErrorShowType {
SILENT = 0,
WARN_MESSAGE = 1,
ERROR_MESSAGE = 2,
NOTIFICATION = 4,
REDIRECT = 9,
}

interface ErrorInfoStructure {
success: boolean;
data?: any;
errorCode?: string;
errorMessage?: string;
showType?: ErrorShowType;
traceId?: string;
host?: string;
[key: string]: any;
}

interface RequestError extends Error {
data?: any;
info?: ErrorInfoStructure;
request?: Context['req'];
response?: Context['res'];
}

const DEFAULT_ERROR_PAGE = '/exception';

let requestMethodInstance: RequestMethod;
const getRequestMethod = () => {
if (requestMethodInstance) {
// request method 已经示例化
return requestMethodInstance;
}

// runtime 配置可能应为依赖顺序的问题在模块初始化的时候无法获取,所以需要封装一层在异步调用后初始化相关方法
// 当用户的 app.ts 中依赖了该文件的情况下就该模块的初始化时间就会被提前,无法获取到运行时配置
const requestConfig: RequestConfig = plugin.applyPlugins({
key: 'request',
type: ApplyPluginsType.modify,
initialValue: {},
});

const errorAdaptor =
requestConfig.errorConfig?.adaptor || ((resData) => resData);

requestMethodInstance = extend({
errorHandler: (error: RequestError) => {
// @ts-ignore
if (error?.request?.options?.skipErrorHandler) {
throw error;
}
let errorInfo: ErrorInfoStructure | undefined;
if (error.name === 'ResponseError' && error.data && error.request) {
const ctx: Context = {
req: error.request,
res: error.response,
};
errorInfo = errorAdaptor(error.data, ctx);
error.message = errorInfo?.errorMessage || error.message;
error.data = error.data;
error.info = errorInfo;
}
errorInfo = error.info;

if (errorInfo) {
const errorMessage = errorInfo?.errorMessage;
const errorCode = errorInfo?.errorCode;
const errorPage =
requestConfig.errorConfig?.errorPage || DEFAULT_ERROR_PAGE;

switch (errorInfo?.showType) {
case ErrorShowType.SILENT:
// do nothing
break;
case ErrorShowType.WARN_MESSAGE:
message.warn(errorMessage);
break;
case ErrorShowType.ERROR_MESSAGE:
message.error(errorMessage);
break;
case ErrorShowType.NOTIFICATION:
notification.open({
description: errorMessage,
message: errorCode,
});
break;
case ErrorShowType.REDIRECT:
// @ts-ignore
history.push({
pathname: errorPage,
query: { errorCode, errorMessage },
});
// redirect to error page
break;
default:
message.error(errorMessage);
break;
}
} else {
message.error(error.message || 'Request error, please retry.');
}
throw error;
},
...requestConfig,
});

// 中间件统一错误处理
// 后端返回格式 { success: boolean, data: any }
// 按照项目具体情况修改该部分逻辑
requestMethodInstance.use(async (ctx, next) => {
await next();
const { req, res } = ctx;
// @ts-ignore
if (req.options?.skipErrorHandler) {
return;
}
const { options } = req;
const { getResponse } = options;
const resData = getResponse ? res.data : res;
const errorInfo = errorAdaptor(resData, ctx);
if (errorInfo.success === false) {
// 抛出错误到 errorHandler 中处理
const error: RequestError = new Error(errorInfo.errorMessage);
error.name = 'BizError';
error.data = resData;
error.info = errorInfo;
error.response = res;
throw error;
}
});

// Add user custom middlewares
const customMiddlewares = requestConfig.middlewares || [];
customMiddlewares.forEach((mw) => {
requestMethodInstance.use(mw);
});

// Add user custom interceptors
const requestInterceptors = requestConfig.requestInterceptors || [];
const responseInterceptors = requestConfig.responseInterceptors || [];
requestInterceptors.map((ri) => {
requestMethodInstance.interceptors.request.use(ri);
});
responseInterceptors.map((ri) => {
requestMethodInstance.interceptors.response.use(ri);
});

return requestMethodInstance;
};

interface RequestMethodInUmi<R = false> {
<T = any>(
url: string,
options: RequestOptionsWithResponse & { skipErrorHandler?: boolean },
): Promise<RequestResponse<T>>;
<T = any>(
url: string,
options: RequestOptionsWithoutResponse & { skipErrorHandler?: boolean },
): Promise<T>;
<T = any>(
url: string,
options?: RequestOptionsInit & { skipErrorHandler?: boolean },
): R extends true ? Promise<RequestResponse<T>> : Promise<T>;
}
const request: RequestMethodInUmi = (url: any, options: any) => {
const requestMethod = getRequestMethod();
return requestMethod(url, options);
};

export { request, useRequest, UseRequestProvider };

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save