继续整理系统开发前的准备

This commit is contained in:
zxx 2022-10-15 16:43:11 +08:00
parent b5bf802ab2
commit e1a5515432
20 changed files with 368 additions and 190 deletions

3
.env
View File

@ -1,9 +1,12 @@
VUE_APP_PUBLIC_PATH=/ VUE_APP_PUBLIC_PATH=/
VUE_APP_BEID=1
VUE_APP_NAME=Admin VUE_APP_NAME=Admin
VUE_APP_ROUTES_KEY=admin.routes VUE_APP_ROUTES_KEY=admin.routes
VUE_APP_PERMISSIONS_KEY=admin.permissions VUE_APP_PERMISSIONS_KEY=admin.permissions
VUE_APP_UID_KEY=admin.uid VUE_APP_UID_KEY=admin.uid
VUE_APP_USER_KEY=admin.user VUE_APP_USER_KEY=admin.user
VUE_APP_PROJECT_KEY=admin.project
VUE_APP_COMPANY_KEY=admin.company
VUE_APP_SETTING_KEY=admin.setting VUE_APP_SETTING_KEY=admin.setting
VUE_APP_USER_SETTINGS_KEY=admin.user.settings VUE_APP_USER_SETTINGS_KEY=admin.user.settings
VUE_APP_TBAS_KEY=admin.tabs VUE_APP_TBAS_KEY=admin.tabs

View File

@ -17,8 +17,8 @@ export default {
locale: {} locale: {}
} }
}, },
created () { created () {
this.setHtmlTitle() // html
this.setLanguage(this.lang) // this.setLanguage(this.lang) //
enquireScreen(isMobile => this.setDevice(isMobile)) // enquireScreen(isMobile => this.setDevice(isMobile)) //
}, },
@ -49,7 +49,8 @@ export default {
} }
}, },
computed: { computed: {
...mapState('setting', ['layout', 'theme', 'weekMode', 'lang']) ...mapState('setting', ['layout', 'theme', 'weekMode', 'lang']),
...mapState('account', ['project']) ,
}, },
methods: { methods: {
...mapMutations('setting', ['setDevice']), ...mapMutations('setting', ['setDevice']),
@ -76,9 +77,10 @@ export default {
} }
}, },
setHtmlTitle() { // html setHtmlTitle() { // html
const project = this.project
const route = this.$route // const route = this.$route //
const key = route.path === '/' ? 'home.name' : getI18nKey(route.matched[route.matched.length - 1].path) // i18n keywords home.name i18n keywords const key = route.path === '/' ? 'home.name' : getI18nKey(route.matched[route.matched.length - 1].path) // i18n keywords home.name i18n keywords
document.title = process.env.VUE_APP_NAME + ' | ' + this.$t(key) // html process.env.VUE_APP_NAME this.$t(key) i18n keywords document.title = project.project_name + ' | ' + this.$t(key) // html process.env.VUE_APP_NAME this.$t(key) i18n keywords
}, },
popContainer() { // popContainer() { //
return document.getElementById("popContainer") // return document.getElementById("popContainer") //

View File

@ -26,10 +26,11 @@ export default {
}, },
methods: { methods: {
backHome() { backHome() {
if (this.homeRoute) { this.$router.push('/')
this.$router.push(this.homeRoute) // if (this.homeRoute) {
} // this.$router.push(this.homeRoute)
this.$emit('backHome', this.type) // }
// this.$emit('backHome', this.type)
} }
} }
} }

View File

@ -10,6 +10,7 @@
<a-icon v-if="item.icon" :type="item.icon" /> <a-icon v-if="item.icon" :type="item.icon" />
<span>{{ item.text }}</span> <span>{{ item.text }}</span>
</a-menu-item> </a-menu-item>
</a-menu> </a-menu>
</template> </template>

View File

