style(projects): 微调
This commit is contained in:
@@ -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: () => {} });
|
||||
}
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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 且我是任务负责人时提示完成(仅单任务,不做级联)
|
||||
|
||||
Reference in New Issue
Block a user