You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
297 lines
7.6 KiB
297 lines
7.6 KiB
<template>
|
|
<el-dialog
|
|
v-model="showDialog"
|
|
:title="popTitle"
|
|
width="500px"
|
|
:destroy-on-close="true"
|
|
>
|
|
<el-form
|
|
:model="formData"
|
|
label-width="90px"
|
|
ref="formRef"
|
|
:rules="formRules"
|
|
class="page-form"
|
|
v-loading="loading"
|
|
>
|
|
<el-form-item :label="t('roleName')" prop="role_name">
|
|
<el-input
|
|
v-model.trim="formData.role_name"
|
|
:placeholder="t('roleNamePlaceholder')"
|
|
clearable
|
|
:disabled="formData.uid"
|
|
class="input-width"
|
|
maxlength="10"
|
|
:show-word-limit="true"
|
|
/>
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="类型">
|
|
<el-radio-group v-model="formData.role_key">
|
|
<span v-for="(item,index) in roleKeyList" class="mr-2">
|
|
<el-radio :label="item.value">{{ item.name }}</el-radio>
|
|
</span>
|
|
</el-radio-group>
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item :label="t('status')">
|
|
<el-radio-group v-model="formData.status">
|
|
<el-radio :label="1">{{ t('startUsing') }}</el-radio>
|
|
<el-radio :label="0">{{ t('statusDeactivate') }}</el-radio>
|
|
</el-radio-group>
|
|
</el-form-item>
|
|
|
|
|
|
|
|
<el-form-item label="部门" >
|
|
<el-select
|
|
class="input-width"
|
|
v-model="formData.dept_id"
|
|
clearable
|
|
placeholder="请选择部门"
|
|
>
|
|
<el-option label="请选择" value=""></el-option>
|
|
<el-option
|
|
v-for="(item, index) in parentDepartmentIdList"
|
|
:key="index"
|
|
:label="item['department_name']"
|
|
:value="item['id']"
|
|
/>
|
|
</el-select>
|
|
</el-form-item>
|
|
|
|
<el-form-item :label="t('permission')" prop="rules">
|
|
<div class="flex items-center justify-between w-11/12">
|
|
<div>
|
|
<el-checkbox v-model="selectAll" :label="t('selectAll')"/>
|
|
<el-checkbox v-model="checkStrictly" :label="t('checkStrictly')"/>
|
|
</div>
|
|
<el-button link type="primary" @click="menuAction()">{{
|
|
t('foldText')
|
|
}}
|
|
</el-button>
|
|
</div>
|
|
<el-scrollbar height="35vh" class="w-full">
|
|
<el-tree
|
|
:data="menus"
|
|
:props="{ label: 'menu_name' }"
|
|
:default-checked-keys="formData.rules"
|
|
:check-strictly="checkStrictly"
|
|
show-checkbox
|
|
default-expand-all
|
|
@check-change="handleCheckChange"
|
|
node-key="menu_key"
|
|
ref="treeRef"
|
|
/>
|
|
</el-scrollbar>
|
|
</el-form-item>
|
|
</el-form>
|
|
|
|
<template #footer>
|
|
<span class="dialog-footer">
|
|
<el-button @click="showDialog = false">{{ t('cancel') }}</el-button>
|
|
<el-button
|
|
type="primary"
|
|
:loading="loading"
|
|
@click="confirm(formRef)"
|
|
>{{ t('confirm') }}</el-button
|
|
>
|
|
</span>
|
|
</template>
|
|
</el-dialog>
|
|
</template>
|
|
|
|
<script lang="ts" setup async>
|
|
import {ref, reactive, computed, watch, toRaw} from 'vue'
|
|
import {t} from '@/lang'
|
|
import {
|
|
getWithDepartmentsList} from '@/app/api/departments'
|
|
import type {FormInstance} from 'element-plus'
|
|
import {addRole, editRole, getRoleInfo} from '@/app/api/sys'
|
|
import {getAuthMenus} from '@/app/api/auth'
|
|
import {useDictionary} from '@/app/api/dict'
|
|
import {debounce} from '@/utils/common'
|
|
|
|
const showDialog = ref(false)
|
|
const loading = ref(false)
|
|
const isOpen = ref(true)
|
|
|
|
let popTitle: string = ''
|
|
|
|
// 获取权限数据
|
|
const menus = ref<Record<string, any>[]>([])
|
|
getAuthMenus({is_button: 0}).then((res) => {
|
|
menus.value = res.data
|
|
})
|
|
|
|
// 全选
|
|
const selectAll = ref(false)
|
|
const checkStrictly = ref(false)
|
|
const treeRef: Record<string, any> | null = ref(null)
|
|
watch(selectAll, () => {
|
|
if (selectAll.value) {
|
|
treeRef.value.setCheckedNodes(toRaw(menus.value))
|
|
} else {
|
|
treeRef.value.setCheckedNodes([])
|
|
}
|
|
})
|
|
|
|
const parentDepartmentIdList = ref([] as any[])
|
|
const setParentDepartmentIdList = async () => {
|
|
parentDepartmentIdList.value = await (await getWithDepartmentsList({})).data
|
|
}
|
|
setParentDepartmentIdList()
|
|
|
|
const roleKeyList = ref([])
|
|
const getRolekeyDictList = async () => {
|
|
roleKeyList.value = await (
|
|
await useDictionary('role_key')
|
|
).data.dictionary
|
|
}
|
|
getRolekeyDictList()
|
|
|
|
const handleCheckChange = debounce((e) => {
|
|
formData.rules = treeRef.value.getCheckedKeys()
|
|
})
|
|
|
|
const menuAction = () => {
|
|
if (isOpen.value) {
|
|
collapseAll(menus.value)
|
|
isOpen.value = false
|
|
} else {
|
|
unFoldAll(menus.value)
|
|
isOpen.value = true
|
|
}
|
|
}
|
|
|
|
// 全部展开
|
|
const unFoldAll = (data: any) => {
|
|
Object.keys(data).forEach((key: string | any) => {
|
|
treeRef.value.store.nodesMap[data[key].menu_key].expanded = true
|
|
if (data[key].children && data[key].children.length > 0)
|
|
collapseAll(data[key].children)
|
|
})
|
|
}
|
|
// 全部折叠
|
|
const collapseAll = (data: any) => {
|
|
Object.keys(data).forEach((key: string | any) => {
|
|
treeRef.value.store.nodesMap[data[key].menu_key].expanded = false
|
|
if (data[key].children && data[key].children.length > 0)
|
|
collapseAll(data[key].children)
|
|
})
|
|
}
|
|
/**
|
|
* 表单数据
|
|
*/
|
|
const initialFormData = {
|
|
role_id: 0,
|
|
role_name: '',
|
|
status: 1,
|
|
role_key: '',
|
|
dept_id:'',
|
|
rules: [],
|
|
}
|
|
const formData: Record<string, any> = reactive({...initialFormData})
|
|
|
|
const formRef = ref<FormInstance>()
|
|
|
|
// 表单验证规则
|
|
const formRules = computed(() => {
|
|
return {
|
|
role_name: [
|
|
{required: true, message: t('roleNamePlaceholder'), trigger: 'blur'},
|
|
],
|
|
rules: [
|
|
{
|
|
validator: (rule: any, value: string, callback: any) => {
|
|
if (!value.length) callback(new Error(t('rulesPlaceholder')))
|
|
else callback()
|
|
},
|
|
trigger: 'blur',
|
|
},
|
|
],
|
|
}
|
|
})
|
|
|
|
const emit = defineEmits(['complete'])
|
|
|
|
/**
|
|
* 确认
|
|
* @param formEl
|
|
*/
|
|
const confirm = async (formEl: FormInstance | undefined) => {
|
|
if (loading.value || !formEl) return
|
|
const save = formData.role_id ? editRole : addRole
|
|
|
|
await formEl.validate(async (valid) => {
|
|
if (valid) {
|
|
loading.value = true
|
|
|
|
const data = Object.assign({}, formData)
|
|
data.rules = data.rules.concat(treeRef.value.getHalfCheckedKeys())
|
|
|
|
save(data)
|
|
.then((res) => {
|
|
loading.value = false
|
|
showDialog.value = false
|
|
|
|
emit('complete')
|
|
})
|
|
.catch(() => {
|
|
loading.value = false
|
|
// showDialog.value = false
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
const setFormData = async (row: any = null) => {
|
|
loading.value = true
|
|
selectAll.value = false
|
|
Object.assign(formData, initialFormData)
|
|
popTitle = t('addRole')
|
|
if (row) {
|
|
popTitle = t('updateRole')
|
|
const data = await (await getRoleInfo(row.role_id)).data
|
|
Object.keys(formData).forEach((key: string) => {
|
|
if (data[key] != undefined) {
|
|
if (key == 'rules') {
|
|
const arr = data.rules
|
|
const newArr: any = []
|
|
|
|
Object.keys(data.rules).forEach((i) => {
|
|
checked(data.rules[i], menus.value, newArr)
|
|
})
|
|
formData[key] = newArr
|
|
} else {
|
|
formData[key] = data[key]
|
|
}
|
|
}
|
|
})
|
|
}
|
|
loading.value = false
|
|
}
|
|
|
|
function checked(menuKey: string, data: any, newArr: any) {
|
|
Object.keys(data).forEach((key: string) => {
|
|
const item = data[key]
|
|
if (item.menu_key == menuKey) {
|
|
if (!item.children || item.children.length == 0) {
|
|
newArr.push(item.menu_key)
|
|
}
|
|
} else {
|
|
if (item.children && item.children.length > 0) {
|
|
checked(menuKey, item.children, newArr)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
defineExpose({
|
|
showDialog,
|
|
setFormData,
|
|
})
|
|
</script>
|
|
|
|
<style lang="scss" scoped></style>
|
|
|