@ -1,21 +1,29 @@
<template> <template>
<a-layout-sider :theme="sideTheme" :class="['side-menu', 'beauty-scroll', isMobile ? null : 'shadow']" width="256px" :collapsible="collapsible" v-model="collapsed" :trigger="null"> <a-layout-sider :theme="sideTheme" :class="['side-menu', 'beauty-scroll', isMobile ? null : 'shadow']" width="256px"
:collapsible="collapsible" v-model="collapsed" :trigger="null">
<div :class="['logo', theme]"> <div :class="['logo', theme]">
<!-- PC端 -->
<router-link to="/dashboard/workplace"> <router-link to="/dashboard/workplace">
<img src="@/assets/img/logo.png"> <img width="80" v-if="!company.company_info.logo" :src="project.project_logo">
<h1>{{systemName}}</h1> <h1 v-if="!company.company_info.name">{{project.project_name}}</h1>
<img width="80" v-if="company.company_info.logo" :src="company.company_info.logo">
<h1 v-if="company.company_info.name">{{company.company_info.name}}</h1>
</router-link> </router-link>
</div> </div>
<i-menu :theme="theme" :collapsed="collapsed" :options="menuData" @select="onSelect" class="menu"/> <i-menu :theme="theme" :collapsed="collapsed" :options="menuData" @select="onSelect" class="menu" />
<div class="footer" style="display: none;">
<page-footer />
</div>
</a-layout-sider> </a-layout-sider>
</template> </template>
<script> <script>
import IMenu from './menu' import IMenu from './menu'
import {mapState} from 'vuex' import { mapState } from 'vuex'
import PageFooter from '@/layouts/footer/PageFooter' //
export default { export default {
name: 'SideMenu', name: 'SideMenu',
components: {IMenu}, components: { IMenu, PageFooter },
props: { props: {
collapsible: { collapsible: {
type: Boolean, type: Boolean,
@ -37,14 +45,25 @@ export default {
default: 'dark' default: 'dark'
} }
}, },
data() {
return {
// Project :localStorage.getItem(process.env.VUE_APP_PROJECT_KEY),
}
},
beforeMount() {
},
computed: { computed: {
...mapState('account', ['project', 'company']), // ,
sideTheme() { sideTheme() {
console.log("localStorage:", this.project)
return this.theme == 'light' ? this.theme : 'dark' return this.theme == 'light' ? this.theme : 'dark'
}, },
...mapState('setting', ['isMobile', 'systemName']) ...mapState('setting', ['isMobile', 'systemName'])
}, },
methods: { methods: {
onSelect (obj) { onSelect(obj) {
this.$emit('menuSelect', obj) this.$emit('menuSelect', obj)
} }
} }
@ -53,4 +72,15 @@ export default {
<style lang="less" scoped> <style lang="less" scoped>
@import "index"; @import "index";
.footer {
color: blanchedalmond !important;
width: 100%;
text-align: center;
//
position: absolute;
bottom: 0;
}
</style> </style>

View File

@ -9,7 +9,7 @@
height: 64px; height: 64px;
position: relative; position: relative;
line-height: 64px; line-height: 64px;
padding-left: 24px; padding-left: 15px;
-webkit-transition: all .3s; -webkit-transition: all .3s;
transition: all .3s; transition: all .3s;
overflow: hidden; overflow: hidden;
@ -28,7 +28,7 @@
vertical-align: middle; vertical-align: middle;
} }
img{ img{
width: 32px; width: 50px;
vertical-align: middle; vertical-align: middle;
} }
} }

View File

