Browse Source

feat: #0000 用户管理 - 权限设置 100%

luoyali 1 year ago
parent
commit
7cab5a5239
3 changed files with 252 additions and 5 deletions
  1. 67 0
      src/api/system/resource.ts
  2. 9 5
      src/views/setting/role/index.vue
  3. 176 0
      src/views/setting/role/permission.vue

+ 67 - 0
src/api/system/resource.ts

@@ -0,0 +1,67 @@
+import request from '@/utils/request'
+import { AxiosPromise } from 'axios'
+
+// apiUrl 菜单管理
+const api = {
+	page: '/sys/resource/page',
+	listTree: '/sys/resource/list-tree',
+	listApi: '/sys/resource/list-api',
+	create: '/sys/resource/create',
+	update: '/sys/resource/update',
+	delete: '/sys/resource/delete'
+}
+/**
+ * 菜单管理 - 列表
+ */
+function resourcePageApi(data: any): AxiosPromise {
+	return request({
+		url: api.page,
+		method: 'get',
+		data
+	})
+}
+
+function resourceListTreeApi(data: any): AxiosPromise {
+	return request({
+		url: api.listTree,
+		method: 'get',
+		data
+	})
+}
+
+function resourceListApi(data: any): AxiosPromise {
+	return request({
+		url: api.listApi,
+		method: 'get',
+		data
+	})
+}
+
+/**
+ * 菜单管理 - 新增编辑保存
+ */
+function resourceAddOrEditSaveApi(data: any): AxiosPromise {
+	return request({
+		url: data.id ? api.update : api.create,
+		method: 'post',
+		data
+	})
+}
+
+/**
+ * 菜单管理 - 删除
+ */
+function resourceDeleteApi(data: any): AxiosPromise {
+	return request({
+		url: api.delete,
+		method: 'post',
+		data
+	})
+}
+export default {
+	resourcePageApi,
+	resourceListTreeApi,
+	resourceListApi,
+	resourceAddOrEditSaveApi,
+	resourceDeleteApi
+}

+ 9 - 5
src/views/setting/role/index.vue

@@ -24,7 +24,7 @@
 							<Delete />
 						</el-icon>
 					</el-button>
-					<el-button type="primary" plain :disabled="!curSelectionRows.length || curSelectionRows.length !== 1">权限设置</el-button>
+					<el-button type="primary" plain :disabled="!curSelectionRows.length || curSelectionRows.length !== 1" @click="visiblePermission = true">权限设置</el-button>
 				</template>
 
 				<template #statusSlot="scope">
@@ -60,6 +60,11 @@
 			:form-options="formOptions"
 			@submit="submitHandler"
 		/>
+
+		<!-- 权限设置 -->
+		<Permission v-if="visiblePermission"
+								:role-id="curSelectionRows.map(item => item.id).join(',')"
+								v-model="visiblePermission" @closed="visiblePermission = false" />
 	</div>
 </template>
 <script lang="tsx" setup>
@@ -69,9 +74,11 @@ import { ElMessage, ElTree } from 'element-plus'
 import { useTablePage } from '@/hooks/useTablePage'
 import { Plus, Delete } from '@element-plus/icons-vue'
 import StatusIndicator from '@/components/StatusIndicator'
+import Permission from './permission.vue'
 
 const visible = ref(false) // 弹窗显示隐藏
 const isCreate = ref(true)
