|
@@ -8,7 +8,32 @@
|
|
<el-col :span="24" class="two">
|
|
<el-col :span="24" class="two">
|
|
<cButton @toAdd="toAdd"></cButton>
|
|
<cButton @toAdd="toAdd"></cButton>
|
|
</el-col>
|
|
</el-col>
|
|
- <el-col :span="24" class="thr"> 列表 </el-col>
|
|
|
|
|
|
+ <el-col :span="24" class="thr">
|
|
|
|
+ <el-table :data="list" row-key="_id" border>
|
|
|
|
+ <el-table-column align="center" label="菜单名称" prop="name"></el-table-column>
|
|
|
|
+ <el-table-column align="center" label="父级菜单" prop="parent_name"></el-table-column>
|
|
|
|
+ <el-table-column align="center" label="图标" width="80">
|
|
|
|
+ <template #default="{ row }"><span :class="['iconfont', row.icon]"></span></template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column align="center" label="顺序" sortable prop="sort" width="80"></el-table-column>
|
|
|
|
+ <el-table-column align="center" label="路由地址" prop="path"></el-table-column>
|
|
|
|
+ <el-table-column align="center" label="组件地址" prop="component"></el-table-column>
|
|
|
|
+ <el-table-column align="center" label="菜单类型" prop="type">
|
|
|
|
+ <template #default="{ row }">{{ getDict(row.type, 'type') }} </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column align="center" label="状态" prop="is_use" width="80">
|
|
|
|
+ <template #default="{ row }">{{ getDict(row.is_use, 'is_use') }} </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ <el-table-column align="center" label="备注" prop="remark"> </el-table-column>
|
|
|
|
+ <el-table-column align="center" label="操作">
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
+ <el-link :underline="false" type="primary" size="mini" @click="toEdit(row)" style="margin-right: 10px">修改</el-link>
|
|
|
|
+ <el-link :underline="false" type="primary" size="mini" @click="toNext(row)" style="margin-right: 10px">添加下一级</el-link>
|
|
|
|
+ <el-link :underline="false" type="danger" size="mini" @click="toDel(row)">删除</el-link>
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
|
|
+ </el-table>
|
|
|
|
+ </el-col>
|
|
</el-col>
|
|
</el-col>
|
|
</el-row>
|
|
</el-row>
|
|
<cDialog :dialog="dialog" @handleClose="toClose">
|
|
<cDialog :dialog="dialog" @handleClose="toClose">
|
|
@@ -19,21 +44,14 @@
|
|
<el-option v-for="(i, index) in typeList" :key="`t${index}`" :label="i.label" :value="i.value"></el-option>
|
|
<el-option v-for="(i, index) in typeList" :key="`t${index}`" :label="i.label" :value="i.value"></el-option>
|
|
</template>
|
|
</template>
|
|
<template #icon>
|
|
<template #icon>
|
|
- <el-option v-for="i in iconList" :key="i.value" :label="i.label" :value="i.value">
|
|
|
|
- <span style="float: left" :class="['iconfont', i.dict_label]"></span>
|
|
|
|
- <span style="float: right; color: #8492a6; font-size: 13px">{{ i.dict_label }}</span>
|
|
|
|
- </el-option>
|
|
|
|
|
|
+ <el-option v-for="i in iconList" :key="i.value" :label="i.label" :value="i.value"> </el-option>
|
|
</template>
|
|
</template>
|
|
- <!-- <template #parent_id>
|
|
|
|
|
|
+ <template #parent_id>
|
|
<el-option v-for="(i, index) in getOneDimensionList()" :key="`m${index}`" :label="i.name" :value="i._id"></el-option>
|
|
<el-option v-for="(i, index) in getOneDimensionList()" :key="`m${index}`" :label="i.name" :value="i._id"></el-option>
|
|
</template>
|
|
</template>
|
|
-
|
|
|
|
- <template #status>
|
|
|
|
- <el-radio-group v-model="form.status">
|
|
|
|
- <el-radio label="0">使用</el-radio>
|
|
|
|
- <el-radio label="1">禁用</el-radio>
|
|
|
|
- </el-radio-group>
|
|
|
|
- </template> -->
|
|
|
|
|
|
+ <template #is_use>
|
|
|
|
+ <el-option v-for="(i, index) in is_useList" :key="`t${index}`" :label="i.label" :value="i.value"></el-option>
|
|
|
|
+ </template>
|
|
</cForm>
|
|
</cForm>
|
|
</el-col>
|
|
</el-col>
|
|
</template>
|
|
</template>
|
|
@@ -43,14 +61,17 @@
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
// 基础
|
|
// 基础
|
|
|
|
+import _ from 'lodash';
|
|
import type { Ref } from 'vue';
|
|
import type { Ref } from 'vue';
|
|
import { onMounted, ref } from 'vue';
|
|
import { onMounted, ref } from 'vue';
|
|
import { useRoute } from 'vue-router';
|
|
import { useRoute } from 'vue-router';
|
|
-
|
|
|
|
|
|
+import { ElMessage, ElMessageBox } from 'element-plus';
|
|
// 接口
|
|
// 接口
|
|
import { MenusStore } from '@common/src/stores/system/menus';
|
|
import { MenusStore } from '@common/src/stores/system/menus';
|
|
|
|
+import { DictDataStore } from '@common/src/stores/system/dictData';
|
|
import type { IQueryResult } from '@/util/types.util';
|
|
import type { IQueryResult } from '@/util/types.util';
|
|
const menusAxios = MenusStore();
|
|
const menusAxios = MenusStore();
|
|
|
|
+const dictAxios = DictDataStore();
|
|
|
|
|
|
// 路由
|
|
// 路由
|
|
const route = useRoute();
|
|
const route = useRoute();
|
|
@@ -67,9 +88,9 @@ const fields: Ref<any> = ref([
|
|
{ label: '菜单名称', model: 'name' },
|
|
{ label: '菜单名称', model: 'name' },
|
|
{ label: '菜单类型', model: 'type', type: 'select' },
|
|
{ label: '菜单类型', model: 'type', type: 'select' },
|
|
{ label: '父级菜单', model: 'parent_id', type: 'select' },
|
|
{ label: '父级菜单', model: 'parent_id', type: 'select' },
|
|
- { label: '顺序', model: 'order_num', type: 'number' },
|
|
|
|
|
|
+ { label: '顺序', model: 'sort', type: 'number' },
|
|
{ label: '图标', model: 'icon', type: 'select' },
|
|
{ label: '图标', model: 'icon', type: 'select' },
|
|
- { label: '状态', model: 'status', custom: true },
|
|
|
|
|
|
+ { label: '是否使用', model: 'is_use', type: 'select' },
|
|
{ label: '备注', model: 'remark', type: 'textarea' }
|
|
{ label: '备注', model: 'remark', type: 'textarea' }
|
|
]);
|
|
]);
|
|
|
|
|
|
@@ -80,10 +101,12 @@ const typeList: Ref<any> = ref([
|
|
{ label: '子页面', value: '2' }
|
|
{ label: '子页面', value: '2' }
|
|
]);
|
|
]);
|
|
const iconList: Ref<any> = ref([]);
|
|
const iconList: Ref<any> = ref([]);
|
|
|
|
+const is_useList: Ref<any> = ref([]);
|
|
// 请求
|
|
// 请求
|
|
onMounted(async () => {
|
|
onMounted(async () => {
|
|
let id = route.query.id;
|
|
let id = route.query.id;
|
|
if (id) module_id.value = id;
|
|
if (id) module_id.value = id;
|
|
|
|
+ await searchOther();
|
|
await search();
|
|
await search();
|
|
});
|
|
});
|
|
const search = async () => {
|
|
const search = async () => {
|
|
@@ -95,12 +118,32 @@ const search = async () => {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
};
|
|
-
|
|
|
|
|
|
+const getDict = (e, model) => {
|
|
|
|
+ if (model == 'type' && e) {
|
|
|
|
+ let data = typeList.value.find((i) => i.value == e);
|
|
|
|
+ if (data) return data.label;
|
|
|
|
+ else return '暂无';
|
|
|
|
+ } else if (model == 'is_use' && e) {
|
|
|
|
+ let data = is_useList.value.find((i) => i.value == e);
|
|
|
|
+ if (data) return data.label;
|
|
|
|
+ else return '暂无';
|
|
|
|
+ }
|
|
|
|
+};
|
|
// 添加
|
|
// 添加
|
|
const toAdd = () => {
|
|
const toAdd = () => {
|
|
form.value = { module_id: module_id.value };
|
|
form.value = { module_id: module_id.value };
|
|
dialog.value = { title: '菜单管理', show: true, type: '1' };
|
|
dialog.value = { title: '菜单管理', show: true, type: '1' };
|
|
};
|
|
};
|
|
|
|
+// 修改
|
|
|
|
+const toEdit = (e) => {
|
|
|
|
+ form.value = e;
|
|
|
|
+ dialog.value = { title: '菜单管理', show: true, type: '1' };
|
|
|
|
+};
|
|
|
|
+// 下一级
|
|
|
|
+const toNext = (e) => {
|
|
|
|
+ form.value = { module_id: module_id.value, parent_id: e._id };
|
|
|
|
+ dialog.value = { title: '菜单管理', show: true, type: '1' };
|
|
|
|
+};
|
|
// 选择
|
|
// 选择
|
|
const dataChange = ({ model, value }) => {
|
|
const dataChange = ({ model, value }) => {
|
|
if (model == 'type') {
|
|
if (model == 'type') {
|
|
@@ -114,15 +157,72 @@ const dataChange = ({ model, value }) => {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
+const getOneDimensionList = () => {
|
|
|
|
+ let dup = _.cloneDeep(list.value);
|
|
|
|
+ let arr = getAllChild(dup);
|
|
|
|
+ return arr;
|
|
|
|
+};
|
|
|
|
+const getAllChild = (children) => {
|
|
|
|
+ let arr = [];
|
|
|
|
+ for (const i of children) {
|
|
|
|
+ const { children, ...others } = i;
|
|
|
|
+ arr.push(others);
|
|
|
|
+ if (children) {
|
|
|
|
+ const marr = getAllChild(children);
|
|
|
|
+ arr.push(...marr);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return arr;
|
|
|
|
+};
|
|
// 提交保存
|
|
// 提交保存
|
|
-const toSave = async (e) => {
|
|
|
|
- console.log(e);
|
|
|
|
|
|
+const toSave = async (data) => {
|
|
|
|
+ let res: IQueryResult;
|
|
|
|
+ if (data._id) res = await menusAxios.update(data);
|
|
|
|
+ else res = await menusAxios.create(data);
|
|
|
|
+ if (res.errcode == '0') {
|
|
|
|
+ ElMessage({ message: '维护信息成功', type: 'success' });
|
|
|
|
+ toClose();
|
|
|
|
+ search();
|
|
|
|
+ } else {
|
|
|
|
+ ElMessage({ message: `${res.errmsg}`, type: 'error' });
|
|
|
|
+ }
|
|
};
|
|
};
|
|
// 关闭弹框
|
|
// 关闭弹框
|
|
const toClose = () => {
|
|
const toClose = () => {
|
|
dialog.value = { title: '菜单管理', show: false, type: '1' };
|
|
dialog.value = { title: '菜单管理', show: false, type: '1' };
|
|
search();
|
|
search();
|
|
};
|
|
};
|
|
|
|
+// 删除
|
|
|
|
+const toDel = async (e) => {
|
|
|
|
+ ElMessageBox.alert('删除该菜单吗?', '提示', {
|
|
|
|
+ confirmButtonText: '确认',
|
|
|
|
+ callback: async (action: any) => {
|
|
|
|
+ if (action == 'confirm') {
|
|
|
|
+ let res: IQueryResult = await menusAxios.del(e._id);
|
|
|
|
+ if (res.errcode == '0') {
|
|
|
|
+ ElMessage({ message: `删除信息成功`, type: 'success' });
|
|
|
|
+ search();
|
|
|
|
+ } else {
|
|
|
|
+ ElMessage({ message: `${res.errmsg}`, type: 'error' });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+};
|
|
|
|
+// 查询其他信息
|
|
|
|
+const searchOther = async () => {
|
|
|
|
+ let res: IQueryResult;
|
|
|
|
+ // 是否使用
|
|
|
|
+ res = await dictAxios.query({ type: 'common_use' });
|
|
|
|
+ if (res.errcode == '0') {
|
|
|
|
+ is_useList.value = res.data;
|
|
|
|
+ }
|
|
|
|
+ // 图标
|
|
|
|
+ res = await dictAxios.query({ type: 'icon' });
|
|
|
|
+ if (res.errcode == '0') {
|
|
|
|
+ iconList.value = res.data;
|
|
|
|
+ }
|
|
|
|
+};
|
|
// 返回上一页
|
|
// 返回上一页
|
|
const toBack = () => {
|
|
const toBack = () => {
|
|
window.history.go(-1);
|
|
window.history.go(-1);
|