Pārlūkot izejas kodu

增加批量绑定菜单的操作

yanglzh 1 gadu atpakaļ
vecāks
revīzija
a15024de73

+ 2 - 1
src/api/system/index.ts

@@ -15,6 +15,7 @@ export default {
     add: (data: object) => post('/system/api/add', data),
     del: (id: number) => del('/system/api/del', { id }),
     edit: (data: object) => put('/system/api/edit', data),
+    bindMenus: (bindMenus: any[]) => post('/system/api/bindMenus', { bindMenus }),
   },
   menu: {
     getList: (params: object) => get('/system/menu/tree', params),
@@ -144,7 +145,7 @@ export default {
   },
   plugin: {
     getList: (params: object) => get('/system/plugins/list', params),
-    del: (ids: object) => del('/system/plugins/del', {ids}),
+    del: (ids: object) => del('/system/plugins/del', { ids }),
     changeStatus: (data: object) => post('/system/plugins/set', data),
     edit: (data: any) => put('/system/plugins/edit', data),
     addPluginFile: (formatDate: FormData) => post('/system/plugins/add', formatDate),

+ 71 - 0
src/views/system/api/component/bind.vue

@@ -0,0 +1,71 @@
+<template>
+	<el-dialog class="api-edit" v-model="showDialog" title="批量关联菜单" width="600px" :close-on-click-modal="false" :close-on-press-escape="false">
+		<el-form ref="formRef" :model="formData" :rules="ruleForm" label-width="80px" @keyup.enter="onSubmit">
+			<el-form-item label="关联页面" prop="menuIds">
+				<el-cascader :options="menuData" :props="{ checkStrictly: true, multiple: true, emitPath: false, value: 'id', label: 'title' }" placeholder="请选择关联页面" filterable clearable class="w100" v-model="formData.menuIds"></el-cascader>
+			</el-form-item>
+		</el-form>
+		<template #footer>
+			<div class="dialog-footer">
+				<el-button @click="showDialog = false">取消</el-button>
+				<el-button type="primary" @click="onSubmit">确定</el-button>
+			</div>
+		</template>
+	</el-dialog>
+</template>
+
+<script lang="ts" setup>
+import { ref, reactive, nextTick, watch } from 'vue';
+import api from '/@/api/system';
+import { ApiRow } from '/@/api/model/system/menu';
+import { ruleRequired } from '/@/utils/validator';
+import { ElMessage } from 'element-plus';
+
+const ids = ref<number[]>([])
+const emit = defineEmits(['getList']);
+
+const showDialog = ref(false);
+const formRef = ref();
+const menuData = ref<any[]>([]);
+
+const baseForm: any = {
+	menuIds: [],
+};
+
+const formData = reactive<ApiRow>({
+	...baseForm,
+});
+
+const ruleForm = {
+	menuIds: [ruleRequired('关联页面不能为空', 'change')],
+};
+
+// 加载菜单列表
+api.menu.getList({ status: -1 }).then((res: any[]) => {
+	menuData.value = res;
+});
+
+const onSubmit = async () => {
+	await formRef.value.validate();
+
+	await api.api.bindMenus(ids.value.map((id: number) => ({ id, menuIds: formData.menuIds })));
+
+	ElMessage.success('操作成功');
+	resetForm();
+	showDialog.value = false;
+	emit('getList');
+};
+
+const resetForm = async () => {
+	Object.assign(formData, { menuIds: [] });
+	formRef.value && formRef.value.resetFields();
+};
+
+const open = async (idsArr: any) => {
+	resetForm();
+	ids.value = idsArr;
+	showDialog.value = true;
+};
+
+defineExpose({ open });
+</script>

+ 10 - 38
src/views/system/api/component/edit.vue

@@ -1,12 +1,5 @@
 <template>
-	<el-dialog
-		class="api-edit"
-		v-model="showDialog"
-		:title="`${formData.id ? '编辑接口' : '新增接口'}`"
-		width="600px"
-		:close-on-click-modal="false"
-		:close-on-press-escape="false"
-	>
+	<el-dialog class="api-edit" v-model="showDialog" :title="`${formData.id ? '编辑接口' : '新增接口'}`" width="600px" :close-on-click-modal="false" :close-on-press-escape="false">
 		<el-form ref="formRef" :model="formData" :rules="ruleForm" label-width="80px" @keyup.enter="onSubmit">
 			<el-form-item label="选择类型" prop="types">
 				<el-radio-group v-model="formData.types">
@@ -16,20 +9,13 @@
 			</el-form-item>
 			<template v-if="formData.types === 1">
 				<el-form-item label="上级分类" prop="parentId">
-					<el-cascader
-						:options="[
-							{
-								id: -1,
-								name: '根节点',
-								children: typeData,
-							},
-						]"
-						:props="{ checkStrictly: true, multiple: false, emitPath: false, value: 'id', label: 'name' }"
-						placeholder="请选择关联页面"
-						clearable
-						class="w100"
-						v-model="formData.parentId"
-					></el-cascader>
+					<el-cascader :options="[
+						{
+							id: -1,
+							name: '根节点',
+							children: typeData,
+						},
+					]" :props="{ checkStrictly: true, multiple: false, emitPath: false, value: 'id', label: 'name' }" placeholder="请选择关联页面" clearable class="w100" v-model="formData.parentId"></el-cascader>
 				</el-form-item>
 				<el-form-item label="分类名称" prop="name">
 					<el-input v-model="formData.name" placeholder="输入接口名称" />
