@tuya-sat/sdf-main-sdk 0.0.1-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +5 -0
- package/README.md +1 -0
- package/antd.less.overwrite.js +56 -0
- package/color.js +140 -0
- package/dark-variable.less +1449 -0
- package/package.json +74 -0
- package/scripts/gen-localize-file.mjs +56 -0
- package/src/App.less +156 -0
- package/src/App.tsx +87 -0
- package/src/api/index.ts +52 -0
- package/src/api/req.ts +23 -0
- package/src/api/res.ts +29 -0
- package/src/api/urls.ts +30 -0
- package/src/api/utils.ts +41 -0
- package/src/assets/imgs/404.svg +194 -0
- package/src/assets/imgs/reLogin.png +0 -0
- package/src/components/404/index.tsx +44 -0
- package/src/components/500/index.tsx +49 -0
- package/src/components/BCustomNav/index.module.less +17 -0
- package/src/components/BCustomNav/index.tsx +108 -0
- package/src/components/BForgot/index.module.less +5 -0
- package/src/components/BForgot/index.tsx +96 -0
- package/src/components/BHeaderUser/account.png +0 -0
- package/src/components/BHeaderUser/app-scan-en.png +0 -0
- package/src/components/BHeaderUser/app-scan-zh.png +0 -0
- package/src/components/BHeaderUser/app-scan.png +0 -0
- package/src/components/BHeaderUser/components/BSwitchLang/index.module.less +6 -0
- package/src/components/BHeaderUser/components/BSwitchLang/index.tsx +56 -0
- package/src/components/BHeaderUser/components/Badge/components/Notice/Drawer/Content.tsx +199 -0
- package/src/components/BHeaderUser/components/Badge/components/Notice/Drawer/index.module.less +11 -0
- package/src/components/BHeaderUser/components/Badge/components/Notice/Drawer/index.tsx +27 -0
- package/src/components/BHeaderUser/components/Badge/components/Notice/hooks.ts +104 -0
- package/src/components/BHeaderUser/components/Badge/components/Notice/index.module.less +70 -0
- package/src/components/BHeaderUser/components/Badge/components/Notice/index.tsx +184 -0
- package/src/components/BHeaderUser/components/Badge/components/Notice/table/index.tsx +184 -0
- package/src/components/BHeaderUser/components/Badge/components/Notice/table/read.tsx +67 -0
- package/src/components/BHeaderUser/components/Badge/components/Notice/tools/index.tsx +116 -0
- package/src/components/BHeaderUser/components/Badge/index.module.less +99 -0
- package/src/components/BHeaderUser/components/Badge/index.tsx +179 -0
- package/src/components/BHeaderUser/index.module.less +105 -0
- package/src/components/BHeaderUser/index.tsx +261 -0
- package/src/components/BHeaderUser/logout.tsx +26 -0
- package/src/components/BLayout/components/Header/index.module.less +27 -0
- package/src/components/BLayout/components/Header/index.tsx +36 -0
- package/src/components/BLayout/components/Layout/empty.tsx +35 -0
- package/src/components/BLayout/components/Layout/emptyPage.png +0 -0
- package/src/components/BLayout/components/Layout/index.tsx +72 -0
- package/src/components/BLayout/components/Logo.tsx +6 -0
- package/src/components/BLayout/components/Menu/collapse.tsx +41 -0
- package/src/components/BLayout/components/Menu/image/close.tsx +26 -0
- package/src/components/BLayout/components/Menu/image/closedefault.tsx +26 -0
- package/src/components/BLayout/components/Menu/image/open.tsx +38 -0
- package/src/components/BLayout/components/Menu/image/opendefault.tsx +38 -0
- package/src/components/BLayout/components/Menu/index.module.less +125 -0
- package/src/components/BLayout/components/Menu/index.tsx +244 -0
- package/src/components/BLayout/components/MenuIcon.module.less +5 -0
- package/src/components/BLayout/components/MenuIcon.tsx +46 -0
- package/src/components/BLayout/components/MultiSider/index.module.less +104 -0
- package/src/components/BLayout/components/MultiSider/index.tsx +172 -0
- package/src/components/BLayout/components/Sider/index.less +64 -0
- package/src/components/BLayout/components/Sider/index.module.less +17 -0
- package/src/components/BLayout/components/Sider/index.tsx +34 -0
- package/src/components/BLayout/index.tsx +78 -0
- package/src/components/BLayoutLogin/index.module.less +65 -0
- package/src/components/BLayoutLogin/index.tsx +68 -0
- package/src/components/BLayoutLogin/login.jpg +0 -0
- package/src/components/BLogin/component/Clause/index.module.less +25 -0
- package/src/components/BLogin/component/Clause/index.tsx +58 -0
- package/src/components/BLogin/component/ForgotBtn/index.module.less +9 -0
- package/src/components/BLogin/component/ForgotBtn/index.tsx +18 -0
- package/src/components/BLogin/component/Password/index.tsx +39 -0
- package/src/components/BLogin/component/SubmitBtn/index.tsx +30 -0
- package/src/components/BLogin/component/TenanSpace/index.tsx +28 -0
- package/src/components/BLogin/component/Title/index.module.less +6 -0
- package/src/components/BLogin/component/Title/index.tsx +12 -0
- package/src/components/BLogin/component/UserName/index.tsx +48 -0
- package/src/components/BLogin/component/VerifyCode/index.module.less +11 -0
- package/src/components/BLogin/component/VerifyCode/index.tsx +165 -0
- package/src/components/BLogin/index.module.less +31 -0
- package/src/components/BLogin/index.tsx +210 -0
- package/src/components/BRegister/components/TenantName/index.tsx +26 -0
- package/src/components/BRegister/index.module.less +5 -0
- package/src/components/BRegister/index.tsx +71 -0
- package/src/components/Back/index.tsx +25 -0
- package/src/components/IconFont/font.js +66 -0
- package/src/components/IconFont/index.tsx +18 -0
- package/src/components/MicroComponent/Header/index.module.less +7 -0
- package/src/components/MicroComponent/Header/index.tsx +220 -0
- package/src/components/PForgot/index.tsx +10 -0
- package/src/components/PLogin/index.tsx +12 -0
- package/src/components/PRegister/index.tsx +10 -0
- package/src/components/PSetting/index.module.less +53 -0
- package/src/components/PSetting/index.tsx +420 -0
- package/src/constant/chargeStatus.ts +6 -0
- package/src/constant/imgs.ts +6 -0
- package/src/constant/index.ts +293 -0
- package/src/dark-variable.less +1449 -0
- package/src/global.d.ts +54 -0
- package/src/hooks/index.ts +133 -0
- package/src/index.css +1493 -0
- package/src/index.tsx +105 -0
- package/src/lang/en.json +266 -0
- package/src/lang/index.ts +44 -0
- package/src/lang/utils.ts +285 -0
- package/src/lang/zh.json +270 -0
- package/src/micro-script/theme/index.ts +29 -0
- package/src/micro-script/theme/theme-css/static.js +73 -0
- package/src/micro-script/theme/theme-css/subscriber.ts +201 -0
- package/src/micro-script/theme/util/index.ts +58 -0
- package/src/mqtt/index.ts +121 -0
- package/src/pages/403.tsx +18 -0
- package/src/pages/404.tsx +17 -0
- package/src/pages/expiration.tsx +23 -0
- package/src/pages/forgot.tsx +9 -0
- package/src/pages/home/index.tsx +172 -0
- package/src/pages/home/setting/index.tsx +7 -0
- package/src/pages/index.ts +50 -0
- package/src/pages/login.tsx +46 -0
- package/src/pages/register.tsx +9 -0
- package/src/pages/relogin/index.module.less +0 -0
- package/src/pages/relogin/index.tsx +54 -0
- package/src/plugins/index.ts +11 -0
- package/src/public-path.js +8 -0
- package/src/qiankun/globalState.ts +6 -0
- package/src/qiankun/index.ts +174 -0
- package/src/qiankun/utils/index.ts +69 -0
- package/src/qiankun/xhook/index.ts +193 -0
- package/src/reportWebVitals.ts +15 -0
- package/src/sentry/index.ts +33 -0
- package/src/sky/index.ts +57 -0
- package/src/theme/custom-dark.less +64 -0
- package/src/theme/custom-light.less +48 -0
- package/src/theme/index.less +327 -0
- package/src/theme/variable.less +13 -0
- package/src/utils/checkPass.ts +21 -0
- package/src/utils/common.ts +195 -0
- package/src/utils/eventBus.ts +112 -0
- package/src/utils/gt.js +293 -0
- package/src/utils/index.ts +89 -0
- package/src/utils/theme/base.ts +110 -0
- package/src/utils/theme/changeCssVariable.ts +157 -0
- package/src/utils/theme/changeMenuCssVariable.ts +176 -0
- package/src/utils/theme/index.ts +85 -0
- package/src/utils/theme/store.ts +37 -0
- package/tsconfig.json +28 -0
- package/typings.d.ts +10 -0
- package/webpack.config.js +103 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import {
|
|
2
|
+
registerMicroApps,
|
|
3
|
+
start,
|
|
4
|
+
addGlobalUncaughtErrorHandler,
|
|
5
|
+
initGlobalState,
|
|
6
|
+
MicroAppStateActions,
|
|
7
|
+
} from 'qiankun';
|
|
8
|
+
import * as Sentry from '@sentry/react';
|
|
9
|
+
import globalState from './globalState';
|
|
10
|
+
|
|
11
|
+
import { modifySelectedMenu } from '@/components/BLayout/components/Menu';
|
|
12
|
+
import { microThemeControl } from '@/micro-script/theme';
|
|
13
|
+
|
|
14
|
+
import mqtt from '@/mqtt';
|
|
15
|
+
import { processHtmlInTheme } from '@/micro-script/theme/util';
|
|
16
|
+
import { skyReportFirstLoadApp, skyReportLoadApp } from '@/sky';
|
|
17
|
+
import { curMicroAppCode } from '@/utils';
|
|
18
|
+
import { themeSubscribe } from '@/utils/theme/store';
|
|
19
|
+
import { getLangResource } from '@/lang/utils';
|
|
20
|
+
import {
|
|
21
|
+
isSupportMobileWithFallback,
|
|
22
|
+
resourcePrefix,
|
|
23
|
+
tyLang,
|
|
24
|
+
permission,
|
|
25
|
+
region,
|
|
26
|
+
processLoadAssetInCss,
|
|
27
|
+
} from './utils';
|
|
28
|
+
import { gMainConfig } from '@/index';
|
|
29
|
+
|
|
30
|
+
export let setGlobalState;
|
|
31
|
+
export const micState: any = {};
|
|
32
|
+
|
|
33
|
+
let apps = [];
|
|
34
|
+
|
|
35
|
+
export const runQiankun = (props) => {
|
|
36
|
+
const { appList, ...microProps } = props;
|
|
37
|
+
|
|
38
|
+
apps = appList
|
|
39
|
+
.filter((item) => item.isAuth)
|
|
40
|
+
.map((item) => {
|
|
41
|
+
const app = {
|
|
42
|
+
name: item.oem_micro_app_id,
|
|
43
|
+
entry: item.resource,
|
|
44
|
+
container: '#container',
|
|
45
|
+
activeRule: item.active_rule,
|
|
46
|
+
props: {
|
|
47
|
+
...microProps,
|
|
48
|
+
base: item.active_rule,
|
|
49
|
+
hasPermission: permission(item.oem_micro_app_id),
|
|
50
|
+
isSupportMobile: isSupportMobileWithFallback(),
|
|
51
|
+
resourcePrefix: resourcePrefix(item.resource),
|
|
52
|
+
tyLang,
|
|
53
|
+
langResource: getLangResource(item.oem_micro_app_id),
|
|
54
|
+
region,
|
|
55
|
+
modifySelectedMenu,
|
|
56
|
+
themeSubscribe,
|
|
57
|
+
mqtt: {
|
|
58
|
+
subscribeTopic: mqtt.subscribeTopic,
|
|
59
|
+
unsubscribeTopic: mqtt.unsubscribeTopic,
|
|
60
|
+
},
|
|
61
|
+
customConfig: item.micro_app_config,
|
|
62
|
+
},
|
|
63
|
+
// loader: renderLoader,
|
|
64
|
+
};
|
|
65
|
+
window._SDF_CONFIG &&
|
|
66
|
+
window._SDF_CONFIG?.sentry?.ENABLE &&
|
|
67
|
+
(app.props = {
|
|
68
|
+
...app.props,
|
|
69
|
+
sentry: {
|
|
70
|
+
captureEvent: Sentry.captureEvent,
|
|
71
|
+
captureMessage: Sentry.captureMessage,
|
|
72
|
+
captureException: Sentry.captureException,
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
return app;
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
console.log('runQiankun');
|
|
79
|
+
|
|
80
|
+
const setLoading = (loading: boolean) => {
|
|
81
|
+
if (window._SDF_CONFIG?.features.is_edgecloud) {
|
|
82
|
+
props.setLoading(loading);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
registerMicroApps(apps, {
|
|
87
|
+
beforeLoad: async () => {
|
|
88
|
+
setLoading(true);
|
|
89
|
+
},
|
|
90
|
+
beforeMount: async (app) => {
|
|
91
|
+
microThemeControl.beforeMount(app);
|
|
92
|
+
},
|
|
93
|
+
afterMount: async (app) => {
|
|
94
|
+
setLoading(false);
|
|
95
|
+
performance.mark(`${app.name}-end`);
|
|
96
|
+
performance.measure(app.name, `${app.name}-start`, `${app.name}-end`);
|
|
97
|
+
const measures = performance.getEntriesByName(app.name);
|
|
98
|
+
if (measures.length == 1) {
|
|
99
|
+
skyReportFirstLoadApp(curMicroAppCode(), measures[0].duration);
|
|
100
|
+
} else {
|
|
101
|
+
skyReportLoadApp(
|
|
102
|
+
curMicroAppCode(),
|
|
103
|
+
measures[measures.length - 1].duration
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
beforeUnmount: async (app) => {},
|
|
108
|
+
afterUnmount: async (app) => {
|
|
109
|
+
//取消订阅
|
|
110
|
+
mqtt.unsubscribeMicTopics();
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const orgOpts = {
|
|
115
|
+
sandbox: { experimentalStyleIsolation: true },
|
|
116
|
+
singular: true,
|
|
117
|
+
fetch: async (url, ...args) => {
|
|
118
|
+
if (typeof url === 'string' && url.endsWith('.html')) {
|
|
119
|
+
return processHtmlInTheme(url, apps);
|
|
120
|
+
}
|
|
121
|
+
if (typeof url === 'string' && url.endsWith('.css')) {
|
|
122
|
+
return processLoadAssetInCss(apps, url, args);
|
|
123
|
+
}
|
|
124
|
+
return window.fetch(url, ...args);
|
|
125
|
+
},
|
|
126
|
+
getTemplate: (tpl) => {
|
|
127
|
+
return microThemeControl.getTemplate(tpl);
|
|
128
|
+
},
|
|
129
|
+
excludeAssetFilter: (url) => {
|
|
130
|
+
if (microThemeControl.cannotExclude(url)) {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
if (url.includes('at.alicdn.com')) {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
if (
|
|
137
|
+
!url.includes('micro_app_lazy') &&
|
|
138
|
+
(url.includes('baidu.com') ||
|
|
139
|
+
url.includes('googleapis.com') ||
|
|
140
|
+
url.includes('static1.tuyacn.com') ||
|
|
141
|
+
url.includes('static1.tuyaus.com') ||
|
|
142
|
+
url.includes('static1-we.tuyaeu.com') ||
|
|
143
|
+
url.includes('static1-ue.tuyaus.com') ||
|
|
144
|
+
url.includes('static1.tuyaeu.com') ||
|
|
145
|
+
url.includes('static1.tuyain.com') ||
|
|
146
|
+
url.includes('/static/apps/'))
|
|
147
|
+
) {
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
return false;
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const opts = gMainConfig?.hooks?.qiankunHook && {
|
|
155
|
+
...orgOpts,
|
|
156
|
+
...gMainConfig?.hooks?.qiankunHook(),
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
start(opts);
|
|
160
|
+
addGlobalUncaughtErrorHandler((error) => {
|
|
161
|
+
window._SDF_CONFIG &&
|
|
162
|
+
window._SDF_CONFIG?.sentry?.ENABLE &&
|
|
163
|
+
Sentry.captureException(error);
|
|
164
|
+
});
|
|
165
|
+
//主应用与微应用 微应用与微应用 之间相互通信
|
|
166
|
+
const actions: MicroAppStateActions = initGlobalState(globalState);
|
|
167
|
+
|
|
168
|
+
actions.onGlobalStateChange((state, prev) => {
|
|
169
|
+
Object.assign(micState, state);
|
|
170
|
+
}, true);
|
|
171
|
+
setGlobalState = (state) => {
|
|
172
|
+
actions.setGlobalState({ ...state });
|
|
173
|
+
};
|
|
174
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import Cookies from 'js-cookie';
|
|
2
|
+
|
|
3
|
+
export const gPermissions = () => window?._SDF?.saasInfo?.permissions || {};
|
|
4
|
+
|
|
5
|
+
export const isSupportMobileWithFallback = () => {
|
|
6
|
+
return (
|
|
7
|
+
window._SDF_CONFIG?.saas?.TOP_MOBLE_ENABLE !== false &&
|
|
8
|
+
window._SDF.saas.is_support_mobile !== false
|
|
9
|
+
);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const resourcePrefix = (resource) => {
|
|
13
|
+
// 移除文件名或结尾的 /。比如:/static/light.1da6e61d.html ===> /static
|
|
14
|
+
return resource.replace(/\/([^/]+\.\w+)?$/, '');
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const tyLang = Cookies.get('main-i18next');
|
|
18
|
+
|
|
19
|
+
export const permission = (appId) => {
|
|
20
|
+
return (permissionCode) => {
|
|
21
|
+
return gPermissions()
|
|
22
|
+
[appId].map((item) => item.permission_group)
|
|
23
|
+
.includes(permissionCode);
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const region = window._SDF?.region;
|
|
28
|
+
|
|
29
|
+
const replacePathInCSS = (css, mapFn) => {
|
|
30
|
+
const hasQuote = /^\s*('|")/;
|
|
31
|
+
return [
|
|
32
|
+
/(@import\s+)(')(.+?)(')/gi,
|
|
33
|
+
/(@import\s+)(")(.+?)(")/gi,
|
|
34
|
+
/(url\s*\()(\s*')([^']+?)(')/gi,
|
|
35
|
+
/(url\s*\()(\s*")([^"]+?)(")/gi,
|
|
36
|
+
/(url\s*\()(\s*)([^\s'")].*?)(\s*\))/gi,
|
|
37
|
+
].reduce((css, reg, index) => {
|
|
38
|
+
return css.replace(reg, (all, lead, quote1, path, quote2) => {
|
|
39
|
+
const ret = mapFn(path, quote1);
|
|
40
|
+
if (hasQuote.test(ret) && hasQuote.test(quote1)) quote1 = quote2 = '';
|
|
41
|
+
return lead + quote1 + ret + quote2;
|
|
42
|
+
});
|
|
43
|
+
}, css);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const isUrlReg = /^(data:|https?:|\/\/)/i;
|
|
47
|
+
export const processLoadAssetInCss = (apps, url, args) => {
|
|
48
|
+
return {
|
|
49
|
+
async text() {
|
|
50
|
+
const res = await window.fetch(url, ...args);
|
|
51
|
+
let css = await res.text();
|
|
52
|
+
let baseUrl = '';
|
|
53
|
+
apps.forEach((app) => {
|
|
54
|
+
if (url.includes(app.props.resourcePrefix)) {
|
|
55
|
+
baseUrl = app.props.resourcePrefix;
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
if (baseUrl) {
|
|
59
|
+
css = replacePathInCSS(css, (path) => {
|
|
60
|
+
if (isUrlReg.test(path)) {
|
|
61
|
+
return path;
|
|
62
|
+
}
|
|
63
|
+
return baseUrl + '/' + path;
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return css;
|
|
67
|
+
},
|
|
68
|
+
} as any;
|
|
69
|
+
};
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import xhook from 'xhook';
|
|
2
|
+
import * as Sentry from '@sentry/react';
|
|
3
|
+
import { saasApis } from '@/utils';
|
|
4
|
+
import { getI18n } from 'react-i18next';
|
|
5
|
+
import { getMicroAppId, curMicroAppCode } from '@/utils';
|
|
6
|
+
import { gMainConfig } from '@/index';
|
|
7
|
+
|
|
8
|
+
let history;
|
|
9
|
+
|
|
10
|
+
const processException = (req, code) => {
|
|
11
|
+
let isToLogin = false;
|
|
12
|
+
if (isCurHostHttp(req)) {
|
|
13
|
+
const {
|
|
14
|
+
location: { pathname },
|
|
15
|
+
} = history;
|
|
16
|
+
switch (code) {
|
|
17
|
+
case 1010:
|
|
18
|
+
case 111:
|
|
19
|
+
isToLogin = true;
|
|
20
|
+
window.location.replace(
|
|
21
|
+
`/application/relogin?from=${encodeURIComponent(pathname)}`
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return isToLogin;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const reportException = (res, data) => {
|
|
31
|
+
if (!data.success) {
|
|
32
|
+
const exception = { msg: data.msg, code: data.code };
|
|
33
|
+
data.t && (exception['t'] = data.t);
|
|
34
|
+
res.finalUrl && (exception['url'] = res.finalUrl);
|
|
35
|
+
Sentry.addBreadcrumb({ message: '接口请求异常', data: exception });
|
|
36
|
+
Sentry.captureException(new Error('接口请求异常'));
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const transformMsg = (data) => {
|
|
41
|
+
switch (data.code) {
|
|
42
|
+
case 1106:
|
|
43
|
+
data.msg = getI18n().language.includes('zh')
|
|
44
|
+
? '暂无权限,请联系管理员添加'
|
|
45
|
+
: 'No permission, please contact the administrator';
|
|
46
|
+
break;
|
|
47
|
+
default:
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const processXMLHttpRequest = (req, res, cb) => {
|
|
53
|
+
if (res.headers['content-type'].includes('application/json')) {
|
|
54
|
+
const data = JSON.parse(res.data);
|
|
55
|
+
transformMsg(data);
|
|
56
|
+
window._SDF_CONFIG &&
|
|
57
|
+
window._SDF_CONFIG?.sentry?.ENABLE &&
|
|
58
|
+
reportException(res, data);
|
|
59
|
+
const isToLogin = processException(req, data.code);
|
|
60
|
+
if (!isToLogin) cb(res);
|
|
61
|
+
} else {
|
|
62
|
+
cb(res);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const processFetch = (req, res, cb) => {
|
|
67
|
+
if (res.headers.get('content-type').includes('application/json')) {
|
|
68
|
+
res.json().then(function (data) {
|
|
69
|
+
transformMsg(data);
|
|
70
|
+
window._SDF_CONFIG &&
|
|
71
|
+
window._SDF_CONFIG?.sentry?.ENABLE &&
|
|
72
|
+
reportException(res, data);
|
|
73
|
+
const isToLogin = processException(req, data.code);
|
|
74
|
+
if (!isToLogin) cb(new Response(JSON.stringify(data)));
|
|
75
|
+
});
|
|
76
|
+
} else {
|
|
77
|
+
cb(res);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const isCurHostHttp = (req) => {
|
|
82
|
+
return new URL(req.url, window.location.origin).origin?.includes(
|
|
83
|
+
window.location.hostname
|
|
84
|
+
);
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
function guardApi<
|
|
88
|
+
T extends { method: string; path: string },
|
|
89
|
+
U extends T & Record<string, any>
|
|
90
|
+
>(
|
|
91
|
+
apiInfo: T,
|
|
92
|
+
allowApis: Array<U>,
|
|
93
|
+
additionalValidator?: (api: U) => boolean
|
|
94
|
+
): boolean {
|
|
95
|
+
const { method, path } = apiInfo;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* 动态 api 路径可能存在的形式
|
|
99
|
+
* 1. /v1.0/assets/:asset_id/list
|
|
100
|
+
* 2. /v1.0/assets/tree/{asset_id}
|
|
101
|
+
* 3. /v1.0/assets/tree/${asset_id}
|
|
102
|
+
*/
|
|
103
|
+
const apiPathMatchReg = /\/(:[^/]+|\$?{[^/]+})/g;
|
|
104
|
+
let isLegal = false;
|
|
105
|
+
|
|
106
|
+
allowApis.forEach((api) => {
|
|
107
|
+
if (isLegal) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (api.method !== method) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
isLegal = new RegExp(
|
|
116
|
+
`^${api.path.replace(apiPathMatchReg, '/[^/]+')}/?$`
|
|
117
|
+
).test(path);
|
|
118
|
+
|
|
119
|
+
// 在匹配 `method`、`path` 的前提下,再使用 `additionalValidator()` 进行校验
|
|
120
|
+
if (isLegal && additionalValidator) {
|
|
121
|
+
isLegal = additionalValidator(api);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
return isLegal;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const getMicroIdByReq = (req) => {
|
|
129
|
+
if (typeof req.url === 'string') {
|
|
130
|
+
const url = new URL(
|
|
131
|
+
req.url.replace(/^\s*\/(custom-api|open-api)/, ''),
|
|
132
|
+
window.location.origin
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
const currentApiInfo = {
|
|
136
|
+
method: req.method,
|
|
137
|
+
path: url.pathname,
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const currentAppId = getMicroAppId();
|
|
141
|
+
const appIds = [
|
|
142
|
+
currentAppId,
|
|
143
|
+
...Object.keys(saasApis).filter((id) => id !== currentAppId),
|
|
144
|
+
];
|
|
145
|
+
|
|
146
|
+
for (const id of appIds) {
|
|
147
|
+
if (saasApis[id] && guardApi(currentApiInfo, saasApis[id])) {
|
|
148
|
+
return id;
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return 'main-app';
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
export const apiIntercept = ({ mainHistory }) => {
|
|
158
|
+
history = mainHistory;
|
|
159
|
+
const _csrf = window.csrf;
|
|
160
|
+
xhook.before((req) => {
|
|
161
|
+
if (isCurHostHttp(req)) {
|
|
162
|
+
if (!req.headers['micro-app-id']?.includes('main-app')) {
|
|
163
|
+
req.headers && (req.headers['micro-app-id'] = getMicroIdByReq(req));
|
|
164
|
+
req.headers && (req.headers['micro-app-code'] = curMicroAppCode());
|
|
165
|
+
}
|
|
166
|
+
_csrf &&
|
|
167
|
+
req.headers &&
|
|
168
|
+
!req.headers['csrf-token'] &&
|
|
169
|
+
(req.headers['csrf-token'] = _csrf);
|
|
170
|
+
|
|
171
|
+
if (gMainConfig?.hooks?.httpHook?.before) {
|
|
172
|
+
gMainConfig?.hooks?.httpHook?.before(req);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
xhook.after((req, res, cb) => {
|
|
178
|
+
if (gMainConfig?.hooks?.httpHook?.after) {
|
|
179
|
+
gMainConfig?.hooks?.httpHook?.after(res, cb);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
try {
|
|
183
|
+
const isFetch = !res.data;
|
|
184
|
+
if (isFetch) {
|
|
185
|
+
processFetch(req, res, cb);
|
|
186
|
+
} else {
|
|
187
|
+
processXMLHttpRequest(req, res, cb);
|
|
188
|
+
}
|
|
189
|
+
} catch (error) {
|
|
190
|
+
cb(res);
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ReportHandler } from 'web-vitals';
|
|
2
|
+
|
|
3
|
+
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
|
|
4
|
+
if (onPerfEntry && onPerfEntry instanceof Function) {
|
|
5
|
+
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
|
6
|
+
getCLS(onPerfEntry);
|
|
7
|
+
getFID(onPerfEntry);
|
|
8
|
+
getFCP(onPerfEntry);
|
|
9
|
+
getLCP(onPerfEntry);
|
|
10
|
+
getTTFB(onPerfEntry);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default reportWebVitals;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as Sentry from '@sentry/react';
|
|
2
|
+
import { Integrations } from '@sentry/tracing';
|
|
3
|
+
import { getMicroAppId, curMicroAppName } from '@/utils';
|
|
4
|
+
|
|
5
|
+
if (window._SDF_CONFIG && window._SDF_CONFIG?.sentry?.ENABLE) {
|
|
6
|
+
Sentry.init({
|
|
7
|
+
dsn: window._SDF_CONFIG.sentry.DSN,
|
|
8
|
+
integrations: [new Integrations.BrowserTracing()],
|
|
9
|
+
tracesSampleRate: window._SDF_CONFIG.sentry.TRACES_SAMPLE_RATE,
|
|
10
|
+
environment: window._SDF_CONFIG.sentry.ENVIRONMENT,
|
|
11
|
+
release: window._SDF_CONFIG.release,
|
|
12
|
+
beforeSend(event) {
|
|
13
|
+
const saasInfo = JSON.parse(localStorage.getItem('SAAS_INFO'));
|
|
14
|
+
const userInfo = JSON.parse(localStorage.getItem('USER_INFO'));
|
|
15
|
+
|
|
16
|
+
saasInfo &&
|
|
17
|
+
(event.tags = {
|
|
18
|
+
...event.tags,
|
|
19
|
+
...{
|
|
20
|
+
saasname: (saasInfo as any).saas_name,
|
|
21
|
+
saasid: (saasInfo as any).saas_id,
|
|
22
|
+
micappname: curMicroAppName(),
|
|
23
|
+
micappid: getMicroAppId() || 'main-id',
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
userInfo &&
|
|
28
|
+
(event.user = { username: userInfo.username, uid: userInfo.uid });
|
|
29
|
+
|
|
30
|
+
return event;
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
}
|
package/src/sky/index.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { browserType } from '@/utils';
|
|
2
|
+
export const initSky = () => {
|
|
3
|
+
window.TPM?.push(['setAppId', 'sdf']);
|
|
4
|
+
window.TPM?.push(['setVersion', window._SDF.runtime]);
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export const skyReport = (microCode: string) => {
|
|
8
|
+
window._SDF?.saas?.skyEyeEnable &&
|
|
9
|
+
window.TPM?.push([
|
|
10
|
+
'uaTrack',
|
|
11
|
+
'ty_l3xrz9m9y5gujut7u8ss3ky08c4hajxa',
|
|
12
|
+
{
|
|
13
|
+
domain: window.location.hostname,
|
|
14
|
+
micro_code: microCode,
|
|
15
|
+
env: curEnv(),
|
|
16
|
+
browser: browserType(),
|
|
17
|
+
},
|
|
18
|
+
]);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const skyReportFirstLoadApp = (microCode: string, time: number) => {
|
|
22
|
+
window._SDF?.saas?.skyEyeEnable &&
|
|
23
|
+
window.TPM?.push([
|
|
24
|
+
'uaTrack',
|
|
25
|
+
'ty_ys4az0dsmmvmmnc4idzm8l7fqbx2y16d',
|
|
26
|
+
{
|
|
27
|
+
micro_code: microCode,
|
|
28
|
+
env: curEnv(),
|
|
29
|
+
browser: browserType(),
|
|
30
|
+
first_load_timing: time,
|
|
31
|
+
},
|
|
32
|
+
]);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const skyReportLoadApp = (microCode: string, time: number) => {
|
|
36
|
+
window._SDF?.saas?.skyEyeEnable &&
|
|
37
|
+
window.TPM?.push([
|
|
38
|
+
'uaTrack',
|
|
39
|
+
'ty_ys4az0dsmmvmmnc4idzm8l7fqbx2y16d',
|
|
40
|
+
{
|
|
41
|
+
micro_code: microCode,
|
|
42
|
+
env: curEnv(),
|
|
43
|
+
browser: browserType(),
|
|
44
|
+
load_timing: time,
|
|
45
|
+
},
|
|
46
|
+
]);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const curEnv = () => {
|
|
50
|
+
if (window.location.hostname.includes('fast-daily')) {
|
|
51
|
+
return 'daily';
|
|
52
|
+
} else if (window.location.hostname.includes('fast-cn')) {
|
|
53
|
+
return 'pre';
|
|
54
|
+
} else {
|
|
55
|
+
return 'prod';
|
|
56
|
+
}
|
|
57
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
@import './custom-light.less';
|
|
2
|
+
@pageBgc: #191c29;
|
|
3
|
+
@cardBgc: #282c3b;
|
|
4
|
+
@navBgc: #2c303f;
|
|
5
|
+
|
|
6
|
+
@splitBgc: rgba(255, 255, 255, 0.12);
|
|
7
|
+
@borderBgc: rgba(255, 255, 255, 0.06);
|
|
8
|
+
@selectBgc: rgba(24, 144, 255, 0.2); // select选择框边框色
|
|
9
|
+
|
|
10
|
+
@select-border-color: rgba(255, 255, 255, 0.2);
|
|
11
|
+
@table-bg: @navBgc;
|
|
12
|
+
@table-header-bg: @cardBgc;
|
|
13
|
+
// @table-border-color:rgba (255, 255, 255, 0.06);
|
|
14
|
+
// 表格边框色
|
|
15
|
+
@border-color-split: rgba(255, 255, 255, 0.06);
|
|
16
|
+
@checkbox-color: rgba(255, 255, 255, 0.06);
|
|
17
|
+
// checkbox 边框色
|
|
18
|
+
@border-color-base: rgba(255, 255, 255, 0.2);
|
|
19
|
+
// 表格hover色
|
|
20
|
+
@table-row-hover-bg: #282c3b;
|
|
21
|
+
@component-background: @navBgc;
|
|
22
|
+
@main-menu-item-selected-color: rgba(255, 255, 255, 0.65);
|
|
23
|
+
@main-menu-item-selected-color-hover: rgb(255, 255, 255);
|
|
24
|
+
@main-menu-background-color: @navBgc;
|
|
25
|
+
|
|
26
|
+
// 分组下 标题背景
|
|
27
|
+
@main-menu-collapsed-title-background: @navBgc;
|
|
28
|
+
// 分组下 hover背景
|
|
29
|
+
@mani-menu-collapsed-item: @selectBgc;
|
|
30
|
+
@main-app-setting-top: @splitBgc;
|
|
31
|
+
|
|
32
|
+
@main-app-layout-header-bottom: @item-hover-bg;
|
|
33
|
+
@popover-bg: @navBgc;
|
|
34
|
+
@layout-header-background: @cardBgc;
|
|
35
|
+
// 菜单栏
|
|
36
|
+
@layout-sider-background: @navBgc;
|
|
37
|
+
// 分组下 菜单背景
|
|
38
|
+
@mani-menu-collapsed-background: @navBgc;
|
|
39
|
+
|
|
40
|
+
@layout-header-background: @cardBgc;
|
|
41
|
+
@select-dropdown-bg: @navBgc;
|
|
42
|
+
@select-item-selected-bg: @primary-color;
|
|
43
|
+
|
|
44
|
+
@body-background: @pageBgc;
|
|
45
|
+
|
|
46
|
+
@menu-item-active-bg: #1f2333;
|
|
47
|
+
|
|
48
|
+
@main-app-scrollbar-thumb-bg: #56606d;
|
|
49
|
+
@main-app-scrollbar-track-bg: #293846;
|
|
50
|
+
|
|
51
|
+
@svg-containter-hover-color: @primary-color;
|
|
52
|
+
@svg-containter-line-hover-color: @primary-color;
|
|
53
|
+
@main-menu-item-icon-bg: rgba(255, 255, 255, 0.5);
|
|
54
|
+
|
|
55
|
+
@main-app-menu-collapsed: #1f2333;
|
|
56
|
+
@text-color-describe: rgba(255, 255, 255, 0.45);
|
|
57
|
+
|
|
58
|
+
@svg-containter-line-color: rgba(255, 255, 255, 0.12);
|
|
59
|
+
|
|
60
|
+
@svg-containter-content-color: #fff;
|
|
61
|
+
|
|
62
|
+
@svg-containter-bg-color: @navBgc;
|
|
63
|
+
|
|
64
|
+
@main-static-color: rgba(255, 255, 255, 0.3);
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
@pageBgc: #f5f5f5;
|
|
2
|
+
@cardBgc: #f1f1f1;
|
|
3
|
+
|
|
4
|
+
@navBgc: @component-background;
|
|
5
|
+
|
|
6
|
+
@splitBgc: @item-hover-bg;
|
|
7
|
+
@borderBgc: @item-hover-bg;
|
|
8
|
+
@select-border-color: #d9d9d9;
|
|
9
|
+
|
|
10
|
+
@table-row-hover-bg: #fafafa;
|
|
11
|
+
@main-menu-item-selected-color: @text-color;
|
|
12
|
+
@main-menu-item-selected-color-hover: @menu-highlight-color;
|
|
13
|
+
@main-menu-background-color: @component-background;
|
|
14
|
+
@main-layout-background-color: @item-hover-bg;
|
|
15
|
+
|
|
16
|
+
@mani-menu-collapsed-background: @component-background;
|
|
17
|
+
|
|
18
|
+
// 分组下 标题背景
|
|
19
|
+
@main-menu-collapsed-title-background: @component-background;
|
|
20
|
+
|
|
21
|
+
// 分组下 hover背景
|
|
22
|
+
@mani-menu-collapsed-item: @item-hover-bg;
|
|
23
|
+
@main-app-setting-top: #eef0f3;
|
|
24
|
+
|
|
25
|
+
@main-app-layout-header-bottom: @item-hover-bg;
|
|
26
|
+
@layout-header-background: #fff;
|
|
27
|
+
|
|
28
|
+
@main-app-scrollbar-thumb-bg: #cccdcc;
|
|
29
|
+
@main-app-scrollbar-track-bg: #ededed;
|
|
30
|
+
|
|
31
|
+
@svg-containter-hover-color: @primary-color;
|
|
32
|
+
|
|
33
|
+
@svg-containter-line-hover-color: @primary-color;
|
|
34
|
+
@main-menu-item-icon-bg: rgba(0, 0, 0, 0);
|
|
35
|
+
|
|
36
|
+
@main-app-drop-down-hover-color: @item-hover-bg;
|
|
37
|
+
|
|
38
|
+
@text-color-describe: rgba(0, 0, 0, 0.45);
|
|
39
|
+
|
|
40
|
+
@main-app-menu-collapsed: @primary-1;
|
|
41
|
+
|
|
42
|
+
@svg-containter-line-color: #f5f5f5;
|
|
43
|
+
|
|
44
|
+
@svg-containter-content-color: #000;
|
|
45
|
+
|
|
46
|
+
@svg-containter-bg-color: #e6e9ea;
|
|
47
|
+
|
|
48
|
+
@main-static-color: rgba(0, 0, 0, 0.25);
|