Commit f4f23daf authored by 赵伟庚's avatar 赵伟庚

updata:菜单管理树形交互,表单交互,对接部分接口

parent 133893b6
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
</template> </template>
<script> <script>
import "https://lf1-cdn-tos.bytegoofy.com/obj/iconpark/svg_19654_206.057df182551c6e61aaed89c0ac5bcc35.js"; import "https://lf1-cdn-tos.bytegoofy.com/obj/iconpark/svg_19654_208.0836ca76f9dc91830ca8aa43b6e894ac.js";
export default { export default {
props: { props: {
......
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
</template> </template>
</bg-filter-group> </bg-filter-group>
<div class="table_container"> <div class="table_container">
<bg-table ref="bgTable" :headers="headers" :rows="tableRows" :isIndex="true" :stripe="true"> <bg-table ref="bgTable" :headers="headers" :rows="tableRows" :isIndex="true" :stripe="true" :select="true">
<template v-slot:updated_time="{ row }"> <template v-slot:updated_time="{ row }">
{{ row.updated_time.split("+")[0].replace("T", " ").replace("Z", " ") }} {{ row.updated_time.split("+")[0].replace("T", " ").replace("Z", " ") }}
</template> </template>
...@@ -222,7 +222,7 @@ const state = reactive({ ...@@ -222,7 +222,7 @@ const state = reactive({
}, },
{ {
name: "禁用", name: "禁用",
value: "2" value: "0"
}, },
], // 启用禁用 ], // 启用禁用
actionRow: null, // 当前操作的数据 actionRow: null, // 当前操作的数据
...@@ -258,7 +258,7 @@ const nodeClick = (item) => { ...@@ -258,7 +258,7 @@ const nodeClick = (item) => {
page: 1, page: 1,
limit: 10, limit: 10,
} }
getTableRows() changePage(1)
} // 切换字典分类 } // 切换字典分类
const searchType = () => { const searchType = () => {
...@@ -376,6 +376,7 @@ const changeUseRow = (row) => { ...@@ -376,6 +376,7 @@ const changeUseRow = (row) => {
const changePage = (page) => { const changePage = (page) => {
state.filter.page = page state.filter.page = page
state.tableRows = []
getTableRows() getTableRows()
} // 改变页码 } // 改变页码
......
...@@ -73,7 +73,14 @@ ...@@ -73,7 +73,14 @@
</div> </div>
<div class="flex_right"> <div class="flex_right">
<div class="main_container"> <div class="main_container">
<div class="base-info bg-scroll">
<menuForm ref="menuFormRef" :data="menuFormData" @action="getMenuFormData"></menuForm>
</div>
<div class="base-btn">
<el-button type="primary" @click="saveMenu(menuFormRef,addType)">
保存
</el-button>
</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -86,11 +93,12 @@ import { reactive, toRefs, ref, nextTick, computed, onBeforeMount, onBeforeUnmou ...@@ -86,11 +93,12 @@ import { reactive, toRefs, ref, nextTick, computed, onBeforeMount, onBeforeUnmou
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import axios from '../../../../request/http.js' import axios from '../../../../request/http.js'
import menuForm from './menu-form.vue'
const router = useRouter(); const router = useRouter();
const menuTree = ref(null) const menuTree = ref(null)
const treeAction = ref(null) const treeAction = ref(null)
const menuFormRef = ref(null)
const acTop = ref(''); const acTop = ref('');
const acLeft = ref(''); const acLeft = ref('');
const acBottom = ref(''); const acBottom = ref('');
...@@ -109,6 +117,9 @@ const state = reactive({ ...@@ -109,6 +117,9 @@ const state = reactive({
label: 'menu_name', label: 'menu_name',
}, },
actionDataIndex: 0, actionDataIndex: 0,
menuFormData: null,
addType: 1, // 1-新增本级 2-新增下级
newMenuId: 0,
}) })
const moveIndex = computed({ const moveIndex = computed({
...@@ -130,15 +141,20 @@ const getMenuTree = () => { ...@@ -130,15 +141,20 @@ const getMenuTree = () => {
if (res.data.code == 200) { if (res.data.code == 200) {
state.data = res.data.data || [] state.data = res.data.data || []
nextTick().then(() => { nextTick().then(() => {
if (state.selectData) {
state.menuTree && state.menuTree.setCurrentKey(state.selectData.menu_id);
handleNodeClick(state.selectData);
}else {
state.menuTree && state.menuTree.setCurrentKey(state.data[0].menu_id); state.menuTree && state.menuTree.setCurrentKey(state.data[0].menu_id);
handleNodeClick(state.data[0]); handleNodeClick(state.data[0]);
}
}) })
}else { }else {
ElMessage.error(res.data.data) ElMessage.error(res.data.data)
} }
}) })
} } // 获取菜单树
const findIndex= (code,arr) => { const findIndex= (code,arr) => {
arr.forEach((e,i) => { arr.forEach((e,i) => {
if (e.menu_id == code) { if (e.menu_id == code) {
...@@ -150,7 +166,7 @@ const findIndex= (code,arr) => { ...@@ -150,7 +166,7 @@ const findIndex= (code,arr) => {
} }
} }
}) })
} } // 处理数据 用于判断能否上下移
const showAction = (e, data,node) => { const showAction = (e, data,node) => {
acTop.value = '' acTop.value = ''
...@@ -182,7 +198,7 @@ const showAction = (e, data,node) => { ...@@ -182,7 +198,7 @@ const showAction = (e, data,node) => {
} }
}) })
}) })
}; } // 树形操作框
const handleNodeClick = (data) => { const handleNodeClick = (data) => {
...@@ -190,19 +206,58 @@ const handleNodeClick = (data) => { ...@@ -190,19 +206,58 @@ const handleNodeClick = (data) => {
return return
} }
state.selectData = data state.selectData = data
console.log(data) menuFormRef.value.setForm(state.selectData)
closeAction() closeAction()
} } // 菜单树节点点击
const fileAction = (val,data,parent,disabled=false) => { const fileAction = (val,data,parent,disabled=false) => {
if (val == 1) { if (val == 1) {
state.addType = 1
console.log("新建本级", data ,parent,disabled) console.log("新建本级", data ,parent,disabled)
test() let newChild = {
menu_name: "新菜单",
menu_id: 'new' + state.newMenuId,
menu_type: 0,
dict_group_id: "",
state: 1,
menu_url: "",
menu_logo: "",
}
state.menuTree.insertAfter(newChild,parent? parent.Child[parent.Child.length-1] : state.data[state.data.length -1])
state.menuTree && state.menuTree.setCurrentKey(newChild.menu_id);
handleNodeClick(newChild);
state.newMenuId++
}else if (val == 2) { }else if (val == 2) {
state.addType = 2
console.log("新建下级",data,parent,disabled) console.log("新建下级",data,parent,disabled)
let newChild = {
menu_name: "新菜单",
menu_id: 'new' + state.newMenuId,
menu_type: 0,
dict_group_id: "",
state: 1,
menu_url: "",
menu_logo: "",
}
state.menuTree.append(newChild,data)
state.menuTree && state.menuTree.setCurrentKey(newChild.menu_id);
handleNodeClick(newChild);
state.selectParentData = data
state.newMenuId++
test() test()
}else if (val == 3) { }else if (val == 3) {
console.log("删除",data,parent,disabled) console.log("删除",data,parent,disabled)
axios
.delete(`/apaas/system/v5/menu/${data.id}`)
.then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.data)
state.selectData = null
getMenuTree()
}else {
ElMessage.error(res.data.data)
}
})
test() test()
}else if (val == 4) { }else if (val == 4) {
console.log("上移",data,parent,disabled) console.log("上移",data,parent,disabled)
...@@ -218,7 +273,16 @@ const fileAction = (val,data,parent,disabled=false) => { ...@@ -218,7 +273,16 @@ const fileAction = (val,data,parent,disabled=false) => {
} }
test() test()
} }
} if (menuFormRef) {
nextTick().then(() => {
menuFormRef.value.menuRef.validate(valid => {
if (!valid) {
menuFormRef.value.menuRef.clearValidate()
}
})
})
}
} // 各种操作按钮
const test = () => { const test = () => {
console.log("执行了") console.log("执行了")
...@@ -226,8 +290,51 @@ const test = () => { ...@@ -226,8 +290,51 @@ const test = () => {
const closeAction = () => { const closeAction = () => {
actionFlag.value = false; actionFlag.value = false;
} } // 点击其他地方,菜单操作框关闭
const getMenuFormData = (date) => {
}
const saveMenu = (el,type) => {
console.log(el,type)
let params = {
menu_name: el.menuForm.menu_name,
menu_type: el.menuForm.menu_type,
dict_group_id: el.menuForm.dict_group_id,
state: el.menuForm.state,
menu_url: el.menuForm.menu_url,
menu_logo: el.menuForm.menu_logo,
}
if (state.selectData.id) { // 编辑
axios
.put(`/apaas/system/v5/menu/${state.selectData.id}`,params)
.then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.msg)
getMenuTree()
}else {
ElMessage.error(res.data.data)
}
})
}else { // 新增
if(type == 1) { // 新增本级
params.p_menu_id = state.selectParentData ? state.selectParentData.menu_id : ""
}else { // 新增下级
params.p_menu_id = state.selectParentData.menu_id
}
console.log(123)
axios
.post(`/apaas/system/v5/menu/add`,params)
.then((res) => {
if (res.data.code == 200) {
ElMessage.success(res.data.data)
getMenuTree()
}else {
ElMessage.error(res.data.data)
}
})
}
}
onBeforeMount(()=>{ onBeforeMount(()=>{
window.addEventListener("click", closeAction) window.addEventListener("click", closeAction)
window.addEventListener("scroll", closeAction,true) window.addEventListener("scroll", closeAction,true)
...@@ -247,6 +354,8 @@ const { ...@@ -247,6 +354,8 @@ const {
defaultProps, defaultProps,
selectParentData, selectParentData,
selectData, selectData,
menuFormData,
addType,
} = toRefs(state) } = toRefs(state)
</script> </script>
...@@ -320,25 +429,24 @@ padding-left: 16px; ...@@ -320,25 +429,24 @@ padding-left: 16px;
color: #616f94; color: #616f94;
} }
.main_container { .main_container {
padding: 15px; height: 100%;
height: 100%;
}
.table_container {
height: calc(100% - 30px);
overflow: auto;
}
.pagination_box {
position: sticky;
margin-top: 16px;
bottom: 0px;
background-color: #fff;
z-index: 1024;
height: 40px;
line-height: 40px;
padding-top: 8px;
}
.bg-pagination {
bottom: unset
} }
</style>
<style lang="scss" scoped>
.main_container {
.base-info {
height: calc(100% - 68px);
padding: 40px 0 0 40px;
}
.base-btn {
height: 68px;
border-top: 1px solid #e6e9ef;
text-align: right;
padding: 16px;
.el-button {
width: 92px;
}
}
}
</style> </style>
\ No newline at end of file
<template>
<el-form
:label-position="'right'"
label-width="68px"
:model="menuForm"
:rules="formRules"
ref="menuRef"
style="width: 856px"
class="menu_form"
>
<el-form-item label="菜单名称" prop="menu_name">
<el-input v-model="menuForm.menu_name" show-word-limit maxlength="8" placeholder="请输入菜单名称" />
</el-form-item>
<el-form-item label="类型" prop="menu_type">
<el-radio-group v-model="menuForm.menu_type">
<el-radio :label="0">目录</el-radio>
<el-radio :label="1">菜单</el-radio>
<el-radio :label="2">子页面</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="分组" prop="dict_group_id" v-if="menuForm.menu_type == 0">
<el-select v-model="menuForm.dict_group_id" placeholder="请选择分组">
<el-option
v-for="item in groupList"
:key="item.dict_id"
:label="item.name"
:value="item.dict_id"
/>
</el-select>
</el-form-item>
<el-form-item label="是否启用" prop="state">
<el-switch
class="bg-switch-ele"
v-model="menuForm.state"
:active-value="1"
:inactive-value="0"
inline-prompt
active-text="是"
inactive-text="否"
/>
</el-form-item>
<el-form-item label="菜单路径" prop="menu_url">
<el-input v-model="menuForm.menu_url" placeholder="请输入菜单路径" />
</el-form-item>
<el-form-item label="菜单图标" prop="menu_logo" v-if="menuForm.menu_type !== 2">
<div class="iconBox" :style="iconFlag ? {'border-color':'#2b4695'} : {} " @click="openIconbox">
<div>
<span>
<bg-icon
class="bgIcon"
style="margin-right: 8px"
:icon="'#' + menuForm.menu_logo"
></bg-icon>
<span>{{menuForm.menu_logo.replace("bg-ic-","")}}</span>
</span>
</div>
<div>
<bg-icon
class="bgIcon clearIcon"
icon="#bg-ic-circle-close"
v-if="menuForm.menu_logo != ''"
@click.stop="clearIcon"
></bg-icon>
<bg-icon
class="bgIcon"
:icon="iconFlag ? '#bg-ic-caret-top' : '#bg-ic-caret-bottom'"
></bg-icon>
</div>
</div>
<div class="icon_box" v-show="iconFlag">
<div class="input_box">
<el-input
placeholder="请输入内容"
:prefix-icon="Search"
v-model="icon_search"
@input="searchIcon"
>
</el-input>
</div>
<div class="icon_content bg-scroll">
<div class="icon_item" v-for="(e,i) in iconArr" :key="i+100" @click="changeIcon(e)">
<span>
<bg-icon
class="selectBgIcon"
:icon="'#' + e.icon"
></bg-icon>
{{e.name}}
</span>
</div>
</div>
</div>
</el-form-item>
</el-form>
</template>
<script setup>
import { Search } from '@element-plus/icons-vue'
import { reactive, ref, onMounted, toRefs } from 'vue'
import axios from '../../../../request/http.js'
import { ElMessage } from 'element-plus'
import allIconArr from '@/assets/js/bg_icon.js'
const menuRef = ref(null)
const props = defineProps({
data: {
type: Object,
default: null,
}
})
const state = reactive({
menuRef,
menuForm: {
menu_name: '',
menu_type: 0,
dict_group_id: "",
state: 1,
menu_url: "",
menu_logo: "",
},
formRules: {
menu_name: [
{ required: true, message: '请输入菜单名称', trigger: 'blur' },
],
menu_type: [
{ required: true, message: '请选择菜单类型', trigger: 'change' },
],
dict_group_id: [
{ required: true, message: '请选择菜单分组', trigger: 'change' },
],
menu_url: [
{ required: true, message: '请输入菜单路径', trigger: 'blur' },
]
},
groupList: [],
iconFlag: false,
icon_search: "",
iconArr: [],
})
const emit = defineEmits(['action'])
const submitForm = async () => {
if (!state.menuRef) return
await state.menuRef.validate((valid, fields) => {
if (valid) {
emit('action', state.menuForm)
} else {
emit('action',null)
}
})
}
const getGroupList = () => {
axios
.get(`/apaas/system/v5/dictionary/list?state=1&id=5`)
.then((res) => {
if (res.data.code == 200) {
state.groupList = res.data.data || []
console.log(state.groupList)
}else {
ElMessage.error(res.data.data)
}
}).catch((err) => {
console.log(err)
})
}
const openIconbox = () => {
state.iconFlag = !state.iconFlag
}
const searchIcon = () => {
}
const clearForm = () => {
if (!state.menuRef) return
state.menuRef.resetFields()
}
const setForm = (data) => {
state.menuForm = Object.assign(state.menuForm, data);
}
const clearIcon = () => {
state.menuForm.menu_logo = ""
}
const changeIcon = (e) => {
console.log(e)
state.menuForm.menu_logo = e.icon
state.iconFlag = false
}
onMounted(() => {
allIconArr.forEach(e => {
state.iconArr.push({
icon: e,
name: e.replace("bg-ic-","")
})
})
})
const {
menuForm,
formRules,
groupList,
iconFlag,
iconArr
} = toRefs(state)
onMounted(() => {
getGroupList()
})
defineExpose({ submitForm, clearForm, setForm , menuForm, menuRef })
</script>
<style lang="scss" scoped>
.menu_form {
.el-form-item {
margin-bottom: 24px;
:deep().el-form-item__label {
padding: 0;
margin-right: 8px;
}
.el-form-item__content {
.el-input,
.el-select {
width: 100%;
}
.bg-switch-ele {
width: 52px;
height: 24px;
:deep().el-switch__core {
width: 100%;
height: 24px;
.el-switch__inner,
.el-switch__action {
top: 3px;
}
}
}
.iconBox {
width: 100%;
display: flex;
padding: 0 12px;
height: 36px;
line-height: 36px;
justify-content: space-between;
border: 1px solid #dadee7;
border-radius: 4px;
cursor: pointer;
.bgIcon {
color: #202531;
width: 8px;
margin-top: 11px;
}
.clearIcon {
margin-right: 8px;
width: 14px;
display: none;
}
&:hover,
&:focus,
&:active {
border-color: #2b4695;
.clearIcon {
display: inline-block;
}
}
&:hover {
border-color: #a9b1c7;
}
}
.icon_box {
width: 100%;
height: 236px;
box-shadow: 0px 4px 12px 0px
rgba(18, 30, 63, 0.1);
border-radius: 4px;
border: solid 1px #e6e9ef;
margin-top: 10px;
padding: 12px 0px 12px 8px;
.input_box {
margin-right: 8px;
}
.icon_content {
width: 100%;
height: 168px;
display: flex;
flex-wrap: wrap;
margin-top: 8px;
.icon_item {
display: inline-block;
border: 1px solid #dadee7;
border-radius: 3px;
width: 182px;
height: 36px;
margin: 0 8px 8px 0;
color: #202531;
padding-left: 16px;
line-height: 36px;
cursor: pointer;
&:hover,
&:active {
background-color: #eaedf5;
border-color: #95a3ca;
}
&:nth-child(4n) {
margin-right: 0;
}
.selectBgIcon {
width: 14px;
margin-right: 10px;
}
}
}
}
}
}
}
</style>
\ No newline at end of file
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