fix(projects): 1、修复管俊提的工时填报完毕后,提示的404报错;2、调整执行协办人可以编辑协办人列表的操作;
This commit is contained in:
@@ -29,7 +29,10 @@ function isTaskMutationActor(task: Api.Project.ProjectTask, identity: TaskMutati
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isExecutionMutationActor(execution: Api.Project.ProjectExecution, identity: TaskMutationIdentity): boolean {
|
export function isExecutionMutationActor(
|
||||||
|
execution: Api.Project.ProjectExecution,
|
||||||
|
identity: TaskMutationIdentity
|
||||||
|
): boolean {
|
||||||
const { currentUserId, projectManagerUserId } = identity;
|
const { currentUserId, projectManagerUserId } = identity;
|
||||||
|
|
||||||
if (!currentUserId) return false;
|
if (!currentUserId) return false;
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ export interface CascadeTriggerPayload {
|
|||||||
|
|
||||||
export interface UseTaskCompletionCascadeOptions {
|
export interface UseTaskCompletionCascadeOptions {
|
||||||
projectId: ComputedRef<string>;
|
projectId: ComputedRef<string>;
|
||||||
executionId: ComputedRef<string>;
|
|
||||||
/** 由调用方提供:打开 StatusActionDialog 的钩子;composable 不持有 dialog 实例 */
|
/** 由调用方提供:打开 StatusActionDialog 的钩子;composable 不持有 dialog 实例 */
|
||||||
openStatusActionDialog: (task: ProjectTask, action: TaskAction, fromCascade: boolean) => void;
|
openStatusActionDialog: (task: ProjectTask, action: TaskAction, fromCascade: boolean) => void;
|
||||||
/** 从 task 的 availableActions 里找出"完成"动作;找不到返回 null */
|
/** 从 task 的 availableActions 里找出"完成"动作;找不到返回 null */
|
||||||
@@ -74,7 +73,7 @@ export function useTaskCompletionCascade(options: UseTaskCompletionCascadeOption
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const siblings = await loadSiblings(completedTask.parentTaskId);
|
const siblings = await loadSiblings(completedTask.parentTaskId, completedTask.executionId);
|
||||||
if (siblings === null) {
|
if (siblings === null) {
|
||||||
window.$message?.warning('父任务级联检查失败');
|
window.$message?.warning('父任务级联检查失败');
|
||||||
return;
|
return;
|
||||||
@@ -84,7 +83,7 @@ export function useTaskCompletionCascade(options: UseTaskCompletionCascadeOption
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const parent = await fetchTaskDetail(completedTask.parentTaskId);
|
const parent = await fetchTaskDetail(completedTask.parentTaskId, completedTask.executionId);
|
||||||
if (!parent) {
|
if (!parent) {
|
||||||
window.$message?.warning('父任务级联检查失败');
|
window.$message?.warning('父任务级联检查失败');
|
||||||
return;
|
return;
|
||||||
@@ -122,7 +121,8 @@ export function useTaskCompletionCascade(options: UseTaskCompletionCascadeOption
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await fetchGetProjectTaskWorklogPage(options.projectId.value, options.executionId.value, task.id, {
|
// 跨执行视角下 workspace 没有执行上下文,级联链路一律取任务自身的 executionId
|
||||||
|
const result = await fetchGetProjectTaskWorklogPage(options.projectId.value, task.executionId, task.id, {
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: -1
|
pageSize: -1
|
||||||
});
|
});
|
||||||
@@ -153,10 +153,10 @@ export function useTaskCompletionCascade(options: UseTaskCompletionCascadeOption
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 拉父级下所有子任务;接口失败返回 null(与"空列表"区分,由调用方降级处理) */
|
/** 拉父级下所有子任务;接口失败返回 null(与"空列表"区分,由调用方降级处理)。父子任务同执行,executionId 取被完成任务自身的值 */
|
||||||
async function loadSiblings(parentTaskId: string): Promise<ProjectTask[] | null> {
|
async function loadSiblings(parentTaskId: string, executionId: string): Promise<ProjectTask[] | null> {
|
||||||
try {
|
try {
|
||||||
const result = await fetchGetProjectTaskPage(options.projectId.value, options.executionId.value, {
|
const result = await fetchGetProjectTaskPage(options.projectId.value, executionId, {
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: -1,
|
pageSize: -1,
|
||||||
parentTaskId
|
parentTaskId
|
||||||
@@ -171,9 +171,9 @@ export function useTaskCompletionCascade(options: UseTaskCompletionCascadeOption
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 拉父任务详情;失败返回 null */
|
/** 拉父任务详情;失败返回 null */
|
||||||
async function fetchTaskDetail(taskId: string): Promise<ProjectTask | null> {
|
async function fetchTaskDetail(taskId: string, executionId: string): Promise<ProjectTask | null> {
|
||||||
try {
|
try {
|
||||||
const result = await fetchGetProjectTask(options.projectId.value, options.executionId.value, taskId);
|
const result = await fetchGetProjectTask(options.projectId.value, executionId, taskId);
|
||||||
if (result.error || !result.data) {
|
if (result.error || !result.data) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
canDeleteTaskByIdentity,
|
canDeleteTaskByIdentity,
|
||||||
canEditExecutionByIdentity,
|
canEditExecutionByIdentity,
|
||||||
canEditTaskByIdentity,
|
canEditTaskByIdentity,
|
||||||
|
isExecutionMutationActor,
|
||||||
isMutable
|
isMutable
|
||||||
} from './task-permission-rules';
|
} from './task-permission-rules';
|
||||||
|
|
||||||
@@ -54,13 +55,24 @@ export function useTaskPermissions() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 协办人弹窗内的写操作(设为负责人 / 失效 / 新增协办人)与编辑同一身份口径:执行负责人或项目负责人 */
|
||||||
function canChangeExecutionOwner(execution: Api.Project.ProjectExecution): boolean {
|
function canChangeExecutionOwner(execution: Api.Project.ProjectExecution): boolean {
|
||||||
return isMutable(execution) && hasPermission('project:execution:owner');
|
return (
|
||||||
|
isMutable(execution) &&
|
||||||
|
isExecutionMutationActor(execution, {
|
||||||
|
currentUserId: currentUserId.value,
|
||||||
|
projectManagerUserId: currentProjectManagerUserId.value
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function canManageExecutionAssignee(execution: Api.Project.ProjectExecution): boolean {
|
function canManageExecutionAssignee(execution: Api.Project.ProjectExecution): boolean {
|
||||||
return (
|
return (
|
||||||
isMutable(execution) && (hasPermission('project:execution:assignee') || currentUserId.value === execution.ownerId)
|
isMutable(execution) &&
|
||||||
|
isExecutionMutationActor(execution, {
|
||||||
|
currentUserId: currentUserId.value,
|
||||||
|
projectManagerUserId: currentProjectManagerUserId.value
|
||||||
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -539,7 +539,6 @@ async function handleOperateSubmit(payload: Api.Project.SaveProjectTaskParams) {
|
|||||||
|
|
||||||
const cascade = useTaskCompletionCascade({
|
const cascade = useTaskCompletionCascade({
|
||||||
projectId: computed(() => props.projectId),
|
projectId: computed(() => props.projectId),
|
||||||
executionId,
|
|
||||||
openStatusActionDialog: async (task, action, fromCascade) => {
|
openStatusActionDialog: async (task, action, fromCascade) => {
|
||||||
currentTask.value = task;
|
currentTask.value = task;
|
||||||
currentStatusAction.value = action;
|
currentStatusAction.value = action;
|
||||||
|
|||||||
Reference in New Issue
Block a user