Files
gr_report_web/src/views/system/role/index.vue
2026-02-10 16:28:33 +08:00

349 lines
9.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<ContentWrap>
<avue-crud
ref="crudRef"
v-model="tableForm"
v-model:page="tablePage"
v-model:search="tableSearch"
:table-loading="loading"
:data="tableData"
:option="tableOption"
:permission="permission"
:before-open="beforeOpen"
@search-change="searchChange"
@search-reset="resetChange"
@row-save="rowSave"
@row-update="rowUpdate"
@row-del="rowDel"
@refresh-change="getTableData"
@size-change="sizeChange"
@current-change="currentChange"
>
<template #menu-left="{ size }">
<el-button
type="success"
plain
:size="size"
icon="el-icon-download"
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['system:role:export']"
>导出</el-button
>
</template>
<template #status="scope">
<dict-tag
v-if="scope.row.status !== undefined"
:type="DICT_TYPE.COMMON_STATUS"
:value="scope.row.status"
/>
</template>
<!-- 自定义操作栏 -->
<template #menu="{ row }">
<el-dropdown @command="menuHandle">
<div class="mt--1px cursor-pointer flex-basis-55px flex-shrink-0 py-8px px-4px">
<el-text type="primary">
{{ t('Avue.crud.moreBtn') }}
<Icon class="ml--2px" icon="iconamoon:arrow-down-2-light" />
</el-text>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item
:command="{ type: 'menu', row }"
v-if="checkPermi(['system:permission:assign-role-data-scope'])"
>
<div class="flex items-center">
<Icon icon="ep:menu" />
<span>菜单权限</span>
</div>
</el-dropdown-item>
<el-dropdown-item
:command="{ type: 'app', row }"
v-if="checkPermi(['system:permission:assign-role-app'])"
>
<div class="flex items-center">
<Icon icon="ep:menu" />
<span>应用权限</span>
</div>
</el-dropdown-item>
<el-dropdown-item
:command="{ type: 'data', row }"
v-if="checkPermi(['system:permission:assign-role-data-scope'])"
>
<div class="flex items-center">
<Icon icon="ep:menu" />
<span>数据权限</span>
</div>
</el-dropdown-item>
<el-dropdown-item
:command="{ type: 'del', row }"
v-if="checkPermi(['system:role:delete'])"
>
<div class="flex items-center">
<Icon icon="ep:delete" />
<span>删除</span>
</div>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
</avue-crud>
</ContentWrap>
<!-- 表单弹窗菜单权限 -->
<RoleAssignMenuForm ref="assignMenuFormRef" @success="getTableData" />
<!-- 表单弹窗数据权限 -->
<RoleDataPermissionForm ref="dataPermissionFormRef" @success="getTableData" />
<!-- 表单弹窗应用权限 -->
<RoleAssignAppForm ref="assignAppFormRef" @success="getTableData" />
</template>
<script lang="ts" setup>
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { dateFormatter, getSearchDate } from '@/utils/formatTime'
import { checkPermi } from '@/utils/permission'
import download from '@/utils/download'
import * as RoleApi from '@/api/system/role'
import { CommonStatusEnum } from '@/utils/constants'
import RoleAssignMenuForm from './RoleAssignMenuForm.vue'
import RoleDataPermissionForm from './RoleDataPermissionForm.vue'
import RoleAssignAppForm from './RoleAssignAppForm.vue'
defineOptions({ name: 'SystemRole' })
const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化
const { getCurrPermi } = useCrudPermi()
const loading = ref(true) // 列表的加载中
const tableOption = reactive({
menuWidth: 160,
align: 'center',
headerAlign: 'center',
searchMenuSpan: 6,
searchMenuPosition: 'left',
labelSuffix: ' ',
span: 12,
dialogWidth: '50%',
delBtn: false,
column: {
name: {
label: '角色名称',
search: true,
minWidth: 90,
rules: [{ required: true, message: '角色名称不能为空', trigger: 'blur' }]
},
type: {
label: '角色类型',
type: 'select',
width: 85,
dicData: getIntDictOptions(DICT_TYPE.SYSTEM_ROLE_TYPE),
rules: [{ required: true, message: '角色类型不能为空', trigger: 'blur' }],
display: false
},
code: {
label: '角色标识',
search: true,
disabled: false,
minWidth: 90,
rules: [{ required: true, message: '角色标识不能为空', trigger: 'blur' }]
},
sort: {
label: '显示顺序',
width: 85,
type: 'number',
rules: [{ required: true, message: '显示顺序不能为空', trigger: 'blur' }]
},
status: {
label: '状态',
search: true,
type: 'select',
width: 85,
span: 24,
dicData: getIntDictOptions(DICT_TYPE.COMMON_STATUS),
rules: [{ required: true, message: '状态不能为空', trigger: 'blur' }],
value: CommonStatusEnum.ENABLE
},
remark: {
label: '备注',
type: 'textarea',
minRows: 2,
maxRows: 4,
minWidth: 120,
span: 24
},
createTime: {
label: '创建时间',
search: true,
searchRange: true,
type: 'date',
searchType: 'daterange',
valueFormat: 'YYYY-MM-DD',
width: 160,
display: false,
startPlaceholder: '开始时间',
endPlaceholder: '结束时间',
formatter: (row, val, value, column) => {
return dateFormatter(row, column, val)
}
}
}
}) //表格配置
const tableForm = ref<{ id?: number }>({})
const tableData = ref([])
const tableSearch = ref<any>({})
const tablePage = ref({
currentPage: 1,
pageSize: 10,
total: 0
})
const permission = getCurrPermi(['system:role'])
const assignAppFormRef = ref()
const crudRef = ref()
useCrudHeight(crudRef)
const exportLoading = ref(false) // 导出的加载中
const menuHandle = ({ row, type }) => {
if (type == 'menu') openAssignMenuForm(row)
else if (type == 'data') openDataPermissionForm(row)
else if (type == 'del') rowDel(row)
else if (type == 'app') openAssignAppForm(row)
}
const openAssignAppForm = (row) => {
assignAppFormRef.value.open(row)
}
/** 查询列表 */
const getTableData = async () => {
loading.value = true
let searchObj = {
...tableSearch.value,
pageNo: tablePage.value.currentPage,
pageSize: tablePage.value.pageSize
}
if (searchObj.createTime?.length) {
searchObj.createTime = getSearchDate(searchObj.createTime)
} else delete searchObj.createTime
for (let key in searchObj) if (searchObj[key] === '') delete searchObj[key]
try {
const data = await RoleApi.getRolePage(searchObj)
tableData.value = data.list
tablePage.value.total = data.total
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
const searchChange = (params, done) => {
tablePage.value.currentPage = 1
getTableData().finally(() => {
done()
})
}
/** 清空按钮操作 */
const resetChange = () => {
searchChange({}, () => {})
}
const sizeChange = (pageSize) => {
tablePage.value.pageSize = pageSize
resetChange()
}
const currentChange = (currentPage) => {
tablePage.value.currentPage = currentPage
getTableData()
}
/** 表单打开前 */
const beforeOpen = async (done, type) => {
if (['edit', 'view'].includes(type) && tableForm.value.id) {
const res = await RoleApi.getRole(tableForm.value.id)
if (type == 'edit') tableOption.column.code.disabled = res.type === 1
tableForm.value = res
}
done()
}
/** 新增操作 */
const rowSave = async (form, done, loading) => {
let bool = await RoleApi.createRole(form).catch(() => false)
if (bool) {
message.success(t('common.createSuccess'))
resetChange()
done()
} else loading()
}
/** 编辑操作 */
const rowUpdate = async (form, index, done, loading) => {
let bool = await RoleApi.updateRole(form).catch(() => false)
if (bool) {
message.success(t('common.updateSuccess'))
getTableData()
done()
} else loading()
}
/** 删除按钮操作 */
const rowDel = async (form) => {
try {
// 删除的二次确认
await message.delConfirm()
// 发起删除
await RoleApi.deleteRole(form.id)
message.success(t('common.delSuccess'))
// 刷新列表
await getTableData()
} catch {}
}
/** 数据权限操作 */
const dataPermissionFormRef = ref()
const openDataPermissionForm = async (row: RoleApi.RoleVO) => {
dataPermissionFormRef.value.open(row)
}
/** 菜单权限操作 */
const assignMenuFormRef = ref()
const openAssignMenuForm = async (row: RoleApi.RoleVO) => {
assignMenuFormRef.value.open(row)
}
/** 导出按钮操作 */
const handleExport = async () => {
try {
// 导出的二次确认
await message.exportConfirm()
// 发起导出
exportLoading.value = true
let searchObj = { ...tableSearch.value }
for (let key in searchObj) if (searchObj[key] === '') delete searchObj[key]
const data = await RoleApi.exportRole(searchObj)
download.excel(data, '角色列表.xls')
} catch {
} finally {
exportLoading.value = false
}
}
/** 初始化 **/
onMounted(async () => {
await getTableData()
})
</script>
<style lang="scss" scoped>
.cardHeight {
width: 100%;
max-height: 340px;
overflow-y: scroll;
}
</style>