style(projects): 微调

This commit is contained in:
2026-06-22 20:47:20 +08:00
parent 4a7f54b0ed
commit b1d52b852f
4 changed files with 51 additions and 8 deletions

View File

@@ -0,0 +1,34 @@
import { type InjectionKey, type Ref, inject, provide, ref } from 'vue';
interface WorkbenchWorklogSignal {
/** 递增版本号:工时类 widget watch 它触发重拉 */
revision: Ref<number>;
/** 任一 widget 内联填报/修改工时后调用,广播给同一工作台内的工时类 widget */
notify: () => void;
}
const WORKBENCH_WORKLOG_SIGNAL: InjectionKey<WorkbenchWorklogSignal> = 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: () => {} });
}

View File

@@ -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();
});

View File

@@ -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<TabKey>('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 `<div style="font-weight:600;margin-bottom:4px">${name} · ${total}h</div>${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),

View File

@@ -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 且我是任务负责人时提示完成(仅单任务,不做级联)