@ -1,4 +1,5 @@
// 此配置为系统默认设置需修改的设置项在src/config/config.js中添加修改项即可。也可直接在此文件中修改。 // 此配置为系统默认设置需修改的设置项在src/config/config.js中添加修改项即可。也可直接在此文件中修改。
module.exports = { module.exports = {
lang: 'CN', //语言,可选 CN(简体)、HK(繁体)、US(英语),也可扩展其它语言 lang: 'CN', //语言,可选 CN(简体)、HK(繁体)、US(英语),也可扩展其它语言
theme: { //主题 theme: { //主题
@ -18,7 +19,7 @@ module.exports = {
cachePage: true, //是否缓存页面数据仅多页签模式下生效true 缓存, false 不缓存 cachePage: true, //是否缓存页面数据仅多页签模式下生效true 缓存, false 不缓存
hideSetting: false, //隐藏设置抽屉true:隐藏false:不隐藏 hideSetting: false, //隐藏设置抽屉true:隐藏false:不隐藏
systemName: 'MES生产管理系统', //系统名称 systemName: 'MES生产管理系统', //系统名称
copyright: '2018 ICZER 工作室出品', //copyright copyright: 'Project.copyright', //copyright
asyncRoutes: false, //异步加载路由true:开启false:不开启 asyncRoutes: false, //异步加载路由true:开启false:不开启
showPageTitle: true, //是否显示页面标题PageLayout 布局中的页面标题true:显示false:不显示 showPageTitle: true, //是否显示页面标题PageLayout 布局中的页面标题true:显示false:不显示
filterMenu: true, //根据权限过滤菜单true:过滤false:不过滤 filterMenu: true, //根据权限过滤菜单true:过滤false:不过滤

View File

@ -28,7 +28,7 @@
</div> </div>
</a-layout-content> </a-layout-content>
<a-layout-footer style="padding: 0px"> <a-layout-footer style="padding: 0px">
<page-footer :link-list="footerLinks" :copyright="copyright" /> <page-footer :link-list="footerLinks" />
</a-layout-footer> </a-layout-footer>
</a-layout> </a-layout>
</a-layout> </a-layout>

View File

@ -6,14 +6,14 @@
</template> </template>
<script> <script>
import PageFooter from '@/layouts/footer/PageFooter' // import PageFooter from '@/layouts/footer/PageFooter'
import {mapState} from 'vuex' // vuex import {mapState} from 'vuex'
export default { export default {
name: 'CommonLayout', // name: 'CommonLayout',
components: {PageFooter}, // components: {PageFooter},
computed: { computed: {
...mapState('setting', ['footerLinks', 'copyright']) // vuex ...mapState('setting', ['footerLinks', 'copyright'])
} }
} }
</script> </script>

View File

@ -1,20 +1,22 @@
<template> <template>
<div class="footer"> <div class="footer">
<div class="links">
<a target="_blank" :key="index" :href="item.link ? item.link : 'javascript: void(0)'" v-for="(item, index) in linkList">
<a-icon v-if="item.icon" :type="item.icon"/>{{item.name}}
</a>
</div>
<div class="copyright"> <div class="copyright">
Copyright<a-icon type="copyright" />{{copyright}} <a-icon type="copyright" />{{project.copyright}} <br />
<a-icon type="copyright" />{{project.en_copyright}} <br />
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import {mapState} from 'vuex'
export default { export default {
name: 'PageFooter', name: 'PageFooter',
props: ['copyright', 'linkList'] computed: {
...mapState('account', ['project']) ,
},
} }
</script> </script>

View File

@ -1,9 +1,13 @@
<template> <template>
<a-layout-header :class="[headerTheme, 'admin-header']"> <a-layout-header :class="[headerTheme, 'admin-header']">
<div :class="['admin-header-wide', layout, pageWidth]"> <div :class="['admin-header-wide', layout, pageWidth]">
<router-link v-if="isMobile || layout === 'head'" to="/" :class="['logo', isMobile ? null : 'pc', headerTheme]"> <!-- 如果是手机端 -->
<img width="32" src="@/assets/img/logo.png" /> <router-link v-if="isMobile || layout === 'head'" to="/dashboard/workplace" :class="['logo', isMobile ? null : 'pc', headerTheme]">
<h1 v-if="!isMobile">{{systemName}}</h1>
<img width="80" v-if="!company.company_info.logo" :src="project.project_logo">
<h1 v-if="!company.company_info.name">{{project.project_name}}</h1>
<img width="80" style="margin-right:5px;" v-if="company.company_info.logo" :src="company.company_info.logo">
<h1 v-if="company.company_info.name">{{company.company_info.name}}</h1>
</router-link> </router-link>
<a-divider v-if="isMobile" type="vertical" /> <a-divider v-if="isMobile" type="vertical" />
<a-icon v-if="layout !== 'head'" class="trigger" :type="collapsed ? 'menu-unfold' : 'menu-fold'" @click="toggleCollapse"/> <a-icon v-if="layout !== 'head'" class="trigger" :type="collapsed ? 'menu-unfold' : 'menu-fold'" @click="toggleCollapse"/>
@ -11,13 +15,15 @@
<i-menu class="head-menu" :theme="headerTheme" mode="horizontal" :options="menuData" @select="onSelect"/> <i-menu class="head-menu" :theme="headerTheme" mode="horizontal" :options="menuData" @select="onSelect"/>
</div> </div>
<div :class="['admin-header-right', headerTheme]"> <div :class="['admin-header-right', headerTheme]">
<header-search class="header-item" @active="val => searchActive = val" /> <!-- 暂时先把搜索隐藏起来 -->
<a-tooltip class="header-item" title="帮助文档" placement="bottom" > <header-search class="header-item" @active="val => searchActive = val" style="display:none" />
<!-- <a-tooltip class="header-item" title="帮助文档" placement="bottom" >
<a href="https://iczer.gitee.io/vue-antd-admin-docs/" target="_blank"> <a href="https://iczer.gitee.io/vue-antd-admin-docs/" target="_blank">
<a-icon type="question-circle-o" /> <a-icon type="question-circle-o" />
</a> </a>
</a-tooltip> </a-tooltip> -->
<header-notice class="header-item"/> <!-- 暂时先把通知隐藏起来 -->
<header-notice class="header-item" style="display:none"/>
<header-avatar class="header-item"/> <header-avatar class="header-item"/>
<a-dropdown class="lang header-item"> <a-dropdown class="lang header-item">
<div> <div>
@ -52,9 +58,14 @@ export default {
], ],
searchActive: false // searchActive: false //
} }
},
beforeCreate(){
}, },
computed: { computed: {
...mapState('setting', ['theme', 'isMobile', 'layout', 'systemName', 'lang', 'pageWidth']), ...mapState('setting', ['theme', 'isMobile', 'layout', 'lang', 'pageWidth']), // vuex settingthemeisMobilelayoutlangpageWidth
...mapState('account', ['project','company']), // ,
// vuex // vuex
headerTheme () { // headerTheme () { //
if (this.layout == 'side' && this.theme.mode == 'dark' && !this.isMobile) { // if (this.layout == 'side' && this.theme.mode == 'dark' && !this.isMobile) { //
@ -80,7 +91,7 @@ export default {
onSelect (obj) { // onSelect (obj) { //
this.$emit('menuSelect', obj) // menuSelect this.$emit('menuSelect', obj) // menuSelect
}, },
...mapMutations('setting', ['setLang']) // vuex ...mapMutations('setting', ['setLang']), // vuex
} }
} }
</script> </script>

View File

