Files
cn-rdms-web/src/views/infra/log-management/index.vue
dk a8e2bac65a feat(log、post、user、project、work-report): 添加用户姓名字段并实现岗位用户导出功能
- 在API访问日志、API错误日志中新增用户姓名字段显示
- 优化日志管理页面布局样式,修复高度自适应问题
- 添加系统岗位数据导出功能及相应API接口
- 添加系统用户数据导出功能及相应API接口
- 新增通用文件下载和导出文件名生成工具函数
- 修复工作报表删除确认提示文案
- 调整项目列表默认展开状态逻辑
- 完善岗位和用户管理页面导出按钮权限控制
- 更新日志实体类型定义,增加用户昵称字段
2026-07-01 17:15:12 +08:00

198 lines
4.7 KiB
Vue

<script setup lang="ts">
import { computed, markRaw, ref, watch } from 'vue';
import { useAuth } from '@/hooks/business/auth';
import LoginLogTab from './login-log/index.vue';
import OperateLogTab from './operate-log/index.vue';
import ApiAccessLogTab from './api-access-log/index.vue';
import ApiErrorLogTab from './api-error-log/index.vue';
import { LOG_TABS, type LogTabKey } from './shared';
defineOptions({ name: 'LogManagement' });
const { hasAuth } = useAuth();
const activeTab = ref<LogTabKey>('login-log');
const visibleTabs = computed(() => LOG_TABS.filter(tab => hasAuth(tab.queryPermission)));
const activeTabMeta = computed(() => visibleTabs.value.find(tab => tab.name === activeTab.value) || null);
const scopeOptions = computed(() =>
visibleTabs.value.map(tab => ({
label: tab.label,
value: tab.name
}))
);
const componentMap: Record<LogTabKey, object> = {
'login-log': markRaw(LoginLogTab),
'operate-log': markRaw(OperateLogTab),
'api-access-log': markRaw(ApiAccessLogTab),
'api-error-log': markRaw(ApiErrorLogTab)
};
watch(
visibleTabs,
tabs => {
if (!tabs.length) return;
if (!tabs.some(tab => tab.name === activeTab.value)) {
activeTab.value = tabs[0].name;
}
},
{ immediate: true }
);
</script>
<template>
<div class="log-management-page">
<ElCard class="log-management-page__context" body-class="log-management-page__context-body">
<div v-if="visibleTabs.length" class="log-management-page__context-layout">
<div class="log-management-page__context-controls">
<ElSegmented v-model="activeTab" :options="scopeOptions" class="log-management-page__segmented" />
</div>
<div class="log-management-page__context-info">
<div class="log-management-page__context-main">
<div class="log-management-page__context-item">
<span class="log-management-page__context-label">当前日志</span>
<strong class="log-management-page__context-value">{{ activeTabMeta?.label || '--' }}</strong>
</div>
</div>
<p class="log-management-page__context-desc">
{{ activeTabMeta?.description || '当前查看系统日志数据。' }}
</p>
</div>
</div>
<ElEmpty v-else description="暂无可查看的日志权限" />
</ElCard>
<div v-if="activeTabMeta" class="log-management-page__content">
<div class="log-management-page__pane">
<KeepAlive>
<component :is="componentMap[activeTab]" class="log-management-page__tab" />
</KeepAlive>
</div>
</div>
</div>
</template>
<style scoped lang="scss">
.log-management-page {
display: flex;
flex-direction: column;
gap: 16px;
height: 100%;
overflow: hidden;
}
.log-management-page__context {
border: 1px solid var(--el-border-color-light);
background: var(--el-fill-color-blank);
box-shadow: none;
}
:deep(.log-management-page__context-body) {
padding: 16px 18px;
}
.log-management-page__context-layout {
display: flex;
align-items: flex-start;
gap: 20px;
}
.log-management-page__context-controls {
flex-shrink: 0;
}
:deep(.log-management-page__segmented) {
padding: 6px;
background: var(--el-fill-color-light);
border-radius: 12px;
}
:deep(.log-management-page__segmented .el-segmented__item) {
min-width: 128px;
min-height: 40px;
padding: 0 24px;
font-size: 14px;
}
.log-management-page__context-info {
flex: 1;
min-width: 0;
padding-left: 20px;
border-left: 1px solid var(--el-border-color-lighter);
}
.log-management-page__context-main {
display: flex;
flex-wrap: wrap;
gap: 24px;
}
.log-management-page__context-item {
display: flex;
align-items: baseline;
gap: 10px;
min-width: 180px;
}
.log-management-page__context-label {
color: var(--el-text-color-secondary);
font-size: 12px;
line-height: 1.5;
}
.log-management-page__context-value {
color: var(--el-text-color-primary);
font-size: 15px;
font-weight: 600;
line-height: 1.5;
}
.log-management-page__context-desc {
margin: 10px 0 0;
color: var(--el-text-color-regular);
font-size: 13px;
line-height: 1.6;
}
.log-management-page__content {
display: flex;
flex: 1;
min-height: 0;
overflow: hidden;
}
.log-management-page__pane {
display: flex;
flex: 1;
min-width: 0;
min-height: 0;
overflow: hidden;
}
:deep(.log-management-page__tab) {
display: flex;
width: 100%;
flex: 1;
min-width: 0;
min-height: 0;
}
@media (width <= 1200px) {
.log-management-page__context-layout {
flex-direction: column;
align-items: stretch;
}
.log-management-page__context-info {
padding-left: 0;
padding-top: 14px;
border-left: none;
border-top: 1px solid var(--el-border-color-lighter);
}
}
</style>