fix(工作台-工时、周报、日志管理): 详细如下。

- 移除历史工作日分隔符兼容逻辑,仅使用显式分隔标记切分
- 扩展工时数据显示范围从5个工作日到7天完整周,并添加周末展示控制
- 在团队工时统计中新增加班工时字段并调整图表展示方式
- 移除团队工时分布中的分类矩阵,简化数据结构
- 为API访问日志和错误日志搜索组件添加用户选择功能
- 调整日志搜索界面布局,将用户编号输入改为用户选择下拉框
- 移除用户类型筛选条件以简化搜索界面
- 更新工时图表配置以支持周末数据显示和新的数据结构
This commit is contained in:
dk
2026-07-14 11:43:47 +08:00
parent 27c136c906
commit 54c97c9729
9 changed files with 182 additions and 133 deletions

View File

@@ -1,7 +1,12 @@
<script setup lang="tsx">
import { computed, reactive, ref } from 'vue';
import { INFRA_OPERATE_TYPE_DICT_CODE } from '@/constants/dict';
import { fetchExportApiAccessLog, fetchGetApiAccessLog, fetchGetApiAccessLogPage } from '@/service/api';
import {
fetchExportApiAccessLog,
fetchGetApiAccessLog,
fetchGetApiAccessLogPage,
fetchGetUserSimpleList
} from '@/service/api';
import { useAuth } from '@/hooks/business/auth';
import { useUIPaginatedTable } from '@/hooks/common/table';
import BusinessTableActionCell, { type BusinessTableAction } from '@/components/custom/business-table-action-cell';
@@ -59,6 +64,7 @@ const searchParams = reactive(createSearchParams());
const detailVisible = ref(false);
const currentRow = ref<Api.SystemLog.ApiAccess.Log | null>(null);
const exporting = ref(false);
const userOptions = ref<Array<{ label: string; value: string }>>([]);
const canExport = computed(() => hasAuth(LogPermission.ApiAccessExport));
const detailSections: LogDetailSection[] = [
@@ -176,6 +182,22 @@ function handleSearch() {
reloadTable(1);
}
async function loadUserOptions() {
const { error, data: userList } = await fetchGetUserSimpleList();
if (error || !userList) {
userOptions.value = [];
return;
}
userOptions.value = userList.map((item: Api.SystemManage.UserSimple) => ({
label: item.username ? `${item.nickname}${item.username}` : item.nickname,
value: item.id
}));
}
loadUserOptions();
async function handleExport() {
exporting.value = true;
const { error, data: blob } = await fetchExportApiAccessLog(searchParams);
@@ -191,7 +213,12 @@ async function handleExport() {
<template>
<div class="h-full min-h-0 flex-col-stretch gap-16px overflow-hidden">
<ApiAccessLogSearch v-model:model="searchParams" @reset="resetSearchParams" @search="handleSearch" />
<ApiAccessLogSearch
v-model:model="searchParams"
:user-options="userOptions"
@reset="resetSearchParams"
@search="handleSearch"
/>
<ElCard class="flex-1-hidden card-wrapper" body-class="business-table-card-body">
<template #header>

View File

@@ -1,6 +1,5 @@
<script setup lang="ts">
import { computed } from 'vue';
import { SYSTEM_USER_TYPE_DICT_CODE } from '@/constants/dict';
import TableSearchFields, { type SearchField } from '@/components/custom/table-search-fields.vue';
defineOptions({ name: 'ApiAccessLogSearch' });
@@ -12,7 +11,19 @@ const emit = defineEmits<{
const model = defineModel<Api.SystemLog.ApiAccess.SearchParams>('model', { required: true });
const props = defineProps<{
userOptions: Array<{ label: string; value: string }>;
}>();
const fields = computed<SearchField[]>(() => [
{
key: 'userId',
label: '用户名',
type: 'select',
placeholder: '请选择用户名',
options: props.userOptions,
filterable: true
},
{
key: 'applicationName',
label: '应用名',
@@ -51,20 +62,14 @@ const fields = computed<SearchField[]>(() => [
},
resolveValue: value => (value === null || value === undefined ? '' : String(value))
},
{
key: 'userId',
label: '用户编号',
type: 'input',
placeholder: '请输入用户编号'
},
{
key: 'userType',
label: '用户类型',
type: 'dict',
placeholder: '请选择用户类型',
dictCode: SYSTEM_USER_TYPE_DICT_CODE,
filterable: true
},
// {
// key: 'userType',
// label: '用户类型',
// type: 'dict',
// placeholder: '请选择用户类型',
// dictCode: SYSTEM_USER_TYPE_DICT_CODE,
// filterable: true
// },
{
key: 'beginTime',
label: '请求时间',

View File

@@ -1,7 +1,12 @@
<script setup lang="tsx">
import { computed, reactive, ref } from 'vue';
import { INFRA_API_ERROR_LOG_PROCESS_STATUS_DICT_CODE } from '@/constants/dict';
import { fetchExportApiErrorLog, fetchGetApiErrorLog, fetchGetApiErrorLogPage } from '@/service/api';
import {
fetchExportApiErrorLog,
fetchGetApiErrorLog,
fetchGetApiErrorLogPage,
fetchGetUserSimpleList
} from '@/service/api';
import { useAuth } from '@/hooks/business/auth';
import { useUIPaginatedTable } from '@/hooks/common/table';
import BusinessTableActionCell, { type BusinessTableAction } from '@/components/custom/business-table-action-cell';
@@ -51,6 +56,7 @@ const searchParams = reactive(createSearchParams());
const detailVisible = ref(false);
const currentRow = ref<Api.SystemLog.ApiError.Log | null>(null);
const exporting = ref(false);
const userOptions = ref<Array<{ label: string; value: string }>>([]);
const canExport = computed(() => hasAuth(LogPermission.ApiErrorExport));
const detailSections: LogDetailSection[] = [
@@ -168,6 +174,22 @@ function handleSearch() {
reloadTable(1);
}
async function loadUserOptions() {
const { error, data: userList } = await fetchGetUserSimpleList();
if (error || !userList) {
userOptions.value = [];
return;
}
userOptions.value = userList.map((item: Api.SystemManage.UserSimple) => ({
label: item.username ? `${item.nickname}${item.username}` : item.nickname,
value: item.id
}));
}
loadUserOptions();
async function handleExport() {
exporting.value = true;
const { error, data: blob } = await fetchExportApiErrorLog(searchParams);
@@ -183,7 +205,12 @@ async function handleExport() {
<template>
<div class="h-full min-h-0 flex-col-stretch gap-16px overflow-hidden">
<ApiErrorLogSearch v-model:model="searchParams" @reset="resetSearchParams" @search="handleSearch" />
<ApiErrorLogSearch
v-model:model="searchParams"
:user-options="userOptions"
@reset="resetSearchParams"
@search="handleSearch"
/>
<ElCard class="flex-1-hidden card-wrapper" body-class="business-table-card-body">
<template #header>

View File

@@ -1,6 +1,6 @@
<script setup lang="ts">
import { computed } from 'vue';
import { INFRA_API_ERROR_LOG_PROCESS_STATUS_DICT_CODE, SYSTEM_USER_TYPE_DICT_CODE } from '@/constants/dict';
import { INFRA_API_ERROR_LOG_PROCESS_STATUS_DICT_CODE } from '@/constants/dict';
import TableSearchFields, { type SearchField } from '@/components/custom/table-search-fields.vue';
defineOptions({ name: 'ApiErrorLogSearch' });
@@ -12,7 +12,19 @@ const emit = defineEmits<{
const model = defineModel<Api.SystemLog.ApiError.SearchParams>('model', { required: true });
const props = defineProps<{
userOptions: Array<{ label: string; value: string }>;
}>();
const fields = computed<SearchField[]>(() => [
{
key: 'userId',
label: '用户名',
type: 'select',
placeholder: '请选择用户名',
options: props.userOptions,
filterable: true
},
{
key: 'applicationName',
label: '应用名',
@@ -33,20 +45,14 @@ const fields = computed<SearchField[]>(() => [
dictCode: INFRA_API_ERROR_LOG_PROCESS_STATUS_DICT_CODE,
filterable: true
},
{
key: 'userId',
label: '用户编号',
type: 'input',
placeholder: '请输入用户编号'
},
{
key: 'userType',
label: '用户类型',
type: 'dict',
placeholder: '请选择用户类型',
dictCode: SYSTEM_USER_TYPE_DICT_CODE,
filterable: true
},
// {
// key: 'userType',
// label: '用户类型',
// type: 'dict',
// placeholder: '请选择用户类型',
// dictCode: SYSTEM_USER_TYPE_DICT_CODE,
// filterable: true
// },
{
key: 'exceptionTime',
label: '异常时间',