+const visiblePermission = ref(false) // 权限设置弹窗显示隐藏
 const activeData = ref({})
 const formsDialog = [
 	{
@@ -153,10 +160,7 @@ const columns = [
 	{
 		prop: 'name',
 		label: '角色名称',
-		minWidth: 80,
-		slots: {
-			default: 'filterAvatarSlot'
-		}
+		minWidth: 80
 	},
 	{
 		prop: 'status',

+ 176 - 0
src/views/setting/role/permission.vue

@@ -0,0 +1,176 @@
+<template>
+	<el-dialog title="角色权限设置" v-model="visibleDialog" :width="500" destroy-on-close @closed="handleCancel">
+		<el-tabs tab-position="top">
+			<el-tab-pane label="菜单权限">
+				<div class="treeMain">
+					<el-tree ref="menuRef" node-key="id" :data="menu.list" :default-checked-keys="menu.checked" :props="menu.props" show-checkbox></el-tree>
+				</div>
+			</el-tab-pane>
+			<el-tab-pane label="控制台">
+				<el-form label-width="100px" label-position="left">
+					<el-form-item label="控制台视图">
+						<el-select v-model="dashboard" placeholder="请选择">
+							<el-option v-for="item in dashboardOptions" :key="item.value" :label="item.label" :value="item.value">
+								<span style="float: left">{{ item.label }}</span>
+								<span style="float: right; color: #8492a6; font-size: 12px">{{ item.views }}</span>
+							</el-option>
+						</el-select>
+						<div class="el-form-item-msg">用于控制角色登录后控制台的视图</div>
+					</el-form-item>
+				</el-form>
+			</el-tab-pane>
+		</el-tabs>
+		<template #footer>
+			<el-button @click="handleCancel">取 消</el-button>
+			<el-button type="primary" :loading="isSaveing" @click="submit()">保 存</el-button>
+		</template>
+	</el-dialog>
+</template>
+
+<script setup>
+import { computed, defineEmits, onMounted, ref, watch, reactive } from 'vue'
+import role from '@/api/system/role'
+import resource from '@/api/system/resource'
+import { ElMessage, ElMessageBox } from 'element-plus'
+
+// props
+const myProps = defineProps({
+	modelValue: {
+		type: Boolean,
+		default: false
+	},
+	roleId: {
+		type: String,
+		default: ''
+	}
+})
+
+// data
+const dashboardOptions = ref([
+	{
+		value: '0',
+		label: '数据统计',
+		views: 'stats'
+	},
+	{
+		value: '1',
+		label: '工作台',
+		views: 'work'
+	}
+])
+const menuRef = ref(null)
+const isSaveing = ref(false)
+const menu = reactive({
+	list: [],
+	checked: [],
+	props: {
+		label: data => {
+			return data.title
+		}
+	}
+})
+const dashboard = ref('0')
+
+// methods
+const open = async roleId => {
+	try {
+		menu.checked = await role.roleResourceIdsApi(roleId)
+	} catch (e) {
+		console.log('根据当前用户获取角色权限失败', e)
+	}
+}
+
+const resourceSet = async ids => {
+	try {
+		await role.roleResourceSetApi({ roleId: myProps.roleId, resourceIds: ids })
+		isSaveing.value = false
+		handleCancel()
+		ElMessage.success('保存角色权限成功')
+	} catch (e) {
+		isSaveing.value = false
+		console.log('保存角色权限失败', e)
+		ElMessage.error('保存角色权限失败')
+	}
+}
+
+const submit = async () => {
+	isSaveing.value = true
+	var checked = menuRef.value.getCheckedNodes(false, false)
+	if (checked.length < 1) {
+		ElMessageBox.confirm(`未选择菜单确定执行清空操作吗?`, '提示')
+			.then(async () => {
+				resourceSet([])
+			})
+			.catch(() => {
+				isSaveing.value = false
+			})
+	} else {
+		var resourceIds = []
+		checked.forEach(function (e) {
+			resourceIds.push(e.id)
+		})
+		try {
+			await resourceSet(resourceIds)
+		} catch (e) {
+			isSaveing.value = false
+			console.log(e)
+		}
+	}
+}
+
+const getMenu = async () => {
+	// 获取菜单树结构
+	try {
+		menu.list = await resource.resourceListTreeApi()
+	} catch (e) {
+		console.log('获取菜单树结构失败', e)
+	}
+}
+
+// 同步值
+const $myEmit = defineEmits(['update:modelValue', 'successFn'])
+
+// 关闭按钮
+const closeDrawer = () => {
+	$myEmit('successFn')
+	$myEmit('update:modelValue', false)
+}
+
+const handleCancel = () => {
+	closeDrawer()
+}
+
+// computed
+const visibleDialog = computed({
+	get() {
+		return myProps.modelValue
+	},
+	set(val) {
+		$myEmit('update:modelValue', val)
+	}
+})
+
+// watch
+watch(
+	() => myProps.modelValue,
+	val => {
+		if (val) {
+			open(myProps.roleId)
+		}
+	},
+	{ immediate: true }
+)
+
+onMounted(() => {
+	getMenu()
+})
+</script>
+
+<style scoped>
+.treeMain {
+	height: 280px;
+	overflow: auto;
+	border: 1px solid #dcdfe6;
+	margin-bottom: 10px;
+}
+</style>