mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-10-08 10:39:59 +00:00
fix(权限): 修复权限校验位置错误并优化用户信息更新逻辑
修复多处权限校验位置错误,将v-hasPerm从按钮移至父级dropdown组件 优化系统管理模块提交后的用户信息更新逻辑,自动刷新权限状态 修复菜单管理表单校验和默认值问题 重构资源管理界面布局和交互体验
This commit is contained in:
@@ -65,6 +65,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<el-dropdown
|
||||
v-hasPerm="['application:myapp:update']"
|
||||
trigger="click"
|
||||
@command="(command) => handleAppAction(command, app)"
|
||||
>
|
||||
@@ -76,8 +77,8 @@
|
||||
/>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item v-hasPerm="['application:myapp:update']" command="edit" icon="Edit">编辑</el-dropdown-item>
|
||||
<el-dropdown-item v-hasPerm="['application:myapp:delete']" command="delete" icon="Delete" divided>删除</el-dropdown-item>
|
||||
<el-dropdown-item command="edit" icon="Edit">编辑</el-dropdown-item>
|
||||
<el-dropdown-item command="delete" icon="Delete" divided>删除</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
|
||||
@@ -64,8 +64,8 @@
|
||||
<div class="data-table__toolbar--actions">
|
||||
<el-button v-hasPerm="['workflow:operator:create']" type="success" icon="plus" @click="handleOpenDialog('create')">新增</el-button>
|
||||
<el-button v-hasPerm="['workflow:operator:delete']" type="danger" icon="delete" :disabled="selectIds.length === 0" @click="handleDelete(selectIds)">批量删除</el-button>
|
||||
<el-dropdown trigger="click">
|
||||
<el-button v-hasPerm="['workflow:operator:status']" type="default" :disabled="selectIds.length === 0" icon="ArrowDown">更多</el-button>
|
||||
<el-dropdown v-hasPerm="['application:myapp:update']" trigger="click">
|
||||
<el-button type="default" :disabled="selectIds.length === 0" icon="ArrowDown">更多</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item icon="Check" @click="handleMoreClick(true)">批量启用</el-dropdown-item>
|
||||
|
||||
@@ -114,8 +114,8 @@
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-tooltip content="列表筛选">
|
||||
<el-dropdown trigger="click">
|
||||
<el-button v-hasPerm="['demo:example:filter']" type="default" icon="operation" circle/>
|
||||
<el-dropdown v-hasPerm="['demo:example:filter']" trigger="click">
|
||||
<el-button type="default" icon="operation" circle/>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item v-for="column in tableColumns" :key="column.prop" :command="column">
|
||||
|
||||
@@ -97,8 +97,8 @@
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-tooltip content="列表筛选">
|
||||
<el-dropdown trigger="click">
|
||||
<el-button v-hasPerm="['generator:demo:filter']" type="default" icon="operation" circle/>
|
||||
<el-dropdown v-hasPerm="['generator:demo:filter']" trigger="click">
|
||||
<el-button type="default" icon="operation" circle/>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item v-for="column in tableColumns" :key="column.prop" :command="column">
|
||||
|
||||
@@ -18,11 +18,26 @@
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>
|
||||
<el-tooltip content="资源文件管理系统">
|
||||
<el-tooltip content="资源文件管理系统: 点击路径可以快速返回上级目录">
|
||||
<QuestionFilled class="w-4 h-4 mx-1" />
|
||||
</el-tooltip>
|
||||
文件列表
|
||||
文件列表(当前路径):
|
||||
</span>
|
||||
<!-- 资源路径 -->
|
||||
<div class="breadcrumb-container">
|
||||
|
||||
<span class="breadcrumb-label"></span>
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item
|
||||
v-for="(item, index) in breadcrumbList"
|
||||
:key="index"
|
||||
:class="{ 'is-link': index < breadcrumbList.length - 1 }"
|
||||
@click="handleBreadcrumbClick(item)"
|
||||
>
|
||||
{{ item.name }}
|
||||
</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -75,28 +90,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 资源路径 -->
|
||||
<div class="breadcrumb-section">
|
||||
<div class="breadcrumb-container">
|
||||
<div class="breadcrumb-header">
|
||||
<el-tooltip content="点击路径可以快速返回上级目录">
|
||||
<el-icon class="breadcrumb-icon"><QuestionFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
<span class="breadcrumb-label">当前路径:</span>
|
||||
</div>
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item
|
||||
v-for="(item, index) in breadcrumbList"
|
||||
:key="index"
|
||||
:class="{ 'is-link': index < breadcrumbList.length - 1 }"
|
||||
@click="handleBreadcrumbClick(item)"
|
||||
>
|
||||
{{ item.name }}
|
||||
</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 表格区域 -->
|
||||
<el-table
|
||||
v-if="viewMode === 'list'"
|
||||
@@ -105,7 +98,7 @@
|
||||
:data="fileList"
|
||||
row-key="file_url"
|
||||
class="data-table__content"
|
||||
height="540"
|
||||
height="450"
|
||||
border
|
||||
stripe
|
||||
@selection-change="handleSelectionChange"
|
||||
@@ -137,11 +130,6 @@
|
||||
<span v-if="!row.is_dir">{{ formatFileSize(row.size) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="类型" prop="file_type" min-width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row.file_type" size="small">{{ row.file_type }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="修改时间" prop="modified_time" min-width="180" sortable />
|
||||
<el-table-column fixed="right" label="操作" align="center" min-width="200">
|
||||
<template #default="{ row }">
|
||||
@@ -314,14 +302,14 @@ const currentPath = ref('/') // 当前路径的响应式变量
|
||||
// 分页查询参数
|
||||
const pagination = reactive({
|
||||
page_no: 1,
|
||||
page_size: 20
|
||||
page_size: 10
|
||||
})
|
||||
|
||||
// 搜索表单数据
|
||||
const queryFormData = reactive<ResourcePageQuery>({
|
||||
name: undefined,
|
||||
page_no: 1,
|
||||
page_size: 20
|
||||
page_size: 10
|
||||
})
|
||||
|
||||
// 对话框状态
|
||||
@@ -377,10 +365,7 @@ async function loadFileList() {
|
||||
const pageResult = response.data?.data
|
||||
|
||||
if (pageResult && Array.isArray(pageResult.items)) {
|
||||
fileList.value = pageResult.items.map(item => ({
|
||||
...item,
|
||||
is_hidden: item.name.startsWith('.')
|
||||
}))
|
||||
fileList.value = pageResult.items
|
||||
total.value = pageResult.total
|
||||
if (pageResult.page_no !== undefined) {
|
||||
pagination.page_no = pageResult.page_no
|
||||
@@ -393,7 +378,6 @@ async function loadFileList() {
|
||||
total.value = 0
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error('加载文件列表失败')
|
||||
console.error('Load file list error:', error)
|
||||
fileList.value = []
|
||||
total.value = 0
|
||||
@@ -515,11 +499,9 @@ async function handleUploadConfirm() {
|
||||
formData.append('target_path', targetPath)
|
||||
|
||||
await ResourceAPI.uploadFile(formData)
|
||||
ElMessage.success('上传成功')
|
||||
uploadDialogVisible.value = false
|
||||
loadFileList()
|
||||
} catch (error) {
|
||||
ElMessage.error('上传失败')
|
||||
console.error('Upload error:', error)
|
||||
} finally {
|
||||
uploading.value = false
|
||||
@@ -552,11 +534,9 @@ async function handleCreateDirConfirm() {
|
||||
parent_path: parentPath,
|
||||
dir_name: createDirForm.dir_name.trim()
|
||||
})
|
||||
ElMessage.success('创建成功')
|
||||
createDirDialogVisible.value = false
|
||||
loadFileList()
|
||||
} catch (error) {
|
||||
ElMessage.error('创建失败')
|
||||
console.error('Create directory error:', error)
|
||||
}
|
||||
}
|
||||
@@ -600,7 +580,6 @@ async function handleDownload(item: ResourceItem) {
|
||||
document.body.removeChild(a)
|
||||
window.URL.revokeObjectURL(url)
|
||||
} catch (error) {
|
||||
ElMessage.error('下载失败')
|
||||
console.error('Download error:', error)
|
||||
}
|
||||
}
|
||||
@@ -625,11 +604,9 @@ async function handleRenameConfirm() {
|
||||
old_path: renameForm.old_path,
|
||||
new_name: renameForm.new_name.trim()
|
||||
})
|
||||
ElMessage.success('重命名成功')
|
||||
renameDialogVisible.value = false
|
||||
loadFileList()
|
||||
} catch (error) {
|
||||
ElMessage.error('重命名失败')
|
||||
console.error('Rename error:', error)
|
||||
}
|
||||
}
|
||||
@@ -649,11 +626,9 @@ async function handleDelete(item: ResourceItem) {
|
||||
|
||||
// 使用file_url字段
|
||||
await ResourceAPI.deleteResource([item.file_url])
|
||||
ElMessage.success('删除成功')
|
||||
loadFileList()
|
||||
} catch (error) {
|
||||
if (error !== 'cancel') {
|
||||
ElMessage.error('删除失败')
|
||||
console.error('Delete error:', error)
|
||||
}
|
||||
}
|
||||
@@ -688,11 +663,9 @@ async function handleBatchDelete() {
|
||||
const paths = selectedItems.value.map(item => item.file_url)
|
||||
|
||||
await ResourceAPI.deleteResource(paths)
|
||||
ElMessage.success('删除成功')
|
||||
loadFileList()
|
||||
} catch (error) {
|
||||
if (error !== 'cancel') {
|
||||
ElMessage.error('删除失败')
|
||||
console.error('Batch delete error:', error)
|
||||
}
|
||||
}
|
||||
@@ -720,122 +693,50 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.app-container {
|
||||
.search-container {
|
||||
margin-bottom: 16px;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
// 使用系统主题颜色
|
||||
.card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.search-buttons {
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.data-table {
|
||||
.card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.breadcrumb-section {
|
||||
margin: 16px 0;
|
||||
padding: 12px 0;
|
||||
// 使用系统主题颜色
|
||||
|
||||
.breadcrumb-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
|
||||
.breadcrumb-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
flex-shrink: 0;
|
||||
|
||||
.breadcrumb-icon {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.breadcrumb-label {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.data-table__toolbar {
|
||||
.data-table__content {
|
||||
.file-name {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
gap: 8px;
|
||||
|
||||
.data-table__toolbar--actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.data-table__toolbar--tools {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.data-table__content {
|
||||
.file-name {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
||||
.file-name-clickable {
|
||||
cursor: pointer;
|
||||
color: var(--el-color-primary);
|
||||
|
||||
&:hover {
|
||||
color: var(--el-color-primary-light-3);
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.grid-view {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
|
||||
gap: 20px;
|
||||
padding: 20px;
|
||||
|
||||
.grid-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 15px;
|
||||
// 使用系统主题颜色
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
.item-icon {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.item-name {
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
word-break: break-all;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.item-size {
|
||||
font-size: 12px;
|
||||
}
|
||||
.file-name-clickable {
|
||||
cursor: pointer;
|
||||
color: var(--el-color-primary);
|
||||
|
||||
&:hover {
|
||||
color: var(--el-color-primary-light-3);
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.grid-view {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
|
||||
gap: 20px;
|
||||
|
||||
.grid-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
// 使用系统主题颜色
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
.item-name {
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
word-break: break-all;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-breadcrumb__item) {
|
||||
|
||||
@@ -202,6 +202,7 @@ defineOptions({
|
||||
});
|
||||
|
||||
import DeptAPI, { DeptTable, DeptForm, DeptPageQuery } from "@/api/system/dept";
|
||||
import { useUserStore } from "@/store";
|
||||
import { formatTree } from "@/utils/common";
|
||||
|
||||
const queryFormRef = ref();
|
||||
@@ -386,28 +387,22 @@ async function handleSubmit() {
|
||||
loading.value = true;
|
||||
// 根据弹窗传入的参数(deatil\create\update)判断走什么逻辑
|
||||
const id = formData.id;
|
||||
if (id) {
|
||||
try {
|
||||
try {
|
||||
if (id) {
|
||||
await DeptAPI.updateDept(id, { id, ...formData })
|
||||
dialogVisible.visible = false;
|
||||
resetForm();
|
||||
handleResetQuery();
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
} else {
|
||||
await DeptAPI.createDept(formData)
|
||||
dialogVisible.visible = false;
|
||||
resetForm();
|
||||
handleResetQuery();
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
dialogVisible.visible = false;
|
||||
resetForm();
|
||||
handleResetQuery();
|
||||
// 更新全局用户状态,刷新部门信息
|
||||
const userStore = useUserStore();
|
||||
await userStore.getUserInfo();
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -271,7 +271,7 @@
|
||||
<el-input v-model="formData.route_path" placeholder="请输入外链完整路径" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="routeName">
|
||||
<el-form-item prop="route_name">
|
||||
<template #label>
|
||||
<div class="flex-y-center">
|
||||
路由名称
|
||||
@@ -288,7 +288,7 @@
|
||||
<el-input v-model="formData.route_name" placeholder="请输入路由名称" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="formData.type == MenuTypeEnum.CATALOG || formData.type == MenuTypeEnum.MENU" prop="routePath">
|
||||
<el-form-item v-if="formData.type == MenuTypeEnum.CATALOG || formData.type == MenuTypeEnum.MENU" prop="route_path">
|
||||
<template #label>
|
||||
<div class="flex-y-center">
|
||||
路由路径
|
||||
@@ -303,8 +303,7 @@
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<el-input v-if="formData.type == MenuTypeEnum.CATALOG" v-model="formData.route_path" placeholder="system" />
|
||||
<el-input v-else v-model="formData.route_path" placeholder="请输入路由路径" />
|
||||
<el-input v-model="formData.route_path" placeholder="请输入路由路径,如:/system" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="formData.type == MenuTypeEnum.MENU" prop="component">
|
||||
@@ -516,14 +515,14 @@ const queryFormData = reactive<MenuPageQuery>({
|
||||
const formData = reactive<MenuForm>({
|
||||
id: undefined,
|
||||
name: undefined,
|
||||
type: MenuTypeEnum.MENU,
|
||||
type: MenuTypeEnum.CATALOG,
|
||||
icon: undefined,
|
||||
order: 1,
|
||||
order: 999,
|
||||
permission: '',
|
||||
route_name: '',
|
||||
route_path: '',
|
||||
component_path: '',
|
||||
redirect: '',
|
||||
component_path: undefined,
|
||||
redirect: undefined,
|
||||
parent_id: undefined,
|
||||
keep_alive: false,
|
||||
hidden: false,
|
||||
@@ -555,7 +554,19 @@ const rules = reactive({
|
||||
order: [{ required: true, message: "请输入排序", trigger: "blur" }],
|
||||
permission: [{ required: true, message: "请输入权限标识", trigger: "blur" }],
|
||||
route_name: [{ required: true, message: "请输入路由名称", trigger: "blur" }],
|
||||
route_path: [{ required: true, message: "请输入路由路径", trigger: "blur" }],
|
||||
route_path: [
|
||||
{ required: true, message: "请输入路由路径", trigger: "blur" },
|
||||
{
|
||||
validator: (rule: any, value: string, callback: any) => {
|
||||
if (value && !value.startsWith('/')) {
|
||||
callback(new Error('目录和菜单路由必须以/开头'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
component_path: [{ required: true, message: "请输入组件路径", trigger: "blur" }],
|
||||
title: [{ required: true, message: "请输入菜单标题", trigger: "blur" }],
|
||||
keep_alive: [{ required: true, message: "请选择是否缓存", trigger: "change" }],
|
||||
@@ -724,30 +735,20 @@ async function handleSubmit() {
|
||||
loading.value = true;
|
||||
// 根据弹窗传入的参数(deatil\create\update)判断走什么逻辑
|
||||
const id = formData.id;
|
||||
if (id) {
|
||||
try {
|
||||
try {
|
||||
if (id) {
|
||||
await MenuAPI.updateMenu(id, formData)
|
||||
await userStore.getUserInfo();
|
||||
dialogVisible.visible = false;
|
||||
resetForm();
|
||||
handleResetQuery();
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
} else {
|
||||
await MenuAPI.createMenu(formData)
|
||||
await userStore.getUserInfo();
|
||||
dialogVisible.visible = false;
|
||||
resetForm();
|
||||
handleResetQuery();
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
await userStore.getUserInfo();
|
||||
dialogVisible.visible = false;
|
||||
resetForm();
|
||||
handleResetQuery();
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -212,6 +212,7 @@ defineOptions({
|
||||
});
|
||||
|
||||
import PositionAPI, { PositionTable, PositionForm, PositionPageQuery } from "@/api/system/position";
|
||||
import { useUserStore } from "@/store";
|
||||
|
||||
const queryFormRef = ref();
|
||||
const dataFormRef = ref();
|
||||
@@ -383,28 +384,22 @@ async function handleSubmit() {
|
||||
loading.value = true;
|
||||
// 根据弹窗传入的参数(deatil\create\update)判断走什么逻辑
|
||||
const id = formData.id;
|
||||
if (id) {
|
||||
try {
|
||||
try {
|
||||
if (id) {
|
||||
await PositionAPI.updatePosition(id, { id, ...formData })
|
||||
dialogVisible.visible = false;
|
||||
resetForm();
|
||||
handleResetQuery();
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
} else {
|
||||
await PositionAPI.createPosition(formData)
|
||||
dialogVisible.visible = false;
|
||||
resetForm();
|
||||
handleResetQuery();
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
dialogVisible.visible = false;
|
||||
resetForm();
|
||||
handleResetQuery();
|
||||
// 更新全局用户状态,刷新岗位信息
|
||||
const userStore = useUserStore();
|
||||
await userStore.getUserInfo();
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!-- 角色授权 -->
|
||||
<!-- 角色授权 -->
|
||||
<template>
|
||||
<!-- 分配权限弹窗 -->
|
||||
<el-drawer v-model="drawerVisible" :title="'【' + props.roleName + '】权限分配'" :size="drawerSize">
|
||||
@@ -152,6 +152,7 @@ import MenuAPI from "@/api/system/menu";
|
||||
import type { TreeInstance } from 'element-plus'
|
||||
import { useAppStore } from "@/store/modules/app.store";
|
||||
import { DeviceEnum } from "@/enums/settings/device.enum";
|
||||
import { useUserStore } from "@/store";
|
||||
|
||||
const appStore = useAppStore();
|
||||
const drawerSize = computed(() => (appStore.device === DeviceEnum.DESKTOP ? "800px" : "90%"));
|
||||
@@ -233,7 +234,7 @@ function handleCancel() {
|
||||
drawerVisible.value = false;
|
||||
}
|
||||
|
||||
// 保存权限设置
|
||||
// 保存权限分配
|
||||
async function handleDrawerSave () {
|
||||
try {
|
||||
loading.value = true;
|
||||
@@ -247,8 +248,14 @@ async function handleDrawerSave () {
|
||||
};
|
||||
|
||||
await RoleAPI.setPermission(submitData)
|
||||
drawerVisible.value = false;
|
||||
|
||||
ElMessage.success('权限分配成功');
|
||||
|
||||
// 更新全局用户状态,刷新权限信息
|
||||
const userStore = useUserStore();
|
||||
await userStore.getUserInfo();
|
||||
|
||||
drawerVisible.value = false;
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
|
||||
@@ -97,10 +97,10 @@
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-tooltip content="列表筛选">
|
||||
<el-dropdown trigger="click">
|
||||
<el-button type="default" icon="operation" circle />
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu v-hasPerm="['system:role:filter']">
|
||||
<el-dropdown v-hasPerm="['system:role:filter']" trigger="click">
|
||||
<el-button type="default" icon="operation" circle />
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item v-for="column in tableColumns" :key="column.prop" :command="column">
|
||||
<el-checkbox v-model="column.show">{{ column.label }}</el-checkbox>
|
||||
</el-dropdown-item>
|
||||
@@ -276,6 +276,7 @@ defineOptions({
|
||||
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import RoleAPI, { RoleTable, RoleForm, TablePageQuery } from "@/api/system/role";
|
||||
import { useUserStore } from "@/store";
|
||||
|
||||
const queryFormRef = ref();
|
||||
const dataFormRef = ref();
|
||||
@@ -454,28 +455,22 @@ async function handleSubmit() {
|
||||
loading.value = true;
|
||||
// 根据弹窗传入的参数(deatil\create\update)判断走什么逻辑
|
||||
const id = formData.id;
|
||||
if (id) {
|
||||
try {
|
||||
try {
|
||||
if (id) {
|
||||
await RoleAPI.updateRole(id, { id, ...formData })
|
||||
dialogVisible.visible = false;
|
||||
resetForm();
|
||||
handleResetQuery();
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
} else {
|
||||
await RoleAPI.createRole(formData)
|
||||
dialogVisible.visible = false;
|
||||
resetForm();
|
||||
handleResetQuery();
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
dialogVisible.visible = false;
|
||||
resetForm();
|
||||
handleResetQuery();
|
||||
// 更新全局用户状态,刷新权限信息
|
||||
const userStore = useUserStore();
|
||||
await userStore.getUserInfo();
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -362,6 +362,7 @@ import DeptAPI from "@/api/system/dept";
|
||||
import RoleAPI from "@/api/system/role";
|
||||
|
||||
import DeptTree from "./components/DeptTree.vue";
|
||||
import { useUserStore } from "@/store";
|
||||
|
||||
const appStore = useAppStore();
|
||||
|
||||
@@ -617,33 +618,24 @@ async function handleSubmit() {
|
||||
loading.value = true;
|
||||
// 根据弹窗传入的参数(deatil\create\update)判断走什么逻辑
|
||||
const id = formData.id;
|
||||
if (id) {
|
||||
try {
|
||||
// 编辑用户时,不传递密码字段
|
||||
const updateData = { id, ...formData };
|
||||
delete updateData.password;
|
||||
await UserAPI.updateUser(id, updateData)
|
||||
dialogVisible.visible = false;
|
||||
resetForm();
|
||||
handleCloseDialog();
|
||||
handleResetQuery();
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
try {
|
||||
if (id) {
|
||||
await UserAPI.updateUser(id, { id, ...formData })
|
||||
} else {
|
||||
await UserAPI.createUser(formData)
|
||||
dialogVisible.visible = false;
|
||||
resetForm();
|
||||
handleCloseDialog();
|
||||
handleResetQuery();
|
||||
} catch (error: any) {
|
||||
console.log(error.message);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
dialogVisible.visible = false;
|
||||
resetForm();
|
||||
handleResetQuery();
|
||||
// 如果当前编辑的是登录用户,更新全局用户状态
|
||||
const userStore = useUserStore();
|
||||
if (id === userStore.basicInfo.id) {
|
||||
await userStore.getUserInfo();
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user