refactor(projects): 1 工作台缓存优化;2 工作日志总工时下进度显示
This commit is contained in:
@@ -56,9 +56,6 @@ async function handleSubmit() {
|
||||
</template>
|
||||
</ElInput>
|
||||
</ElFormItem>
|
||||
<div class="pb-18px">
|
||||
<ElCheckbox>{{ $t('page.login.pwdLogin.rememberMe') }}</ElCheckbox>
|
||||
</div>
|
||||
<ElButton
|
||||
type="primary"
|
||||
size="large"
|
||||
|
||||
@@ -31,6 +31,8 @@ interface Props {
|
||||
userOptions: Api.SystemManage.UserSimple[];
|
||||
taskOptions: Api.Project.ProjectTask[];
|
||||
plannedEndShortcuts?: PlannedEndShortcutOffset[];
|
||||
/** 编辑态是否可内联管理协办人(对应 canManageTaskAssignee);false 时只读回显 */
|
||||
canManageAssignee?: boolean;
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
@@ -39,6 +41,7 @@ interface Emits {
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
defaultParentTaskId: null,
|
||||
canManageAssignee: false,
|
||||
plannedEndShortcuts: () => [
|
||||
{ text: '三天', days: 3 },
|
||||
{ text: '一星期', days: 7 },
|
||||
@@ -94,6 +97,56 @@ const dialogTitle = computed(() => {
|
||||
|
||||
const selectableParentTasks = computed(() => props.taskOptions.filter(item => item.id !== props.rowData?.id));
|
||||
|
||||
/** 编辑态 + 任务已开始(statusCode 离开 pending)→ 负责人锁定不可切换 */
|
||||
const ownerLocked = computed(() => {
|
||||
const status = props.rowData?.statusCode;
|
||||
return props.mode === 'edit' && Boolean(status) && status !== 'pending';
|
||||
});
|
||||
|
||||
/**
|
||||
* 负责人下拉选项 = 执行协办人池 ∪ 当前任务负责人(兜底)。
|
||||
* owner 可能已不在执行协办人池里,用任务自带 ownerNickname 兜底回显,避免锁定态显示成裸 userId。
|
||||
*/
|
||||
const ownerSelectOptions = computed<Api.SystemManage.UserSimple[]>(() => {
|
||||
const ownerId = props.rowData?.ownerId;
|
||||
if (props.mode === 'create' || !ownerId || props.userOptions.some(item => item.id === ownerId)) {
|
||||
return props.userOptions;
|
||||
}
|
||||
return [...props.userOptions, { id: ownerId, nickname: props.rowData?.ownerNickname || ownerId }];
|
||||
});
|
||||
|
||||
/** 编辑态无协办人管理权限时只读回显(create 恒可交互) */
|
||||
const assigneeSelectDisabled = computed(() => props.mode !== 'create' && !props.canManageAssignee);
|
||||
|
||||
const assigneePlaceholder = computed(() => (assigneeSelectDisabled.value ? '暂无协办人' : '请选择协办人'));
|
||||
|
||||
/**
|
||||
* 候选项 = 执行协办人池 ∪ 当前任务已有协办人中已不在池里的成员 ∪ 当前任务负责人。
|
||||
* 已有协办人用任务自带 nickname 兜底回显,避免协办人被移出执行后在编辑态显示成裸 userId;
|
||||
* 负责人并入是为了让 owner 在协办人下拉里以「负责人」标记展示(不可移除),用 ownerNickname 兜底。
|
||||
*/
|
||||
const assigneeSelectOptions = computed(() => {
|
||||
const options = props.userOptions.map(item => ({ id: item.id, nickname: item.nickname }));
|
||||
const known = new Set(options.map(item => item.id));
|
||||
|
||||
if (props.mode !== 'create' && props.rowData) {
|
||||
props.rowData.assignees?.forEach(assignee => {
|
||||
if (assignee.userId && !known.has(assignee.userId)) {
|
||||
options.push({ id: assignee.userId, nickname: assignee.nickname || assignee.userId });
|
||||
known.add(assignee.userId);
|
||||
}
|
||||
});
|
||||
|
||||
const ownerId = props.rowData.ownerId;
|
||||
if (ownerId && !known.has(ownerId)) {
|
||||
options.push({ id: ownerId, nickname: props.rowData.ownerNickname || ownerId });
|
||||
known.add(ownerId);
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
});
|
||||
|
||||
/** 左栏容器 ref:用其高度动态驱动右侧富文本,让两栏视觉等高 */
|
||||
const leftColRef = ref<HTMLElement>();
|
||||
const editorHeight = ref<string>('45vh');
|
||||
@@ -212,14 +265,11 @@ function normalizeAssigneeIds(ids: string[]) {
|
||||
const autoOwnerAssigneeId = ref<string | null>(null);
|
||||
|
||||
/**
|
||||
* UI 层把 owner 也加进 model.assigneeUserIds,让协办人 select 视觉上显示 owner
|
||||
* (体验上让用户感知"负责人也在团队里")。提交时由 normalizeAssigneeIds 过滤掉 owner。
|
||||
* UI 层把 owner 也并进 model.assigneeUserIds,让协办人 select 视觉上显示 owner(带「负责人」标记、不可移除),
|
||||
* 让用户感知"负责人也在团队里"。create / edit 同口径;提交时由 normalizeAssigneeIds 过滤掉 owner。
|
||||
* 切换 owner 时按 previousOwnerId(上一任已并入的 owner)移除旧值,避免旧负责人残留在协办人里。
|
||||
*/
|
||||
function syncOwnerAssignee(ownerId: string | null, previousOwnerId: string | null = autoOwnerAssigneeId.value) {
|
||||
if (props.mode !== 'create') {
|
||||
return;
|
||||
}
|
||||
|
||||
const current = Array.from(new Set((model.assigneeUserIds ?? []).filter(Boolean)));
|
||||
const withoutPrevious = previousOwnerId ? current.filter(userId => userId !== previousOwnerId) : current;
|
||||
model.assigneeUserIds = ownerId ? Array.from(new Set([...withoutPrevious, ownerId])) : withoutPrevious;
|
||||
@@ -246,17 +296,16 @@ async function handleConfirm() {
|
||||
attachments: [...model.attachments]
|
||||
};
|
||||
|
||||
if (props.mode === 'create') {
|
||||
payload.assigneeUserIds = normalizeAssigneeIds(model.assigneeUserIds);
|
||||
}
|
||||
// create:作为创建入参直接生效;edit:父级据此与原协办人 diff 出加入/失效调用(更新接口本身忽略此字段)
|
||||
payload.assigneeUserIds = normalizeAssigneeIds(model.assigneeUserIds);
|
||||
|
||||
emit('submit', payload);
|
||||
}
|
||||
|
||||
function handleAssigneeChange(value: string[]) {
|
||||
// UI 层保持 owner 不掉队;提交时再由 normalizeAssigneeIds 过滤
|
||||
// UI 层保持 owner 不掉队(owner 选项 disabled,正常无法取消,这里兜底);提交时再由 normalizeAssigneeIds 过滤
|
||||
const cleaned = Array.from(new Set(value.filter(Boolean)));
|
||||
if (props.mode === 'create' && model.ownerId && !cleaned.includes(model.ownerId)) {
|
||||
if (model.ownerId && !cleaned.includes(model.ownerId)) {
|
||||
cleaned.push(model.ownerId);
|
||||
}
|
||||
model.assigneeUserIds = cleaned;
|
||||
@@ -276,7 +325,10 @@ function applyRowDataToModel() {
|
||||
const row = props.rowData;
|
||||
model.parentTaskId = props.mode === 'create' ? (props.defaultParentTaskId ?? null) : row?.parentTaskId || null;
|
||||
applyBasicFieldsFromRow(row);
|
||||
model.assigneeUserIds = [];
|
||||
// 编辑态回显任务现有协办人 + 并入负责人(owner 仅做视觉展示,提交时过滤);创建态留空
|
||||
const baseAssignees = props.mode === 'create' ? [] : (row?.assignees ?? []).map(item => item.userId);
|
||||
model.assigneeUserIds =
|
||||
model.ownerId && !baseAssignees.includes(model.ownerId) ? [...baseAssignees, model.ownerId] : baseAssignees;
|
||||
model.attachments = row?.attachments ? [...row.attachments] : [];
|
||||
}
|
||||
|
||||
@@ -288,7 +340,8 @@ watch(
|
||||
}
|
||||
|
||||
applyRowDataToModel();
|
||||
autoOwnerAssigneeId.value = null;
|
||||
// 记录已自动并入协办人列表的 owner,供后续切换负责人时移除上一任
|
||||
autoOwnerAssigneeId.value = model.ownerId || null;
|
||||
|
||||
await nextTick();
|
||||
// 让附件组件把当前 model 视作 original,必须在 model 填充之后
|
||||
@@ -300,8 +353,9 @@ watch(
|
||||
|
||||
watch(
|
||||
() => model.ownerId,
|
||||
(ownerId, previousOwnerId) => {
|
||||
syncOwnerAssignee(ownerId || null, previousOwnerId || null);
|
||||
ownerId => {
|
||||
// previousOwnerId 取 autoOwnerAssigneeId(上一任已并入的 owner),避免跨任务残留误删协办人
|
||||
syncOwnerAssignee(ownerId || null);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -365,35 +419,33 @@ defineExpose({
|
||||
</ElFormItem>
|
||||
|
||||
<ElFormItem label="负责人" prop="ownerId">
|
||||
<BusinessUserSelect v-model="model.ownerId" :options="userOptions" placeholder="请选择负责人" />
|
||||
</ElFormItem>
|
||||
|
||||
<ElFormItem v-if="mode === 'create'" label="协办人" prop="assigneeUserIds">
|
||||
<ElSelect
|
||||
v-model="model.assigneeUserIds"
|
||||
multiple
|
||||
filterable
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
:max-collapse-tags="2"
|
||||
class="w-full"
|
||||
placeholder="请选择协办人"
|
||||
@change="handleAssigneeChange"
|
||||
>
|
||||
<ElOption
|
||||
v-for="item in userOptions"
|
||||
:key="item.id"
|
||||
:label="item.id === model.ownerId ? `${item.nickname}(负责人)` : item.nickname"
|
||||
:value="item.id"
|
||||
:disabled="item.id === model.ownerId"
|
||||
/>
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
<ElFormItem v-else>
|
||||
<template #label>
|
||||
<template v-if="ownerLocked" #label>
|
||||
<span class="business-form-label-with-tip">
|
||||
<ElTooltip
|
||||
content="如需调整协办人,请关闭此弹层后点击列表「协办人」按钮。"
|
||||
content="任务已开始,负责人不可变更。"
|
||||
popper-class="business-form-label-tooltip"
|
||||
placement="top-start"
|
||||
>
|
||||
<span class="business-form-label-tip">
|
||||
<icon-fe:question />
|
||||
</span>
|
||||
</ElTooltip>
|
||||
<span>负责人</span>
|
||||
</span>
|
||||
</template>
|
||||
<BusinessUserSelect
|
||||
v-model="model.ownerId"
|
||||
:options="ownerSelectOptions"
|
||||
:disabled="ownerLocked"
|
||||
placeholder="请选择负责人"
|
||||
/>
|
||||
</ElFormItem>
|
||||
|
||||
<ElFormItem label="协办人" prop="assigneeUserIds">
|
||||
<template v-if="mode !== 'create'" #label>
|
||||
<span class="business-form-label-with-tip">
|
||||
<ElTooltip
|
||||
content="协办人的加入 / 失效变更历史可在列表「协办人」按钮中查看。"
|
||||
popper-class="business-form-label-tooltip"
|
||||
placement="top-start"
|
||||
>
|
||||
@@ -405,15 +457,25 @@ defineExpose({
|
||||
</span>
|
||||
</template>
|
||||
<ElSelect
|
||||
:model-value="model.assigneeUserIds"
|
||||
v-model="model.assigneeUserIds"
|
||||
multiple
|
||||
disabled
|
||||
filterable
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
:max-collapse-tags="2"
|
||||
:disabled="assigneeSelectDisabled"
|
||||
class="w-full"
|
||||
placeholder="暂无协办人"
|
||||
/>
|
||||
:placeholder="assigneePlaceholder"
|
||||
@change="handleAssigneeChange"
|
||||
>
|
||||
<ElOption
|
||||
v-for="item in assigneeSelectOptions"
|
||||
:key="item.id"
|
||||
:label="item.id === model.ownerId ? `${item.nickname}(负责人)` : item.nickname"
|
||||
:value="item.id"
|
||||
:disabled="item.id === model.ownerId"
|
||||
/>
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
|
||||
<ElFormItem label="计划开始日期" prop="plannedStartDate">
|
||||
|
||||
@@ -63,9 +63,30 @@ const totalHoursText = computed(() => {
|
||||
return `${totalHours.value.toFixed(1)} h`;
|
||||
});
|
||||
|
||||
// 每个 userId 在 records 中"最近一条" worklog 的 progressRate。
|
||||
// records 与 panel 的 externalList 同源,已由后端按 end_date desc, id desc 排序,第一条即最近。
|
||||
const latestProgressByUser = computed(() => {
|
||||
const map = new Map<string, number>();
|
||||
for (const item of records.value) {
|
||||
if (!map.has(item.userId)) {
|
||||
map.set(item.userId, item.progressRate);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
});
|
||||
|
||||
// 单个用户在工时明细里的进度文案:责任人取任务整体进度,协办人取最近 worklog 进度,从未填报标记"未填报"
|
||||
function resolveUserProgressText(rowIsOwner: boolean, latest: number | undefined) {
|
||||
if (rowIsOwner) return getProgressText(props.task?.progressRate);
|
||||
if (latest !== undefined) return getProgressText(latest);
|
||||
return '未填报';
|
||||
}
|
||||
|
||||
// "总工时" hover 展示按用户分组的明细(查看全部开放,所有人都看得到)。
|
||||
// 候选范围:责任人 + 所有协办人 + records 中出现过的用户(兜底已退出协办人);
|
||||
// 没填过工时的显示 0h
|
||||
// 没填过工时的显示 0h。进度口径对齐「填报人」筛选:
|
||||
// - 责任人:任务整体进度(责任人填报会回写任务进度)
|
||||
// - 协办人/其他:本人最近一条 worklog 进度;从未填报显示"未填报"
|
||||
const hoursByUserDetail = computed(() => {
|
||||
const sumMap = new Map<string, number>();
|
||||
for (const item of records.value) {
|
||||
@@ -89,11 +110,20 @@ const hoursByUserDetail = computed(() => {
|
||||
pushUser(item.userId, item.userNickname);
|
||||
}
|
||||
|
||||
const arr = userIds.map(userId => ({
|
||||
userId,
|
||||
name: nicknameMap.get(userId) || userId,
|
||||
hours: sumMap.get(userId) ?? 0
|
||||
}));
|
||||
const arr = userIds.map(userId => {
|
||||
const rowIsOwner = userId === props.task?.ownerId;
|
||||
const latest = latestProgressByUser.value.get(userId);
|
||||
// 责任人恒显示任务进度;协办人取最近 worklog 进度,未填报则标记
|
||||
const hasProgress = rowIsOwner || latest !== undefined;
|
||||
return {
|
||||
userId,
|
||||
name: nicknameMap.get(userId) || userId,
|
||||
isOwner: rowIsOwner,
|
||||
hours: sumMap.get(userId) ?? 0,
|
||||
progressText: resolveUserProgressText(rowIsOwner, latest),
|
||||
hasProgress
|
||||
};
|
||||
});
|
||||
|
||||
// 责任人置顶,其余按工时降序(0h 自然落在最后)
|
||||
arr.sort((a, b) => {
|
||||
@@ -192,12 +222,18 @@ watch(
|
||||
<div v-for="item in hoursByUserDetail" :key="item.userId" class="task-worklog-content__hours-detail-row">
|
||||
<span
|
||||
class="task-worklog-content__hours-detail-name"
|
||||
:class="{ 'is-owner': item.userId === task?.ownerId }"
|
||||
:class="{ 'is-owner': item.isOwner }"
|
||||
:title="item.name"
|
||||
>
|
||||
{{ item.name }}
|
||||
</span>
|
||||
<span class="task-worklog-content__hours-detail-hours">{{ item.hours.toFixed(1) }}h</span>
|
||||
<span class="task-worklog-content__hours-detail-meta">
|
||||
<span class="task-worklog-content__hours-detail-hours">{{ item.hours.toFixed(1) }}h</span>
|
||||
<span class="task-worklog-content__hours-detail-sep">·</span>
|
||||
<span class="task-worklog-content__hours-detail-progress" :class="{ 'is-empty': !item.hasProgress }">
|
||||
{{ item.progressText }}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -325,9 +361,28 @@ watch(
|
||||
}
|
||||
}
|
||||
|
||||
.task-worklog-content__hours-detail-meta {
|
||||
display: inline-flex;
|
||||
align-items: baseline;
|
||||
gap: 4px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.task-worklog-content__hours-detail-hours {
|
||||
flex: 0 0 auto;
|
||||
color: var(--el-color-primary);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.task-worklog-content__hours-detail-sep {
|
||||
color: var(--el-text-color-placeholder);
|
||||
}
|
||||
|
||||
.task-worklog-content__hours-detail-progress {
|
||||
color: var(--el-text-color-secondary);
|
||||
|
||||
&.is-empty {
|
||||
color: var(--el-text-color-placeholder);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -116,6 +116,14 @@ const currentAssigneeTask = ref<Api.Project.ProjectTask | null>(null);
|
||||
const currentAssignees = ref<Api.Project.TaskAssigneeRef[]>([]);
|
||||
const assigneesLoading = ref(false);
|
||||
|
||||
/** 编辑弹层内联失效协办人时使用的默认原因(无提示,统一审计文案) */
|
||||
const TASK_ASSIGNEE_INLINE_INACTIVE_REASON = '编辑任务时调整协办人';
|
||||
|
||||
/** 编辑弹层是否允许内联管理协办人(与列表「协办人」按钮同权限口径) */
|
||||
const canManageCurrentTaskAssignee = computed(() =>
|
||||
currentTask.value ? canManageTaskAssignee(currentTask.value) : false
|
||||
);
|
||||
|
||||
const worklogDialogVisible = ref(false);
|
||||
const worklogDialogTask = ref<Api.Project.ProjectTask | null>(null);
|
||||
|
||||
@@ -466,25 +474,61 @@ async function handleStatusAction(row: Api.Project.ProjectTask, action: TaskStat
|
||||
statusActionVisible.value = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑态把弹层选中的协办人与任务原协办人做 diff,翻译成加入 / 失效调用。
|
||||
* 更新任务接口本身忽略 assigneeUserIds,协办人只能走独立端点;失效用默认原因、无提示。
|
||||
* 返回是否全部成功(含无变更)。
|
||||
*/
|
||||
async function applyTaskAssigneeDiff(task: Api.Project.ProjectTask, nextUserIds: string[]) {
|
||||
const originalAssignees = task.assignees ?? [];
|
||||
const nextSet = new Set(nextUserIds);
|
||||
const originalSet = new Set(originalAssignees.map(item => item.userId));
|
||||
|
||||
const toAdd = nextUserIds.filter(userId => !originalSet.has(userId));
|
||||
const toInactivate = originalAssignees.filter(item => !nextSet.has(item.userId));
|
||||
|
||||
if (!toAdd.length && !toInactivate.length) return true;
|
||||
|
||||
const requests = [
|
||||
...toAdd.map(userId => fetchCreateProjectTaskAssignee(props.projectId, task.executionId, task.id, { userId })),
|
||||
...toInactivate.map(assignee =>
|
||||
fetchInactiveProjectTaskAssignee(props.projectId, task.executionId, task.id, assignee.id, {
|
||||
reason: TASK_ASSIGNEE_INLINE_INACTIVE_REASON
|
||||
})
|
||||
)
|
||||
];
|
||||
|
||||
const results = await Promise.all(requests);
|
||||
return results.every(item => !item.error);
|
||||
}
|
||||
|
||||
async function handleOperateSubmit(payload: Api.Project.SaveProjectTaskParams) {
|
||||
// 新建必须锚定到具体执行;编辑跟随任务自身的 executionId(跨执行视角下 props.execution 为 null)
|
||||
let assigneeOk = true;
|
||||
|
||||
if (operateMode.value === 'create') {
|
||||
// 新建必须锚定到具体执行
|
||||
if (!props.execution) return;
|
||||
} else if (!currentTask.value) {
|
||||
return;
|
||||
const result = await fetchCreateProjectTask(props.projectId, props.execution.id, payload);
|
||||
if (result.error) return;
|
||||
window.$message?.success('任务创建成功');
|
||||
} else {
|
||||
// 编辑跟随任务自身的 executionId(跨执行视角下 props.execution 为 null)
|
||||
const task = currentTask.value;
|
||||
if (!task) return;
|
||||
|
||||
// 协办人不走更新接口,单独 diff;其余字段照常更新
|
||||
const { assigneeUserIds = [], ...taskData } = payload;
|
||||
const result = await fetchUpdateProjectTask(props.projectId, task.executionId, { taskId: task.id, data: taskData });
|
||||
if (result.error) return;
|
||||
|
||||
assigneeOk = !canManageTaskAssignee(task) || (await applyTaskAssigneeDiff(task, assigneeUserIds));
|
||||
if (assigneeOk) {
|
||||
window.$message?.success('任务更新成功');
|
||||
} else {
|
||||
window.$message?.warning('任务已更新,部分协办人调整未成功,请在「协办人」中确认');
|
||||
}
|
||||
}
|
||||
|
||||
const result =
|
||||
operateMode.value === 'create'
|
||||
? await fetchCreateProjectTask(props.projectId, props.execution!.id, payload)
|
||||
: await fetchUpdateProjectTask(props.projectId, currentTask.value!.executionId, {
|
||||
taskId: currentTask.value!.id,
|
||||
data: payload
|
||||
});
|
||||
|
||||
if (result.error) return;
|
||||
|
||||
window.$message?.success(operateMode.value === 'create' ? '任务创建成功' : '任务更新成功');
|
||||
await taskOperateDialogRef.value?.commit();
|
||||
operateVisible.value = false;
|
||||
await Promise.all([refreshTableData(), loadTaskStatusBoard()]);
|
||||
@@ -918,6 +962,7 @@ defineExpose({
|
||||
:default-parent-task-id="presetParentTaskId"
|
||||
:user-options="executionAssigneeOptions"
|
||||
:task-options="taskOptions"
|
||||
:can-manage-assignee="canManageCurrentTaskAssignee"
|
||||
@submit="handleOperateSubmit"
|
||||
/>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
import { computed, onActivated, ref, watch } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { RDMS_REQ_PRIORITY_DICT_CODE } from '@/constants/dict';
|
||||
import { OBJECT_CONTEXT_QUERY_KEY } from '@/constants/object-context';
|
||||
@@ -31,7 +31,8 @@ const { loading, refresh } = useWorkbenchRefresh(async () => {
|
||||
items.value = buildWorkbenchMyExecutionItems(data?.list ?? []);
|
||||
});
|
||||
|
||||
onMounted(refresh);
|
||||
// 工作台路由 keepAlive:切回不重挂,用 onActivated 替代 onMounted,每次激活重拉(首挂也会触发,不漏首屏)
|
||||
onActivated(refresh);
|
||||
|
||||
// 按项目归类:未完成执行数多的项目在前;项目内按计划结束日升序(更紧的在前)
|
||||
const groups = computed<Array<{ projectId: string; projectName: string; items: MyExecutionItem[] }>>(() => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
import { computed, onActivated, ref, watch } from 'vue';
|
||||
import { fetchGetMyOwnedProjectPage, fetchGetMyParticipatedProjectPage } from '@/service/api';
|
||||
import { useRouterPush } from '@/hooks/common/router';
|
||||
import {
|
||||
@@ -46,7 +46,8 @@ const { loading, refresh } = useWorkbenchRefresh(async () => {
|
||||
}
|
||||
});
|
||||
|
||||
onMounted(refresh);
|
||||
// 工作台路由 keepAlive:切回不重挂,用 onActivated 替代 onMounted,每次激活重拉(首挂也会触发,不漏首屏)
|
||||
onActivated(refresh);
|
||||
|
||||
const currentOwnedId = ref<string>('');
|
||||
watch(ownedItems, list => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { computed, onActivated, ref } from 'vue';
|
||||
import { fetchGetMyTeamLoad } from '@/service/api';
|
||||
import { getWorkbenchItemColor } from '../composables/use-workbench-colors';
|
||||
import {
|
||||
@@ -45,7 +45,8 @@ function toTeamLoadSource(member: Api.Project.TeamLoadMember, index: number): Wo
|
||||
|
||||
const view = computed(() => buildWorkbenchTeamLoadView({ members: teamLoadMembers.value.map(toTeamLoadSource) }));
|
||||
|
||||
onMounted(loadTeamLoad);
|
||||
// 工作台路由 keepAlive:切回不重挂,用 onActivated 替代 onMounted,每次激活经 refresh 重拉(首挂也会触发,不漏首屏)
|
||||
onActivated(refresh);
|
||||
|
||||
const LEVEL_LABEL: Record<WorkbenchTeamLoadLevel, string> = {
|
||||
high: '高负载',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { type Component, computed, markRaw, onMounted, ref, watch } from 'vue';
|
||||
import { type Component, computed, markRaw, onActivated, ref, watch } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import type { RouteKey } from '@elegant-router/types';
|
||||
import { OBJECT_CONTEXT_QUERY_KEY } from '@/constants/object-context';
|
||||
@@ -865,14 +865,8 @@ function getDeadlineToneClass(item: WorkbenchTodoItem) {
|
||||
return 'workbench-todo__deadline--slate';
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await Promise.all([
|
||||
loadMyTaskItems(),
|
||||
loadPersonalTodoItems(),
|
||||
loadOvertimeApprovalItems(),
|
||||
loadWorkReportApprovalItems()
|
||||
]);
|
||||
});
|
||||
// 工作台路由 keepAlive:切回不重挂,用 onActivated 替代 onMounted,每次激活经 refresh 重拉(首挂也会触发,不漏首屏)
|
||||
onActivated(refresh);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
Reference in New Issue
Block a user