feat: 给编码管理添加按钮级权限管理

This commit is contained in:
皓月归尘 2025-02-23 23:50:54 +08:00
parent c0c127d090
commit 4687f9dd31
6 changed files with 198 additions and 28 deletions

View File

@ -112,8 +112,16 @@ export const getQueryCodeAPI = (id: string) => {
export const getCodeLogListAPI = (params: { export const getCodeLogListAPI = (params: {
page: number; page: number;
pageSize: number; pageSize: number;
startTime?: string; /**用户账号 */
endTime?: string; username?: string;
/**用户昵称 */
nickname?: string;
/**部门ID */
department_id?: string;
/**开始时间 */
startTime?: string | number;
/**结束时间 */
endTime?: string | number;
}) => { }) => {
return http.request<QueryListResult<QueryCodeLogInfo>>( return http.request<QueryListResult<QueryCodeLogInfo>>(
"get", "get",
@ -131,8 +139,18 @@ export const getCodeLogInfoAPI = (id: string) => {
/**获取所有查询编码列表 */ /**获取所有查询编码列表 */
export const getCodeLogListAllAPI = (params: { export const getCodeLogListAllAPI = (params: {
startTime?: string; /**用户账号 */
endTime?: string; username?: string;
/**用户昵称 */
nickname?: string;
/**部门ID */
department_id?: string;
/**登录状态 */
status?: number | string;
/**开始时间 */
startTime?: string | number;
/**结束时间 */
endTime?: string | number;
}) => { }) => {
return http.request<QueryListResult<QueryCodeLogInfo>>( return http.request<QueryListResult<QueryCodeLogInfo>>(
"get", "get",

View File

@ -39,15 +39,19 @@
<PureTableBar title="编码管理" :columns="columns" @refresh="onSearch"> <PureTableBar title="编码管理" :columns="columns" @refresh="onSearch">
<template #buttons> <template #buttons>
<el-button <el-button
v-if="hasAuth('code:btn:add')"
type="primary" type="primary"
:disabled="!hasAuth('code:btn:add')"
:icon="useRenderIcon(AddFill)" :icon="useRenderIcon(AddFill)"
@click="openDialog('新增')" @click="openDialog('新增')"
> >
{{ t("buttons:Add") }} {{ t("buttons:Add") }}
</el-button> </el-button>
<el-button <el-button
v-if="hasAuth('code:btn:import')"
type="primary" type="primary"
:icon="useRenderIcon(AddFill)" :icon="useRenderIcon(AddFill)"
:disabled="!hasAuth('code:btn:import')"
@click="showUploadArea = !showUploadArea" @click="showUploadArea = !showUploadArea"
> >
{{ showUploadArea ? t("buttons:Hide") : t("buttons:Import") }} {{ showUploadArea ? t("buttons:Hide") : t("buttons:Import") }}
@ -78,15 +82,23 @@
</el-upload> </el-upload>
<template #footer> <template #footer>
<div class="flex items-center justify-center"> <div class="flex items-center justify-center">
<el-button class="w-full my-2" @click="onDownloadTemplate">{{ <el-button
t("buttons:DownLodedTemplate") v-if="hasAuth('code:btn:uploadTemplate')"
}}</el-button> class="w-full my-2"
<el-popconfirm title="是否确认上传?" @confirm="handleUpload"> :disabled="!hasAuth('code:btn:uploadTemplate')"
@click="onDownloadTemplate"
>{{ t("buttons:DownLodedTemplate") }}</el-button
>
<el-popconfirm
v-if="hasAuth('code:btn:import')"
title="是否确认上传?"
@confirm="handleUpload"
>
<template #reference> <template #reference>
<el-button <el-button
class="w-full my-2" class="w-full my-2"
type="primary" type="primary"
:disabled="uploadStatus" :disabled="uploadStatus || !hasAuth('code:btn:import')"
>{{ t("buttons:ConfirmUpload") }}</el-button >{{ t("buttons:ConfirmUpload") }}</el-button
> >
</template> </template>
@ -110,9 +122,18 @@
{{ t("buttons:Deselect") }} {{ t("buttons:Deselect") }}
</el-button> </el-button>
</div> </div>
<el-popconfirm title="是否确认删除?" @confirm="onbatchDel"> <el-popconfirm
v-if="hasAuth('code:btn:delete')"
title="是否确认删除?"
@confirm="onbatchDel"
>
<template #reference> <template #reference>
<el-button type="danger" text class="mr-1"> <el-button
type="danger"
text
class="mr-1"
:disabled="selectedNum < 0 || !hasAuth('code:btn:delete')"
>
{{ t("buttons:DeleteInBatches") }} {{ t("buttons:DeleteInBatches") }}
</el-button> </el-button>
</template> </template>
@ -147,6 +168,7 @@
link link
type="primary" type="primary"
:size="size" :size="size"
:disabled="!hasAuth('code:btn:update')"
:icon="useRenderIcon(EditPen)" :icon="useRenderIcon(EditPen)"
@click="openDialog('修改', row)" @click="openDialog('修改', row)"
> >
@ -162,6 +184,7 @@
link link
type="danger" type="danger"
:size="size" :size="size"
:disabled="!hasAuth('code:btn:delete')"
:icon="useRenderIcon(Delete)" :icon="useRenderIcon(Delete)"
> >
{{ t("buttons:Delete") }} {{ t("buttons:Delete") }}
@ -189,6 +212,7 @@ import EditPen from "@iconify-icons/ep/edit-pen";
import Refresh from "@iconify-icons/ep/refresh"; import Refresh from "@iconify-icons/ep/refresh";
import AddFill from "@iconify-icons/ri/add-circle-line"; import AddFill from "@iconify-icons/ri/add-circle-line";
import UploadIcon from "@iconify-icons/ri/upload-2-line"; import UploadIcon from "@iconify-icons/ri/upload-2-line";
import { hasAuth } from "@/utils/auth";
const { t } = useI18n(); const { t } = useI18n();
/** /**

View File

@ -31,6 +31,7 @@
{{ t("buttons:Reset") }} {{ t("buttons:Reset") }}
</el-button> </el-button>
<el-button <el-button
v-if="hasAuth('code:btn:importQuery')"
type="primary" type="primary"
:icon="useRenderIcon(UploadIcon)" :icon="useRenderIcon(UploadIcon)"
@click="showUploadArea = !showUploadArea" @click="showUploadArea = !showUploadArea"
@ -64,15 +65,18 @@
</el-upload> </el-upload>
<template #footer> <template #footer>
<div class="flex items-center justify-center"> <div class="flex items-center justify-center">
<el-button class="w-full my-2" @click="onDownloadTemplate">{{ <el-button
t("buttons:DownLodedTemplate") class="w-full my-2"
}}</el-button> :disabled="hasAuth('code:btn:queryTemplate')"
@click="onDownloadTemplate"
>{{ t("buttons:DownLodedTemplate") }}</el-button
>
<el-popconfirm title="是否确认上传?" @confirm="handleUpload"> <el-popconfirm title="是否确认上传?" @confirm="handleUpload">
<template #reference> <template #reference>
<el-button <el-button
class="w-full my-2" class="w-full my-2"
type="primary" type="primary"
:disabled="uploadStatus" :disabled="uploadStatus || !hasAuth('code:btn:importQuery')"
>{{ t("buttons:ConfirmUpload") }}</el-button >{{ t("buttons:ConfirmUpload") }}</el-button
> >
</template> </template>
@ -100,8 +104,10 @@
<PureTableBar title="查询结果" :columns="columns" @refresh="onSearch"> <PureTableBar title="查询结果" :columns="columns" @refresh="onSearch">
<template #buttons> <template #buttons>
<el-button <el-button
v-if="hasAuth('code:btn:export')"
type="primary" type="primary"
:icon="useRenderIcon(Export)" :icon="useRenderIcon(Export)"
:disabled="!hasAuth('code:btn:export')"
@click="exportToExcel([queryResult], '查询结果')" @click="exportToExcel([queryResult], '查询结果')"
> >
{{ t("buttons:ExportAll") }} {{ t("buttons:ExportAll") }}
@ -124,7 +130,11 @@
{{ t("buttons:Deselect") }} {{ t("buttons:Deselect") }}
</el-button> </el-button>
</div> </div>
<el-popconfirm title="是否确认导出?" @confirm="onbatchExport"> <el-popconfirm
v-if="hasAuth('code:btn:export')"
title="是否确认导出?"
@confirm="onbatchExport"
>
<template #reference> <template #reference>
<el-button type="primary" text class="mr-1"> <el-button type="primary" text class="mr-1">
{{ t("buttons:ExportInBatches") }} {{ t("buttons:ExportInBatches") }}
@ -159,6 +169,7 @@
link link
type="primary" type="primary"
:size="size" :size="size"
:disabled="!hasAuth('code:btn:logInfo')"
:icon="useRenderIcon(EditPen)" :icon="useRenderIcon(EditPen)"
@click="handleDetail(row)" @click="handleDetail(row)"
> >
@ -220,6 +231,7 @@ import Refresh from "@iconify-icons/ep/refresh";
import UploadIcon from "@iconify-icons/ri/upload-2-line"; import UploadIcon from "@iconify-icons/ri/upload-2-line";
import Export from "@iconify-icons/ri/download-2-line"; import Export from "@iconify-icons/ri/download-2-line";
const { t } = useI18n(); const { t } = useI18n();
import { hasAuth } from "@/utils/auth";
/** /**
* 表格Ref * 表格Ref
*/ */

View File

@ -18,14 +18,22 @@
</el-card> </el-card>
<PureTableBar title="查询结果" :columns="columns"> <PureTableBar title="查询结果" :columns="columns">
<template #buttons> <template #buttons>
<el-popconfirm
v-if="hasAuth('code:btn:export')"
title="确定要导出所有查询数据吗?"
@confirm="exportToExcel([queryInfo], '查询结果')"
>
<template #reference>
<el-button <el-button
type="primary" type="primary"
:icon="useRenderIcon(Export)" :icon="useRenderIcon(Export)"
@click="exportToExcel([queryInfo], '查询结果')" :disabled="!hasAuth('code:btn:export')"
> >
{{ t("buttons:ExportAll") }} {{ t("buttons:ExportAll") }}
</el-button> </el-button>
</template> </template>
</el-popconfirm>
</template>
<template v-slot="{ size, dynamicColumns }"> <template v-slot="{ size, dynamicColumns }">
<div <div
v-if="selectedNum > 0" v-if="selectedNum > 0"
@ -43,9 +51,18 @@
{{ t("buttons:Deselect") }} {{ t("buttons:Deselect") }}
</el-button> </el-button>
</div> </div>
<el-popconfirm title="是否确认导出?" @confirm="onbatchExport"> <el-popconfirm
v-if="hasAuth('code:btn:export')"
title="是否确认导出?"
@confirm="onbatchExport"
>
<template #reference> <template #reference>
<el-button type="primary" text class="mr-1"> <el-button
type="primary"
text
class="mr-1"
:disabled="selectedNum < 0 || !hasAuth('code:btn:export')"
>
{{ t("buttons:ExportInBatches") }} {{ t("buttons:ExportInBatches") }}
</el-button> </el-button>
</template> </template>
@ -77,6 +94,7 @@
link link
type="primary" type="primary"
:size="size" :size="size"
:disabled="!hasAuth('code:btn:logInfo')"
:icon="useRenderIcon(EditPen)" :icon="useRenderIcon(EditPen)"
@click="handleDetail(row)" @click="handleDetail(row)"
> >
@ -145,6 +163,7 @@ import type {
import { getCodeLogInfoAPI } from "@/api/code"; import { getCodeLogInfoAPI } from "@/api/code";
import { PaginationProps } from "@pureadmin/table"; import { PaginationProps } from "@pureadmin/table";
import { message } from "@/utils/message"; import { message } from "@/utils/message";
import { hasAuth } from "@/utils/auth";
const { t } = useI18n(); const { t } = useI18n();
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();

View File

@ -6,7 +6,44 @@
:model="form" :model="form"
class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto" class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto"
> >
<el-form-item label="操作时间" prop="operatingTime"> <el-form-item label="用户账号" prop="username">
<el-input
v-model="form.username"
placeholder="请输入用户账号~"
clearable
class="!w-[150px]"
/>
</el-form-item>
<el-form-item label="用户名称" prop="nickname">
<el-input
v-model="form.nickname"
placeholder="请输入用户名称~"
clearable
class="!w-[150px]"
/>
</el-form-item>
<el-form-item label="所属部门:" prop="department_id">
<el-cascader
v-model="form.department_id"
class="!w-[150px]"
:options="departments"
:props="{
value: 'id',
label: 'name',
emitPath: false,
checkStrictly: true
}"
clearable
filterable
placeholder="请选择所属部门~"
>
<template #default="{ node, data }">
<span>{{ data.name }}</span>
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
</template>
</el-cascader>
</el-form-item>
<el-form-item label="查询时间" prop="timeRange">
<el-date-picker <el-date-picker
v-model="form.timeRange" v-model="form.timeRange"
:shortcuts="getPickerShortcuts()" :shortcuts="getPickerShortcuts()"
@ -36,11 +73,16 @@
<PureTableBar title="查询日志" :columns="columns" @refresh="onSearch"> <PureTableBar title="查询日志" :columns="columns" @refresh="onSearch">
<template #buttons> <template #buttons>
<el-popconfirm <el-popconfirm
v-if="hasAuth('code:btn:export')"
title="确定要导出所有日志数据吗?" title="确定要导出所有日志数据吗?"
@confirm="onExportQueryAll" @confirm="onExportQueryAll"
> >
<template #reference> <template #reference>
<el-button type="primary" :icon="useRenderIcon(Export)"> <el-button
type="primary"
:icon="useRenderIcon(Export)"
:disabled="!hasAuth('code:btn:export')"
>
{{ t("buttons:ExportAll") }} {{ t("buttons:ExportAll") }}
</el-button> </el-button>
</template> </template>
@ -64,11 +106,17 @@
</el-button> </el-button>
</div> </div>
<el-popconfirm <el-popconfirm
v-if="hasAuth('code:btn:export')"
title="是否确认批量导出日志数据?" title="是否确认批量导出日志数据?"
@confirm="onbatchExport" @confirm="onbatchExport"
> >
<template #reference> <template #reference>
<el-button type="primary" text class="mr-1"> <el-button
type="primary"
text
class="mr-1"
:disabled="selectedNum < 0 || !hasAuth('code:btn:export')"
>
{{ t("buttons:ExportInBatches") }} {{ t("buttons:ExportInBatches") }}
</el-button> </el-button>
</template> </template>
@ -100,6 +148,7 @@
link link
type="primary" type="primary"
:size="size" :size="size"
:disabled="!hasAuth('code:btn:logInfo')"
:icon="useRenderIcon(View)" :icon="useRenderIcon(View)"
@click="onClickDetails(row)" @click="onClickDetails(row)"
> >
@ -130,6 +179,7 @@ const router = useRouter();
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { useQueryLog } from "./utils/hook"; import { useQueryLog } from "./utils/hook";
import { QueryCodeLogInfo } from "types/code"; import { QueryCodeLogInfo } from "types/code";
import { hasAuth } from "@/utils/auth";
const formRef = ref(); const formRef = ref();
const tableRef = ref(); const tableRef = ref();
const { t } = useI18n(); const { t } = useI18n();
@ -138,6 +188,7 @@ const {
loading, loading,
columns, columns,
dataList, dataList,
departments,
pagination, pagination,
selectedNum, selectedNum,
onSearch, onSearch,

View File

@ -11,11 +11,16 @@ import type { QueryCodeLogInfo } from "types/code";
import * as XLSX from "xlsx"; import * as XLSX from "xlsx";
import { getCodeLogListAllAPI, getCodeLogListAPI } from "@/api/code"; import { getCodeLogListAllAPI, getCodeLogListAPI } from "@/api/code";
import { message } from "@/utils/message"; import { message } from "@/utils/message";
import { cloneDeep, getKeyList } from "@pureadmin/utils"; import { cloneDeep, getKeyList, handleTree } from "@pureadmin/utils";
import type { DepartmentInfo } from "types/system";
import { getDepartmentListAPI } from "@/api/system";
export const useQueryLog = (tableRef: Ref) => { export const useQueryLog = (tableRef: Ref) => {
/**查询表单 */ /**查询表单 */
const form = reactive({ const form = reactive({
username: "",
nickname: "",
department_id: "",
timeRange: [null, null] timeRange: [null, null]
}); });
/**数据列表 */ /**数据列表 */
@ -101,6 +106,9 @@ export const useQueryLog = (tableRef: Ref) => {
const res = await getCodeLogListAPI({ const res = await getCodeLogListAPI({
page: pagination.currentPage, page: pagination.currentPage,
pageSize: val, pageSize: val,
username: form.username,
nickname: form.nickname,
department_id: form.department_id,
startTime: form.timeRange[0] ? form.timeRange[0] : null, startTime: form.timeRange[0] ? form.timeRange[0] : null,
endTime: form.timeRange[1] ? form.timeRange[1] : null endTime: form.timeRange[1] ? form.timeRange[1] : null
}); });
@ -108,12 +116,16 @@ export const useQueryLog = (tableRef: Ref) => {
dataList.value = res.data.result; dataList.value = res.data.result;
pagination.total = res.data.total; pagination.total = res.data.total;
pagination.currentPage = res.data.page; pagination.currentPage = res.data.page;
pagination.pageSize = res.data.pageSize;
} }
}; };
const handleCurrentChange = async (val: number) => { const handleCurrentChange = async (val: number) => {
const res = await getCodeLogListAPI({ const res = await getCodeLogListAPI({
page: val, page: val,
pageSize: pagination.pageSize, pageSize: pagination.pageSize,
username: form.username,
nickname: form.nickname,
department_id: form.department_id,
startTime: form.timeRange[0] ? form.timeRange[0] : null, startTime: form.timeRange[0] ? form.timeRange[0] : null,
endTime: form.timeRange[1] ? form.timeRange[1] : null endTime: form.timeRange[1] ? form.timeRange[1] : null
}); });
@ -121,6 +133,7 @@ export const useQueryLog = (tableRef: Ref) => {
dataList.value = res.data.result; dataList.value = res.data.result;
pagination.total = res.data.total; pagination.total = res.data.total;
pagination.currentPage = res.data.page; pagination.currentPage = res.data.page;
pagination.pageSize = res.data.pageSize;
} }
}; };
@ -142,6 +155,9 @@ export const useQueryLog = (tableRef: Ref) => {
const res = await getCodeLogListAPI({ const res = await getCodeLogListAPI({
page: pagination.currentPage, page: pagination.currentPage,
pageSize: pagination.pageSize, pageSize: pagination.pageSize,
username: form.username,
nickname: form.nickname,
department_id: form.department_id,
startTime: form.timeRange[0] ? form.timeRange[0] : null, startTime: form.timeRange[0] ? form.timeRange[0] : null,
endTime: form.timeRange[1] ? form.timeRange[1] : null endTime: form.timeRange[1] ? form.timeRange[1] : null
}); });
@ -149,6 +165,7 @@ export const useQueryLog = (tableRef: Ref) => {
dataList.value = res.data.result; dataList.value = res.data.result;
pagination.total = res.data.total; pagination.total = res.data.total;
pagination.currentPage = res.data.page; pagination.currentPage = res.data.page;
pagination.pageSize = res.data.pageSize;
} }
setTimeout(() => { setTimeout(() => {
@ -395,6 +412,9 @@ export const useQueryLog = (tableRef: Ref) => {
/**导出所有查询结果 */ /**导出所有查询结果 */
const onExportQueryAll = async () => { const onExportQueryAll = async () => {
const res = await getCodeLogListAllAPI({ const res = await getCodeLogListAllAPI({
username: form.username,
nickname: form.nickname,
department_id: form.department_id,
startTime: form.timeRange[0] ? form.timeRange[0] : null, startTime: form.timeRange[0] ? form.timeRange[0] : null,
endTime: form.timeRange[1] ? form.timeRange[1] : null endTime: form.timeRange[1] ? form.timeRange[1] : null
}); });
@ -417,8 +437,33 @@ export const useQueryLog = (tableRef: Ref) => {
exportToExcel(selecteList, "查询结果"); exportToExcel(selecteList, "查询结果");
}; };
/**部门列表 */
const departments = ref<DepartmentInfo[]>([]);
/**获取部门列表 */
const getDepartments = async () => {
const res = await getDepartmentListAPI({ page: 1, pageSize: 9999 });
if (res.success) {
departments.value = formatHigherOptions(
handleTree(res.data.result, "id", "parent_id")
);
} else {
departments.value = [];
}
};
const formatHigherOptions = (treeList: any) => {
// 根据返回数据的status字段值判断追加是否禁用disabled字段返回处理后的树结构用于上级部门级联选择器的展示实际开发中也是如此不可能前端需要的每个字段后端都会返回这时需要前端自行根据后端返回的某些字段做逻辑处理
if (!treeList || !treeList.length) return;
const newTreeList = [];
for (let i = 0; i < treeList.length; i++) {
treeList[i].disabled = treeList[i].status === 0 ? true : false;
formatHigherOptions(treeList[i].children);
newTreeList.push(treeList[i]);
}
return newTreeList;
};
onMounted(async () => { onMounted(async () => {
await onSearch(); await onSearch();
await getDepartments();
}); });
return { return {
form, form,
@ -426,6 +471,7 @@ export const useQueryLog = (tableRef: Ref) => {
dataList, dataList,
columns, columns,
selectedNum, selectedNum,
departments,
pagination, pagination,
onSearch, onSearch,
getPickerShortcuts, getPickerShortcuts,