|
@@ -10,26 +10,30 @@
|
|
|
</slot>
|
|
|
</template>
|
|
|
|
|
|
- <el-form ref="ruleFormRef" label-width="100px" label-suffix=" :" :rules="rules" :model="drawerProps.row" @submit.enter.prevent="handleConfirm">
|
|
|
- <el-form-item label="参数名称" prop="name">
|
|
|
- <el-input v-model="drawerProps.row.name" placeholder="填写参数名称" clearable />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="权限标识" prop="code">
|
|
|
- <el-input v-model="drawerProps.row.code" :disabled="drawerProps.row.roleId === '1'" placeholder="填写权限标识" clearable />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="排序" prop="orderNum">
|
|
|
- <el-input-number v-model="drawerProps.row.orderNum" :precision="0" :min="1" :max="999999" />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="状态" prop="status">
|
|
|
- <el-radio-group v-model="drawerProps.row.status">
|
|
|
- <el-radio-button :value="item.dictValue" v-for="(item, index) in commonStatus" :key="index" :label="item.dictLabel" />
|
|
|
- </el-radio-group>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="备注" prop="remark">
|
|
|
- <el-input v-model="drawerProps.row.remark" placeholder="请填写备注" clearable />
|
|
|
- </el-form-item>
|
|
|
- </el-form>
|
|
|
+ <el-table :data="mergeData" :span-method="objectSpanMethod" border style="width: 100%; margin-top: 20px">
|
|
|
+ <el-table-column prop="moduleName" width="180">
|
|
|
+ <template #header>
|
|
|
+ <el-checkbox label="权限模块" @change="handleChange"></el-checkbox>
|
|
|
+ </template>
|
|
|
+ <template #default="{ row }">
|
|
|
+ <div>
|
|
|
+ <el-checkbox v-model="row.parentCheck" :label="row.moduleName" @change="handleParentCheck(row)"></el-checkbox>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="code">
|
|
|
+ <template #header>
|
|
|
+ <el-checkbox label="权限点" @change="handleChange"></el-checkbox>
|
|
|
+ </template>
|
|
|
+ <template #default="{ row }">
|
|
|
+ <div>
|
|
|
+ <el-checkbox v-model="row.itemCheck" :label="row.code" @change="handleItemCheck(row)"></el-checkbox>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
|
|
|
+ <el-table-column prop="name" label="名称" />
|
|
|
+ </el-table>
|
|
|
<template #footer>
|
|
|
<slot name="footer">
|
|
|
<ElButton @click="drawerVisible = false">取 消</ElButton>
|
|
@@ -40,31 +44,99 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts" name="PermissionsDrawer">
|
|
|
-import { RoleBO } from '@/api/interface/system/role'
|
|
|
+import { PermissionsVO } from '@/api/interface/system/permissions'
|
|
|
+import { RoleVO } from '@/api/interface/system/role'
|
|
|
+import RoleApi from '@/api/module/system/role'
|
|
|
import { ResultEnum } from '@/enums/HttpEnum'
|
|
|
-import { useDictOptions } from '@/hooks'
|
|
|
-
|
|
|
-const commonStatus = useDictOptions('COMMON_STATUS')
|
|
|
-
|
|
|
-import { FormInstance } from 'element-plus'
|
|
|
-const rules = reactive({
|
|
|
- name: [{ required: true, message: '请填写角色名称' }],
|
|
|
- code: [{ required: true, message: '请填权限标识' }],
|
|
|
- orderNum: [{ required: true, message: '排序不能为空' }],
|
|
|
- status: [{ required: true, message: '状态不能为空' }]
|
|
|
-})
|
|
|
|
|
|
interface EcoDrawerProps {
|
|
|
api?: (params: any) => Promise<any> // 调用接口
|
|
|
title: string // 顶部标题
|
|
|
- isView: boolean
|
|
|
- row: Partial<RoleBO>
|
|
|
+ row: Partial<RoleVO>
|
|
|
getTableList?: () => void
|
|
|
}
|
|
|
|
|
|
+interface MergeDataProps extends PermissionsVO {
|
|
|
+ parentCheck: boolean
|
|
|
+ itemCheck: boolean
|
|
|
+}
|
|
|
+const getSpanArr = (data: MergeDataProps[], prop: keyof MergeDataProps) => {
|
|
|
+ const spanArr: { first: number; count: number }[] = []
|
|
|
+ let pos = 0
|
|
|
+
|
|
|
+ for (let i = 0; i < data.length; i++) {
|
|
|
+ if (i === 0) {
|
|
|
+ spanArr.push({ first: 0, count: 1 })
|
|
|
+ pos = 0
|
|
|
+ } else {
|
|
|
+ if (data[i][prop] === data[i - 1][prop]) {
|
|
|
+ spanArr[pos].count++
|
|
|
+ spanArr.push({ first: -1, count: 0 })
|
|
|
+ } else {
|
|
|
+ spanArr.push({ first: i, count: 1 })
|
|
|
+ pos = i
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return spanArr
|
|
|
+}
|
|
|
+const nameSpanArr = computed(() => getSpanArr(mergeData.value, 'moduleName'))
|
|
|
+
|
|
|
+const objectSpanMethod = ({ row, column, rowIndex, columnIndex }: { row: MergeDataProps; column: any; rowIndex: number; columnIndex: number }) => {
|
|
|
+ if (column.property === 'moduleName') {
|
|
|
+ const span = nameSpanArr.value[rowIndex]
|
|
|
+ if (span.first === rowIndex) {
|
|
|
+ return {
|
|
|
+ rowspan: span.count,
|
|
|
+ colspan: 1
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return {
|
|
|
+ rowspan: 0,
|
|
|
+ colspan: 0
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 获取选中的 address IDs
|
|
|
+const selectedPermIds = computed(() => {
|
|
|
+ return mergeData.value.filter(item => item.itemCheck).map(item => item.id)
|
|
|
+})
|
|
|
+
|
|
|
+// 处理 moduleName 复选框变化
|
|
|
+const handleParentCheck = (row: MergeDataProps) => {
|
|
|
+ const itemRows = mergeData.value.filter(item => item.moduleName === row.moduleName)
|
|
|
+ itemRows.forEach(item => {
|
|
|
+ item.itemCheck = row.parentCheck
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const handleChange = (val: boolean) => {
|
|
|
+ mergeData.value.forEach(item => {
|
|
|
+ item.parentCheck = val
|
|
|
+ item.itemCheck = val
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 处理 code 复选框变化
|
|
|
+const handleItemCheck = (row: MergeDataProps) => {
|
|
|
+ const sameItemRows = mergeData.value.filter(item => item.moduleName === row.moduleName)
|
|
|
+ const parentSelected = sameItemRows.every(item => item.itemCheck)
|
|
|
+
|
|
|
+ // 更新对应 moduleName 的选中状态
|
|
|
+ sameItemRows.forEach(item => {
|
|
|
+ item.parentCheck = parentSelected
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const allPermissions = ref<PermissionsVO[]>([])
|
|
|
+const hasPermissions = ref<string[]>([])
|
|
|
+const mergeData = ref<MergeDataProps[]>([])
|
|
|
+
|
|
|
const drawerVisible = ref(false)
|
|
|
const drawerProps = ref<EcoDrawerProps>({
|
|
|
- isView: false,
|
|
|
title: '',
|
|
|
row: {}
|
|
|
})
|
|
@@ -76,28 +148,52 @@ const emit = defineEmits(['submit'])
|
|
|
const acceptParams = (params: EcoDrawerProps) => {
|
|
|
drawerProps.value = params
|
|
|
drawerVisible.value = true
|
|
|
- drawerProps.value.row.status = drawerProps.value.row.status || '1'
|
|
|
+ getPermissions(params.row.roleId || '')
|
|
|
}
|
|
|
|
|
|
-// 提交数据(新增/编辑)
|
|
|
-const ruleFormRef = ref<FormInstance>()
|
|
|
-const handleConfirm = () => {
|
|
|
- ruleFormRef.value!.validate(async valid => {
|
|
|
- if (!valid) return
|
|
|
- try {
|
|
|
- const { code } = await drawerProps.value.api!(drawerProps.value.row)
|
|
|
- if (code == ResultEnum.SUCCESS) {
|
|
|
- ElMessage.success({ message: `${drawerProps.value.title}成功!` })
|
|
|
- drawerProps.value.getTableList!()
|
|
|
- emit('submit')
|
|
|
- drawerVisible.value = false
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- console.log(error)
|
|
|
+/**
|
|
|
+ * 获取权限信息
|
|
|
+ * @param roleId
|
|
|
+ */
|
|
|
+const getPermissions = (roleId: string) => {
|
|
|
+ if (!roleId) return
|
|
|
+ RoleApi.getPermissions(roleId).then(res => {
|
|
|
+ allPermissions.value = res.data.allPermissions
|
|
|
+ hasPermissions.value = res.data.hasPermissions
|
|
|
+ handelAllPermissions(allPermissions.value, hasPermissions.value)
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+const handelAllPermissions = (allPerms: PermissionsVO[], hasPerms: string[]) => {
|
|
|
+ mergeData.value = allPerms.map(item => {
|
|
|
+ return { ...item, parentCheck: false, itemCheck: false }
|
|
|
+ })
|
|
|
+
|
|
|
+ mergeData.value.forEach(perm => {
|
|
|
+ if (hasPerms.length > 0) {
|
|
|
+ hasPerms.forEach(permId => {
|
|
|
+ if (perm.id === permId) {
|
|
|
+ perm.itemCheck = true
|
|
|
+ }
|
|
|
+ })
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
|
|
|
+const handleConfirm = async () => {
|
|
|
+ try {
|
|
|
+ const { code } = await drawerProps.value.api!({ roleId: drawerProps.value.row.roleId, permIds: selectedPermIds.value })
|
|
|
+ if (code == ResultEnum.SUCCESS) {
|
|
|
+ ElMessage.success({ message: `${drawerProps.value.title}成功!` })
|
|
|
+ drawerProps.value.getTableList!()
|
|
|
+ emit('submit')
|
|
|
+ drawerVisible.value = false
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
defineExpose({
|
|
|
acceptParams
|
|
|
})
|