@epxing/core 5.3.0-beta.2 → 5.3.0-beta.3
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/API.md +26 -25
- package/README.md +3 -1
- package/dist/.cache/route-chart-release/frontend/frame/public/js/ecStat.min.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/public/js/echarts-wordcloud.min.js +4 -0
- package/dist/.cache/route-chart-release/frontend/frame/public/js/echarts.min.js +4 -0
- package/dist/_virtual/_plugin-vue_export-helper.js +10 -0
- package/dist/_virtual/jsencrypt.min.js +1 -1
- package/dist/assets/ecStat.min-BrTYPOXX.js +1 -0
- package/dist/assets/echarts-wordcloud.min-nWR4Hzny.js +3 -0
- package/dist/assets/echarts.min-DROS9E5X.js +45 -0
- package/dist/assets/role_select-DTqRlFNz.webp +0 -0
- package/dist/{_vendor → frontend/frame/_vendor}/.pnpm/jsencrypt@3.5.4/_vendor/jsencrypt/bin/jsencrypt.min.js +1 -1
- package/dist/src/RootApp.js +54 -0
- package/dist/src/api/createHttp.js +6 -0
- package/dist/src/app-ui-settings.js +49 -0
- package/dist/src/axios.js +10 -15
- package/dist/src/chart-runtime-assets.js +9 -0
- package/dist/src/create-app.js +3 -6
- package/dist/src/index.js +2 -0
- package/dist/src/loadComponent.js +2 -2
- package/dist/src/menu-route.js +11 -0
- package/dist/src/mixins/component.js +3 -0
- package/dist/src/navigation-context.js +47 -0
- package/dist/src/navigation.js +43 -12
- package/dist/src/package-install.js +3 -2
- package/dist/src/plugins/element-plus.js +8 -8
- package/dist/src/public-api.js +4 -2
- package/dist/src/route-components.js +9 -0
- package/dist/src/router/config.js +7 -8
- package/dist/src/runtime-services.js +1 -1
- package/dist/src/runtime-utils/meta.js +3 -0
- package/dist/src/runtime-utils/pdf.viewer.js +31 -15
- package/dist/src/runtime-utils/util.js +29 -5
- package/dist/src/shared-packages.js +1 -3
- package/dist/src/store/modules/list.js +25 -3
- package/dist/src/store/modules/meta.js +49 -7
- package/dist/src/style-presets.js +4 -4
- package/dist/src/ui-settings.js +90 -18
- package/dist/src/views/App.js +48 -0
- package/dist/src/views/AppRoleSelect.js +233 -0
- package/dist/src/views/Error.js +210 -0
- package/dist/src/views/Module.js +173 -0
- package/dist/style.css +251 -0
- package/package.json +4 -4
- package/src/RootApp.vue +75 -0
- package/src/api/createHttp.js +7 -0
- package/src/api/index.js +47 -47
- package/src/app-ui-settings.js +31 -0
- package/src/axios.js +311 -318
- package/src/chart-runtime-assets.js +7 -0
- package/src/create-app.js +3 -7
- package/src/index.js +28 -28
- package/src/install.js +157 -157
- package/src/loadComponent.js +187 -187
- package/src/loadLibrary.js +99 -99
- package/src/menu-route.js +12 -1
- package/src/mixins/component.js +1464 -1461
- package/src/navigation-context.js +49 -0
- package/src/navigation.js +208 -176
- package/src/package-install.js +2 -1
- package/src/plugins/element-plus.js +302 -302
- package/src/plugins/frame.js +178 -178
- package/src/public-api.js +1 -0
- package/src/route-components.js +7 -0
- package/src/router/config.js +861 -864
- package/src/router/public.js +1 -1
- package/src/runtime-services.js +1 -1
- package/src/runtime-utils/fieldFactory.js +179 -179
- package/src/runtime-utils/meta.js +399 -378
- package/src/runtime-utils/pdf.viewer.js +672 -644
- package/src/runtime-utils/util.js +1357 -1330
- package/src/shared-packages.js +1 -3
- package/src/store/modules/config.js +351 -351
- package/src/store/modules/list.js +30 -3
- package/src/store/modules/locale.js +236 -236
- package/src/store/modules/meta.js +314 -265
- package/src/style-presets.js +4 -4
- package/src/ui-settings.js +84 -23
- package/src/views/App.vue +53 -0
- package/src/views/AppRoleSelect.vue +334 -0
- package/src/views/Error.vue +63 -0
- package/src/views/Module.vue +210 -0
- package/src/xss.js +26 -26
- package/types/app.d.ts +10 -10
- package/types/axios.d.ts +1 -1
- package/types/component-mixin.d.ts +1 -1
- package/types/field-factory.d.ts +1 -1
- package/types/global-mixin.d.ts +1 -1
- package/types/http.d.ts +1 -1
- package/types/index.d.ts +3 -0
- package/types/meta.d.ts +1 -1
- package/types/navigation.d.ts +21 -21
- package/types/pdf-viewer.d.ts +1 -1
- package/types/runtime.d.ts +13 -13
- package/types/store.d.ts +1 -1
- package/types/util.d.ts +2 -2
- /package/dist/{build → .cache/route-chart-release/frontend/frame/build}/stubs/empty-components.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/element-icons.names.js +0 -0
- /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/element-plus.lazy.js +0 -0
- /package/dist/{_vendor → frontend/frame/_vendor}/.pnpm/element-plus@2.14.3_vue@3.5.39_typescript@5.9.3_/_vendor/element-plus/dist/locale/en.js +0 -0
- /package/dist/{_vendor → frontend/frame/_vendor}/.pnpm/element-plus@2.14.3_vue@3.5.39_typescript@5.9.3_/_vendor/element-plus/dist/locale/zh-cn.js +0 -0
package/src/ui-settings.js
CHANGED
|
@@ -31,6 +31,7 @@ const LEGACY_PERSIST = 'epx_frame_tabs_persist'
|
|
|
31
31
|
export const DEFAULTS = {
|
|
32
32
|
themeMode: 'light', // 主题模式 light|dark|auto(auto 跟随系统 prefers-color-scheme)
|
|
33
33
|
themeColor: '', // 主题色预设名(classicblue/purple/...;'' = 默认蓝,走既有 data-theme 兜底)
|
|
34
|
+
customTheme: null, // 用户选择的自定义主题色快照 { code, color },刷新后也能在引导期恢复
|
|
34
35
|
grayMode: false, // 灰色模式(全站置灰,哀悼日用)
|
|
35
36
|
weakMode: false, // 色弱模式(invert 反色,参考 pure-admin;与灰色模式可叠加)
|
|
36
37
|
menuAccordion: true, // 菜单手风琴(唯一展开)——参考 pure-admin;false=可同时展开多组
|
|
@@ -54,7 +55,7 @@ export const DEFAULTS = {
|
|
|
54
55
|
tabsPosition: 'below', // 标签行位置 below|nav|none
|
|
55
56
|
tabsStyle: 'smart', // 页签风格 smart|card|chrome(谷歌)
|
|
56
57
|
tabsKeepAlive: true, // 页签缓存(会话级 keep-alive):开=切走保活/点回保持原样;关=切走即销毁/每次点开重新加载。不落盘不整组恢复
|
|
57
|
-
settingsGroups: ['theme', 'layout', 'tabs', 'page', 'security'] // 设置抽屉折叠分组的展开态(记住用户的折叠选择,跨会话)
|
|
58
|
+
settingsGroups: ['theme', 'style', 'layout', 'tabs', 'page', 'security'] // 设置抽屉折叠分组的展开态(记住用户的折叠选择,跨会话)
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
// 导航布局模式 → 顶部/侧边导航显示 + 双列(供 AppIndex/module-index-page 派生显隐)
|
|
@@ -173,19 +174,17 @@ let _suppressPersist = false
|
|
|
173
174
|
// applyAppDefaults 注入的“应用默认值”(键→值):persistDiff 据此把它排除在用户偏好之外(跨 HMR 保号)
|
|
174
175
|
const _appDefaultVals = (_hot && _hot.data.appDefaultVals) || {}
|
|
175
176
|
if (_hot) _hot.data.appDefaultVals = _appDefaultVals
|
|
176
|
-
//
|
|
177
|
-
|
|
178
|
-
// 不会把应用默认当成用户选择去遮蔽其它应用的默认(旧实现整包 JSON.stringify 落盘正是此 bug 根源)。
|
|
179
|
-
function persistDiff () {
|
|
177
|
+
// 只记录本次由用户改变的字段。默认值注入期间关闭监听,避免把应用默认记成个人选择。
|
|
178
|
+
function persistDiff (current, previous) {
|
|
180
179
|
try {
|
|
181
|
-
const out = {}
|
|
180
|
+
const out = JSON.parse(window.localStorage.getItem(KEY) || '{}') || {}
|
|
181
|
+
const next = JSON.parse(current)
|
|
182
|
+
const before = JSON.parse(previous)
|
|
182
183
|
for (const k of Object.keys(DEFAULTS)) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
const cur = uiSettings[k]; const def = DEFAULTS[k]
|
|
186
|
-
const changed = Array.isArray(def) ? JSON.stringify(cur) !== JSON.stringify(def) : cur !== def
|
|
187
|
-
if (changed) out[k] = cur
|
|
184
|
+
// 显式选回 false、空串或平台默认值同样是个人覆盖,不能按值相等丢弃。
|
|
185
|
+
if (k !== 'tabsKeepAlive' && JSON.stringify(next[k]) !== JSON.stringify(before[k])) out[k] = next[k]
|
|
188
186
|
}
|
|
187
|
+
delete out.tabsKeepAlive
|
|
189
188
|
window.localStorage.setItem(KEY, JSON.stringify(out))
|
|
190
189
|
} catch (e) {}
|
|
191
190
|
}
|
|
@@ -195,10 +194,10 @@ export function persistUiSettings () {
|
|
|
195
194
|
if (_hot) _hot.data.watching = true
|
|
196
195
|
else _watching = true
|
|
197
196
|
// flush:'sync' —— 让 _suppressPersist 的开合与写盘同步生效(设置变更低频,同步落盘无性能负担)
|
|
198
|
-
watch(uiSettings, () => {
|
|
197
|
+
watch(() => JSON.stringify(Object.fromEntries(Object.keys(DEFAULTS).map(k => [k, uiSettings[k]]))), (current, previous) => {
|
|
199
198
|
if (_suppressPersist) return
|
|
200
|
-
persistDiff()
|
|
201
|
-
}, {
|
|
199
|
+
persistDiff(current, previous)
|
|
200
|
+
}, { flush: 'sync' })
|
|
202
201
|
}
|
|
203
202
|
// import 即开始持久化(副作用一次)
|
|
204
203
|
persistUiSettings()
|
|
@@ -208,11 +207,41 @@ let _mql = null
|
|
|
208
207
|
// 用户主题色之外的“底色” data-theme(角色/自定义肤色,initTheme 时快照)——清空主题色时回退到它,
|
|
209
208
|
// 否则选过预设色再清空/恢复默认时 data-theme 会卡住(老 applyTheme 无 else 分支的 bug)。
|
|
210
209
|
let _baseTheme = ''
|
|
210
|
+
// --color-primary 使用 RGB 三元组,不能直接写入 #hex 或 rgb(...)。
|
|
211
|
+
export function normalizeThemeColor (color) {
|
|
212
|
+
if (typeof color !== 'string') return ''
|
|
213
|
+
const value = color.trim()
|
|
214
|
+
const hex = value.match(/^#([\da-f]{3}|[\da-f]{6})$/i)
|
|
215
|
+
if (hex) {
|
|
216
|
+
const full = hex[1].length === 3 ? [...hex[1]].map(c => c + c).join('') : hex[1]
|
|
217
|
+
return [0, 2, 4].map(i => parseInt(full.slice(i, i + 2), 16)).join(',')
|
|
218
|
+
}
|
|
219
|
+
const rgb = value.match(/^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/i)
|
|
220
|
+
return rgb && rgb.slice(1).every(c => Number(c) <= 255) ? rgb.slice(1).map(Number).join(',') : ''
|
|
221
|
+
}
|
|
222
|
+
|
|
211
223
|
export function applyTheme () {
|
|
212
224
|
const html = document.documentElement
|
|
225
|
+
const preset = THEME_COLORS.find(c => c.name === uiSettings.themeColor)
|
|
226
|
+
const custom = uiSettings.customTheme?.code === uiSettings.themeColor ? uiSettings.customTheme : null
|
|
227
|
+
const channels = normalizeThemeColor(preset?.color || custom?.color)
|
|
228
|
+
// 显式选择覆盖旧换肤写在 body 上的颜色;选择预设和自定义色走同一条路径。
|
|
229
|
+
let colorStyle = document.getElementById('epx-ui-theme-color')
|
|
230
|
+
if (channels) {
|
|
231
|
+
html.style.removeProperty('--color-primary')
|
|
232
|
+
if (!colorStyle) {
|
|
233
|
+
colorStyle = document.createElement('style')
|
|
234
|
+
colorStyle.id = 'epx-ui-theme-color'
|
|
235
|
+
document.head.appendChild(colorStyle)
|
|
236
|
+
}
|
|
237
|
+
const selector = `html[data-theme="${preset ? preset.name : 'custom'}"]`
|
|
238
|
+
colorStyle.textContent = `${selector}, ${selector} body { --color-primary: ${channels}; }`
|
|
239
|
+
} else if (colorStyle) {
|
|
240
|
+
colorStyle.remove()
|
|
241
|
+
}
|
|
213
242
|
// 主题色:非空 → data-theme=预设名(既有换肤链);为空 → 回退底色(角色/自定义肤色),无底色则移除属性
|
|
214
243
|
if (uiSettings.themeColor) {
|
|
215
|
-
html.setAttribute('data-theme', uiSettings.themeColor)
|
|
244
|
+
html.setAttribute('data-theme', custom && channels ? 'custom' : uiSettings.themeColor)
|
|
216
245
|
} else if (_baseTheme) {
|
|
217
246
|
html.setAttribute('data-theme', _baseTheme)
|
|
218
247
|
} else {
|
|
@@ -248,7 +277,7 @@ export function initTheme () {
|
|
|
248
277
|
if (!_baseTheme) _baseTheme = document.documentElement.getAttribute('data-theme') || ''
|
|
249
278
|
applyTheme()
|
|
250
279
|
watch(() => [
|
|
251
|
-
uiSettings.themeMode, uiSettings.themeColor, uiSettings.grayMode, uiSettings.weakMode,
|
|
280
|
+
uiSettings.themeMode, uiSettings.themeColor, uiSettings.customTheme, uiSettings.grayMode, uiSettings.weakMode,
|
|
252
281
|
uiSettings.styleRadius, uiSettings.styleFont, uiSettings.styleDensity, uiSettings.styleElevation
|
|
253
282
|
], applyTheme)
|
|
254
283
|
if (window.matchMedia) {
|
|
@@ -261,22 +290,29 @@ export function initTheme () {
|
|
|
261
290
|
|
|
262
291
|
// 应用级默认注入:页面配置里配了、且用户没在设置里改过的项,用应用默认兜底。
|
|
263
292
|
// 只覆盖“用户未显式设过”的项——已在 localStorage 的用户偏好不动。
|
|
264
|
-
export function applyAppDefaults (defaults = {}) {
|
|
293
|
+
export function applyAppDefaults (defaults = {}, { replace = false } = {}) {
|
|
265
294
|
let userSet = {}
|
|
266
295
|
try { userSet = JSON.parse(window.localStorage.getItem(KEY) || '{}') || {} } catch (e) {}
|
|
267
296
|
// 注入期暂停落盘:应用默认只改内存生效值,不写进用户偏好(否则会跨应用串味、且遮蔽后续应用的默认)
|
|
268
297
|
_suppressPersist = true
|
|
269
298
|
try {
|
|
299
|
+
if (replace) {
|
|
300
|
+
Object.keys(_appDefaultVals).forEach(k => { delete _appDefaultVals[k] })
|
|
301
|
+
_baseTheme = ''
|
|
302
|
+
document.getElementById('custom-theme')?.remove()
|
|
303
|
+
document.documentElement.style.removeProperty('--color-primary')
|
|
304
|
+
}
|
|
270
305
|
for (const k of Object.keys(DEFAULTS)) {
|
|
271
|
-
|
|
272
|
-
if (defaults[k] !== undefined
|
|
273
|
-
|
|
274
|
-
|
|
306
|
+
if (defaults[k] !== undefined) _appDefaultVals[k] = defaults[k]
|
|
307
|
+
if (replace || defaults[k] !== undefined) {
|
|
308
|
+
const value = userSet[k] !== undefined ? userSet[k] : (_appDefaultVals[k] ?? DEFAULTS[k])
|
|
309
|
+
uiSettings[k] = Array.isArray(value) ? [...value] : value
|
|
275
310
|
}
|
|
276
311
|
}
|
|
277
312
|
} finally {
|
|
278
313
|
_suppressPersist = false
|
|
279
314
|
}
|
|
315
|
+
if (replace) applyTheme()
|
|
280
316
|
}
|
|
281
317
|
|
|
282
318
|
// 老单值主题键(epx_frame_theme:预设名 / 'dark' / 自定义肤色码)→ ui-settings 的迁移。
|
|
@@ -302,14 +338,39 @@ export function migrateLegacyTheme (src) {
|
|
|
302
338
|
|
|
303
339
|
// 恢复默认(设置面板「恢复默认」):回到代码默认 + 清底色/旧键/自定义肤色 style,并即时应用
|
|
304
340
|
export function resetUiSettings () {
|
|
305
|
-
|
|
341
|
+
_suppressPersist = true
|
|
342
|
+
Object.assign(uiSettings, DEFAULTS, { settingsGroups: [...DEFAULTS.settingsGroups] })
|
|
343
|
+
_suppressPersist = false
|
|
344
|
+
Object.keys(_appDefaultVals).forEach(k => { delete _appDefaultVals[k] })
|
|
345
|
+
try { window.localStorage.removeItem(KEY) } catch (e) {}
|
|
306
346
|
_baseTheme = '' // 清除角色/自定义肤色底色,真正回到平台默认
|
|
307
347
|
try {
|
|
308
348
|
const legacyKeys = ['epx_frame_theme', LEGACY_STYLE, LEGACY_PERSIST]
|
|
309
|
-
legacyKeys.forEach(k =>
|
|
349
|
+
legacyKeys.forEach(k => {
|
|
350
|
+
window.localStorage.removeItem(k)
|
|
351
|
+
window.sessionStorage.removeItem(k)
|
|
352
|
+
})
|
|
310
353
|
} catch (e) {}
|
|
311
354
|
const custom = document.getElementById('custom-theme')
|
|
312
355
|
if (custom && custom.parentNode) custom.parentNode.removeChild(custom)
|
|
356
|
+
document.documentElement.style.removeProperty('--color-primary')
|
|
357
|
+
applyTheme()
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// 清除个人覆盖后重新采用当前应用默认,应用默认始终不写入个人存储。
|
|
361
|
+
export function restoreAppUiDefaults () {
|
|
362
|
+
const defaults = { ..._appDefaultVals }
|
|
363
|
+
const baseTheme = _baseTheme
|
|
364
|
+
const legacyColor = document.getElementById('custom-theme')?.textContent
|
|
365
|
+
resetUiSettings()
|
|
366
|
+
applyAppDefaults(defaults, { replace: true })
|
|
367
|
+
_baseTheme = baseTheme
|
|
368
|
+
if (legacyColor) {
|
|
369
|
+
const style = document.createElement('style')
|
|
370
|
+
style.id = 'custom-theme'
|
|
371
|
+
style.textContent = legacyColor
|
|
372
|
+
document.head.appendChild(style)
|
|
373
|
+
}
|
|
313
374
|
applyTheme()
|
|
314
375
|
}
|
|
315
376
|
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<!-- app入口 -->
|
|
3
|
+
<component v-if="load" :is="component" :page="firstPage"></component>
|
|
4
|
+
</template>
|
|
5
|
+
|
|
6
|
+
<script>
|
|
7
|
+
/**
|
|
8
|
+
* 应用入口 获取应用配置模板
|
|
9
|
+
*/
|
|
10
|
+
export default {
|
|
11
|
+
name: 'epx-app',
|
|
12
|
+
computed: {
|
|
13
|
+
appConfig () {
|
|
14
|
+
return this.$store.state.config.appConfig
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
data () {
|
|
19
|
+
return {
|
|
20
|
+
load: false,
|
|
21
|
+
component: 'epx-app-index',
|
|
22
|
+
firstPage: {}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
methods: {
|
|
26
|
+
getPage () {
|
|
27
|
+
const { FIRST_PAGE, MOBILE_FIRST_PAGE } = this.appConfig
|
|
28
|
+
this.$store.dispatch({ // 加回调
|
|
29
|
+
type: 'ADD_PAGE',
|
|
30
|
+
pageId: this.$isMobile ? MOBILE_FIRST_PAGE : FIRST_PAGE
|
|
31
|
+
})
|
|
32
|
+
.then((page = {}) => {
|
|
33
|
+
const { pagePath } = page
|
|
34
|
+
this.firstPage = page
|
|
35
|
+
this.component = this.$loadComponent(pagePath, this.component)
|
|
36
|
+
this.load = true
|
|
37
|
+
})
|
|
38
|
+
.catch(() => {
|
|
39
|
+
// this.component = this.$loadComponent(null, this.component)
|
|
40
|
+
this.load = true
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
created () {
|
|
45
|
+
this.getPage()
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<style>
|
|
52
|
+
|
|
53
|
+
</style>
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div :class="{'role-select': true, 'm-role-select': $isMobile}" v-if="roleList">
|
|
3
|
+
<div class="role-select__bg" :style="clientConfig.BACKGROUND_CHOICEROLE? {backgroundImage: `url(${$util.getFileUrl(clientConfig.BACKGROUND_CHOICEROLE)})`}: {}"></div>
|
|
4
|
+
<div class="select__modal">
|
|
5
|
+
<div class="app__title">
|
|
6
|
+
<span class="app__prefix" :style="{background: appConfig.COLOR}">
|
|
7
|
+
<i :class="['app__icon fa',appConfig.ICON || 'el-icon-menu' ]"></i>
|
|
8
|
+
</span>
|
|
9
|
+
<i class="app__name">{{appConfig.NAME}}</i>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="role__title">请选择您的角色</div>
|
|
12
|
+
<template v-if="roleList.length>0">
|
|
13
|
+
<el-radio-group class="radio-group" v-model="mainRole" @change="setMainRole">
|
|
14
|
+
<ul :class="{'role__list': true, 'm_role_list': $isMobile}">
|
|
15
|
+
<li class="role__item" v-for="role in roleList" :key="role.ID" @click="openApp(role)">
|
|
16
|
+
<span class="role__prefix" :style="{background: appConfig.ROLE_COLOR}">
|
|
17
|
+
<i :class="['fa',role.ICON || 'el-icon-user-solid']"></i>
|
|
18
|
+
</span>
|
|
19
|
+
<span class="role__name">{{role.NAME}}</span>
|
|
20
|
+
<span class="role__opera" @click.stop>
|
|
21
|
+
<el-radio class="radio" :label="role.ID" :value="role.ID">设为默认</el-radio>
|
|
22
|
+
</span>
|
|
23
|
+
</li>
|
|
24
|
+
</ul>
|
|
25
|
+
</el-radio-group>
|
|
26
|
+
</template>
|
|
27
|
+
<div class="no-role" v-else>
|
|
28
|
+
<p>对不起,您还未得到该应用的访问授权!</p>
|
|
29
|
+
<el-button type="primary" @click="logout">退出登录</el-button>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
</template>
|
|
34
|
+
|
|
35
|
+
<script>
|
|
36
|
+
import { mapState } from 'vuex'
|
|
37
|
+
import { roleStorage } from '@epxing/core/src/menu-route'
|
|
38
|
+
import { migrateLegacyTheme, initTheme } from '@epxing/core/src/ui-settings'
|
|
39
|
+
import storage from '@epxing/utils/src/storage'
|
|
40
|
+
// 应用角色选择
|
|
41
|
+
export default {
|
|
42
|
+
name: 'epx-app-role-select',
|
|
43
|
+
data () {
|
|
44
|
+
return {
|
|
45
|
+
roleList: null,
|
|
46
|
+
radio: '',
|
|
47
|
+
mainRole: null
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
computed: {
|
|
51
|
+
...mapState({
|
|
52
|
+
clientConfig: state => state.config.clientConfig || {},
|
|
53
|
+
appConfig: state => state.config.appConfig || {}, // 应用配置
|
|
54
|
+
$isMobile: state => state.config.isMobile // 是否为移动端
|
|
55
|
+
})
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
methods: {
|
|
59
|
+
setTheme () {
|
|
60
|
+
const { 'CLIENT|THEME': clientTheme, 'SYSTEM|THEME': systemTheme } = this.appConfig
|
|
61
|
+
// 主题应用统一交给 core/ui-settings:个性化设置抽屉里选的主题色/暗色优先,老单值键
|
|
62
|
+
// epx_frame_theme 与应用配置(SYSTEM|THEME / CLIENT|THEME)只作兜底。
|
|
63
|
+
// 老实现在这里直接 setAttribute('data-theme', 老键),会把用户在设置抽屉里选的主题色**盖掉**
|
|
64
|
+
// ——本页是顶层路由、不渲染 AppIndex,与「登录页个性化主题色不生效」是同一个病根。
|
|
65
|
+
// 预设名单也不再在本文件手抄一份(此前 AppIndex/本文件各一份,改一处即漂移)。
|
|
66
|
+
// 读取用 storage.get(sessionStorage 优先、localStorage 兜底,隐私模式/禁用存储时不抛错)而非裸 localStorage。
|
|
67
|
+
const skinCode = migrateLegacyTheme(storage.get('epx_frame_theme') || systemTheme || clientTheme)
|
|
68
|
+
// 自定义肤色码:查 SKIN_COLOR 取色注入 body{--color-primary}(data-theme=custom 迁移函数已写好)
|
|
69
|
+
if (skinCode) {
|
|
70
|
+
this.$http.find({
|
|
71
|
+
entityId: 'SKIN_COLOR',
|
|
72
|
+
'scope.CODE': skinCode
|
|
73
|
+
})
|
|
74
|
+
.then(data => {
|
|
75
|
+
const flag = /rgb\(([\d,\s]+)\)/.test(data.data.COLOR)
|
|
76
|
+
if (flag) {
|
|
77
|
+
const style = `body {--color-primary: ${RegExp.$1}}`
|
|
78
|
+
var css = document.createElement('style')
|
|
79
|
+
css.type = 'text/css'
|
|
80
|
+
css.id = 'custom-theme'
|
|
81
|
+
if (css.styleSheet) {
|
|
82
|
+
css.styleSheet.cssText = style
|
|
83
|
+
} else {
|
|
84
|
+
css.appendChild(document.createTextNode(style))
|
|
85
|
+
}
|
|
86
|
+
document.head.appendChild(css)
|
|
87
|
+
}
|
|
88
|
+
})
|
|
89
|
+
}
|
|
90
|
+
// 引导期 src/App.vue 已 initTheme(),此处幂等 no-op;保留是为了不依赖某个外壳一定调过它。
|
|
91
|
+
initTheme()
|
|
92
|
+
},
|
|
93
|
+
getServiceRoles () {
|
|
94
|
+
return this.$http.get({
|
|
95
|
+
action: 'getServiceRoles',
|
|
96
|
+
entityId: 'FM_ROLE',
|
|
97
|
+
serviceId: this.appConfig.ID,
|
|
98
|
+
order_fields: 'ORDER_NUM,LOG_C_TIME',
|
|
99
|
+
order_mode: 'asc,asc'
|
|
100
|
+
})
|
|
101
|
+
.then(role => {
|
|
102
|
+
if (role.entitys.length === 1) {
|
|
103
|
+
this.openApp(role.entitys[0])
|
|
104
|
+
} else {
|
|
105
|
+
const mainRole = role.entitys.find(role => role.MAIN_ROLE === 'true')
|
|
106
|
+
if (mainRole) {
|
|
107
|
+
this.mainRole = mainRole.ID
|
|
108
|
+
this.openApp(mainRole)
|
|
109
|
+
} else {
|
|
110
|
+
// 多个角色且没有设置默认角色
|
|
111
|
+
this.roleList = [...role.entitys]
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
})
|
|
115
|
+
},
|
|
116
|
+
setMainRole () {
|
|
117
|
+
this.$http.save({
|
|
118
|
+
action: 'setMainRole',
|
|
119
|
+
entityId: 'FM_USER_SERVICE_MAIN_ROLE',
|
|
120
|
+
serviceId: this.appConfig.ID,
|
|
121
|
+
roleId: this.mainRole
|
|
122
|
+
})
|
|
123
|
+
.then(() => {
|
|
124
|
+
this.$message.success('设置成功')
|
|
125
|
+
})
|
|
126
|
+
},
|
|
127
|
+
openApp (role) {
|
|
128
|
+
const roleCode = role.CODE + (role.TYPE === 'client' ? '-client' : '')
|
|
129
|
+
// 获取应用参数
|
|
130
|
+
const { CODE, 'SYSTEM|CODE': systemCode, 'CLIENT|CODE': clientCode } = this.appConfig
|
|
131
|
+
const { client = clientCode, system = systemCode, name: lastRouteName, ...otherParams } = this.$route.params
|
|
132
|
+
// 选定角色持久化(菜单直达路由不带 role 段,取数点从 localStorage 读)
|
|
133
|
+
roleStorage.set(client, system, roleCode)
|
|
134
|
+
let name = 'app1'
|
|
135
|
+
if (systemCode === 'epxing-frame') {
|
|
136
|
+
switch (CODE) {
|
|
137
|
+
case 'FM_SERVICE_SYSTEM':
|
|
138
|
+
name = 'system'
|
|
139
|
+
break
|
|
140
|
+
case 'FM_SERVICE_CLIENT':
|
|
141
|
+
name = 'client'
|
|
142
|
+
break
|
|
143
|
+
case 'FM_SERVICE_HALL':
|
|
144
|
+
name = 'hall'
|
|
145
|
+
break
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// 从菜单直达链接被拦到本页的(守卫塞了 backMenu):选完角色回到原菜单 URL
|
|
149
|
+
const { backMenu, ...restQuery } = this.$route.query
|
|
150
|
+
if (backMenu) {
|
|
151
|
+
return this.$router.replace({
|
|
152
|
+
name: name === 'hall' ? 'hallMenu' : 'appMenu',
|
|
153
|
+
params: { client, system, app: CODE, menuKey: backMenu },
|
|
154
|
+
query: restQuery
|
|
155
|
+
})
|
|
156
|
+
}
|
|
157
|
+
this.$router.replace({
|
|
158
|
+
name: lastRouteName || name,
|
|
159
|
+
params: {
|
|
160
|
+
client,
|
|
161
|
+
system,
|
|
162
|
+
app: CODE,
|
|
163
|
+
role: roleCode,
|
|
164
|
+
...otherParams
|
|
165
|
+
},
|
|
166
|
+
query: { ...this.$route.query }
|
|
167
|
+
})
|
|
168
|
+
},
|
|
169
|
+
logout () {
|
|
170
|
+
this.$http.logout()
|
|
171
|
+
.then(() => {
|
|
172
|
+
this.$util.toLogin(true)
|
|
173
|
+
})
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
created () {
|
|
177
|
+
this.getServiceRoles()
|
|
178
|
+
this.setTheme()
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
</script>
|
|
182
|
+
|
|
183
|
+
<style lang="scss" scoped>
|
|
184
|
+
.role-select{
|
|
185
|
+
height: 100%;
|
|
186
|
+
background: #F1F3F7;
|
|
187
|
+
}
|
|
188
|
+
.role-select__bg {
|
|
189
|
+
height: 50%;
|
|
190
|
+
background: url('@/assets/images/role_select.webp') no-repeat center;
|
|
191
|
+
background-size: cover;
|
|
192
|
+
}
|
|
193
|
+
.select__modal {
|
|
194
|
+
width: 1200px;
|
|
195
|
+
height: 520px;
|
|
196
|
+
overflow: auto;
|
|
197
|
+
box-sizing: border-box;
|
|
198
|
+
padding: 30px;
|
|
199
|
+
background: var(--epx-bg-card);
|
|
200
|
+
position: relative;
|
|
201
|
+
left: 50%;
|
|
202
|
+
top: -260px;
|
|
203
|
+
margin-left: -600px;
|
|
204
|
+
}
|
|
205
|
+
.app__prefix {
|
|
206
|
+
float: left;
|
|
207
|
+
width: 56px;
|
|
208
|
+
height: 56px;
|
|
209
|
+
border-radius: 50%;
|
|
210
|
+
@include bg_color_primary;
|
|
211
|
+
margin-right: 20px;
|
|
212
|
+
text-align: center;
|
|
213
|
+
i {
|
|
214
|
+
font-size: 24px;
|
|
215
|
+
color: #fff;
|
|
216
|
+
line-height: 56px;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
.app__name {
|
|
220
|
+
font-size: var(--epx-font-size-xl);
|
|
221
|
+
line-height: 56px;
|
|
222
|
+
}
|
|
223
|
+
.role__title {
|
|
224
|
+
font-size: 18px;
|
|
225
|
+
line-height: 48px;
|
|
226
|
+
text-align: center;
|
|
227
|
+
position: relative;
|
|
228
|
+
&::after {
|
|
229
|
+
content: '';
|
|
230
|
+
display: block;
|
|
231
|
+
position: absolute;
|
|
232
|
+
left: 50%;
|
|
233
|
+
bottom: 0;
|
|
234
|
+
margin-left: -38px;
|
|
235
|
+
width: 76px;
|
|
236
|
+
height: 2px;
|
|
237
|
+
background: #333333;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
.radio-group {
|
|
241
|
+
width: 100%;
|
|
242
|
+
}
|
|
243
|
+
.role__list {
|
|
244
|
+
display: flex;
|
|
245
|
+
justify-content: center;
|
|
246
|
+
flex-wrap: wrap;
|
|
247
|
+
margin-top: 48px;
|
|
248
|
+
}
|
|
249
|
+
.role__item {
|
|
250
|
+
width: 200px;
|
|
251
|
+
height: 220px;
|
|
252
|
+
display: flex;
|
|
253
|
+
flex-direction: column;
|
|
254
|
+
align-items: center;
|
|
255
|
+
justify-content: center;
|
|
256
|
+
margin: 0 12px;
|
|
257
|
+
cursor: pointer;
|
|
258
|
+
&:hover {
|
|
259
|
+
box-shadow: 0px 1px 16px 2px rgba(0, 0, 0, 0.1);
|
|
260
|
+
.role__opera .radio {
|
|
261
|
+
display: block;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.role__prefix {
|
|
267
|
+
display: block;
|
|
268
|
+
width: 82px;
|
|
269
|
+
height: 82px;
|
|
270
|
+
border-radius: 50%;
|
|
271
|
+
@include bg_color_primary;
|
|
272
|
+
text-align: center;
|
|
273
|
+
i {
|
|
274
|
+
font-size: 36px;
|
|
275
|
+
color: #fff;
|
|
276
|
+
line-height: 82px;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
.role__name {
|
|
280
|
+
display: inline-block;
|
|
281
|
+
font-size: var(--epx-font-size-l);
|
|
282
|
+
padding: 20px 0;
|
|
283
|
+
}
|
|
284
|
+
.role__opera {
|
|
285
|
+
display: block;
|
|
286
|
+
height: 20px;
|
|
287
|
+
.radio {
|
|
288
|
+
display: none;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
.no-role {
|
|
292
|
+
margin-top: 60px;
|
|
293
|
+
text-align: center;
|
|
294
|
+
>p {
|
|
295
|
+
font-size: 30px;
|
|
296
|
+
margin-bottom: 40px;
|
|
297
|
+
color: red;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
.m-role-select {
|
|
301
|
+
.select__modal{
|
|
302
|
+
width: 100%;
|
|
303
|
+
height: 100%;
|
|
304
|
+
left: 0;
|
|
305
|
+
margin-left: 0;
|
|
306
|
+
padding: 10px 0;
|
|
307
|
+
}
|
|
308
|
+
.app__title {
|
|
309
|
+
display: none;
|
|
310
|
+
}
|
|
311
|
+
.role__list {
|
|
312
|
+
margin-top: 24px;
|
|
313
|
+
justify-content: flex-start;
|
|
314
|
+
}
|
|
315
|
+
.role__item {
|
|
316
|
+
width: calc(33.3% - 24px);
|
|
317
|
+
height: auto;
|
|
318
|
+
margin: 0 12px;
|
|
319
|
+
}
|
|
320
|
+
.role__prefix {
|
|
321
|
+
width: 48px;
|
|
322
|
+
height: 48px;
|
|
323
|
+
i {
|
|
324
|
+
font-size: 24px;
|
|
325
|
+
line-height: 48px;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
.role__name {
|
|
329
|
+
font-size: var(--epx-font-size-base);
|
|
330
|
+
padding: 10px 0;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
</style>
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="error off" v-if="errCode==='error.service.off'">
|
|
3
|
+
<svg t="1646217353171" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2495" width="360" height="360"><path d="M0 759.466667a512 125.155556 0 1 0 1024 0 512 125.155556 0 1 0-1024 0Z" fill="#E5E5E5" p-id="2496"></path><path d="M910.222222 238.674489H113.777778V159.891911C113.777778 148.562489 122.936889 139.377778 134.240711 139.377778h755.518578C901.063111 139.377778 910.222222 148.562489 910.222222 159.891911v78.782578z" fill="#253369" p-id="2497"></path><path d="M889.759289 745.244444H134.240711C122.936889 745.244444 113.777778 736.059733 113.777778 724.730311V231.796622h796.444444v492.933689c0 11.329422-9.159111 20.514133-20.462933 20.514133" fill="#E9EEF7" p-id="2498"></path><path d="M162.133333 263.085511m2.844445 0l699.733333 0q2.844444 0 2.844445 2.844445l0 34.133333q0 2.844444-2.844445 2.844444l-699.733333 0q-2.844444 0-2.844445-2.844444l0-34.133333q0-2.844444 2.844445-2.844445Z" fill="#D5DCE9" opacity=".398" p-id="2499"></path><path d="M162.133333 328.507733m2.844445 0l179.2 0q2.844444 0 2.844444 2.844445l0 199.111111q0 2.844444-2.844444 2.844444l-179.2 0q-2.844444 0-2.844445-2.844444l0-199.111111q0-2.844444 2.844445-2.844445Z" fill="#D5DCE9" opacity=".398" p-id="2500"></path><path d="M369.777778 328.507733m2.844444 0l492.088889 0q2.844444 0 2.844445 2.844445l0 199.111111q0 2.844444-2.844445 2.844444l-492.088889 0q-2.844444 0-2.844444-2.844444l0-199.111111q0-2.844444 2.844444-2.844445Z" fill="#D5DCE9" opacity=".398" p-id="2501"></path><path d="M162.133333 558.907733m2.844445 0l492.088889 0q2.844444 0 2.844444 2.844445l0 145.066666q0 2.844444-2.844444 2.844445l-492.088889 0q-2.844444 0-2.844445-2.844445l0-145.066666q0-2.844444 2.844445-2.844445Z" fill="#D5DCE9" opacity=".398" p-id="2502"></path><path d="M682.666667 558.907733m2.844444 0l179.2 0q2.844444 0 2.844445 2.844445l0 145.066666q0 2.844444-2.844445 2.844445l-179.2 0q-2.844444 0-2.844444-2.844445l0-145.066666q0-2.844444 2.844444-2.844445Z" fill="#D5DCE9" opacity=".398" p-id="2503"></path><path d="M180.590933 185.585778c0 9.708089-7.850667 17.578667-17.530311 17.578666-9.682489 0-17.530311-7.870578-17.530311-17.578666 0-9.705244 7.850667-17.572978 17.530311-17.572978 9.682489 0 17.530311 7.867733 17.530311 17.572978" fill="#FF7946" p-id="2504"></path><path d="M246.055822 185.585778c0 9.708089-7.847822 17.578667-17.530311 17.578666-9.679644 0-17.527467-7.870578-17.527467-17.578666 0-9.705244 7.847822-17.572978 17.527467-17.572978 9.682489 0 17.530311 7.867733 17.530311 17.572978" fill="#FFC53D" p-id="2505"></path><path d="M311.523556 185.585778c0 9.708089-7.850667 17.578667-17.530312 17.578666-9.682489 0-17.530311-7.870578-17.530311-17.578666 0-9.705244 7.850667-17.572978 17.530311-17.572978 9.682489 0 17.530311 7.867733 17.530312 17.572978" fill="#BAE637" p-id="2506"></path><path d="M142.279111 648.533333s-26.601244 68.107378-23.665778 95.544889c2.121956 20.181333 26.493156 18.7392 29.354667 3.862756 5.532444-28.814222-5.688889-99.407644-5.688889-99.407645" fill="#75AE16" p-id="2507"></path><path d="M98.642489 682.459022s-9.597156 63.451022 0.568889 84.807111c7.486578 15.678578 32.147911 6.951822 31.212089-6.001777-1.820444-25.076622-31.780978-78.805333-31.780978-78.805334" fill="#5F960C" p-id="2508"></path><path d="M56.888889 692.969244s7.04 64.603022 22.175289 83.470223c11.087644 13.878044 32.381156 0 28.182755-12.529778C99.108978 739.569778 56.888889 692.969244 56.888889 692.969244" fill="#4B8108" p-id="2509"></path><path d="M170.197333 708.206933s-38.200889 35.134578-40.9088 53.341867c-1.979733 13.397333 20.969244 19.740444 26.567111 11.184356 10.851556-16.554667 14.341689-64.526222 14.341689-64.526223" fill="#2A6A13" p-id="2510"></path><path d="M61.604978 778.746311l3.794489-7.2704a13.175467 13.175467 0 0 1 8.684089-6.701511 13.371733 13.371733 0 0 1 10.823111 2.133333c1.991111 1.427911 4.753067 1.1776 6.448355-0.585955l3.925334-4.104534a17.194667 17.194667 0 0 1 13.357511-5.228088 17.129244 17.129244 0 0 1 12.669155 6.678755 4.952178 4.952178 0 0 0 5.944889 1.501867l2.542933-1.137778a20.622222 20.622222 0 0 1 19.029334 1.166222l7.890489 4.755911a4.969244 4.969244 0 0 0 4.639289 0.256 4.972089 4.972089 0 0 1 3.953777-0.079644c1.271467 0.517689 2.264178 1.541689 2.730667 2.816l2.338133 6.371555c0.540444 1.479111 0.318578 3.126044-0.603022 4.411734-0.918756 1.288533-2.417778 2.053689-4.010667 2.053689H65.948444a4.920889 4.920889 0 0 1-4.175644-2.321067 4.7616 4.7616 0 0 1-0.170667-4.716089" fill="#424242" p-id="2511"></path><path d="M108.168533 720.517689c2.929778 5.831111 6.411378 10.763378 6.920534 10.567111 0.509156-0.196267-0.557511-5.566578-3.447467-11.406222-2.8928-5.8368-6.638933-9.921422-7.145244-9.728-0.509156 0.201956 0.750933 4.738844 3.672177 10.567111z" fill="#8FAE16" p-id="2512"></path><path d="M140.814222 703.587556c0.605867 0 1.635556-4.8128 1.635556-10.749156 0-5.933511-1.058133-10.746311-1.635556-10.746311-0.577422 0-1.627022 4.8128-1.627022 10.746311 0 5.936356 1.021156 10.749156 1.627022 10.749156z" fill="#B3CE4F" p-id="2513"></path><path d="M152.5504 747.207111c-2.599822 5.671822-3.785956 10.4192-3.316622 10.609778 0.463644 0.187733 3.478756-4.260978 6.072889-9.938489 2.596978-5.674667 3.800178-10.402133 3.328-10.589867-0.463644-0.210489-3.478756 4.238222-6.084267 9.915734zM78.6176 733.954844c4.252444 5.262222 8.570311 9.264356 8.994133 8.96 0.426667-0.304356-2.153244-4.835556-6.4-10.089244-4.243911-5.256533-8.576-9.244444-9.005511-8.96-0.426667 0.312889 2.153244 4.827022 6.411378 10.089244z" fill="#6A960C" p-id="2514"></path><path d="M924.529778 583.111111s-39.899022 101.438578-35.498667 142.301867c3.185778 30.057244 39.739733 27.909689 44.032 5.751466 8.300089-42.916978-8.533333-148.053333-8.533333-148.053333" fill="#75AE16" p-id="2515"></path><path d="M859.073422 626.619733s-14.395733 94.498133 0.859022 126.3104c11.227022 23.3472 48.219022 10.350933 46.813867-8.942933-2.733511-37.347556-47.672889-117.367467-47.672889-117.367467" fill="#5F960C" p-id="2516"></path><path d="M796.444444 649.289956s10.561422 96.219022 33.260089 124.322133c16.631467 20.664889 48.574578 0 42.279823-18.6624C859.773156 718.697244 796.444444 649.289956 796.444444 649.289956" fill="#4B8108" p-id="2517"></path><path d="M966.405689 671.985778s-57.298489 52.3264-61.3632 79.445333c-2.9696 19.953778 31.453867 29.397333 39.850667 16.659911 16.278756-24.655644 21.512533-96.105244 21.512533-96.105244" fill="#2A6A13" p-id="2518"></path><path d="M803.518578 771.413333l5.688889-10.823111a19.740444 19.740444 0 0 1 13.0304-9.981155 20.1728 20.1728 0 0 1 16.233244 3.177244 7.486578 7.486578 0 0 0 9.671111-0.873244l5.888-6.112711a25.890133 25.890133 0 0 1 20.036267-7.788089c7.5264 0.418133 14.478222 4.059022 19.006578 9.949866a7.463822 7.463822 0 0 0 8.917333 2.235734l3.811556-1.692445a31.1296 31.1296 0 0 1 28.549688 1.732267l11.832889 7.085511c2.104889 1.262933 4.721778 1.408 6.957511 0.384a7.509333 7.509333 0 0 1 5.930667-0.125156c1.908622 0.776533 3.393422 2.301156 4.096 4.201245l3.5072 9.486222a7.051378 7.051378 0 0 1-0.904533 6.570667 7.404089 7.404089 0 0 1-6.018845 3.057778h-149.720177a7.392711 7.392711 0 0 1-6.260623-3.458845 7.048533 7.048533 0 0 1-0.256-7.025778" fill="#424242" p-id="2519"></path><path d="M873.366756 690.321067c4.388978 8.686933 9.614222 16.031289 10.376533 15.738311 0.762311-0.290133-0.836267-8.291556-5.168356-16.984178-4.340622-8.698311-9.955556-14.782578-10.720711-14.4896-0.762311 0.298667 1.1264 7.054222 5.512534 15.735467z" fill="#8FAE16" p-id="2520"></path><path d="M922.333867 665.105067c0.907378 0 2.451911-7.168 2.451911-16.005689 0-8.840533-1.5872-16.005689-2.451911-16.005689-0.8704 0-2.440533 7.165156-2.440534 16.005689 0 8.840533 1.530311 16.005689 2.440534 16.005689z" fill="#B3CE4F" p-id="2521"></path><path d="M939.938133 730.069333c-3.902578 8.450844-5.680356 15.522133-4.977777 15.803734 0.696889 0.284444 5.219556-6.345956 9.110755-14.799645 3.896889-8.453689 5.697422-15.493689 4.994845-15.772444-0.696889-0.312889-5.219556 6.314667-9.127823 14.768355zM829.036089 710.337422c6.380089 7.839289 12.856889 13.795556 13.4912 13.340445 0.642844-0.452267-3.228444-7.196444-9.597156-15.024356-6.368711-7.827911-12.868267-13.7728-13.511111-13.340444-0.634311 0.4608 3.231289 7.185067 9.614222 15.024355z" fill="#6A960C" p-id="2522"></path><path d="M418.178844 463.644444c0 51.913956 42.083556 94.000356 94.000356 94.000356 51.911111 0 93.997511-42.0864 93.997511-94.000356 0-51.913956-42.083556-94.000356-94.000355-94.000355-51.911111 0-93.997511 42.0864-93.997512 94.000355z" fill="#FF7575" p-id="2523"></path><path d="M505.179022 481.132089c1.1776 3.512889 3.510044 5.822578 6.997334 5.822578 3.512889 0 5.822578-2.332444 7.000177-5.822578l4.667734-64.1536c0-7.000178-5.822578-11.667911-11.665067-11.667911-7.000178 0-11.667911 5.822578-11.667911 12.845511l4.664889 62.976z m6.997334 17.513244c-6.997333 0-11.665067 4.664889-11.665067 11.665067 0 7.000178 4.664889 11.667911 11.665067 11.667911 7.000178 0 11.667911-4.664889 11.667911-11.667911 0-6.997333-4.664889-11.665067-11.665067-11.665067z" fill="#FFFFFF" p-id="2524"></path></svg>
|
|
4
|
+
<p>该应用已停止使用</p>
|
|
5
|
+
</div>
|
|
6
|
+
<div class="error" v-else>
|
|
7
|
+
<i class="epx-icon-color-a-500"></i>
|
|
8
|
+
<p>应用加载错误,<a @click="reload">点击刷新</a></p>
|
|
9
|
+
</div>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<script>
|
|
13
|
+
export default {
|
|
14
|
+
name: 'epx-error',
|
|
15
|
+
data () {
|
|
16
|
+
return {
|
|
17
|
+
errCode: ''
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
methods: {
|
|
21
|
+
reload () {
|
|
22
|
+
window.location.reload(true)
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
created () {
|
|
26
|
+
const url = this.$util.search('url')
|
|
27
|
+
this.errCode = this.$util.search('code')
|
|
28
|
+
setTimeout(() => {
|
|
29
|
+
window.history.replaceState(null, null, url)
|
|
30
|
+
}, 10)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<style lang="scss" scoped>
|
|
36
|
+
.error {
|
|
37
|
+
font-size: 140px;
|
|
38
|
+
text-align: center;
|
|
39
|
+
line-height: 1;
|
|
40
|
+
position: absolute;
|
|
41
|
+
top: 50%;
|
|
42
|
+
width: 100%;
|
|
43
|
+
margin-top: -150px;
|
|
44
|
+
p {
|
|
45
|
+
font-size: 18px;
|
|
46
|
+
color:var(--epx-text);
|
|
47
|
+
margin-top: 30px
|
|
48
|
+
}
|
|
49
|
+
a {
|
|
50
|
+
cursor: pointer;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
.off {
|
|
54
|
+
margin-top: -170px;
|
|
55
|
+
svg {
|
|
56
|
+
width: 300px;
|
|
57
|
+
height: 300px;
|
|
58
|
+
}
|
|
59
|
+
p {
|
|
60
|
+
margin-top: -10px;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
</style>
|