Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
Starter Web Vue
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Package Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
product
kim3-web-vue
Starter Web Vue
Commits
8846a011
Commit
8846a011
authored
Jun 27, 2021
by
水落(YangLei)
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 菜单管理页面大体完成
parent
ea21c88e
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
257 additions
and
84 deletions
+257
-84
src/api/index.js
src/api/index.js
+1
-0
src/api/menu.js
src/api/menu.js
+13
-0
src/components/popconfirm_delete/index.vue
src/components/popconfirm_delete/index.vue
+19
-0
src/components/table/index.vue
src/components/table/index.vue
+51
-68
src/main.js
src/main.js
+1
-1
src/pages/system/view/menu/MenuManagement.vue
src/pages/system/view/menu/MenuManagement.vue
+44
-11
src/pages/system/view/menu/form.vue
src/pages/system/view/menu/form.vue
+96
-0
src/utils/i18nUtil.js
src/utils/i18nUtil.js
+0
-1
src/utils/index.js
src/utils/index.js
+8
-2
src/utils/requestUtil.js
src/utils/requestUtil.js
+24
-1
No files found.
src/api/index.js
View file @
8846a011
import
{
request
,
METHOD
}
from
'
@/utils
'
;
import
{
request
,
METHOD
}
from
'
@/utils
'
;
export
*
from
'
./menu
'
;
export
function
getUserDetailInfoApi
()
{
export
function
getUserDetailInfoApi
()
{
return
request
(
'
/api/v1/detail
'
,
METHOD
.
GET
);
return
request
(
'
/api/v1/detail
'
,
METHOD
.
GET
);
...
...
src/api/menu.js
0 → 100644
View file @
8846a011
import
{
delReq
,
getReq
,
postReq
}
from
'
@/utils
'
;
export
function
delMenuApi
(
id
)
{
return
delReq
(
`/api/v1/menus/
${
id
}
`
);
}
export
function
getMenuDataApi
()
{
return
getReq
(
'
/api/v1/menus
'
);
}
export
function
addMenuApi
(
data
)
{
return
postReq
(
'
/api/v1/menus
'
,
data
);
}
src/components/popconfirm_delete/index.vue
0 → 100644
View file @
8846a011
<
template
>
<a-popconfirm
title=
"确认是否删除"
ok-text=
"确认"
cancel-text=
"取消"
@
confirm=
"onOk"
@
cancel=
"onCancel"
>
<a>
删除
</a>
</a-popconfirm>
</
template
>
<
script
>
import
{
EMPTY_FUN
}
from
'
@/utils
'
;
export
default
{
props
:
{
onOk
:
Function
,
onCancel
:
{
type
:
Function
,
default
:
EMPTY_FUN
,
},
},
};
</
script
>
src/components/table/index.vue
View file @
8846a011
...
@@ -23,7 +23,7 @@
...
@@ -23,7 +23,7 @@
</
template
>
</
template
>
</a-space>
</a-space>
<a-table
:data-source=
"data"
:loading=
"loading"
v-bind=
"$attrs"
>
<a-table
:data-source=
"data"
:loading=
"loading"
v-bind=
"$attrs"
:pagination=
"!noPage"
>
<slot
/>
<slot
/>
</a-table>
</a-table>
</div>
</div>
...
@@ -35,9 +35,23 @@
...
@@ -35,9 +35,23 @@
:visible=
"addVisible"
:visible=
"addVisible"
@
close=
"addDrawerClose"
@
close=
"addDrawerClose"
v-if=
"addBtn"
v-if=
"addBtn"
:maskClosable=
"addBtn.maskClosable"
:maskClosable=
"!!addBtn.maskClosable"
:closable=
"false"
:drawerStyle=
"drawerStyle"
:bodyStyle=
"bodyStyle"
:width=
"addBtn.width"
destroyOnClose
>
>
<div
class=
"tw-overflow-y-hidden"
>
<div
class=
"tw-overflow-y-auto tw-h-full"
>
<slot
name=
"add"
/>
<slot
name=
"add"
/>
</div>
</div>
<a-divider
/>
<a-space>
<a-button
@
click=
"addVisible = false"
>
取消
</a-button>
<a-button
type=
"primary"
@
click=
"submit"
:loading=
"submitLoading"
>
确认
</a-button>
</a-space>
</a-drawer>
</a-drawer>
</div>
</div>
</template>
</template>
...
@@ -45,71 +59,6 @@
...
@@ -45,71 +59,6 @@
<
script
>
<
script
>
import
{
request
,
METHOD
}
from
'
@/utils/requestUtil
'
;
import
{
request
,
METHOD
}
from
'
@/utils/requestUtil
'
;
const
data
=
[
{
key
:
1
,
name
:
'
John Brown sr.
'
,
age
:
60
,
address
:
'
New York No. 1 Lake Park
'
,
children
:
[
{
key
:
11
,
name
:
'
John Brown
'
,
age
:
42
,
address
:
'
New York No. 2 Lake Park
'
,
},
{
key
:
12
,
name
:
'
John Brown jr.
'
,
age
:
30
,
address
:
'
New York No. 3 Lake Park
'
,
children
:
[
{
key
:
121
,
name
:
'
Jimmy Brown
'
,
age
:
16
,
address
:
'
New York No. 3 Lake Park
'
,
},
],
},
{
key
:
13
,
name
:
'
Jim Green sr.
'
,
age
:
72
,
address
:
'
London No. 1 Lake Park
'
,
children
:
[
{
key
:
131
,
name
:
'
Jim Green
'
,
age
:
42
,
address
:
'
London No. 2 Lake Park
'
,
children
:
[
{
key
:
1311
,
name
:
'
Jim Green jr.
'
,
age
:
25
,
address
:
'
London No. 3 Lake Park
'
,
},
{
key
:
1312
,
name
:
'
Jimmy Green sr.
'
,
age
:
18
,
address
:
'
London No. 4 Lake Park
'
,
},
],
},
],
},
],
},
{
key
:
2
,
name
:
'
Joe Black
'
,
age
:
32
,
address
:
'
Sidney No. 1 Lake Park
'
,
},
];
export
default
{
export
default
{
props
:
{
props
:
{
url
:
String
,
url
:
String
,
...
@@ -121,6 +70,7 @@ export default {
...
@@ -121,6 +70,7 @@ export default {
type
:
Object
,
type
:
Object
,
},
},
formatData
:
Function
,
formatData
:
Function
,
noPage
:
Boolean
,
},
},
data
()
{
data
()
{
return
{
return
{
...
@@ -128,8 +78,25 @@ export default {
...
@@ -128,8 +78,25 @@ export default {
queryForm
:
{},
queryForm
:
{},
loading
:
false
,
loading
:
false
,
addVisible
:
false
,
addVisible
:
false
,
submitLoading
:
false
,
drawerStyle
:
{
display
:
'
flex
'
,
flexDirection
:
'
column
'
,
overflowY
:
'
hidden
'
,
},
bodyStyle
:
{
flex
:
1
,
overflow
:
'
hidden
'
,
display
:
'
flex
'
,
flexDirection
:
'
column
'
,
},
};
};
},
},
watch
:
{
addVisible
(
val
)
{
if
(
!
val
&&
this
.
addBtn
.
onCancel
)
this
.
addBtn
.
onCancel
();
},
},
mounted
()
{
mounted
()
{
console
.
log
(
this
.
addBtn
);
console
.
log
(
this
.
addBtn
);
this
.
getData
();
this
.
getData
();
...
@@ -153,6 +120,22 @@ export default {
...
@@ -153,6 +120,22 @@ export default {
addDrawerClose
()
{
addDrawerClose
()
{
this
.
addVisible
=
false
;
this
.
addVisible
=
false
;
},
},
async
submit
()
{
this
.
submitLoading
=
true
;
try
{
await
this
.
addBtn
?.
onOk
();
}
catch
(
error
)
{
// todo
}
this
.
submitLoading
=
false
;
this
.
addVisible
=
false
;
},
showAdd
()
{
this
.
addVisible
=
true
;
},
refresh
()
{
this
.
getData
();
},
},
},
};
};
</
script
>
</
script
>
...
...
src/main.js
View file @
8846a011
...
@@ -34,7 +34,7 @@ const store = new Vuex.Store({
...
@@ -34,7 +34,7 @@ const store = new Vuex.Store({
Vue
.
use
(
Router
);
Vue
.
use
(
Router
);
const
isAsynRount
=
store
.
state
.
settingModule
.
asyncRoutes
;
const
isAsynRount
=
store
.
state
.
settingModule
.
asyncRoutes
;
const
options
=
initRouter
(
isAsynRount
);
const
options
=
initRouter
(
isAsynRount
);
const
router
=
new
Router
(
options
);
const
router
=
new
Router
(
{
mode
:
'
history
'
,
...
options
}
);
//装载vue-i18n控件 如果语言优先级 请直接修改这里localeLang和fallbackLang
//装载vue-i18n控件 如果语言优先级 请直接修改这里localeLang和fallbackLang
Vue
.
use
(
VueI18n
);
Vue
.
use
(
VueI18n
);
...
...
src/pages/system/view/menu/MenuManagement.vue
View file @
8846a011
<
template
>
<
template
>
<my-table
url=
"/api/v1/menus"
:addBtn=
"addBtn"
:formatData=
"formatData"
rowKey=
"menuId"
>
<my-table
url=
"/api/v1/menus"
:addBtn=
"addBtn"
:formatData=
"formatData"
rowKey=
"menuId"
noPage
ref=
"table"
>
<template
#search
="
{query}">
<template
#search
="
{query}">
<a-form-model-item
label=
"菜单、目录名称"
>
<a-form-model-item
label=
"菜单、目录名称"
>
<a-input
v-model=
"query.name"
/>
<a-input
v-model=
"query.name"
/>
</a-form-model-item>
</a-form-model-item>
</
template
>
</
template
>
<
template
#add
>
<
template
#add
>
<
a-input
v-model=
"add.name
"
/>
<
Form
ref=
"addForm
"
/>
</
template
>
</
template
>
<a-table-column
title=
"名称"
data-index=
"menuName"
/>
<a-table-column
title=
"名称"
data-index=
"menuName"
/>
<a-table-column
title=
"类型"
data-index=
"menuTypeName"
/>
<a-table-column
title=
"类型"
data-index=
"menuTypeName"
/>
<a-table-column
title=
"显示排序"
data-index=
"viewIndex"
:sorter=
"sorter"
sortOrder=
"ascend"
/>
<a-table-column
title=
"显示排序"
data-index=
"viewIndex"
:sorter=
"sorter"
sortOrder=
"ascend"
/>
<a-table-column
title=
"显示图标"
data-index=
"menuIcon"
/>
<a-table-column
title=
"显示图标"
data-index=
"menuIcon"
/>
<a-table-column
title=
"模块URL"
data-index=
"menuUrl"
/>
<a-table-column
title=
"模块URL"
data-index=
"menuUrl"
/>
<a-table-column
title=
"操作"
>
<a-table-column
title=
"操作"
>
<
template
#default
>
<
template
#default=
"row"
>
<span>
<a
@
click=
"() => edit(row)"
>
编辑
</a>
<a>
编辑
</a>
<a-divider
type=
"vertical"
/>
<a-divider
type=
"vertical"
/>
<a>
删除
</a>
<PopconfirmDelete
:onOk=
"() => delMenu(row.menuId)"
/>
</span>
</
template
>
</
template
>
</a-table-column>
</a-table-column>
</my-table>
</my-table>
...
@@ -27,19 +34,45 @@
...
@@ -27,19 +34,45 @@
<
script
>
<
script
>
import
{
convertListToTree
}
from
'
@/utils
'
;
import
{
convertListToTree
}
from
'
@/utils
'
;
import
PopconfirmDelete
from
'
@/components/popconfirm_delete/index.vue
'
;
import
{
delMenuApi
}
from
'
@/api
'
;
import
Form
from
'
./form.vue
'
;
export
default
{
export
default
{
data
:
()
=>
({
data
:
vm
=>
({
add
:
{},
addBtn
:
{
addBtn
:
{
text
:
'
新建
'
,
title
:
'
菜单配置
'
},
text
:
'
新建
'
,
title
:
'
菜单配置
'
,
width
:
400
,
async
onOk
()
{
await
vm
.
$refs
[
'
addForm
'
]?.
submit
();
vm
.
refreshTable
();
},
},
sortOrder
:
'
ascend
'
,
sortOrder
:
'
ascend
'
,
}),
}),
components
:
{
PopconfirmDelete
,
Form
},
methods
:
{
methods
:
{
formatData
:
convertListToTree
,
formatData
:
convertListToTree
,
refreshTable
()
{
this
.
$refs
[
'
table
'
].
refresh
();
},
async
delMenu
(
id
)
{
await
delMenuApi
(
id
);
this
.
refreshTable
();
},
sorter
(
pre
,
next
)
{
sorter
(
pre
,
next
)
{
return
pre
.
viewIndex
-
next
.
viewIndex
;
return
pre
.
viewIndex
-
next
.
viewIndex
;
},
},
edit
(
data
)
{
console
.
log
(
data
);
this
.
$refs
[
'
table
'
]?.
showAdd
();
this
.
$nextTick
(()
=>
{
this
.
$refs
[
'
addForm
'
].
setEdit
(
data
);
});
},
},
},
};
};
</
script
>
</
script
>
src/pages/system/view/menu/form.vue
0 → 100644
View file @
8846a011
<
template
>
<a-form-model
layout=
"vertical"
:model=
"form"
:rules=
"rules"
>
<a-form-model-item
label=
"父级"
v-if=
"isAdd"
>
<a-tree
v-model=
"checkedKeys"
:selectable=
"false"
checkable
checkStrictly
:replaceFields=
"replaceFields"
:tree-data=
"treeData"
@
check=
"onCheck"
style=
"max-height:400px"
class=
"tw-overflow-y-auto"
/>
</a-form-model-item>
<a-form-model-item
label=
"类型"
>
<a-radio-group
v-model=
"form.menuType"
:disabled=
"isEdit"
>
<a-radio
value=
"CATALOG"
>
目录
</a-radio>
<a-radio
value=
"MENU"
>
菜单
</a-radio>
</a-radio-group>
</a-form-model-item>
<a-form-model-item
label=
"中文名称"
>
<a-input
v-model=
"form.menuName"
/>
</a-form-model-item>
<a-form-model-item
label=
"英文名称"
>
<a-input
/>
</a-form-model-item>
<a-form-model-item
label=
"模块URL"
prop=
"menuUrl"
>
<a-input
v-model=
"form.menuUrl"
/>
</a-form-model-item>
<a-form-model-item
label=
"显示排序"
prop=
"viewIndex"
>
<a-input-number
v-model=
"form.viewIndex"
/>
</a-form-model-item>
<a-form-model-item
label=
"显示图标"
prop=
"menuIcon"
>
<a-input
v-model=
"form.menuIcon"
/>
</a-form-model-item>
<a-form-model-item
label=
"说明"
prop=
"menuRemark"
>
<a-textarea
v-model=
"form.menuRemark"
/>
</a-form-model-item>
</a-form-model>
</
template
>
<
script
>
import
{
getMenuDataApi
,
addMenuApi
}
from
'
@/api
'
;
import
{
convertListToTree
}
from
'
@/utils
'
;
export
default
{
data
:
()
=>
({
type
:
0
,
form
:
{
menuType
:
'
CATALOG
'
,
parentMenuId
:
0
,
menuName
:
''
,
},
rules
:
{
menuUrl
:
[{
required
:
true
}],
},
replaceFields
:
{
title
:
'
menuName
'
,
key
:
'
menuId
'
,
},
checkedKeys
:
{
checked
:
[],
halfChecked
:
[],
},
treeData
:
[],
}),
mounted
()
{
this
.
getMenuData
();
},
computed
:
{
isAdd
()
{
return
this
.
type
===
0
;
},
isEdit
()
{
return
this
.
type
===
1
;
},
},
methods
:
{
async
getMenuData
()
{
this
.
treeData
=
convertListToTree
(
await
getMenuDataApi
(),
true
);
console
.
log
(
this
.
treeData
);
},
submit
()
{
return
addMenuApi
({
...
this
.
form
,
parentMenuId
:
this
.
checkedKeys
.
checked
[
0
]
??
0
});
},
onCheck
(
checkedKeys
)
{
this
.
checkedKeys
.
checked
=
checkedKeys
.
checked
.
slice
(
-
1
);
},
setEdit
(
data
)
{
this
.
type
=
1
;
this
.
form
=
data
;
},
},
};
</
script
>
src/utils/i18nUtil.js
View file @
8846a011
...
@@ -11,7 +11,6 @@ import { getI18nKey } from '@/utils/routerUtil';
...
@@ -11,7 +11,6 @@ import { getI18nKey } from '@/utils/routerUtil';
function
generateI18n
(
lang
,
routes
,
valueKey
)
{
function
generateI18n
(
lang
,
routes
,
valueKey
)
{
routes
.
forEach
(
route
=>
{
routes
.
forEach
(
route
=>
{
let
keys
=
getI18nKey
(
route
.
fullPath
).
split
(
'
.
'
);
let
keys
=
getI18nKey
(
route
.
fullPath
).
split
(
'
.
'
);
console
.
log
(
keys
);
let
value
=
let
value
=
valueKey
===
'
path
'
valueKey
===
'
path
'
?
route
[
valueKey
]
?
route
[
valueKey
]
...
...
src/utils/index.js
View file @
8846a011
...
@@ -13,9 +13,13 @@ export function setUserId(val) {
...
@@ -13,9 +13,13 @@ export function setUserId(val) {
/**
/**
* 转变菜单列表为tree结构
* 转变菜单列表为tree结构
* @param {Array} menuList 菜单列表
* @param {Array} menuList 菜单列表
* @param {Boolean} filterMenu 是否过滤掉菜单,只保留目录
*/
*/
export
function
convertListToTree
(
menuList
)
{
export
function
convertListToTree
(
menuList
,
filterMenu
=
false
)
{
const
tempMenu
=
[...
menuList
];
let
tempMenu
=
[...
menuList
];
if
(
filterMenu
)
{
tempMenu
=
tempMenu
.
filter
(
m
=>
m
.
menuType
!==
'
MENU
'
);
}
for
(
const
menu
of
menuList
)
{
for
(
const
menu
of
menuList
)
{
if
(
menu
.
parentMenuId
===
0
)
continue
;
if
(
menu
.
parentMenuId
===
0
)
continue
;
const
parent
=
menuList
.
find
(
m
=>
m
.
menuId
===
menu
.
parentMenuId
);
const
parent
=
menuList
.
find
(
m
=>
m
.
menuId
===
menu
.
parentMenuId
);
...
@@ -23,3 +27,5 @@ export function convertListToTree(menuList) {
...
@@ -23,3 +27,5 @@ export function convertListToTree(menuList) {
}
}
return
tempMenu
.
filter
(
m
=>
m
.
parentMenuId
===
0
);
return
tempMenu
.
filter
(
m
=>
m
.
parentMenuId
===
0
);
}
}
export
function
EMPTY_FUN
()
{}
src/utils/requestUtil.js
View file @
8846a011
...
@@ -133,4 +133,27 @@ function checkAuthorization() {
...
@@ -133,4 +133,27 @@ function checkAuthorization() {
return
!!
getToken
();
return
!!
getToken
();
}
}
export
{
METHOD
,
request
,
parseUrlParams
,
loadResponseInterceptor
,
setToken
,
checkAuthorization
,
clearToken
};
function
delReq
(
url
,
config
)
{
return
request
(
url
,
METHOD
.
DELETE
,
config
);
}
function
getReq
(
url
,
params
,
config
)
{
return
request
(
url
,
METHOD
.
GET
,
params
,
config
);
}
function
postReq
(
url
,
data
,
config
)
{
return
request
(
url
,
METHOD
.
POST
,
data
,
config
);
}
export
{
METHOD
,
request
,
parseUrlParams
,
loadResponseInterceptor
,
setToken
,
checkAuthorization
,
clearToken
,
delReq
,
getReq
,
postReq
,
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment