Commit fae68cde by qinjianhui

feat: 菜单管理

parent d227f9f7
......@@ -16,5 +16,6 @@ module.exports = {
'comma-dangle': ['error', 'always-multiline'],
'space-before-function-paren': 'off',
indent: 'off',
'multiline-ternary': 'off',
},
}
......@@ -14,7 +14,9 @@
"js-md5": "^0.7.3",
"vue": "^2.6.14",
"vue-router": "^3.5.1",
"vuex": "^3.6.2"
"vuex": "^3.6.2",
"vxe-table": "^3.5.9",
"xe-utils": "^3.5.7"
},
"devDependencies": {
"@babel/core": "^7.12.16",
......@@ -11694,6 +11696,15 @@
"vue": "^2.0.0"
}
},
"node_modules/vxe-table": {
"version": "3.5.9",
"resolved": "https://registry.npmjs.org/vxe-table/-/vxe-table-3.5.9.tgz",
"integrity": "sha512-8idPnu377Ufwyv6/8GsAk2s9KNcF2nVdp3M8izMmrapOJ2fJRTWmaBTH//XbKqF4ELmvRPXAtkEOl6h37T7RaA==",
"peerDependencies": {
"vue": "^2.6.0",
"xe-utils": "^3.5.0"
}
},
"node_modules/watchpack": {
"version": "2.4.0",
"resolved": "https://registry.npmmirror.com/watchpack/-/watchpack-2.4.0.tgz",
......@@ -12303,6 +12314,11 @@
}
}
},
"node_modules/xe-utils": {
"version": "3.5.7",
"resolved": "https://registry.npmjs.org/xe-utils/-/xe-utils-3.5.7.tgz",
"integrity": "sha512-3H+fDBKBR2wLJgyA7k9C/w1Xljx6Maml5ukV0WDY06HjYyGs2FEz6XhcwRCLIDXX4pBP3Gu0nX9DbCeuuRA2Ew=="
},
"node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz",
......@@ -21074,6 +21090,12 @@
"integrity": "sha512-ETW44IqCgBpVomy520DT5jf8n0zoCac+sxWnn+hMe/CzaSejb/eVw2YToiXYX+Ex/AuHHia28vWTq4goAexFbw==",
"requires": {}
},
"vxe-table": {
"version": "3.5.9",
"resolved": "https://registry.npmjs.org/vxe-table/-/vxe-table-3.5.9.tgz",
"integrity": "sha512-8idPnu377Ufwyv6/8GsAk2s9KNcF2nVdp3M8izMmrapOJ2fJRTWmaBTH//XbKqF4ELmvRPXAtkEOl6h37T7RaA==",
"requires": {}
},
"watchpack": {
"version": "2.4.0",
"resolved": "https://registry.npmmirror.com/watchpack/-/watchpack-2.4.0.tgz",
......@@ -21515,6 +21537,11 @@
"dev": true,
"requires": {}
},
"xe-utils": {
"version": "3.5.7",
"resolved": "https://registry.npmjs.org/xe-utils/-/xe-utils-3.5.7.tgz",
"integrity": "sha512-3H+fDBKBR2wLJgyA7k9C/w1Xljx6Maml5ukV0WDY06HjYyGs2FEz6XhcwRCLIDXX4pBP3Gu0nX9DbCeuuRA2Ew=="
},
"y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz",
......
......@@ -14,7 +14,9 @@
"js-md5": "^0.7.3",
"vue": "^2.6.14",
"vue-router": "^3.5.1",
"vuex": "^3.6.2"
"vuex": "^3.6.2",
"vxe-table": "^3.5.9",
"xe-utils": "^3.5.7"
},
"devDependencies": {
"@babel/core": "^7.12.16",
......
<template>
<div id="app">
<router-view/>
<router-view />
</div>
</template>
<script>
export default {
data() {
return {}
},
created() {
addEventListener('keydown', (e) => {
this.$store.dispatch('setKeyCode', e.key)
})
addEventListener('keyup', () => {
this.$store.dispatch('setKeyCode', null)
})
},
}
</script>
<style lang="less">
* {
......
import axios from '../axios'
export function updateSysmenu({ id, enable, type }) {
return axios.post('/sysMenu/update', null, {
params: { id, enable, type },
})
}
export function getAllMenusTree() {
return axios.get('sysMenu/getAllMenusTree')
}
export function addMenu(data) {
return axios.post('sysMenu/add', data)
}
export function updateMenu(data) {
return axios.post('sysMenu/update', data)
}
export function deleteMenu(id) {
return axios.post(`sysMenu/delete/${id}`)
}
<script>
export default {
name: 'myLayout',
inheritAttrs: false,
props: {
isleftshow: {
default: true,
type: Boolean,
},
},
data() {
return {
isLeft: true,
}
},
methods: {
leftChange() {
this.isLeft = !this.isLeft
},
},
render() {
const {
$scopedSlots,
$attrs,
isLeft,
isleftshow,
$vnode,
} = this
const leftStyle = $attrs?.leftStyle || {}
let { width, ...attrs } = leftStyle
if (!width) width = '200px'
return (
<div class="page_main">
{$scopedSlots.header && (
<div class="page_header">
{$scopedSlots.header()}
</div>
)}
<div
class="layout_wrap"
style={$vnode.data.staticStyle}
>
{$scopedSlots.page_left && (
<div
class="page_left"
style={{
...attrs,
width: isLeft ? width : '1px',
}}
>
{$scopedSlots.page_left()}
</div>
)}
{isleftshow && (
<div class="separation">
<span
class="left_toggle"
title={isLeft ? '点击收起' : '点击展开'}
onClick={this.leftChange}
>
<i
class={
isLeft
? 'el-icon-caret-left'
: 'el-icon-caret-right'
}
></i>
</span>
</div>
)}
{$scopedSlots.page_right && (
<div
class="page_right"
style={$attrs?.rightStyle || {}}
>
{$scopedSlots.page_right()}
</div>
)}
{$scopedSlots.default && $scopedSlots.default()}
</div>
</div>
)
},
}
</script>
<style scoped>
.page_main {
height: calc(100vh - 86px);
box-sizing: border-box;
display: flex;
flex-direction: column;
margin: 0;
overflow: hidden;
position: relative;
}
.page_main .layout_wrap {
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
position: relative;
}
.page_main:not(.mobile) {
margin-right: 40px;
}
/* .page_main.home .tool_warper {
display: none;
} */
.page_main.row .layout_wrap {
flex-direction: row;
}
.page_main.wrap .layout_wrap {
background: #fff;
box-sizing: border-box;
border-radius: 10px;
padding-top: 10px;
}
.page_main.wrap .layout_wrap >>> form:nth-of-type(1) {
margin-left: 10px;
}
.page_main.mobile {
height: calc(100vh - 56px);
}
.page_header {
background: #fff;
padding-top: 10px;
margin-bottom: 10px;
}
.page_left {
position: relative;
display: flex;
flex-direction: column;
width: 200px;
height: 100%;
background: var(--background-color);
box-sizing: border-box;
border-radius: 5px 5px 0 0;
overflow: auto;
}
.separation {
display: none;
position: relative;
width: 1px;
}
.row .separation {
display: block;
}
.separation .left_toggle {
position: absolute;
right: -16px;
width: 17px;
height: 24px;
background: #dedede;
z-index: 1000;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
}
.separation .left_toggle::before {
position: absolute;
width: 0px;
height: 0px;
content: '';
top: 10px;
left: -12px;
pointer-events: none;
transform: rotate(45deg);
border-width: 12px;
border-style: solid;
border-color: rgba(0, 0, 0, 0) #dedede rgba(0, 0, 0, 0)
rgba(0, 0, 0, 0);
border-radius: 5px;
}
.separation .left_toggle::after {
position: absolute;
width: 0px;
height: 0px;
top: -10px;
left: -12px;
pointer-events: none;
content: '';
transform: rotate(-45deg);
border-width: 12px;
border-style: solid;
border-color: rgba(0, 0, 0, 0) #dedede rgba(0, 0, 0, 0)
rgba(0, 0, 0, 0);
border-radius: 5px;
}
.separation .left_toggle i {
display: block;
margin-top: 3px;
pointer-events: none;
}
.separation:hover .left_toggle {
display: block;
}
.page_right {
flex: 1;
display: flex;
flex-direction: column;
margin-left: 10px;
box-sizing: border-box;
overflow: hidden;
}
.page_main:not(.drag) .page_right {
background: var(--background-color);
border-radius: 5px 5px 0 0;
padding-top: 10px;
box-sizing: border-box;
}
.page_main .page_right >>> form:nth-of-type(1),
.page_main .page_left >>> form,
.page_main.drag >>> form {
padding-left: 10px;
}
/* .page_right >>> .top {
padding-top: 0;
} */
.page_main.drag .page_right {
/* padding-top: 10px; */
background: transparent;
}
</style>
......@@ -16,6 +16,8 @@ import {
Switch,
Select,
Option,
Cascader,
Radio,
} from 'element-ui'
const components = [
......@@ -31,6 +33,8 @@ const components = [
Switch,
Select,
Option,
Cascader,
Radio,
]
export default {
......
import 'xe-utils'
import 'vxe-table/lib/style.css'
import {
Table,
Column,
Header,
Footer,
Filter,
Edit,
Menu,
Export,
Keyboard,
Validator,
Icon,
Grid,
Toolbar,
Pager,
Checkbox,
Radio,
Input,
Button,
Modal,
Tooltip,
Form,
Select,
Switch,
List,
Colgroup,
} from 'vxe-table'
const vxes = [
Column,
Header,
Footer,
Filter,
Edit,
Menu,
Export,
Keyboard,
Validator,
Icon,
Grid,
Toolbar,
Pager,
Checkbox,
Radio,
Input,
Button,
Modal,
Tooltip,
Form,
Select,
Switch,
List,
Colgroup,
Table,
]
export default {
install(Vue) {
vxes.forEach((v) => {
Vue.use(v)
})
},
}
// 给 vue 实例挂载内部对象,例如:
// Vue.prototype.$XModal = VXETable.modal
// Vue.prototype.$XPrint = VXETable.print
// Vue.prototype.$XSaveFile = VXETable.saveFile
// Vue.prototype.$XReadFile = VXETable.readFile
......@@ -3,11 +3,13 @@ import App from './App.vue'
import router from './router'
import store from './store'
import element from '@/common/components/element-ui.js'
import vxeTable from '@/common/components/vxeTable.js'
import './common/style/index.scss'
Vue.config.productionTip = false
Vue.use(element)
Vue.use(vxeTable)
new Vue({
router,
......
......@@ -3,6 +3,7 @@ import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'
import SaasManage from '@/views/saasManage/indexPage.vue'
import LoginPage from '@/views/LoginPage.vue'
import menu from '@/views/menu'
Vue.use(VueRouter)
......@@ -22,6 +23,11 @@ const routes = [
name: 'saasManage',
component: SaasManage,
},
{
path: '/saas/menu',
component: menu,
name: 'saasMenu',
},
]
const router = new VueRouter({
......
......@@ -4,9 +4,19 @@ import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {},
state: {
keyCode: null,
},
getters: {},
mutations: {},
actions: {},
mutations: {
setKeyCode(state, msg) {
state.keyCode = msg
},
},
actions: {
setKeyCode({ commit }, msg) {
commit('setKeyCode', msg)
},
},
modules: {},
})
......@@ -247,6 +247,7 @@
style="width: 200px"
v-model.trim="editForm.domain"
size="small"
:disabled="!!editId"
clearable
@change="onChange"
placeholder="请输入域名"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment