feat: 添加子任务升级为主任务功能

This commit is contained in:
kuaifan 2025-10-24 05:34:23 +00:00
parent 1a6abf4e1b
commit e2296a6f64
5 changed files with 220 additions and 6 deletions

View File

@ -45,6 +45,7 @@ use App\Models\ProjectTaskVisibilityUser;
use App\Models\ProjectTaskTemplate;
use App\Models\ProjectTag;
use App\Models\ProjectTaskRelation;
use App\Observers\ProjectTaskObserver;
/**
* @apiDefine project
@ -2230,6 +2231,131 @@ class ProjectController extends AbstractController
return Base::retSuccess('添加成功', $data);
}
/**
* @api {get} api/project/task/upgrade 36. 子任务升级为主任务
*
* @apiDescription 需要token身份项目、任务负责人
* @apiVersion 1.0.0
* @apiGroup project
* @apiName task__upgrade
*
* @apiParam {Number} task_id 子任务ID
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
*/
public function task__upgrade()
{
$user = User::auth();
//
$task_id = intval(Request::input('task_id'));
//
$task = ProjectTask::userTask($task_id, true, true, ['taskUser']);
if ($task->parent_id == 0) {
return Base::retError('当前任务已是主任务');
}
//
$project = Project::userProject($task->project_id);
ProjectPermission::userTaskPermission($project, ProjectPermission::TASK_MOVE, $task);
//
$parentTask = ProjectTask::withTrashed()->find($task->parent_id);
$visibilityUserids = [];
if ($task->visibility == 3) {
$visibilityUserids = ProjectTaskVisibilityUser::whereTaskId($task->id)->pluck('userid')->toArray();
if (empty($visibilityUserids) && $parentTask) {
$visibilityUserids = ProjectTaskVisibilityUser::whereTaskId($parentTask->id)->pluck('userid')->toArray();
}
}
//
DB::transaction(function () use ($task, $parentTask, $visibilityUserids) {
$task->lockForUpdate();
$task->parent_id = 0;
if ($parentTask) {
$task->p_level = $parentTask->p_level;
$task->p_name = $parentTask->p_name;
$task->p_color = $parentTask->p_color;
}
$task->save();
ProjectTaskUser::whereTaskId($task->id)->update(['task_pid' => $task->id]);
if ($task->visibility == 3 && !empty($visibilityUserids)) {
ProjectTaskVisibilityUser::whereTaskId($task->id)->delete();
foreach (array_unique($visibilityUserids) as $userid) {
if (!$userid) {
continue;
}
ProjectTaskVisibilityUser::createInstance([
'project_id' => $task->project_id,
'task_id' => $task->id,
'userid' => $userid,
])->save();
}
}
if ($parentTask) {
$parentTask->addLog("子任务升级为主任务", [
'subtask' => [
'id' => $task->id,
'name' => $task->name,
],
]);
}
$task->addLog("升级为主任务");
});
//
$task->refresh()->loadMissing(['project', 'taskUser']);
if ($task->visibility != 1) {
ProjectTaskObserver::visibilityUpdate($task);
}
$taskData = ProjectTask::oneTask($task->id);
$parentData = null;
if ($parentTask && !$parentTask->trashed()) {
$parentTask->refresh()->loadMissing(['project', 'taskUser']);
$parentData = ProjectTask::oneTask($parentTask->id);
}
//
$taskArray = $taskData ? $taskData->toArray() : [];
$parentArray = $parentData ? $parentData->toArray() : null;
if ($taskArray) {
$task->pushMsg('update', $taskArray);
}
if ($parentArray && $parentTask) {
$parentTask->pushMsg('update', $parentArray);
}
if ($parentTask && !$parentTask->trashed()) {
$mentionRelation = ProjectTaskRelation::updateOrCreate(
[
'task_id' => $task->id,
'related_task_id' => $parentTask->id,
'direction' => ProjectTaskRelation::DIRECTION_MENTIONED_BY,
],
[
'userid' => $user->userid ?? null,
]
);
$mentionedByRelation = ProjectTaskRelation::updateOrCreate(
[
'task_id' => $parentTask->id,
'related_task_id' => $task->id,
'direction' => ProjectTaskRelation::DIRECTION_MENTION,
],
[
'userid' => $user->userid ?? null,
]
);
if ($mentionRelation->wasRecentlyCreated || $mentionRelation->wasChanged()) {
$task->pushMsg('relation', null, null, false);
}
if ($mentionedByRelation->wasRecentlyCreated || $mentionedByRelation->wasChanged()) {
$parentTask->pushMsg('relation', null, null, false);
}
}
//
return Base::retSuccess('操作成功', [
'task' => $taskArray,
'parent' => $parentArray,
]);
}
/**
* @api {post} api/project/task/update 35. 修改任务、子任务
*

View File

@ -920,4 +920,8 @@ URL格式不正确
收藏记录不存在
修改备注成功
请输入修改备注
备注最多支持(*)个字符
备注最多支持(*)个字符
当前任务已是主任务
子任务升级为主任务
升级为主任务

View File

@ -2214,3 +2214,8 @@ AI 未生成内容
暂无共同群组
(*)个
查看更多...
子任务升级为主任务
升级为主任务
升主任务
你确定要将子任务【(*)】升级为主任务吗?

View File

@ -86,11 +86,18 @@
</EDropdownItem>
</template>
</template>
<EDropdownItem v-else-if="operationShow" command="remove" :divided="turns.length > 0">
<div class="item">
<Icon type="md-trash" />{{$L('删除')}}
</div>
</EDropdownItem>
<template v-else-if="operationShow">
<EDropdownItem command="upgrade" :divided="turns.length > 0">
<div class="item">
<Icon type="md-arrow-round-up" />{{$L('升主任务')}}
</div>
</EDropdownItem>
<EDropdownItem command="remove">
<div class="item hover-del">
<Icon type="md-trash" />{{$L('删除')}}
</div>
</EDropdownItem>
</template>
</ul>
</li>
</EDropdownMenu>
@ -342,6 +349,10 @@ export default {
this.$refs.forwarder.onSelection()
break;
case 'upgrade':
this.upgradeSubtask();
break;
case 'archived':
case 'remove':
this.archivedOrRemoveTask(command);
@ -391,6 +402,33 @@ export default {
})
},
upgradeSubtask() {
if (this.loadIng) {
return;
}
$A.modalConfirm({
title: '升级为主任务',
content: `你确定要将子任务【${this.task.name}】升级为主任务吗?`,
loading: true,
onOk: () => {
if (this.loadIng) {
return;
}
return new Promise((resolve, reject) => {
this.$store.dispatch("taskConvertToMain", this.task.id).then(({data, msg}) => {
$A.messageSuccess(msg);
this.hide();
this.$store.dispatch("openTask", data?.task?.id || this.task.id);
resolve();
}).catch(({msg}) => {
$A.modalError(msg);
reject();
});
})
}
});
},
archivedOrRemoveTask(type) {
let typeDispatch = 'removeTask';
let typeName = '删除';

View File

@ -2276,6 +2276,47 @@ export default {
});
},
/**
* 子任务升级为主任务
* @param dispatch
* @param data Number|JSONObject{task_id}
* @returns {Promise<unknown>}
*/
taskConvertToMain({dispatch}, data) {
return new Promise(function (resolve, reject) {
if (/^\d+$/.test(data)) {
data = {task_id: data}
}
if ($A.runNum(data.task_id) === 0) {
reject({msg: 'Parameter error'});
return;
}
dispatch("setLoad", {
key: `task-${data.task_id}`,
delay: 300
})
dispatch("call", {
url: 'project/task/upgrade',
data,
}).then(result => {
const {task, parent} = result.data || {};
if (task) {
dispatch("saveTask", task);
}
if (parent) {
dispatch("saveTask", parent);
}
resolve(result)
}).catch(e => {
console.warn(e);
dispatch("getTaskOne", data.task_id).catch(() => {})
reject(e)
}).finally(_ => {
dispatch("cancelLoad", `task-${data.task_id}`)
});
});
},
/**
* 获取任务详细描述
* @param state