@@ -37,24 +23,10 @@
 			</template>
 			<template v-else>
 				<el-form-item label="上级分类" prop="parentId">
-					<el-cascader
-						:options="typeData"
-						:props="{ checkStrictly: true, multiple: false, emitPath: false, value: 'id', label: 'name' }"
-						placeholder="请选择关联页面"
-						clearable
-						class="w100"
-						v-model="formData.parentId"
-					></el-cascader>
+					<el-cascader :options="typeData" :props="{ checkStrictly: true, multiple: false, emitPath: false, value: 'id', label: 'name' }" placeholder="请选择关联页面" clearable class="w100" v-model="formData.parentId"></el-cascader>
 				</el-form-item>
 				<el-form-item label="关联页面" prop="menuIds">
-					<el-cascader
-						:options="menuData"
-						:props="{ checkStrictly: false, multiple: true, emitPath: false, value: 'id', label: 'title' }"
-						placeholder="请选择关联页面"
-						clearable
-						class="w100"
-						v-model="formData.menuIds"
-					></el-cascader>
+					<el-cascader :options="menuData" :props="{ checkStrictly: true, multiple: true, emitPath: false, value: 'id', label: 'title' }" placeholder="请选择关联页面" filterable clearable class="w100" v-model="formData.menuIds"></el-cascader>
 				</el-form-item>
 				<el-form-item label="接口名称" prop="name">
 					<el-input v-model="formData.name" placeholder="输入接口名称" />

+ 24 - 8
src/views/system/api/index.vue

@@ -35,17 +35,19 @@
 							</el-icon>
 							新增接口
 						</el-button>
+						<el-button type="primary" :disabled="!ids.length" @click="bindMenus()" v-auth="'add'">
+							<el-icon>
+								<ele-Grid />
+							</el-icon>
+							批量绑定菜单
+						</el-button>
 					</el-form-item>
 				</el-form>
 			</div>
-			<el-table
-				:data="tableData"
-				style="width: 100%"
-				v-loading="loading"
-				row-key="id"
-				:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
-			>
-				<el-table-column type="index" label="序号" width="60" align="center" />
+			<el-table :data="tableData" @selection-change="handleSelectionChange" style="width: 100%" v-loading="loading" :expand-row-keys="['41']" row-key="id" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
+				<el-table-column type="selection" width="55" align="center" />
+				<!-- <el-table-column type="index" label="序号" width="60" align="center" /> -->
+				<el-table-column prop="id" label="ID" width="100" align="center" />
 				<el-table-column prop="name" v-col="'name'" label="接口名称" show-overflow-tooltip></el-table-column>
 				<el-table-column prop="address" v-col="'address'" label="接口地址" show-overflow-tooltip></el-table-column>
 				<el-table-column prop="status" v-col="'status'" label="状态" min-width="100" align="center">
@@ -54,6 +56,7 @@
 						<el-tag type="info" size="small" v-else>禁用</el-tag>
 					</template>
 				</el-table-column>
+				<el-table-column prop="menuIds" label="绑定菜单" show-overflow-tooltip></el-table-column>
 				<el-table-column label="操作" width="100" align="center" v-col="'handle'">
 					<template #default="scope">
 						<el-button size="small" text type="warning" @click="addOrEdit(scope.row)" v-auth="'edit'">修改</el-button>
@@ -64,19 +67,23 @@
 			<pagination v-if="params.total" :total="params.total" v-model:page="params.pageNum" v-model:limit="params.pageSize" @pagination="getList()" />
 		</el-card>
 		<EditForm ref="editFormRef" @getList="getList()"></EditForm>
+		<bindVue ref="bindRef" @getList="getList()"></bindVue>
 	</div>
 </template>
 
 <script lang="ts" setup>
 import { ref } from 'vue'
 import EditForm from './component/edit.vue'
+import bindVue from './component/bind.vue'
 import { ApiRow } from '/@/api/model/system/menu'
 import api from '/@/api/system'
 import { ElMessageBox, ElMessage } from 'element-plus'
 import { useSearch } from '/@/hooks/useCommon'
 
 const editFormRef = ref()
+const bindRef = ref()
 const queryRef = ref()
+const ids = ref<number[]>([])
 
 const { params, tableData, getList, loading } = useSearch<ApiRow[]>(api.api.getList, 'Info', { name: '', address: '', types: -1 })
 
@@ -92,12 +99,21 @@ const addOrEdit = async (row?: ApiRow) => {
 	}
 }
 
+const handleSelectionChange = (selection: any[]) => {
+	ids.value = selection.filter(item => item.types === 2).map((item) => item.id);
+};
+
 // 重置表单
 const resetQuery = () => {
 	queryRef.value.resetFields()
 	getList(1)
 }
 
+// 重置表单
+const bindMenus = () => {
+	bindRef.value.open(ids.value)
+}
+
 const onDel = (row: ApiRow) => {
 	ElMessageBox.confirm(`此操作将删除接口:“${row.name}”,是否继续?`, '提示', {
 		confirmButtonText: '确认',