智慧教务系统
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

<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>