重建入口
This commit is contained in:
parent
ef40b81a50
commit
71fa900582
4
public/config.js
vendored
4
public/config.js
vendored
|
@ -1,7 +1,7 @@
|
|||
window._CONFIG = {
|
||||
ImageryProviderUrl: 'http://127.0.0.1:8090/mapWX/{z}/{x}/{y}.jpg',
|
||||
ImageryProviderUrl: '/map/mapWX/{z}/{x}/{y}.jpg',
|
||||
RoadProviderUrl: '',
|
||||
TerrainProviderUrl: 'http://127.0.0.1:8090/mapDem/',
|
||||
TerrainProviderUrl: '/map/mapDem/',
|
||||
thirdLoginUrl: 'http://127.0.0.1:8080/thirdLogin',
|
||||
clientId: '0123456789',
|
||||
evaluationSrc: 'http://127.0.0.1:8000',
|
||||
|
|
74
src/App.vue
74
src/App.vue
|
@ -129,4 +129,78 @@ export default {
|
|||
.scroller-y {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.oh {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.pr {
|
||||
position: relative;
|
||||
}
|
||||
.pa {
|
||||
position: absolute;
|
||||
}
|
||||
.pf {
|
||||
position: fixed;
|
||||
}
|
||||
.zi0 {
|
||||
z-index: 0;
|
||||
}
|
||||
.zi1 {
|
||||
z-index: 1;
|
||||
}
|
||||
.zi2 {
|
||||
z-index: 2;
|
||||
}
|
||||
.zi3 {
|
||||
z-index: 3;
|
||||
}
|
||||
.zi4 {
|
||||
z-index: 4;
|
||||
}
|
||||
.zi5 {
|
||||
z-index: 5;
|
||||
}
|
||||
.zi6 {
|
||||
z-index: 6;
|
||||
}
|
||||
.zi7 {
|
||||
z-index: 7;
|
||||
}
|
||||
.zi8 {
|
||||
z-index: 8;
|
||||
}
|
||||
.zi9 {
|
||||
z-index: 9;
|
||||
}
|
||||
.zi10 {
|
||||
z-index: 10;
|
||||
}
|
||||
.zi20 {
|
||||
z-index: 20;
|
||||
}
|
||||
.zi50 {
|
||||
z-index: 50;
|
||||
}
|
||||
.zi100 {
|
||||
z-index: 100;
|
||||
}
|
||||
.zi200 {
|
||||
z-index: 200;
|
||||
}
|
||||
.zi500 {
|
||||
z-index: 500;
|
||||
}
|
||||
.zi1000 {
|
||||
z-index: 1000;
|
||||
}
|
||||
.zi2000 {
|
||||
z-index: 2000;
|
||||
}
|
||||
.zi5000 {
|
||||
z-index: 5000;
|
||||
}
|
||||
.zi9999 {
|
||||
z-index: 9999;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -7,156 +7,7 @@ const RouteView = {
|
|||
render: (h) => h('router-view'),
|
||||
}
|
||||
|
||||
export const asyncRouterMap = [
|
||||
{
|
||||
path: '/',
|
||||
name: 'index',
|
||||
component: BasicLayout,
|
||||
meta: { title: 'menu.home' },
|
||||
redirect: '/user/thirdLogin',
|
||||
children: [
|
||||
// dashboard
|
||||
{
|
||||
path: '/dashboard',
|
||||
name: 'dashboard',
|
||||
redirect: '/dashboard/workplace',
|
||||
component: RouteView,
|
||||
// meta: { title: 'menu.dashboard', keepAlive: true, icon: bxAnaalyse, permission: ['dashboard'] },
|
||||
meta: { title: '基础数据管理工具', keepAlive: true, icon: bxAnaalyse },
|
||||
children: [
|
||||
{
|
||||
path: '/dashboard/workplace',
|
||||
name: 'Workplace',
|
||||
component: () => import('@/views/dashboard/WorkplaceEquipment'),
|
||||
meta: { title: '主页', keepAlive: true },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/map',
|
||||
name: 'map',
|
||||
redirect: '/map/index',
|
||||
component: RouteView,
|
||||
// meta: { title: 'menu.dashboard', keepAlive: true, icon: bxAnaalyse, permission: ['dashboard'] },
|
||||
meta: { title: '地图资源库', keepAlive: true, icon: bxAnaalyse },
|
||||
children: [
|
||||
{
|
||||
path: '/map/index',
|
||||
name: 'mapIndex',
|
||||
component: () => import('@/views/map/mapIndex'),
|
||||
meta: { title: '主页', keepAlive: true },
|
||||
},
|
||||
],
|
||||
},
|
||||
// isystem
|
||||
{
|
||||
path: '/isystem',
|
||||
name: 'isystem',
|
||||
// redirect: '/isystem/workplace',
|
||||
component: RouteView,
|
||||
meta: { title: '后台管理', keepAlive: true, icon: bxAnaalyse, permission: ['isystem'] },
|
||||
children: [
|
||||
{
|
||||
path: '/isystem/userlist',
|
||||
name: 'userlist',
|
||||
component: () => import('@/views/isystem/userList'),
|
||||
meta: { title: '用户管理', keepAlive: true, permission: ['isystem'] },
|
||||
},
|
||||
{
|
||||
path: '/isystem/rolelist',
|
||||
name: 'rolelist',
|
||||
component: () => import('@/views/isystem/roleList'),
|
||||
meta: { title: '角色管理', keepAlive: true, permission: ['isystem'] },
|
||||
},
|
||||
{
|
||||
path: '/isystem/cookieList',
|
||||
name: 'cookieList',
|
||||
component: () => import('@/views/isystem/cookieList'),
|
||||
meta: { title: '缓存管理', keepAlive: true, permission: ['isystem'] },
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// account
|
||||
{
|
||||
path: '/account',
|
||||
component: RouteView,
|
||||
redirect: '/account/center',
|
||||
name: 'account',
|
||||
hidden: true,
|
||||
meta: { title: 'menu.account', icon: 'user', keepAlive: true, hidden: true, permission: ['user'] },
|
||||
children: [
|
||||
{
|
||||
path: '/account/center',
|
||||
name: 'center',
|
||||
component: () => import('@/views/account/center'),
|
||||
meta: { title: 'menu.account.center', keepAlive: true, permission: ['user'] },
|
||||
},
|
||||
{
|
||||
path: '/account/settings',
|
||||
name: 'settings',
|
||||
component: () => import('@/views/account/settings/Index'),
|
||||
meta: { title: 'menu.account.settings', hideHeader: true, permission: ['user'] },
|
||||
redirect: '/account/settings/basic',
|
||||
hideChildrenInMenu: true,
|
||||
children: [
|
||||
{
|
||||
path: '/account/settings/basic',
|
||||
name: 'BasicSettings',
|
||||
component: () => import('@/views/account/settings/BasicSetting'),
|
||||
meta: { title: 'account.settings.menuMap.basic', hidden: true, permission: ['user'] },
|
||||
},
|
||||
{
|
||||
path: '/account/settings/security',
|
||||
name: 'SecuritySettings',
|
||||
component: () => import('@/views/account/settings/Security'),
|
||||
meta: {
|
||||
title: 'account.settings.menuMap.security',
|
||||
hidden: true,
|
||||
keepAlive: true,
|
||||
permission: ['user'],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/account/settings/custom',
|
||||
name: 'CustomSettings',
|
||||
component: () => import('@/views/account/settings/Custom'),
|
||||
meta: { title: 'account.settings.menuMap.custom', hidden: true, keepAlive: true, permission: ['user'] },
|
||||
},
|
||||
{
|
||||
path: '/account/settings/binding',
|
||||
name: 'BindingSettings',
|
||||
component: () => import('@/views/account/settings/Binding'),
|
||||
meta: {
|
||||
title: 'account.settings.menuMap.binding',
|
||||
hidden: true,
|
||||
keepAlive: true,
|
||||
permission: ['user'],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/account/settings/notification',
|
||||
name: 'NotificationSettings',
|
||||
component: () => import('@/views/account/settings/Notification'),
|
||||
meta: {
|
||||
title: 'account.settings.menuMap.notification',
|
||||
hidden: true,
|
||||
keepAlive: true,
|
||||
permission: ['user'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '*',
|
||||
redirect: '/404',
|
||||
hidden: true,
|
||||
},
|
||||
]
|
||||
export const asyncRouterMap = []
|
||||
|
||||
/**
|
||||
* 基础路由
|
||||
|
@ -164,143 +15,17 @@ export const asyncRouterMap = [
|
|||
*/
|
||||
export const constantRouterMap = [
|
||||
{
|
||||
path: '/user',
|
||||
component: UserLayout,
|
||||
redirect: '/user/login',
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: 'login',
|
||||
name: 'login',
|
||||
component: () => import(/* webpackChunkName: "user" */ '@/views/user/Login'),
|
||||
path: '/',
|
||||
name: 'index',
|
||||
component: RouteView,
|
||||
meta: { title: '某仿真分析方法工具' },
|
||||
redirect: '/user/welcome',
|
||||
},
|
||||
{
|
||||
path: 'thirdLogin',
|
||||
name: 'thirdLogin',
|
||||
component: () => import(/* webpackChunkName: "user" */ '@/views/user/ThirdLogin'),
|
||||
},
|
||||
{
|
||||
path: 'register',
|
||||
name: 'register',
|
||||
component: () => import(/* webpackChunkName: "user" */ '@/views/user/Register'),
|
||||
},
|
||||
{
|
||||
path: 'register-result',
|
||||
name: 'registerResult',
|
||||
component: () => import(/* webpackChunkName: "user" */ '@/views/user/RegisterResult'),
|
||||
},
|
||||
{
|
||||
path: 'recover',
|
||||
name: 'recover',
|
||||
component: undefined,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
path: '/other',
|
||||
component: BasicLayout,
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: 'resetPwd',
|
||||
name: '重置密码',
|
||||
meta: {
|
||||
title: '重置密码',
|
||||
},
|
||||
component: () => import('@/views/user/ResetPwd.vue'),
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
path: '/simulationScene',
|
||||
name: 'SimulationScene',
|
||||
component: () => import(/* webpackChunkName: "fail" */ '@/views/simulationScene/index.vue'),
|
||||
redirect: '/simulationScene/centralControl',
|
||||
children: [
|
||||
{
|
||||
path: '/simulationScene/trainer',
|
||||
name: 'SimulationSceneTrainer',
|
||||
//component: () => import(/* webpackChunkName: "fail" */ '@/views/simulationScene/trainer/index.vue'),
|
||||
component: () => import(/* webpackChunkName: "fail" */ '@/views/simulationScene/instructor/index.vue'),
|
||||
meta: { title: '训练员系统' },
|
||||
},
|
||||
{
|
||||
path: '/simulationScene/trainerSystem',
|
||||
name: 'SimulationSceneTrainerSystem',
|
||||
component: () => import(/* webpackChunkName: "fail" */ '@/views/simulationScene/trainer/system/index.vue'),
|
||||
children: [
|
||||
{
|
||||
path: '/simulationScene/trainerSystem/simulationModel',
|
||||
name: 'SimulationSceneTrainerSystemSimulationModel',
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "fail" */ '@/views/simulationScene/trainer/system/simulationModel/index1.vue'),
|
||||
},
|
||||
{
|
||||
path: '/simulationScene/trainerSystem/sceneEditing',
|
||||
name: 'SimulationSceneTrainerSystemSceneEditing',
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "fail" */ '@/views/simulationScene/trainer/system/sceneEditing/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/simulationScene/trainerSystem/display',
|
||||
name: 'SimulationSceneTrainerSystemDisplay',
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "fail" */ '@/views/simulationScene/trainer/system/display/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/simulationScene/trainerSystem/evaluation',
|
||||
name: 'SimulationSceneTrainerSystemEvaluation',
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "fail" */ '@/views/simulationScene/trainer/system/evaluation/index.vue'),
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
path: '/simulationScene/instructor',
|
||||
name: 'SimulationSceneInstructor',
|
||||
component: () => import(/* webpackChunkName: "fail" */ '@/views/simulationScene/instructor/index.vue'),
|
||||
meta: { title: '教员系统' },
|
||||
},
|
||||
{
|
||||
path: '/simulationScene/instructorSystem',
|
||||
name: 'SimulationSceneInstructorSystem',
|
||||
component: () => import(/* webpackChunkName: "fail" */ '@/views/simulationScene/instructor/system/index.vue'),
|
||||
children: [
|
||||
{
|
||||
path: '/simulationScene/instructorSystem/simulationModel',
|
||||
name: 'SimulationSceneInstructorSystemSimulationModel',
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "fail" */ '@/views/simulationScene/instructor/system/simulationModel/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/simulationScene/instructorSystem/sceneEditing',
|
||||
name: 'SimulationSceneInstructorSystemSceneEditing',
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "fail" */ '@/views/simulationScene/instructor/system/sceneEditing/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/simulationScene/instructorSystem/display',
|
||||
name: 'SimulationSceneInstructorSystemDisplay',
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "fail" */ '@/views/simulationScene/instructor/system/display/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/simulationScene/instructorSystem/evaluation',
|
||||
name: 'SimulationSceneInstructorSystemEvaluation',
|
||||
component: () =>
|
||||
import(/* webpackChunkName: "fail" */ '@/views/simulationScene/instructor/system/evaluation/index.vue'),
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
path: '/simulationScene/systemSelect',
|
||||
name: 'SimulationSceneSystemSelect',
|
||||
component: () => import(/* webpackChunkName: "fail" */ '@/views/simulationScene/systemSelect/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/simulationScene/centralControl',
|
||||
name: 'SimulationSceneCentralControl',
|
||||
|
@ -323,6 +48,7 @@ export const constantRouterMap = [
|
|||
path: '/simulationScene/sceneEditing',
|
||||
name: 'SimulationSceneSceneEditing',
|
||||
component: () => import(/* webpackChunkName: "fail" */ '@/views/simulationScene/sceneEditing/index.vue'),
|
||||
meta: { title: '场景编辑子系统' },
|
||||
},
|
||||
{
|
||||
path: '/simulationScene/display',
|
||||
|
@ -338,9 +64,30 @@ export const constantRouterMap = [
|
|||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
path: '/user',
|
||||
component: UserLayout,
|
||||
redirect: '/user/login',
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: '/user/login',
|
||||
name: 'login',
|
||||
component: () => import(/* webpackChunkName: "user" */ '@/views/user/Login'),
|
||||
},
|
||||
{
|
||||
path: '/user/welcome',
|
||||
name: 'Welcome',
|
||||
component: () => import(/* webpackChunkName: "user" */ '@/views/user/Welcome'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/404',
|
||||
component: () => import(/* webpackChunkName: "fail" */ '@/views/exception/404'),
|
||||
},
|
||||
{
|
||||
path: '*',
|
||||
redirect: '/404',
|
||||
},
|
||||
]
|
||||
|
|
|
@ -9,71 +9,38 @@
|
|||
:i18nRender="i18nRender"
|
||||
v-bind="settings"
|
||||
>
|
||||
<!-- Ads begin
|
||||
广告代码 真实项目中请移除
|
||||
production remove this Ads
|
||||
-->
|
||||
<ads v-if="isProPreviewSite && !collapsed"/>
|
||||
<!-- Ads end -->
|
||||
|
||||
<!-- 1.0.0+ 版本 pro-layout 提供 API,
|
||||
我们推荐使用这种方式进行 LOGO 和 title 自定义
|
||||
-->
|
||||
<template v-slot:menuHeaderRender>
|
||||
<div>
|
||||
<logo-svg />
|
||||
<h1>{{ title }}</h1>
|
||||
</div>
|
||||
<div></div>
|
||||
</template>
|
||||
|
||||
<!-- 1.0.0+ 版本 pro-layout 提供 API,
|
||||
增加 Header 左侧内容区自定义
|
||||
-->
|
||||
<template v-slot:headerContentRender>
|
||||
<!-- <template v-slot:headerContentRender>
|
||||
<div>
|
||||
<a-tooltip title="刷新页面">
|
||||
<a-icon type="reload" style="font-size: 18px;cursor: pointer;" @click="() => { $message.info('页面刷新') }" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
</template> -->
|
||||
|
||||
<!-- <setting-drawer v-if="isDev" :settings="settings" @change="handleSettingChange">
|
||||
<div style="margin: 12px 0;">
|
||||
This is SettingDrawer custom footer content.
|
||||
</div>
|
||||
</setting-drawer> -->
|
||||
<template v-slot:rightContentRender>
|
||||
<right-content :top-menu="settings.layout === 'topmenu'" :is-mobile="isMobile" :theme="settings.theme" />
|
||||
</template>
|
||||
<!-- custom footer / 自定义Footer -->
|
||||
<template v-slot:footerRender>
|
||||
<global-footer />
|
||||
</template>
|
||||
<router-view />
|
||||
</pro-layout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { SettingDrawer, updateTheme } from '@ant-design-vue/pro-layout'
|
||||
import { i18nRender } from '@/locales'
|
||||
import { mapState } from 'vuex'
|
||||
import { CONTENT_WIDTH_TYPE, SIDEBAR_TYPE, TOGGLE_MOBILE_TYPE } from '@/store/mutation-types'
|
||||
|
||||
import defaultSettings from '@/config/defaultSettings'
|
||||
import RightContent from '@/components/GlobalHeader/RightContent'
|
||||
import GlobalFooter from '@/components/GlobalFooter'
|
||||
import Ads from '@/components/Other/CarbonAds'
|
||||
import LogoSvg from '../assets/logo.svg?inline'
|
||||
|
||||
export default {
|
||||
name: 'BasicLayout',
|
||||
components: {
|
||||
SettingDrawer,
|
||||
RightContent,
|
||||
GlobalFooter,
|
||||
LogoSvg,
|
||||
Ads
|
||||
},
|
||||
data () {
|
||||
data() {
|
||||
return {
|
||||
// preview.pro.antdv.com only use.
|
||||
isProPreviewSite: process.env.VUE_APP_PREVIEW === 'true' && process.env.NODE_ENV !== 'development',
|
||||
|
@ -99,24 +66,23 @@ export default {
|
|||
colorWeak: defaultSettings.colorWeak,
|
||||
|
||||
hideHintAlert: false,
|
||||
hideCopyButton: false
|
||||
hideCopyButton: false,
|
||||
},
|
||||
// 媒体查询
|
||||
query: {},
|
||||
|
||||
// 是否手机模式
|
||||
isMobile: false
|
||||
isMobile: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
// 动态主路由
|
||||
mainMenu: state => state.permission.addRouters
|
||||
})
|
||||
mainMenu: (state) => state.permission.addRouters,
|
||||
}),
|
||||
},
|
||||
created () {
|
||||
const routes = this.mainMenu.find(item => item.path === '/')
|
||||
this.menus = (routes && routes.children) || []
|
||||
created() {
|
||||
this.menus = this.mainMenu || []
|
||||
// 处理侧栏收起状态
|
||||
this.$watch('collapsed', () => {
|
||||
this.$store.commit(SIDEBAR_TYPE, this.collapsed)
|
||||
|
@ -125,7 +91,7 @@ export default {
|
|||
this.$store.commit(TOGGLE_MOBILE_TYPE, this.isMobile)
|
||||
})
|
||||
},
|
||||
mounted () {
|
||||
mounted() {
|
||||
const userAgent = navigator.userAgent
|
||||
if (userAgent.indexOf('Edge') > -1) {
|
||||
this.$nextTick(() => {
|
||||
|
@ -135,16 +101,10 @@ export default {
|
|||
}, 16)
|
||||
})
|
||||
}
|
||||
|
||||
// first update color
|
||||
// TIPS: THEME COLOR HANDLER!! PLEASE CHECK THAT!!
|
||||
if (process.env.NODE_ENV !== 'production' || process.env.VUE_APP_PREVIEW === 'true') {
|
||||
updateTheme(this.settings.primaryColor)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
i18nRender,
|
||||
handleMediaQuery (val) {
|
||||
handleMediaQuery(val) {
|
||||
this.query = val
|
||||
if (this.isMobile && !val['screen-xs']) {
|
||||
this.isMobile = false
|
||||
|
@ -157,10 +117,10 @@ export default {
|
|||
// this.settings.fixSiderbar = false
|
||||
}
|
||||
},
|
||||
handleCollapse (val) {
|
||||
handleCollapse(val) {
|
||||
this.collapsed = val
|
||||
},
|
||||
handleSettingChange ({ type, value }) {
|
||||
handleSettingChange({ type, value }) {
|
||||
console.log('type', type, value)
|
||||
type && (this.settings[type] = value)
|
||||
switch (type) {
|
||||
|
@ -176,11 +136,11 @@ export default {
|
|||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@import "./BasicLayout.less";
|
||||
@import './BasicLayout.less';
|
||||
</style>
|
||||
|
|
|
@ -1,165 +1,27 @@
|
|||
<template>
|
||||
<div id="userLayout" :class="['user-layout-wrapper', isMobile && 'mobile']">
|
||||
<img style="position: absolute; left: 0; top: 0; width: 100%; height: 100%; object-fit: cover" :src="bg" alt="" />
|
||||
<div class="container">
|
||||
<div class="user-layout-lang">
|
||||
<!-- <select-lang class="select-lang-trigger" /> -->
|
||||
<Grid class="user-layout-wrapper">
|
||||
<div class="bg-wrapper" style="grid-area: 1 / 1 / 2 / 2">
|
||||
<img style="width: 100%; height: 100%; object-fit: cover" :src="bg" alt="" />
|
||||
</div>
|
||||
<div class="user-layout-content">
|
||||
<div class="page-wrapper" style="grid-area: 1 / 1 / 2 / 2">
|
||||
<router-view />
|
||||
|
||||
<div class="footer">
|
||||
<div class="copyright">
|
||||
<!-- Copyright © 2022 北京五木恒润科技有限公司 -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Grid>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { deviceMixin } from '@/store/device-mixin'
|
||||
// import SelectLang from '@/components/SelectLang'
|
||||
|
||||
export default {
|
||||
name: 'UserLayout',
|
||||
// components: {
|
||||
// SelectLang,
|
||||
// },
|
||||
mixins: [deviceMixin],
|
||||
data() {
|
||||
return {
|
||||
bg: require('@/assets/images/user/bg.jpg'),
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
document.body.classList.add('userLayout')
|
||||
},
|
||||
beforeDestroy() {
|
||||
document.body.classList.remove('userLayout')
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
#userLayout.user-layout-wrapper {
|
||||
.user-layout-wrapper {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
&.mobile {
|
||||
.container {
|
||||
.main {
|
||||
max-width: 368px;
|
||||
width: 98%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
// background: #f0f2f5 url(~@/assets/background.png) no-repeat 50%;
|
||||
background-size: 100%;
|
||||
//padding: 50px 0 84px;
|
||||
position: relative;
|
||||
|
||||
.user-layout-lang {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
line-height: 44px;
|
||||
text-align: right;
|
||||
|
||||
.select-lang-trigger {
|
||||
cursor: pointer;
|
||||
padding: 12px;
|
||||
margin-right: 24px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 18px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.user-layout-content {
|
||||
padding: 32px 0 24px;
|
||||
|
||||
.top {
|
||||
text-align: center;
|
||||
|
||||
.header {
|
||||
height: 44px;
|
||||
line-height: 44px;
|
||||
|
||||
.badge {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
vertical-align: middle;
|
||||
margin-left: -12px;
|
||||
margin-top: -10px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 44px;
|
||||
vertical-align: top;
|
||||
margin-right: 16px;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 33px;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
font-family: Avenir, 'Helvetica Neue', Arial, Helvetica, sans-serif;
|
||||
font-weight: 600;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
}
|
||||
.desc {
|
||||
font-size: 14px;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
margin-top: 12px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.main {
|
||||
min-width: 260px;
|
||||
width: 368px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.footer {
|
||||
// position: absolute;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
padding: 0 16px;
|
||||
margin: 48px 0 24px;
|
||||
text-align: center;
|
||||
|
||||
.links {
|
||||
margin-bottom: 8px;
|
||||
font-size: 14px;
|
||||
a {
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
transition: all 0.3s;
|
||||
&:not(:last-child) {
|
||||
margin-right: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.copyright {
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -35,7 +35,6 @@ router.beforeEach((to, from, next) => {
|
|||
// 根据roles权限生成可访问的路由表
|
||||
// 动态添加可访问路由表
|
||||
// VueRouter@3.5.0+ New API
|
||||
console.log(2345)
|
||||
|
||||
store.getters.addRouters.forEach((r) => {
|
||||
router.addRoute(r)
|
||||
|
|
|
@ -82,17 +82,12 @@ export const generatorDynamicRouter = token => {
|
|||
.then(res => {
|
||||
console.log('generatorDynamicRouter response:', res)
|
||||
const data = res.data
|
||||
const menuNav = []
|
||||
const childrenNav = []
|
||||
// console.log('data', res.data)
|
||||
// 后端数据, 根级树数组, 根级 PID
|
||||
listToTree(data, childrenNav, '')
|
||||
console.log('childrenNav', childrenNav)
|
||||
rootRouter.children = childrenNav
|
||||
menuNav.push(rootRouter)
|
||||
console.log('menuNav', menuNav)
|
||||
const routers = generator(menuNav)
|
||||
routers.push(notFoundRouter)
|
||||
const routers = generator(childrenNav)
|
||||
console.log('routers', routers)
|
||||
resolve(routers)
|
||||
})
|
||||
|
|
|
@ -7,26 +7,25 @@ import { generatorDynamicRouter } from '@/router/generator-routers'
|
|||
const permission = {
|
||||
state: {
|
||||
routers: constantRouterMap,
|
||||
addRouters: []
|
||||
addRouters: [],
|
||||
},
|
||||
mutations: {
|
||||
SET_ROUTERS: (state, routers) => {
|
||||
state.addRouters = routers
|
||||
state.routers = constantRouterMap.concat(routers)
|
||||
}
|
||||
state.routers = [].concat(routers, constantRouterMap)
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
GenerateRoutes ({ commit }, data) {
|
||||
return new Promise(resolve => {
|
||||
GenerateRoutes({ commit }, data) {
|
||||
return new Promise((resolve) => {
|
||||
// const { token } = data
|
||||
generatorDynamicRouter().then(routers => {
|
||||
console.log(routers,'routers')
|
||||
generatorDynamicRouter().then((routers) => {
|
||||
commit('SET_ROUTERS', routers)
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export default permission
|
||||
|
|
|
@ -64,7 +64,6 @@ const permission = {
|
|||
},
|
||||
actions: {
|
||||
GenerateRoutes ({ commit }, data) {
|
||||
console.log('adfafadfasddf')
|
||||
return new Promise(resolve => {
|
||||
const { roles } = data
|
||||
const routerMap = cloneDeep(asyncRouterMap)
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
<div class="simulation-scene-page flex-c">
|
||||
<Flex v-if="title" jc="sb" ai="c" class="simulation-scene-header">
|
||||
<div class="simulation-scene-title">{{ title }}</div>
|
||||
<div><a-icon type="poweroff" title="退出系统" style="color: red" @click="handleQuit" /></div>
|
||||
</Flex>
|
||||
<div class="simulation-scene-main">
|
||||
<router-view></router-view>
|
||||
|
@ -22,11 +21,6 @@ export default {
|
|||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleQuit() {
|
||||
this.$router.push({ name: 'thirdLogin' })
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,44 +1,13 @@
|
|||
<template>
|
||||
<div class="flexColumnCenterCenter" style="width: 100%; height: 100vh; position: fixed; left: 0; top: 0">
|
||||
<div
|
||||
style="
|
||||
height: 36px;
|
||||
font-size: 36px;
|
||||
line-height: 1;
|
||||
font-weight: bolder;
|
||||
letter-spacing: 7px;
|
||||
color: #ffffff;
|
||||
margin-bottom: 75px;
|
||||
"
|
||||
>
|
||||
某仿真分析方法工具
|
||||
<Flex class="user-login-page" fd="co" ai="c" jc="c" style="height: 100%">
|
||||
<div class="user-login-title">某仿真分析方法工具</div>
|
||||
<Grid style="width: 917px; height: 445px" :columns="['524px', '329px', '0px']" gap="32px">
|
||||
<div class="oh" style="grid-area: 1 / 1 / 2 / 4">
|
||||
<img class="user-login-bg" :src="bgLogin" alt="" />
|
||||
</div>
|
||||
<div style="width: 917px; height: 445px; position: relative; overflow: hidden" class="flexRowStart">
|
||||
<img
|
||||
style="position: absolute; left: -10px; top: -8px; z-index: 1; width: 937px; height: 465px"
|
||||
:src="bgLogin"
|
||||
alt=""
|
||||
/>
|
||||
<div style="width: 524px; height: 100%; position: relative; z-index: 2" class="flexColumnCenterCenter">
|
||||
<!-- <img src="@/assets/loginLeft.png" alt="" style="width: 100%;height: 100%;"> -->
|
||||
</div>
|
||||
<div style="width: 393px; height: 100%; padding: 48px 32px; position: relative; z-index: 3">
|
||||
<div class="main">
|
||||
<div
|
||||
style="
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
font-weight: bolder;
|
||||
font-stretch: normal;
|
||||
letter-spacing: 5px;
|
||||
color: #ffffff;
|
||||
margin-bottom: 27px;
|
||||
"
|
||||
>
|
||||
用户登录
|
||||
</div>
|
||||
<a-form id="formLogin" class="user-layout-login" ref="formLogin" :form="form" @submit="handleSubmit">
|
||||
<!-- <a-alert v-if="isLoginError" type="error" showIcon style="margin-bottom: 24px;" :message="$t('user.login.message-invalid-credentials')" /> -->
|
||||
<Flex class="pr zi1" fd="co" jc="c" style="grid-area: 1 / 2 / 2 / 3">
|
||||
<div class="user-login-form-title">用户登录</div>
|
||||
<a-form class="user-login-form-body" :form="form" @submit="handleSubmit">
|
||||
<a-form-item>
|
||||
<a-input
|
||||
size="large"
|
||||
|
@ -71,10 +40,10 @@
|
|||
<a-icon slot="prefix" type="lock" :style="{ color: 'rgba(0,0,0,.25)' }" />
|
||||
</a-input-password>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item>
|
||||
<div class="f-item">
|
||||
<div class="pr">
|
||||
<a-input
|
||||
class="login-ipt"
|
||||
size="large"
|
||||
type="text"
|
||||
placeholder="验证码"
|
||||
|
@ -87,19 +56,10 @@
|
|||
]"
|
||||
>
|
||||
</a-input>
|
||||
<img class="code" :src="codeImg" @click="codeClick" ref="code" alt="更新验证码" />
|
||||
<img class="code pa" :src="codeImg" @click="codeClick" ref="code" alt="更新验证码" />
|
||||
</div>
|
||||
</a-form-item>
|
||||
|
||||
<!-- <a-form-item>
|
||||
<a-checkbox v-decorator="['rememberMe', { valuePropName: 'checked' }]">{{ $t('user.login.remember-me') }}</a-checkbox>
|
||||
<router-link
|
||||
:to="{ name: 'recover', params: { user: 'aaa'} }"
|
||||
class="forge-password"
|
||||
style="float: right;"
|
||||
>{{ $t('user.login.forgot-password') }}</router-link>
|
||||
</a-form-item> -->
|
||||
|
||||
<a-form-item style="margin-top: 16px">
|
||||
<a-button
|
||||
size="large"
|
||||
|
@ -109,69 +69,39 @@
|
|||
:loading="state.loginBtn"
|
||||
:disabled="state.loginBtn"
|
||||
>
|
||||
{{ $t('user.login.login') }}
|
||||
登录
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<two-step-captcha
|
||||
v-if="requiredTwoStepCaptcha"
|
||||
:visible="stepCaptchaVisible"
|
||||
@success="stepCaptchaSuccess"
|
||||
@cancel="stepCaptchaCancel"
|
||||
></two-step-captcha>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Flex>
|
||||
</Grid>
|
||||
</Flex>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import md5 from 'md5'
|
||||
import TwoStepCaptcha from '@/components/tools/TwoStepCaptcha'
|
||||
import { mapActions } from 'vuex'
|
||||
import { timeFix } from '@/utils/util'
|
||||
import { getSmsCaptcha } from '@/api/login'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
TwoStepCaptcha,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
bgLogin: require('@/assets/images/user/bg-login.png'),
|
||||
customActiveKey: 'tab1',
|
||||
loginBtn: false,
|
||||
// login type: 0 email, 1 username, 2 telephone
|
||||
loginType: 0,
|
||||
isLoginError: false,
|
||||
requiredTwoStepCaptcha: false,
|
||||
stepCaptchaVisible: false,
|
||||
form: this.$form.createForm(this),
|
||||
state: {
|
||||
time: 60,
|
||||
loginBtn: false,
|
||||
// login type: 0 email, 1 username, 2 telephone
|
||||
loginType: 0,
|
||||
smsSendBtn: false,
|
||||
},
|
||||
clientCode: '',
|
||||
codeImg: '',
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// get2step({ })
|
||||
// .then(res => {
|
||||
// this.requiredTwoStepCaptcha = res.result.stepCode
|
||||
// })
|
||||
// .catch(() => {
|
||||
// this.requiredTwoStepCaptcha = false
|
||||
// })
|
||||
// this.requiredTwoStepCaptcha = true
|
||||
this.codeClick()
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['Login', 'Logout']),
|
||||
...mapActions(['Login']),
|
||||
codeClick() {
|
||||
this.clientCode = 'c' + Math.random() * 100000000
|
||||
this.codeImg = '/api/validateCode?t=' + new Date().getTime() + '&clientCode=' + this.clientCode
|
||||
|
@ -187,26 +117,20 @@ export default {
|
|||
}
|
||||
callback()
|
||||
},
|
||||
handleTabClick(key) {
|
||||
this.customActiveKey = key
|
||||
// this.form.resetFields()
|
||||
},
|
||||
handleSubmit(e) {
|
||||
e.preventDefault()
|
||||
const {
|
||||
form: { validateFields },
|
||||
state,
|
||||
customActiveKey,
|
||||
Login,
|
||||
} = this
|
||||
|
||||
state.loginBtn = true
|
||||
|
||||
const validateFieldsKey = customActiveKey === 'tab1' ? ['username', 'password', 'code'] : ['mobile', 'captcha']
|
||||
const validateFieldsKey = ['username', 'password', 'code']
|
||||
|
||||
validateFields(validateFieldsKey, { force: true }, (err, values) => {
|
||||
if (!err) {
|
||||
console.log('login form', values)
|
||||
const loginParams = { ...values, clientCode: this.clientCode }
|
||||
delete loginParams.username
|
||||
loginParams[!state.loginType ? 'email' : 'userName'] = values.username
|
||||
|
@ -217,7 +141,6 @@ export default {
|
|||
})
|
||||
.catch((err) => {
|
||||
this.requestFailed(err)
|
||||
console.log(err)
|
||||
})
|
||||
.finally(() => {
|
||||
state.loginBtn = false
|
||||
|
@ -229,69 +152,9 @@ export default {
|
|||
}
|
||||
})
|
||||
},
|
||||
getCaptcha(e) {
|
||||
e.preventDefault()
|
||||
const {
|
||||
form: { validateFields },
|
||||
state,
|
||||
} = this
|
||||
|
||||
validateFields(['mobile'], { force: true }, (err, values) => {
|
||||
if (!err) {
|
||||
state.smsSendBtn = true
|
||||
|
||||
const interval = window.setInterval(() => {
|
||||
if (state.time-- <= 0) {
|
||||
state.time = 60
|
||||
state.smsSendBtn = false
|
||||
window.clearInterval(interval)
|
||||
}
|
||||
}, 1000)
|
||||
|
||||
const hide = this.$message.loading('验证码发送中..', 0)
|
||||
getSmsCaptcha({ mobile: values.mobile })
|
||||
.then((res) => {
|
||||
setTimeout(hide, 2500)
|
||||
this.$notification['success']({
|
||||
message: '提示',
|
||||
description: '验证码获取成功,您的验证码为:' + res.result.captcha,
|
||||
duration: 8,
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
setTimeout(hide, 1)
|
||||
clearInterval(interval)
|
||||
state.time = 60
|
||||
state.smsSendBtn = false
|
||||
this.requestFailed(err)
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
stepCaptchaSuccess() {
|
||||
this.loginSuccess()
|
||||
},
|
||||
stepCaptchaCancel() {
|
||||
this.Logout().then(() => {
|
||||
this.loginBtn = false
|
||||
this.stepCaptchaVisible = false
|
||||
})
|
||||
},
|
||||
loginSuccess(res) {
|
||||
console.log(res)
|
||||
// check res.homePage define, set $router.push name res.homePage
|
||||
// Why not enter onComplete
|
||||
/*
|
||||
this.$router.push({ name: 'analysis' }, () => {
|
||||
console.log('onComplete')
|
||||
this.$notification.success({
|
||||
message: '欢迎',
|
||||
description: `${timeFix()},欢迎回来`
|
||||
})
|
||||
})
|
||||
*/
|
||||
// this.$router.push({ path: '/' })
|
||||
this.$router.push({ path: '/user/thirdLogin' })
|
||||
this.$router.push({ path: '/' })
|
||||
// 延迟 1 秒显示欢迎信息
|
||||
setTimeout(() => {
|
||||
this.$notification.success({
|
||||
|
@ -299,10 +162,9 @@ export default {
|
|||
description: `${timeFix()},欢迎回来`,
|
||||
})
|
||||
}, 1000)
|
||||
this.isLoginError = false
|
||||
},
|
||||
requestFailed(err) {
|
||||
this.isLoginError = true
|
||||
console.log(err)
|
||||
this.$notification['error']({
|
||||
message: '错误',
|
||||
description: ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试',
|
||||
|
@ -314,55 +176,30 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@import '../../assets/bootstrap.css';
|
||||
#login-wrapper {
|
||||
margin: 50px auto 0;
|
||||
position: relative;
|
||||
z-index: 5;
|
||||
}
|
||||
#logo-login {
|
||||
background: rgba(48, 65, 96, 0.8);
|
||||
border-radius: 3px 3px 0 0;
|
||||
.user-login-title {
|
||||
height: 36px;
|
||||
font-size: 36px;
|
||||
line-height: 1;
|
||||
font-weight: bolder;
|
||||
letter-spacing: 7px;
|
||||
color: #ffffff;
|
||||
padding: 1px 0 14px 25px;
|
||||
margin-bottom: 75px;
|
||||
}
|
||||
.f-item {
|
||||
position: relative;
|
||||
.user-login-bg {
|
||||
width: 937px;
|
||||
height: 465px;
|
||||
transform: translate(-10px, -8px);
|
||||
}
|
||||
.code {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 50%;
|
||||
height: 52px;
|
||||
object-fit: cover;
|
||||
.user-login-form-title {
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
font-weight: bolder;
|
||||
font-stretch: normal;
|
||||
letter-spacing: 5px;
|
||||
color: #ffffff;
|
||||
margin-bottom: 27px;
|
||||
}
|
||||
.account-box {
|
||||
-moz-border-radius: 0 0 4px 4px;
|
||||
-webkit-border-radius: 0 0 4px 4px;
|
||||
-khtml-border-radius: 0 0 4px 4px;
|
||||
border-radius: 0 0 4px 4px;
|
||||
z-index: 3;
|
||||
font-size: 13px !important;
|
||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
background-color: #ffffff;
|
||||
padding: 20px;
|
||||
}
|
||||
.user-layout-login {
|
||||
label {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.getCaptcha {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.forge-password {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.user-login-form-body {
|
||||
button.login-button {
|
||||
padding: 0 15px;
|
||||
font-size: 16px;
|
||||
|
@ -372,28 +209,13 @@ export default {
|
|||
border: none;
|
||||
background-position: -2px 0px;
|
||||
}
|
||||
|
||||
.user-login-other {
|
||||
text-align: left;
|
||||
margin-top: 24px;
|
||||
line-height: 22px;
|
||||
|
||||
.item-icon {
|
||||
font-size: 24px;
|
||||
color: rgba(0, 0, 0, 0.2);
|
||||
margin-left: 16px;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
transition: color 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: #1890ff;
|
||||
}
|
||||
}
|
||||
|
||||
.register {
|
||||
float: right;
|
||||
}
|
||||
.code {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 50%;
|
||||
height: 52px;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
::v-deep {
|
||||
|
|
|
@ -1,316 +0,0 @@
|
|||
<template>
|
||||
<div class="main user-layout-register">
|
||||
<h3><span>{{ $t('user.register.register') }}</span></h3>
|
||||
<a-form ref="formRegister" :form="form" id="formRegister">
|
||||
<a-form-item>
|
||||
<a-input
|
||||
size="large"
|
||||
type="text"
|
||||
:placeholder="$t('user.register.email.placeholder')"
|
||||
v-decorator="['email', {rules: [{ required: true, type: 'email', message: $t('user.email.required') }], validateTrigger: ['change', 'blur']}]"
|
||||
></a-input>
|
||||
</a-form-item>
|
||||
|
||||
<a-popover
|
||||
placement="rightTop"
|
||||
:trigger="['focus']"
|
||||
:getPopupContainer="(trigger) => trigger.parentElement"
|
||||
v-model="state.passwordLevelChecked">
|
||||
<template slot="content">
|
||||
<div :style="{ width: '240px' }" >
|
||||
<div :class="['user-register', passwordLevelClass]">{{ $t(passwordLevelName) }}</div>
|
||||
<a-progress :percent="state.percent" :showInfo="false" :strokeColor=" passwordLevelColor " />
|
||||
<div style="margin-top: 10px;">
|
||||
<span>{{ $t('user.register.password.popover-message') }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<a-form-item>
|
||||
<a-input-password
|
||||
size="large"
|
||||
@click="handlePasswordInputClick"
|
||||
:placeholder="$t('user.register.password.placeholder')"
|
||||
v-decorator="['password', {rules: [{ required: true, message: $t('user.password.required') }, { validator: this.handlePasswordLevel }], validateTrigger: ['change', 'blur']}]"
|
||||
></a-input-password>
|
||||
</a-form-item>
|
||||
</a-popover>
|
||||
|
||||
<a-form-item>
|
||||
<a-input-password
|
||||
size="large"
|
||||
:placeholder="$t('user.register.confirm-password.placeholder')"
|
||||
v-decorator="['password2', {rules: [{ required: true, message: $t('user.password.required') }, { validator: this.handlePasswordCheck }], validateTrigger: ['change', 'blur']}]"
|
||||
></a-input-password>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item>
|
||||
<a-input size="large" :placeholder="$t('user.login.mobile.placeholder')" v-decorator="['mobile', {rules: [{ required: true, message: $t('user.phone-number.required'), pattern: /^1[3456789]\d{9}$/ }, { validator: this.handlePhoneCheck } ], validateTrigger: ['change', 'blur'] }]">
|
||||
<a-select slot="addonBefore" size="large" defaultValue="+86">
|
||||
<a-select-option value="+86">+86</a-select-option>
|
||||
<a-select-option value="+87">+87</a-select-option>
|
||||
</a-select>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<!--<a-input-group size="large" compact>
|
||||
<a-select style="width: 20%" size="large" defaultValue="+86">
|
||||
<a-select-option value="+86">+86</a-select-option>
|
||||
<a-select-option value="+87">+87</a-select-option>
|
||||
</a-select>
|
||||
<a-input style="width: 80%" size="large" placeholder="11 位手机号"></a-input>
|
||||
</a-input-group>-->
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col class="gutter-row" :span="16">
|
||||
<a-form-item>
|
||||
<a-input size="large" type="text" :placeholder="$t('user.login.mobile.verification-code.placeholder')" v-decorator="['captcha', {rules: [{ required: true, message: '请输入验证码' }], validateTrigger: 'blur'}]">
|
||||
<a-icon slot="prefix" type="mail" :style="{ color: 'rgba(0,0,0,.25)' }"/>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col class="gutter-row" :span="8">
|
||||
<a-button
|
||||
class="getCaptcha"
|
||||
size="large"
|
||||
:disabled="state.smsSendBtn"
|
||||
@click.stop.prevent="getCaptcha"
|
||||
v-text="!state.smsSendBtn && $t('user.register.get-verification-code')||(state.time+' s')"></a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-form-item>
|
||||
<a-button
|
||||
size="large"
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
class="register-button"
|
||||
:loading="registerBtn"
|
||||
@click.stop.prevent="handleSubmit"
|
||||
:disabled="registerBtn">{{ $t('user.register.register') }}
|
||||
</a-button>
|
||||
<router-link class="login" :to="{ name: 'login' }">{{ $t('user.register.sign-in') }}</router-link>
|
||||
</a-form-item>
|
||||
|
||||
</a-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getSmsCaptcha } from '@/api/login'
|
||||
import { deviceMixin } from '@/store/device-mixin'
|
||||
import { scorePassword } from '@/utils/util'
|
||||
|
||||
const levelNames = {
|
||||
0: 'user.password.strength.short',
|
||||
1: 'user.password.strength.low',
|
||||
2: 'user.password.strength.medium',
|
||||
3: 'user.password.strength.strong'
|
||||
}
|
||||
const levelClass = {
|
||||
0: 'error',
|
||||
1: 'error',
|
||||
2: 'warning',
|
||||
3: 'success'
|
||||
}
|
||||
const levelColor = {
|
||||
0: '#ff0000',
|
||||
1: '#ff0000',
|
||||
2: '#ff7e05',
|
||||
3: '#52c41a'
|
||||
}
|
||||
export default {
|
||||
name: 'Register',
|
||||
components: {
|
||||
},
|
||||
mixins: [deviceMixin],
|
||||
data () {
|
||||
return {
|
||||
form: this.$form.createForm(this),
|
||||
|
||||
state: {
|
||||
time: 60,
|
||||
level: 0,
|
||||
smsSendBtn: false,
|
||||
passwordLevel: 0,
|
||||
passwordLevelChecked: false,
|
||||
percent: 10,
|
||||
progressColor: '#FF0000'
|
||||
},
|
||||
registerBtn: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
passwordLevelClass () {
|
||||
return levelClass[this.state.passwordLevel]
|
||||
},
|
||||
passwordLevelName () {
|
||||
return levelNames[this.state.passwordLevel]
|
||||
},
|
||||
passwordLevelColor () {
|
||||
return levelColor[this.state.passwordLevel]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handlePasswordLevel (rule, value, callback) {
|
||||
if (value === '') {
|
||||
return callback()
|
||||
}
|
||||
console.log('scorePassword ; ', scorePassword(value))
|
||||
if (value.length >= 6) {
|
||||
if (scorePassword(value) >= 30) {
|
||||
this.state.level = 1
|
||||
}
|
||||
if (scorePassword(value) >= 60) {
|
||||
this.state.level = 2
|
||||
}
|
||||
if (scorePassword(value) >= 80) {
|
||||
this.state.level = 3
|
||||
}
|
||||
} else {
|
||||
this.state.level = 0
|
||||
callback(new Error(this.$t('user.password.strength.msg')))
|
||||
}
|
||||
this.state.passwordLevel = this.state.level
|
||||
this.state.percent = this.state.level * 33
|
||||
|
||||
callback()
|
||||
},
|
||||
|
||||
handlePasswordCheck (rule, value, callback) {
|
||||
const password = this.form.getFieldValue('password')
|
||||
// console.log('value', value)
|
||||
if (value === undefined) {
|
||||
callback(new Error(this.$t('user.password.required')))
|
||||
}
|
||||
if (value && password && value.trim() !== password.trim()) {
|
||||
callback(new Error(this.$t('user.password.twice.msg')))
|
||||
}
|
||||
callback()
|
||||
},
|
||||
|
||||
handlePhoneCheck (rule, value, callback) {
|
||||
console.log('handlePhoneCheck, rule:', rule)
|
||||
console.log('handlePhoneCheck, value', value)
|
||||
console.log('handlePhoneCheck, callback', callback)
|
||||
|
||||
callback()
|
||||
},
|
||||
|
||||
handlePasswordInputClick () {
|
||||
if (!this.isMobile) {
|
||||
this.state.passwordLevelChecked = true
|
||||
return
|
||||
}
|
||||
this.state.passwordLevelChecked = false
|
||||
},
|
||||
|
||||
handleSubmit () {
|
||||
const { form: { validateFields }, state, $router } = this
|
||||
validateFields({ force: true }, (err, values) => {
|
||||
if (!err) {
|
||||
state.passwordLevelChecked = false
|
||||
$router.push({ name: 'registerResult', params: { ...values } })
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
getCaptcha (e) {
|
||||
e.preventDefault()
|
||||
const { form: { validateFields }, state, $message, $notification } = this
|
||||
|
||||
validateFields(['mobile'], { force: true },
|
||||
(err, values) => {
|
||||
if (!err) {
|
||||
state.smsSendBtn = true
|
||||
|
||||
const interval = window.setInterval(() => {
|
||||
if (state.time-- <= 0) {
|
||||
state.time = 60
|
||||
state.smsSendBtn = false
|
||||
window.clearInterval(interval)
|
||||
}
|
||||
}, 1000)
|
||||
|
||||
const hide = $message.loading('验证码发送中..', 0)
|
||||
|
||||
getSmsCaptcha({ mobile: values.mobile }).then(res => {
|
||||
setTimeout(hide, 2500)
|
||||
$notification['success']({
|
||||
message: '提示',
|
||||
description: '验证码获取成功,您的验证码为:' + res.result.captcha,
|
||||
duration: 8
|
||||
})
|
||||
}).catch(err => {
|
||||
setTimeout(hide, 1)
|
||||
clearInterval(interval)
|
||||
state.time = 60
|
||||
state.smsSendBtn = false
|
||||
this.requestFailed(err)
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
requestFailed (err) {
|
||||
this.$notification['error']({
|
||||
message: '错误',
|
||||
description: ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试',
|
||||
duration: 4
|
||||
})
|
||||
this.registerBtn = false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'state.passwordLevel' (val) {
|
||||
console.log(val)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less">
|
||||
.user-register {
|
||||
|
||||
&.error {
|
||||
color: #ff0000;
|
||||
}
|
||||
|
||||
&.warning {
|
||||
color: #ff7e05;
|
||||
}
|
||||
|
||||
&.success {
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.user-layout-register {
|
||||
.ant-input-group-addon:first-child {
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="less" scoped>
|
||||
.user-layout-register {
|
||||
|
||||
& > h3 {
|
||||
font-size: 16px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.getCaptcha {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.register-button {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.login {
|
||||
float: right;
|
||||
line-height: 40px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,44 +0,0 @@
|
|||
<template>
|
||||
<a-result
|
||||
:isSuccess="true"
|
||||
:content="false"
|
||||
:title="email"
|
||||
:sub-title="description">
|
||||
|
||||
<template #extra>
|
||||
<a-button size="large" type="primary">查看邮箱</a-button>
|
||||
<a-button size="large" style="margin-left: 8px" @click="goHomeHandle">返回首页</a-button>
|
||||
</template>
|
||||
|
||||
</a-result>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'RegisterResult',
|
||||
data () {
|
||||
return {
|
||||
description: '激活邮件已发送到你的邮箱中,邮件有效期为24小时。请及时登录邮箱,点击邮件中的链接激活帐户。',
|
||||
form: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
email () {
|
||||
const v = this.form && this.form.email || 'xxx'
|
||||
return `你的账户:${v} 注册成功`
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.form = this.$route.params
|
||||
},
|
||||
methods: {
|
||||
goHomeHandle () {
|
||||
this.$router.push({ name: 'login' })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -1,75 +0,0 @@
|
|||
<template>
|
||||
<a-card>
|
||||
<a-form-model ref="form" :model="model" :rules="rules" :label-col="labelCol" :wrapper-col="wrapperCol">
|
||||
<a-form-model-item label="旧密码" prop="oldPassword">
|
||||
<a-input v-model="model.oldPassword" type="password" placeholder="请输入旧密码" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="新密码" prop="password">
|
||||
<a-input v-model="model.password" type="password" placeholder="请输入新密码" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="确认密码" prop="confirm">
|
||||
<a-input v-model="model.confirm" type="password" placeholder="请输入重新输入密码" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label=" " :colon="false">
|
||||
<a-button type="primary" @click="handleResetPwd">确认修改</a-button>
|
||||
<a-button @click="returnPage" style="margin-left: 10px;">返回</a-button>
|
||||
</a-form-model-item>
|
||||
</a-form-model>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { resetPwd } from '@/api/system/user'
|
||||
export default {
|
||||
name: 'ResetPwd',
|
||||
data () {
|
||||
const comparePassword = (rule, value, callback) => {
|
||||
if (value && value !== this.model.password) {
|
||||
callback(new Error('两次密码不一致!'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
return {
|
||||
model: {},
|
||||
labelCol: { xs: { span: 24 }, sm: { span: 6 } },
|
||||
wrapperCol: { xs: { span: 24 }, sm: { span: 15 } },
|
||||
rules: {
|
||||
oldPassword: [{ required: true, message: '请输入旧密码', trigger: 'blur' }],
|
||||
password: [{ required: true, message: '请输入新密码', trigger: 'blur' }],
|
||||
confirm: [
|
||||
{ required: true, message: '请输入重新输入密码', trigger: 'blur' },
|
||||
{ validator: comparePassword, trigger: 'change' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleResetPwd () {
|
||||
this.$refs.form.validate(valid => {
|
||||
if (valid) {
|
||||
const target = { ...this.model }
|
||||
console.log(target)
|
||||
const userInfo = this.$store.getters.userInfo
|
||||
resetPwd({ ...target, id: userInfo.id }).then(res => {
|
||||
if (res.data) {
|
||||
this.$notification.success({ message: '修改密码成功' })
|
||||
} else {
|
||||
this.$notification.error({ message: res.message })
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
returnPage () {
|
||||
this.$router.back()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
125
src/views/user/Welcome.vue
Normal file
125
src/views/user/Welcome.vue
Normal file
|
@ -0,0 +1,125 @@
|
|||
<template>
|
||||
<Grid :rows="['50px', 1]" style="height: 100%">
|
||||
<Flex jc="fe" style="grid-area: 1 / 1 / 2 / 2">
|
||||
<span class="welcome-content">{{ userInfo.nickName }},欢迎您!</span>
|
||||
</Flex>
|
||||
<Flex ai="c" jc="c" style="grid-area: 1 / 1 / 3 / 2">
|
||||
<Grid style="width: 917px; height: 445px" :columns="[1, 1, 1]" :rows="[1, 1]">
|
||||
<Flex
|
||||
v-for="module in systemModules"
|
||||
:key="module.moduleCode"
|
||||
fd="co"
|
||||
ai="c"
|
||||
jc="sb"
|
||||
class="module-block"
|
||||
@click="handleClick(module)"
|
||||
>
|
||||
<img class="icon" :src="module.icon" alt="" />
|
||||
<div class="title">{{ module.moduleName }}</div>
|
||||
</Flex>
|
||||
</Grid>
|
||||
</Flex>
|
||||
</Grid>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
systemPathMap: {
|
||||
db_system: '/simulationScene/database',
|
||||
simulation_system: '/simulationScene/simulationModel',
|
||||
scenario_system: '/simulationScene/sceneEditing',
|
||||
display_system: '/simulationScene/display',
|
||||
evaluation_system: '/simulationScene/evaluation',
|
||||
},
|
||||
systemModules: [
|
||||
{
|
||||
moduleCode: 'db_system',
|
||||
moduleName: '数据库子系统',
|
||||
icon: require('@/assets/images/simulation-scene/system-icon/database.png'),
|
||||
modulePath: '/simulationScene/database',
|
||||
},
|
||||
{
|
||||
moduleCode: 'simulation_system',
|
||||
moduleName: '仿真模型子系统',
|
||||
icon: require('@/assets/images/simulation-scene/system-icon/model.png'),
|
||||
modulePath: '/simulationScene/simulationModel',
|
||||
},
|
||||
{
|
||||
moduleCode: 'scenario_system',
|
||||
moduleName: '场景编辑子系统',
|
||||
icon: require('@/assets/images/simulation-scene/system-icon/editing.png'),
|
||||
modulePath: '/simulationScene/sceneEditing',
|
||||
},
|
||||
{
|
||||
moduleCode: 'display_system',
|
||||
moduleName: '显示子系统',
|
||||
icon: require('@/assets/images/simulation-scene/system-icon/display.png'),
|
||||
modulePath: '/simulationScene/display',
|
||||
},
|
||||
{
|
||||
moduleCode: 'evaluation_system',
|
||||
moduleName: '评估子系统',
|
||||
icon: require('@/assets/images/simulation-scene/system-icon/evaluation.png'),
|
||||
modulePath: '/simulationScene/evaluation',
|
||||
},
|
||||
{
|
||||
moduleCode: 'control_system',
|
||||
moduleName: '系统控制子系统',
|
||||
icon: require('@/assets/images/simulation-scene/system-icon/database.png'),
|
||||
modulePath: '/simulationScene/centralControl',
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
userInfo: (state) => state.user.info,
|
||||
}),
|
||||
},
|
||||
methods: {
|
||||
handleClick(module) {
|
||||
window.open(
|
||||
window.location.origin + module.modulePath,
|
||||
'_blank',
|
||||
'height=' +
|
||||
window.screen.height +
|
||||
',width=' +
|
||||
window.screen.width +
|
||||
',top=0,left=0,toolbar=no,menubar=no,scrollbars=no,resizable=no,location=no,status=no'
|
||||
)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.welcome-content {
|
||||
font-size: 20px;
|
||||
line-height: 50px;
|
||||
font-weight: bolder;
|
||||
color: #00deff;
|
||||
letter-spacing: 2px;
|
||||
margin: 0 20px;
|
||||
}
|
||||
.module-block {
|
||||
border: 1px solid #06445f;
|
||||
background-color: #062e45;
|
||||
padding-bottom: 32px;
|
||||
cursor: pointer;
|
||||
.icon {
|
||||
transform: translateY(calc(80px - 50%));
|
||||
}
|
||||
.title {
|
||||
color: #9cd3f5;
|
||||
font-size: 24px;
|
||||
line-height: 32px;
|
||||
}
|
||||
}
|
||||
.module-block:hover {
|
||||
border-color: #00deff;
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue
Block a user