mirror of
https://github.com/kuaifan/dootask.git
synced 2026-04-23 10:18:41 +00:00
feat(task): 增加解除任务关联功能
支持用户在任务详情中解除误关联的任务,权限与修改任务一致(项目负责人、任务负责人、任务协助人)。 - 新增 ProjectTaskRelation::deleteRelation() 删除双向关联并推送 WebSocket - 新增 API POST /api/project/task/related/delete 接口 - 前端关联任务列表 hover 显示删除按钮,点击确认后解除关联 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
4068966700
commit
04708cedb6
@ -1987,6 +1987,44 @@ class ProjectController extends AbstractController
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {post} api/project/task/related/delete 删除任务关联
|
||||
*
|
||||
* @apiDescription 需要token身份(限:项目、任务负责人)
|
||||
* @apiVersion 1.0.0
|
||||
* @apiGroup project
|
||||
* @apiName task__related__delete
|
||||
*
|
||||
* @apiParam {Number} task_id 任务ID
|
||||
* @apiParam {Number} related_task_id 关联任务ID
|
||||
*
|
||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||
* @apiSuccess {Object} data 返回数据
|
||||
*/
|
||||
public function task__related__delete()
|
||||
{
|
||||
User::auth();
|
||||
//
|
||||
$task_id = intval(Request::input('task_id'));
|
||||
$related_task_id = intval(Request::input('related_task_id'));
|
||||
if ($task_id <= 0 || $related_task_id <= 0) {
|
||||
return Base::retError('参数错误');
|
||||
}
|
||||
//
|
||||
$task = ProjectTask::userTask($task_id);
|
||||
//
|
||||
$project = Project::userProject($task->project_id);
|
||||
ProjectPermission::userTaskPermission($project, ProjectPermission::TASK_UPDATE, $task);
|
||||
//
|
||||
$success = ProjectTaskRelation::deleteRelation($task_id, $related_task_id);
|
||||
if (!$success) {
|
||||
return Base::retError('关联不存在');
|
||||
}
|
||||
//
|
||||
return Base::retSuccess('操作成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* @api {get} api/project/task/content 获取任务详细描述
|
||||
*
|
||||
|
||||
@ -143,6 +143,41 @@ class ProjectTaskRelation extends AbstractModel
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除双向任务关联
|
||||
*
|
||||
* @param int $taskId 任务ID
|
||||
* @param int $relatedTaskId 关联任务ID
|
||||
* @return bool 是否删除成功
|
||||
*/
|
||||
public static function deleteRelation(int $taskId, int $relatedTaskId): bool
|
||||
{
|
||||
// 删除正向关联
|
||||
$deleted1 = static::whereTaskId($taskId)
|
||||
->whereRelatedTaskId($relatedTaskId)
|
||||
->delete();
|
||||
|
||||
// 删除反向关联
|
||||
$deleted2 = static::whereTaskId($relatedTaskId)
|
||||
->whereRelatedTaskId($taskId)
|
||||
->delete();
|
||||
|
||||
if ($deleted1 || $deleted2) {
|
||||
// 推送关联更新
|
||||
$sourceTask = ProjectTask::with('project')->find($taskId);
|
||||
$targetTask = ProjectTask::with('project')->find($relatedTaskId);
|
||||
if ($sourceTask?->project) {
|
||||
$sourceTask->pushMsg('relation', null, null, false);
|
||||
}
|
||||
if ($targetTask?->project) {
|
||||
$targetTask->pushMsg('relation', null, null, false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function recordMentionsFromMessage(WebSocketDialogMsg $msg): void
|
||||
{
|
||||
if ($msg->type !== 'text') {
|
||||
|
||||
@ -376,6 +376,10 @@
|
||||
class="related-status archived">
|
||||
{{$L('已归档')}}
|
||||
</span>
|
||||
<Icon
|
||||
type="md-close"
|
||||
class="related-remove"
|
||||
@click.native.stop="removeRelatedTask(item)"/>
|
||||
</li>
|
||||
</ul>
|
||||
</FormItem>
|
||||
@ -1597,6 +1601,26 @@ export default {
|
||||
this.$store.dispatch('openTask', item.related_task_id);
|
||||
},
|
||||
|
||||
removeRelatedTask(item) {
|
||||
if (!item || !item.related_task_id) {
|
||||
return;
|
||||
}
|
||||
$A.modalConfirm({
|
||||
title: '温馨提示',
|
||||
content: '确定要解除与任务 #' + item.related_task_id + ' 的关联吗?',
|
||||
onOk: () => {
|
||||
this.$store.dispatch('deleteTaskRelated', {
|
||||
taskId: this.taskId,
|
||||
relatedTaskId: item.related_task_id,
|
||||
}).then(() => {
|
||||
this.loadRelatedTasks();
|
||||
}).catch(({msg}) => {
|
||||
$A.modalError(msg);
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
onTaskRelationUpdate(taskId) {
|
||||
if (!taskId || taskId !== this.taskId) {
|
||||
return;
|
||||
|
||||
13
resources/assets/js/store/actions.js
vendored
13
resources/assets/js/store/actions.js
vendored
@ -2635,6 +2635,19 @@ export default {
|
||||
});
|
||||
},
|
||||
|
||||
deleteTaskRelated({commit, dispatch}, {taskId, relatedTaskId}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
dispatch("call", {
|
||||
url: 'project/task/related/delete',
|
||||
data: {task_id: taskId, related_task_id: relatedTaskId},
|
||||
}).then(({msg}) => {
|
||||
commit('task/related/clear', taskId);
|
||||
commit('task/related/clear', relatedTaskId);
|
||||
resolve(msg);
|
||||
}).catch(reject);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 添加子任务
|
||||
* @param dispatch
|
||||
|
||||
@ -674,6 +674,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
.related-remove {
|
||||
flex-shrink: 0;
|
||||
font-size: 14px;
|
||||
color: #c5c8ce;
|
||||
cursor: pointer;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s ease, color 0.2s ease;
|
||||
margin-left: 4px;
|
||||
|
||||
&:hover {
|
||||
color: #ed4014;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover .related-remove {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.ivu-tag {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user