From b1d52b852fc0af4ec4e19808f54a82f304ff56f8 Mon Sep 17 00:00:00 2001 From: hongawen <83944980@qq.com> Date: Mon, 22 Jun 2026 20:47:20 +0800 Subject: [PATCH] =?UTF-8?q?style(projects):=20=E5=BE=AE=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../use-workbench-worklog-signal.ts | 34 +++++++++++++++++++ src/views/workbench/index.vue | 4 +++ .../modules/workbench-my-week-worklog.vue | 15 ++++---- .../modules/workbench-todo-panel.vue | 6 ++++ 4 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 src/views/workbench/composables/use-workbench-worklog-signal.ts diff --git a/src/views/workbench/composables/use-workbench-worklog-signal.ts b/src/views/workbench/composables/use-workbench-worklog-signal.ts new file mode 100644 index 0000000..d90e101 --- /dev/null +++ b/src/views/workbench/composables/use-workbench-worklog-signal.ts @@ -0,0 +1,34 @@ +import { type InjectionKey, type Ref, inject, provide, ref } from 'vue'; + +interface WorkbenchWorklogSignal { + /** 递增版本号:工时类 widget watch 它触发重拉 */ + revision: Ref; + /** 任一 widget 内联填报/修改工时后调用,广播给同一工作台内的工时类 widget */ + notify: () => void; +} + +const WORKBENCH_WORKLOG_SIGNAL: InjectionKey = Symbol('workbench-worklog-signal'); + +/** + * 工作台内联填报工时的跨 widget 刷新信号。 + * + * todo 面板等 widget 可在工作台路由内弹层填报工时,不触发工作台 keepAlive 的 onActivated, + * 「我的工时」widget 因此停在旧数据。用 provide/inject 在工作台根广播一个版本号, + * 填报方 notify、展示方 watch revision 重拉,作用域限定在工作台子树、不进全局 store。 + */ +export function provideWorkbenchWorklogSignal(): WorkbenchWorklogSignal { + const revision = ref(0); + const signal: WorkbenchWorklogSignal = { + revision, + notify: () => { + revision.value += 1; + } + }; + provide(WORKBENCH_WORKLOG_SIGNAL, signal); + return signal; +} + +/** widget 内消费:notify 上报变更、revision 供 watch 重拉;脱离工作台根时退化为无操作 */ +export function useWorkbenchWorklogSignal(): WorkbenchWorklogSignal { + return inject(WORKBENCH_WORKLOG_SIGNAL, { revision: ref(0), notify: () => {} }); +} diff --git a/src/views/workbench/index.vue b/src/views/workbench/index.vue index 8ff50f1..6cbec11 100644 --- a/src/views/workbench/index.vue +++ b/src/views/workbench/index.vue @@ -5,6 +5,7 @@ import { ElMessageBox } from 'element-plus'; import { GridItem, GridLayout } from 'grid-layout-plus'; import { useWorkbenchStore } from '@/store/modules/workbench'; import { type WorkbenchModuleKey, useWorkbenchModules } from './composables/use-workbench-modules'; +import { provideWorkbenchWorklogSignal } from './composables/use-workbench-worklog-signal'; import type { WorkbenchGridItem } from './composables/workbench-layout-types'; import WorkbenchBanner from './modules/workbench-banner.vue'; import WorkbenchEditOverlay from './modules/workbench-edit-overlay.vue'; @@ -40,6 +41,9 @@ const libraryOpen = ref(false); // 暴露给 workbench-module-card 内的"编辑布局"按钮,避免每个 widget 都透传 emit provide('workbenchEnterEditing', () => workbench.enterEditing()); +// 工作台内联填报工时的跨 widget 刷新信号:填报方 notify、工时类 widget watch revision 重拉 +provideWorkbenchWorklogSignal(); + onMounted(() => { workbench.load(); }); diff --git a/src/views/workbench/modules/workbench-my-week-worklog.vue b/src/views/workbench/modules/workbench-my-week-worklog.vue index 7f71d71..ab070c5 100644 --- a/src/views/workbench/modules/workbench-my-week-worklog.vue +++ b/src/views/workbench/modules/workbench-my-week-worklog.vue @@ -6,6 +6,7 @@ import { OBJECT_CONTEXT_QUERY_KEY } from '@/constants/object-context'; import { fetchGetMyWorklogWeek, fetchGetTeamWorklogWeek } from '@/service/api'; import { type ECOption, useEcharts } from '@/hooks/common/echarts'; import { getWorkbenchItemColor } from '../composables/use-workbench-colors'; +import { useWorkbenchWorklogSignal } from '../composables/use-workbench-worklog-signal'; import { type WorkbenchWorklogDistributionItem, buildWorkbenchTeamWorklogView, @@ -86,6 +87,10 @@ const activeTab = ref('my'); // 周切换(含初始)拉取两 tab 数据;竞态由 loadWorklogWeek 内请求序号兜底 watch(selectedWeekStart, loadWorklogWeek, { immediate: true }); +// 同一工作台内(如 todo 面板)弹层填报工时不切路由、不触发 onActivated,靠信号驱动重拉当前周 +const { revision: worklogRevision } = useWorkbenchWorklogSignal(); +watch(worklogRevision, loadWorklogWeek); + // 工作台路由 keepAlive:切回时组件不重挂载,immediate watch 不再触发。 // 每次激活归位到当前周并重拉;首次激活与挂载同拍(上面 immediate 已拉过),跳过避免双发 let activatedOnce = false; @@ -262,14 +267,8 @@ function buildTeamBarOption(): ECOption { return `
${name} · ${total}h
${lines}`; } }, - legend: { - type: 'scroll', - bottom: 0, - itemWidth: 10, - itemHeight: 10, - textStyle: { color: '#6b7280', fontSize: 11 } - }, - grid: { left: 32, right: 12, top: 16, bottom: 40, containLabel: false }, + // 不显示项目图例:团队参与项目繁杂,图例会很长很乱;项目明细由 tooltip 悬浮呈现 + grid: { left: 32, right: 12, top: 16, bottom: 24, containLabel: false }, xAxis: { type: 'category', data: v.members.map(m => m.memberName), diff --git a/src/views/workbench/modules/workbench-todo-panel.vue b/src/views/workbench/modules/workbench-todo-panel.vue index 7863c86..79aebfc 100644 --- a/src/views/workbench/modules/workbench-todo-panel.vue +++ b/src/views/workbench/modules/workbench-todo-panel.vue @@ -50,6 +50,7 @@ import { sortWorkbenchTodoItemsByPriority } from '../homepage'; import { useWorkbenchRefresh } from '../composables/use-workbench-refresh'; +import { useWorkbenchWorklogSignal } from '../composables/use-workbench-worklog-signal'; import WorkbenchModuleCard from './workbench-module-card.vue'; import IconMdiCheckCircleOutline from '~icons/mdi/check-circle-outline'; import IconMdiClipboardEditOutline from '~icons/mdi/clipboard-edit-outline'; @@ -80,6 +81,9 @@ const { routerPushByKey } = useRouterPush(); const authStore = useAuthStore(); const currentUserId = computed(() => authStore.userInfo.userId || ''); +// 工时填报在工作台内弹层完成(不切路由),需广播给「我的工时」widget 重拉 +const { notify: notifyWorklogChanged } = useWorkbenchWorklogSignal(); + const { loading, refresh } = useWorkbenchRefresh(async () => { await Promise.all([ loadMyTaskItems(), @@ -290,6 +294,7 @@ async function handlePersonalStatusSubmit(reason: string | null) { } async function handlePersonalWorklogChanged() { + notifyWorklogChanged(); await loadPersonalTodoItems(); } @@ -323,6 +328,7 @@ async function openTaskWorklog(item: WorkbenchTodoItem) { // 填报会联动任务进度/状态(如 auto_start),变更后刷新任务列表 async function handleTaskWorklogChanged(payload: WorklogChangedPayload) { + notifyWorklogChanged(); await loadMyTaskItems(); // 与任务工作区联动一致:进度填到 100 且我是任务负责人时提示完成(仅单任务,不做级联)