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 { GridItem, GridLayout } from 'grid-layout-plus';
|
||||||
import { useWorkbenchStore } from '@/store/modules/workbench';
|
import { useWorkbenchStore } from '@/store/modules/workbench';
|
||||||
import { type WorkbenchModuleKey, useWorkbenchModules } from './composables/use-workbench-modules';
|
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 type { WorkbenchGridItem } from './composables/workbench-layout-types';
|
||||||
import WorkbenchBanner from './modules/workbench-banner.vue';
|
import WorkbenchBanner from './modules/workbench-banner.vue';
|
||||||
import WorkbenchEditOverlay from './modules/workbench-edit-overlay.vue';
|
import WorkbenchEditOverlay from './modules/workbench-edit-overlay.vue';
|
||||||
@@ -40,6 +41,9 @@ const libraryOpen = ref(false);
|
|||||||
// 暴露给 workbench-module-card 内的"编辑布局"按钮,避免每个 widget 都透传 emit
|
// 暴露给 workbench-module-card 内的"编辑布局"按钮,避免每个 widget 都透传 emit
|
||||||
provide('workbenchEnterEditing', () => workbench.enterEditing());
|
provide('workbenchEnterEditing', () => workbench.enterEditing());
|
||||||
|
|
||||||
|
// 工作台内联填报工时的跨 widget 刷新信号:填报方 notify、工时类 widget watch revision 重拉
|
||||||
|
provideWorkbenchWorklogSignal();
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
workbench.load();
|
workbench.load();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { OBJECT_CONTEXT_QUERY_KEY } from '@/constants/object-context';
|
|||||||
import { fetchGetMyWorklogWeek, fetchGetTeamWorklogWeek } from '@/service/api';
|
import { fetchGetMyWorklogWeek, fetchGetTeamWorklogWeek } from '@/service/api';
|
||||||
import { type ECOption, useEcharts } from '@/hooks/common/echarts';
|
import { type ECOption, useEcharts } from '@/hooks/common/echarts';
|
||||||
import { getWorkbenchItemColor } from '../composables/use-workbench-colors';
|
import { getWorkbenchItemColor } from '../composables/use-workbench-colors';
|
||||||
|
import { useWorkbenchWorklogSignal } from '../composables/use-workbench-worklog-signal';
|
||||||
import {
|
import {
|
||||||
type WorkbenchWorklogDistributionItem,
|
type WorkbenchWorklogDistributionItem,
|
||||||
buildWorkbenchTeamWorklogView,
|
buildWorkbenchTeamWorklogView,
|
||||||
@@ -86,6 +87,10 @@ const activeTab = ref<TabKey>('my');
|
|||||||
// 周切换(含初始)拉取两 tab 数据;竞态由 loadWorklogWeek 内请求序号兜底
|
// 周切换(含初始)拉取两 tab 数据;竞态由 loadWorklogWeek 内请求序号兜底
|
||||||
watch(selectedWeekStart, loadWorklogWeek, { immediate: true });
|
watch(selectedWeekStart, loadWorklogWeek, { immediate: true });
|
||||||
|
|
||||||
|
// 同一工作台内(如 todo 面板)弹层填报工时不切路由、不触发 onActivated,靠信号驱动重拉当前周
|
||||||
|
const { revision: worklogRevision } = useWorkbenchWorklogSignal();
|
||||||
|
watch(worklogRevision, loadWorklogWeek);
|
||||||
|
|
||||||
// 工作台路由 keepAlive:切回时组件不重挂载,immediate watch 不再触发。
|
// 工作台路由 keepAlive:切回时组件不重挂载,immediate watch 不再触发。
|
||||||
// 每次激活归位到当前周并重拉;首次激活与挂载同拍(上面 immediate 已拉过),跳过避免双发
|
// 每次激活归位到当前周并重拉;首次激活与挂载同拍(上面 immediate 已拉过),跳过避免双发
|
||||||
let activatedOnce = false;
|
let activatedOnce = false;
|
||||||
@@ -262,14 +267,8 @@ function buildTeamBarOption(): ECOption {
|
|||||||
return `<div style="font-weight:600;margin-bottom:4px">${name} · ${total}h</div>${lines}`;
|
return `<div style="font-weight:600;margin-bottom:4px">${name} · ${total}h</div>${lines}`;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
legend: {
|
// 不显示项目图例:团队参与项目繁杂,图例会很长很乱;项目明细由 tooltip 悬浮呈现
|
||||||
type: 'scroll',
|
grid: { left: 32, right: 12, top: 16, bottom: 24, containLabel: false },
|
||||||
bottom: 0,
|
|
||||||
itemWidth: 10,
|
|
||||||
itemHeight: 10,
|
|
||||||
textStyle: { color: '#6b7280', fontSize: 11 }
|
|
||||||
},
|
|
||||||
grid: { left: 32, right: 12, top: 16, bottom: 40, containLabel: false },
|
|
||||||
xAxis: {
|
xAxis: {
|
||||||
type: 'category',
|
type: 'category',
|
||||||
data: v.members.map(m => m.memberName),
|
data: v.members.map(m => m.memberName),
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ import {
|
|||||||
sortWorkbenchTodoItemsByPriority
|
sortWorkbenchTodoItemsByPriority
|
||||||
} from '../homepage';
|
} from '../homepage';
|
||||||
import { useWorkbenchRefresh } from '../composables/use-workbench-refresh';
|
import { useWorkbenchRefresh } from '../composables/use-workbench-refresh';
|
||||||
|
import { useWorkbenchWorklogSignal } from '../composables/use-workbench-worklog-signal';
|
||||||
import WorkbenchModuleCard from './workbench-module-card.vue';
|
import WorkbenchModuleCard from './workbench-module-card.vue';
|
||||||
import IconMdiCheckCircleOutline from '~icons/mdi/check-circle-outline';
|
import IconMdiCheckCircleOutline from '~icons/mdi/check-circle-outline';
|
||||||
import IconMdiClipboardEditOutline from '~icons/mdi/clipboard-edit-outline';
|
import IconMdiClipboardEditOutline from '~icons/mdi/clipboard-edit-outline';
|
||||||
@@ -80,6 +81,9 @@ const { routerPushByKey } = useRouterPush();
|
|||||||
const authStore = useAuthStore();
|
const authStore = useAuthStore();
|
||||||
const currentUserId = computed(() => authStore.userInfo.userId || '');
|
const currentUserId = computed(() => authStore.userInfo.userId || '');
|
||||||
|
|
||||||
|
// 工时填报在工作台内弹层完成(不切路由),需广播给「我的工时」widget 重拉
|
||||||
|
const { notify: notifyWorklogChanged } = useWorkbenchWorklogSignal();
|
||||||
|
|
||||||
const { loading, refresh } = useWorkbenchRefresh(async () => {
|
const { loading, refresh } = useWorkbenchRefresh(async () => {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
loadMyTaskItems(),
|
loadMyTaskItems(),
|
||||||
@@ -290,6 +294,7 @@ async function handlePersonalStatusSubmit(reason: string | null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handlePersonalWorklogChanged() {
|
async function handlePersonalWorklogChanged() {
|
||||||
|
notifyWorklogChanged();
|
||||||
await loadPersonalTodoItems();
|
await loadPersonalTodoItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,6 +328,7 @@ async function openTaskWorklog(item: WorkbenchTodoItem) {
|
|||||||
|
|
||||||
// 填报会联动任务进度/状态(如 auto_start),变更后刷新任务列表
|
// 填报会联动任务进度/状态(如 auto_start),变更后刷新任务列表
|
||||||
async function handleTaskWorklogChanged(payload: WorklogChangedPayload) {
|
async function handleTaskWorklogChanged(payload: WorklogChangedPayload) {
|
||||||
|
notifyWorklogChanged();
|
||||||
await loadMyTaskItems();
|
await loadMyTaskItems();
|
||||||
|
|
||||||
// 与任务工作区联动一致:进度填到 100 且我是任务负责人时提示完成(仅单任务,不做级联)
|
// 与任务工作区联动一致:进度填到 100 且我是任务负责人时提示完成(仅单任务,不做级联)
|
||||||
|
|||||||
Reference in New Issue
Block a user