@ -2,40 +2,27 @@
<common-layout> <common-layout>
<div class="top"> <div class="top">
<div class="header"> <div class="header">
<img alt="logo" class="logo" src="@/assets/img/logo.png" /> <img alt="logo" class="logo" :src="Project.project_logo" />
<span class="title">{{systemName}}</span> <span class="title">{{Project.project_name}}</span>
</div> </div>
<div class="desc">Ant Design 是西湖区最具影响力的 Web 设计规范</div> <div class="desc">{{Project.project_sub_title}}</div>
</div> </div>
<div class="login"> <div class="login">
<a-form <a-form @submit="onSubmit" :form="form">
@submit="onSubmit"
:form="form"
>
<a-tabs size="large" :tabBarStyle="{textAlign: 'center'}" style="padding: 0 2px;"> <a-tabs size="large" :tabBarStyle="{textAlign: 'center'}" style="padding: 0 2px;">
<a-tab-pane tab="账户密码登录" key="1"> <a-tab-pane tab="账户密码登录" key="1">
<a-alert type="error" :closable="true" v-show="error" :message="error" showIcon style="margin-bottom: 24px;" /> <a-alert type="error" :closable="true" v-show="error" :message="error" showIcon
style="margin-bottom: 24px;" />
<a-form-item> <a-form-item>
<a-input <a-input autocomplete="autocomplete" size="large" placeholder="admin"
autocomplete="autocomplete" v-decorator="['name', {rules: [{ required: true, message: '请输入账户名', whitespace: true}]}]">
size="large"
placeholder="admin"
v-decorator="['name', {rules: [{ required: true, message: '请输入账户名', whitespace: true}]}]"
>
<!-- --> <!-- -->
<a-icon slot="prefix" type="user" /> <a-icon slot="prefix" type="user" />
</a-input> </a-input>
</a-form-item> </a-form-item>
<a-form-item> <a-form-item>
<a-input <a-input size="large" placeholder="888888" autocomplete="autocomplete" type="password"
size="large" v-decorator="['password', {rules: [{ required: true, message: '请输入密码', whitespace: true}]}]">
placeholder="888888"
autocomplete="autocomplete"
type="password"
v-decorator="['password', {rules: [{ required: true, message: '请输入密码', whitespace: true}]}]"
>
<!-- --> <!-- -->
<a-icon slot="prefix" type="lock" /> <a-icon slot="prefix" type="lock" />
</a-input> </a-input>
@ -43,7 +30,7 @@
</a-tab-pane> </a-tab-pane>
<a-tab-pane tab="手机号登录" key="2"> <a-tab-pane tab="手机号登录" key="2">
<a-form-item> <a-form-item>
<a-input size="large" placeholder="mobile number" > <a-input size="large" placeholder="mobile number">
<a-icon slot="prefix" type="mobile" /> <a-icon slot="prefix" type="mobile" />
</a-input> </a-input>
</a-form-item> </a-form-item>
@ -62,18 +49,19 @@
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
<div> <div>
<a-checkbox :checked="true" >自动登录</a-checkbox> <a-checkbox :checked="true">自动登录</a-checkbox>
<a style="float: right">忘记密码</a> <a style="float: right">忘记密码</a>
</div> </div>
<a-form-item> <a-form-item>
<a-button :loading="logging" style="width: 100%;margin-top: 24px" size="large" htmlType="submit" type="primary">登录</a-button> <a-button :loading="logging" style="width: 100%;margin-top: 24px" size="large" htmlType="submit"
type="primary">登录</a-button>
</a-form-item> </a-form-item>
<div> <div>
其他登录方式 其他登录方式
<a-icon class="icon" type="alipay-circle" /> <a-icon class="icon" type="alipay-circle" />
<a-icon class="icon" type="taobao-circle" /> <a-icon class="icon" type="taobao-circle" />
<a-icon class="icon" type="weibo-circle" /> <a-icon class="icon" type="weibo-circle" />
<router-link style="float: right" to="/dashboard/workplace" >注册账户</router-link> <router-link style="float: right" to="/dashboard/workplace">注册账户</router-link>
</div> </div>
</a-form> </a-form>
</div> </div>
@ -82,10 +70,10 @@
<script> <script>
import CommonLayout from '@/layouts/CommonLayout' import CommonLayout from '@/layouts/CommonLayout'
import {login,getUserInfo, getRoutesConfig,getPermission,getSettings} from '@/services/base/user' import { login, getUserInfo, getRoutesConfig, getPermission, getSettings, getCompany, getProject } from '@/services/base/user'
import {setAuthorization} from '@/utils/request' import { setAuthorization } from '@/utils/request'
import {loadRoutes} from '@/utils/routerUtil' import { loadRoutes } from '@/utils/routerUtil'
import {mapMutations} from 'vuex' import { mapMutations } from 'vuex'
@ -94,8 +82,8 @@ import {mapMutations} from 'vuex'
// import axios from 'axios' // import axios from 'axios'
export default { export default {
name: 'Login', name: 'Login',
components: {CommonLayout}, components: { CommonLayout },
data () { data() {
return { return {
logging: false, logging: false,
error: '', error: '',
@ -103,16 +91,24 @@ export default {
user: { user: {
mobile: '18678390480', mobile: '18678390480',
password: '888888' password: '888888'
} , },
Project: [],
} }
}, },
computed: { computed: {
systemName () {
return this.$store.state.setting.systemName
}
}, },
created(){ beforeMount() {
getProject().then(result => { //
this.Project = result.data.data
const project = result.data.data
this.setProject(project) // vuex
})
},
created() {
this.$nextTick(() => { this.$nextTick(() => {
@ -127,9 +123,9 @@ export default {
}, },
methods: { methods: {
...mapMutations('account', ['setUid','setUser','setPermissions','setRoutesConfig','setSettings']), ...mapMutations('account', ['setUid', 'setUser', 'setPermissions', 'setRoutesConfig', 'setSettings', 'setCompany', 'setProject']),
onSubmit (e) { onSubmit(e) {
e.preventDefault() e.preventDefault()
this.form.validateFields((err) => { this.form.validateFields((err) => {
if (!err) { if (!err) {
@ -147,36 +143,47 @@ export default {
if (loginRes.code == 200) { if (loginRes.code == 200) {
const uid = loginRes.data.uid const uid = loginRes.data.uid
setAuthorization({token: loginRes.data.access_token, expireAt: new Date(loginRes.data.access_expire*1000)}) // token setAuthorization({ token: loginRes.data.access_token, expireAt: new Date(loginRes.data.access_expire * 1000) }) // token
this.setUid(uid) // id this.setUid(uid) // id
getUserInfo().then(result =>{ // getUserInfo().then(result => { //
console.log("UserInforesult:",result) if (result.data.data != null) {
const UserInfo = result.data.data.user_info const UserInfo = result.data.data.user_info
console.log("UserInfo",UserInfo)
this.setUser(UserInfo) this.setUser(UserInfo)
}
}) })
getPermission().then(result => { // getPermission().then(result => { //
const Permission = result.data.data.permission if (result.data.data != null) {
console.log("Permissionresult:",result) const Permission = result.data.data.setPermissions
this.setPermissions(Permission) this.setPermissions(Permission)
}
}) })
getRoutesConfig().then(result => { // getRoutesConfig().then(result => { //
if (result.data.data != null) {
const routesConfig = result.data.data const routesConfig = result.data.data
this.setRoutesConfig(routesConfig) this.setRoutesConfig(routesConfig)
loadRoutes([routesConfig]) loadRoutes([routesConfig])
this.$router.push('/dashboard/workplace') this.$router.push('/dashboard/workplace')
this.$message.success(loginRes.msg, 3) this.$message.success(loginRes.msg, 3)
}
}) })
getSettings().then(result => { // getSettings().then(result => { //
if (result.data.data != null) {
const settings = result.data.data const settings = result.data.data
this.setSettings(settings) this.setSettings(settings)
}
}) })
getCompany().then(result => { //
if (result.data.data != null) {
const company = result.data.data
this.setCompany(company) // vuex
}
})
} else { } else {
console.log("登录失败") console.log("登录失败")
@ -188,20 +195,24 @@ export default {
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.common-layout{ .common-layout {
.top { .top {
text-align: center; text-align: center;
.header { .header {
height: 44px; height: 44px;
line-height: 44px; line-height: 44px;
a { a {
text-decoration: none; text-decoration: none;
} }
.logo { .logo {
height: 44px; height: 44px;
vertical-align: top; vertical-align: top;
margin-right: 16px; margin-right: 16px;
} }
.title { .title {
font-size: 33px; font-size: 33px;
color: @title-color; color: @title-color;
@ -211,6 +222,7 @@ export default {
top: 2px; top: 2px;
} }
} }
.desc { .desc {
font-size: 14px; font-size: 14px;
color: @text-color-second; color: @text-color-second;
@ -218,17 +230,21 @@ export default {
margin-bottom: 40px; margin-bottom: 40px;
} }
} }
.login{
.login {
width: 368px; width: 368px;
margin: 0 auto; margin: 0 auto;
@media screen and (max-width: 576px) { @media screen and (max-width: 576px) {
width: 95%; width: 95%;
} }
@media screen and (max-width: 320px) { @media screen and (max-width: 320px) {
.captcha-button{ .captcha-button {
font-size: 14px; font-size: 14px;
} }
} }
.icon { .icon {
font-size: 24px; font-size: 24px;
color: @text-color-second; color: @text-color-second;
@ -242,5 +258,5 @@ export default {
} }
} }
} }
} }
</style> </style>

View File

@ -5,7 +5,7 @@ import { formatRoutes } from '@/utils/routerUtil' // 引入路由格式化工具
// -------------------------------- 以下为刷新页面时,重新加载路由 权限 用户信息的代码 -------------------------------- // -------------------------------- 以下为刷新页面时,重新加载路由 权限 用户信息的代码 --------------------------------
import { getUserInfo, getRoutesConfig, getPermission,getSettings } from '@/services/base/user' // 刷新用户信息 import { getUserInfo, getRoutesConfig, getPermission, getSettings, getCompany, getProject } from '@/services/base/user' // 刷新用户信息
import { loadRoutes } from '@/utils/routerUtil' import { loadRoutes } from '@/utils/routerUtil'
import store from '@/store' // 引入vuex store 实例 import store from '@/store' // 引入vuex store 实例
import xsrfHeaderName from '@/utils/request' // 引入request import xsrfHeaderName from '@/utils/request' // 引入request
@ -15,28 +15,48 @@ const Authorization = Cookie.get(xsrfHeaderName).Authorization
if (Authorization != null) { if (Authorization != null) {
getUserInfo().then(result => { // 获取用户信息 getUserInfo().then(result => { // 获取用户信息
if (result.data.data != null) {
const UserInfo = result.data.data.user_info const UserInfo = result.data.data.user_info
console.log("UserInfo: ", UserInfo)
store.commit('account/setRoutesConfig', UserInfo) // 将用户信息存入vuex store.commit('account/setRoutesConfig', UserInfo) // 将用户信息存入vuex
}
}) })
getPermission().then(result => { // 获取权限 getPermission().then(result => { // 获取权限
if (result.data.data != null) {
const Permission = result.data.data.permission const Permission = result.data.data.permission
console.log("Permission: ", Permission)
store.commit('account/setPermissions', Permission) // 将权限信息存入vuex store.commit('account/setPermissions', Permission) // 将权限信息存入vuex
}
}) })
getRoutesConfig().then(result => { // 获取路由配置 getRoutesConfig().then(result => { // 获取路由配置
if (result.data.data != null) {
const routesConfig = result.data.data const routesConfig = result.data.data
console.log("routesConfig: ", routesConfig)
store.commit('account/setRoutesConfig', routesConfig) // 将路由配置信息存入vuex store.commit('account/setRoutesConfig', routesConfig) // 将路由配置信息存入vuex
loadRoutes([routesConfig]) // 加载路由 loadRoutes([routesConfig]) // 加载路由
}
}) })
getSettings().then(result => { // 获取系统配置 getSettings().then(result => { // 获取系统配置
if (result.data.data != null) {
const settings = result.data.data const settings = result.data.data
store.commit('account/setRoutesConfig', settings) // 将系统配置信息存入vuex store.commit('account/setSettings', settings) // 将系统配置信息存入vuex
}
}) })
getCompany().then(result => { // 获取公司信息
if (result.data.data != null) {
const company = result.data.data
store.commit('account/setCompany', company) // 将公司信息存入vuex
}
})
getProject().then(result => { // 获取项目信息
if (result.data.data != null) {
const project = result.data.data
store.commit('account/setProject', project) // 将项目信息存入vuex
}
})
} }
// -------------------------------- 以上为刷新页面时,重新加载路由 权限 用户信息的代码 -------------------------------- // -------------------------------- 以上为刷新页面时,重新加载路由 权限 用户信息的代码 --------------------------------

View File

@ -5,6 +5,8 @@ const BASE_URL = process.env.VUE_APP_API_BASE_URL // 获取环境变量VUE_APP_A
module.exports = { module.exports = {
BASE_URL, BASE_URL,
PROJECT: `${BASE_URL}/AdminUser/v1/project`,
COMPANY: `${BASE_URL}/AdminUser/v1/company`,
LOGIN: `${BASE_URL}/AdminUser/v1/login`, LOGIN: `${BASE_URL}/AdminUser/v1/login`,
ROUTES: `${BASE_URL}/AdminUser/v1/routers`, ROUTES: `${BASE_URL}/AdminUser/v1/routers`,
USERINFO: `${BASE_URL}/AdminUser/v1/userinfo`, USERINFO: `${BASE_URL}/AdminUser/v1/userinfo`,

View File

@ -1,4 +1,4 @@
import {LOGIN, ROUTES, USERINFO,PERMISSION,SETTINGS} from '@/services/base/api' import {LOGIN, ROUTES, USERINFO,PERMISSION,SETTINGS,PROJECT,COMPANY} from '@/services/base/api'
import {request, METHOD, removeAuthorization} from '@/utils/request' import {request, METHOD, removeAuthorization} from '@/utils/request'
/** /**
* 登录服务 * 登录服务
@ -60,6 +60,30 @@ export async function getSettings() { // 获取用户设置
}) })
} }
/**
* 获取项目信息
* @param beid
* @returns {Promise<AxiosResponse<Tuple>>}
*/
export async function getProject() { // 获取项目信息
return request(PROJECT, METHOD.POST, {
beid:parseInt(process.env.VUE_APP_BEID)
})
}
/**
* 获取公司信息
* @param company_id
* @returns {Promise<AxiosResponse<T>>}
*/
export async function getCompany() { // 获取公司信息
const userId = parseInt(localStorage.getItem(process.env.VUE_APP_UID_KEY)) // 获取用户id并转换为整数
return request(COMPANY, METHOD.POST, {
uid: userId
})
}
/** /**
* 退出登录 * 退出登录
*/ */
@ -68,6 +92,8 @@ export function logout() {
localStorage.removeItem(process.env.VUE_APP_PERMISSIONS_KEY) // 删除权限配置 localStorage.removeItem(process.env.VUE_APP_PERMISSIONS_KEY) // 删除权限配置
localStorage.removeItem(process.env.VUE_APP_USER_KEY) // 删除用户信息 localStorage.removeItem(process.env.VUE_APP_USER_KEY) // 删除用户信息
localStorage.removeItem(process.env.VUE_APP_UID_KEY) // 删除用户id localStorage.removeItem(process.env.VUE_APP_UID_KEY) // 删除用户id
localStorage.removeItem(process.env.VUE_APP_USER_SETTINGS_KEY) // 删除用户设置
localStorage.removeItem(process.env.VUE_APP_COMPANY_KEY) // 删除公司信息
removeAuthorization() removeAuthorization()
} }
export default { export default {
@ -76,5 +102,7 @@ export default {
getRoutesConfig, getRoutesConfig,
getPermission, getPermission,
getUserInfo, getUserInfo,
getSettings getSettings,
getProject,
getCompany,
} }

View File

@ -2,10 +2,12 @@ export default {
namespaced: true, namespaced: true,
state: { state: {
uid: 0, uid: 0,
user: undefined, // 用户信息
permissions: undefined, // 权限
routesConfig: undefined, // 路由配置 routesConfig: undefined, // 路由配置
settings: undefined // 用户配置 user: [], // 用户信息
permissions: [], // 权限
settings: [], // 用户配置
project: [], // 项目信息
company: [], // 公司信息
}, },
getters: { getters: {
uid: state => { // 用户id uid: state => { // 用户id
@ -61,26 +63,57 @@ export default {
try { try {
const settings = localStorage.getItem(process.env.VUE_APP_USER_SETTINGS_KEY) // 获取用户配置 const settings = localStorage.getItem(process.env.VUE_APP_USER_SETTINGS_KEY) // 获取用户配置
state.settings = JSON.parse(settings) // 将字符串转换为json对象 state.settings = JSON.parse(settings) // 将字符串转换为json对象
state.settings = state.settings ? state.settings : {} // 如果state.settings为null则赋值为空对象 state.settings = state.settings ? state.settings : [] // 如果state.settings为null则赋值为空对象
} catch (e) { // 捕获异常 } catch (e) { // 捕获异常
console.error(e.message) console.error(e.message)
} }
} }
return state.settings // 如果有用户配置,则返回用户配置 return state.settings // 如果有用户配置,则返回用户配置
},
project: state => { // 项目信息
if (!state.project) { // 如果没有项目信息
try {
const project = localStorage.getItem(process.env.VUE_APP_PROJECT_KEY) // 获取项目信息
state.project = JSON.parse(project) // 将字符串转换为json对象
state.project = state.project ? state.project : [] // 如果state.project为null则赋值为空对象
} catch (e) { // 捕获异常
console.error(e.message)
}
} }
}, },
company: state => { // 公司信息
if (!state.company) { // 如果没有公司信息
try {
const company = localStorage.getItem(process.env.VUE_APP_COMPANY_KEY) // 获取公司信息
state.company = JSON.parse(company) // 将字符串转换为json对象
state.company = state.company ? state.company : [] // 如果state.company为null则赋值为空对象
}
catch (e) { // 捕获异常
console.error(e.message)
}
}
},
},
mutations: { mutations: {
setUid (state, uid) { // 设置用户uid setUid (state, uid) { // 设置用户uid
state.uid = uid state.uid = uid
localStorage.setItem(process.env.VUE_APP_UID_KEY, JSON.stringify(uid))// 将所有用户信息存储到process.env.VUE_APP_UID_KEY key中 localStorage.setItem(process.env.VUE_APP_UID_KEY, JSON.stringify(uid))// 将所有用户信息存储到process.env.VUE_APP_UID_KEY key中
}, },
setUser (state, user) { // 设置用户信息 setUser (state, user) { // 设置用户信息
state.user = user state.user = user
if (JSON.stringify(user) === undefined){
user = []
}
localStorage.setItem(process.env.VUE_APP_USER_KEY, JSON.stringify(user))// 将所有用户信息存储到process.env.VUE_APP_USER_KEY中 localStorage.setItem(process.env.VUE_APP_USER_KEY, JSON.stringify(user))// 将所有用户信息存储到process.env.VUE_APP_USER_KEY中
}, },
setPermissions(state, permissions) { // 设置权限 setPermissions(state, permissions) { // 设置权限
state.permissions = permissions state.permissions = permissions
if (JSON.stringify(permissions) === undefined){
permissions = []
}
localStorage.setItem(process.env.VUE_APP_PERMISSIONS_KEY, JSON.stringify(permissions)) // 将所有权限信息存储到process.env.VUE_APP_PERMISSIONS_KEY中 localStorage.setItem(process.env.VUE_APP_PERMISSIONS_KEY, JSON.stringify(permissions)) // 将所有权限信息存储到process.env.VUE_APP_PERMISSIONS_KEY中
}, },
setRoutesConfig(state, routesConfig) { // 设置路由配置 setRoutesConfig(state, routesConfig) { // 设置路由配置
@ -89,7 +122,25 @@ export default {
}, },
setSettings(state, settings) { // 设置用户配置 setSettings(state, settings) { // 设置用户配置
state.settings = settings state.settings = settings
localStorage.setItem(process.env.VUE_APP_USER_SETTINGS_KEY, JSON.stringify(settings)) // 将所有用户配置信息存储到process.env.VUE_APP_USER_SETTINGS_KEY中 if (JSON.stringify(settings) === undefined){
settings = []
} }
localStorage.setItem(process.env.VUE_APP_USER_SETTINGS_KEY, JSON.stringify(settings)) // 将所有用户配置信息存储到process.env.VUE_APP_USER_SETTINGS_KEY中
},
setProject(state, project) { // 设置项目信息
state.project = project
if (JSON.stringify(project) === undefined){
project = []
}
localStorage.setItem(process.env.VUE_APP_PROJECT_KEY, JSON.stringify(project)) // 将所有项目信息存储到process.env.VUE_APP_PROJECT_KEY中
},
setCompany(state, company) { // 设置公司信息
state.company = company
if (JSON.stringify(company) === undefined){
company = []
}
localStorage.setItem(process.env.VUE_APP_COMPANY_KEY, JSON.stringify(company)) // 将所有公司信息存储到process.env.VUE_APP_COMPANY_KEY中
},
} }
} }

View File

@ -13,14 +13,18 @@
*/ */
function hasAuthority(to, permissions) { // 权限校验 function hasAuthority(to, permissions) { // 权限校验
// 循环 to.meta.authority.permission 集合 // 循环 to.meta.authority.permission 集合
if (to.meta && to.meta.authority.permission.length > 0) { if (to.meta.authority.permission){
if (to.meta.authority.permission.length > 0) {
for (let i = 0; i < to.meta.authority.permission.length; i++) { for (let i = 0; i < to.meta.authority.permission.length; i++) {
// 判断用户权限集合中是否包含 to.meta.authority.permission 中的权限 // 判断用户权限集合中是否包含 to.meta.authority.permission 中的权限
if (permissions){
if (permissions.includes(to.meta.authority.permission[i])) { if (permissions.includes(to.meta.authority.permission[i])) {
return false return false
} }
} }
} }
}
}
// 如果 to.meta.authority.permission 匹配到了 permissions 中的某个权限就返回false // 如果 to.meta.authority.permission 匹配到了 permissions 中的某个权限就返回false
return true // 如果都满足返回true return true // 如果都满足返回true
} }
@ -35,7 +39,7 @@ function hasAuthority(to, permissions) { // 权限校验
function filterMenu(menuData, permissions, roles) { // 过滤菜单 function filterMenu(menuData, permissions, roles) { // 过滤菜单
return menuData.filter(menu => { return menuData.filter(menu => {
if (menu.meta && menu.meta.invisible === undefined) { // 如果菜单有meta属性并且没有invisible属性 if (menu.meta && menu.meta.invisible === undefined) { // 如果菜单有meta属性并且没有invisible属性
if (!hasAuthority(menu, permissions, roles)) { // 如果没有权限 if (!hasAuthority(menu, permissions)) { // 如果没有权限
return false // 返回false return false // 返回false
} }
} }

View File

@ -63,8 +63,10 @@ const reqCommon = { // 请求拦截器
const {url, xsrfCookieName} = config // 获取config中的url和xsrfCookieName const {url, xsrfCookieName} = config // 获取config中的url和xsrfCookieName
if (url.indexOf('login') === -1 && xsrfCookieName && !Cookie.get(xsrfCookieName)) { if (url.indexOf('login') === -1 && xsrfCookieName && !Cookie.get(xsrfCookieName)) {
// 如果url中不包含login并且xsrfCookieName存在并且Cookie中不存在xsrfCookieName // 如果url中不包含login并且xsrfCookieName存在并且Cookie中不存在xsrfCookieName
if (localStorage.getItem(process.env.VUE_APP_UID_KEY)) {
message.warning('认证 token 已过期,请重新登录') // 提示 message.warning('认证 token 已过期,请重新登录') // 提示
} }
}
return config return config
}, },
/** /**

View File

@ -33,7 +33,9 @@ const METHOD = {
* @returns {Promise<AxiosResponse<T>>} * @returns {Promise<AxiosResponse<T>>}
*/ */
async function request(url, method, params, config) { // 请求方法 async function request(url, method, params, config) { // 请求方法
if (Cookie.get(xsrfHeaderName)) { // 检查cookie中是否存在认证信息
axios.defaults.headers.common[xsrfHeaderName] = Cookie.get(xsrfHeaderName) axios.defaults.headers.common[xsrfHeaderName] = Cookie.get(xsrfHeaderName)
}
switch (method) { switch (method) {
case METHOD.GET: case METHOD.GET:
return axios.get(url, {params, ...config}) return axios.get(url, {params, ...config})
@ -165,6 +167,7 @@ function parseUrlParams(url) { // 解析 url 中的参数
export { export {
METHOD, METHOD,
AUTH_TYPE, AUTH_TYPE,
xsrfHeaderName,
request, request,
setAuthorization, setAuthorization,
removeAuthorization, removeAuthorization,

View File

@ -90,6 +90,7 @@ function parseRoutes(routesConfig, routerMap) { // 解析路由
// 根据权限过滤路由 // 根据权限过滤路由
function filterRoutesConfig(routes, permissions) { function filterRoutesConfig(routes, permissions) {
const res = [] const res = []
routes.forEach(route => { routes.forEach(route => {
const tmp = { ...route } const tmp = { ...route }
if (hasPermission(permissions, tmp)) { if (hasPermission(permissions, tmp)) {