feat(projects): 工作台部分组件调成真实数据

This commit is contained in:
2026-06-04 11:26:51 +08:00
parent acef4418d8
commit 39458386ae
33 changed files with 1033 additions and 1169 deletions

View File

@@ -13,19 +13,21 @@ import {
buildWorkbenchWeekWorklogView
} from '../homepage';
import { workbenchMyWeekWorklogMock, workbenchTeamWorklogMock } from '../mock';
import { useWorkbenchRefresh } from '../composables/use-workbench-refresh';
import WorkbenchModuleCard from './workbench-module-card.vue';
defineOptions({ name: 'WorkbenchMyWeekWorklog' });
interface Props {
editing?: boolean;
collapsed?: boolean;
}
withDefaults(defineProps<Props>(), { editing: false, collapsed: false });
defineEmits<{ (e: 'hide'): void; (e: 'toggle-collapse'): void }>();
withDefaults(defineProps<Props>(), { editing: false });
defineEmits<{ (e: 'hide'): void }>();
const router = useRouter();
const { loading, refresh } = useWorkbenchRefresh();
// EP type='week' 默认 firstDayOfWeek=7从日历点选时返回当周"周日"。
// 我们按 ISO 周(周一-周日)存储;遇到周日 +1 天再 startOf('isoWeek'),避免回退到上一周。
function resolveIsoWeekStart(weekDate: Date | null) {
@@ -302,12 +304,12 @@ watch(activeTab, async tab => {
<template>
<WorkbenchModuleCard
v-loading="loading"
title="工时"
icon="mdi:timer-outline"
:editing="editing"
:collapsed="collapsed"
@hide="$emit('hide')"
@toggle-collapse="$emit('toggle-collapse')"
@refresh="refresh"
>
<div class="ww-tabbar">
<ElTabs v-model="activeTab" class="ww-tabs">
@@ -327,7 +329,7 @@ watch(activeTab, async tab => {
</div>
<!-- ============ 我的工时 tab ============ -->
<div v-show="activeTab === 'my'">
<div v-show="activeTab === 'my'" class="ww-tab-content">
<template v-if="myView">
<div class="ww-headline">
<div class="ww-section-title">
@@ -375,7 +377,7 @@ watch(activeTab, async tab => {
</div>
<!-- ============ 团队工时 tab ============ -->
<div v-show="activeTab === 'team'">
<div v-show="activeTab === 'team'" class="ww-tab-content">
<template v-if="teamView">
<div class="tw-kpis">
<div class="tw-kpi">
@@ -444,6 +446,19 @@ watch(activeTab, async tab => {
gap: 12px;
margin-bottom: 10px;
border-bottom: 1px solid var(--el-border-color-lighter);
flex-shrink: 0;
}
/* tab 内容区填充剩余高度flex 列布局,图表区自适应撑满,不写死高度、不内部滚动 */
.ww-tab-content {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
overflow: hidden;
}
.ww-tab-content :deep(.el-empty) {
margin: auto;
}
.ww-tabs {
flex: 1;
@@ -468,12 +483,15 @@ watch(activeTab, async tab => {
align-items: center;
gap: 16px;
margin-bottom: 10px;
flex-shrink: 0;
}
.ww-grid {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
gap: 16px;
flex: 1;
min-height: 0;
}
@media (width <= 520px) {
.ww-grid {
@@ -488,6 +506,7 @@ watch(activeTab, async tab => {
display: flex;
flex-direction: column;
min-width: 0;
min-height: 0;
}
.ww-section-title {
@@ -508,7 +527,8 @@ watch(activeTab, async tab => {
.ww-pie-wrap {
position: relative;
width: 100%;
height: 280px;
flex: 1;
min-height: 0;
}
.ww-pie {
width: 100%;
@@ -517,7 +537,8 @@ watch(activeTab, async tab => {
.ww-bar {
width: 100%;
height: 280px;
flex: 1;
min-height: 0;
}
.ww-bar-legend {
display: flex;
@@ -526,6 +547,7 @@ watch(activeTab, async tab => {
margin-top: 8px;
font-size: 11px;
color: var(--el-text-color-secondary);
flex-shrink: 0;
}
.ww-bar-legend__item {
display: inline-flex;
@@ -547,6 +569,7 @@ watch(activeTab, async tab => {
padding-top: 10px;
border-top: 1px solid var(--el-border-color-lighter);
font-size: 13px;
flex-shrink: 0;
}
.ww-footer b {
font-weight: 700;
@@ -570,6 +593,7 @@ watch(activeTab, async tab => {
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 10px;
margin-bottom: 12px;
flex-shrink: 0;
}
.tw-kpi {
display: flex;
@@ -609,7 +633,8 @@ watch(activeTab, async tab => {
.tw-bar {
width: 100%;
height: 240px;
flex: 1;
min-height: 0;
}
.tw-footer {
@@ -619,6 +644,7 @@ watch(activeTab, async tab => {
margin-top: 8px;
font-size: 12px;
color: var(--el-text-color-secondary);
flex-shrink: 0;
}
.tw-footer b {
color: var(--el-text-color-primary);