mirror of
https://github.com/kuaifan/dootask.git
synced 2026-04-23 02:08:51 +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 获取任务详细描述
|
* @api {get} api/project/task/content 获取任务详细描述
|
||||||
*
|
*
|
||||||
|
|||||||
@ -143,6 +143,41 @@ class ProjectTaskRelation extends AbstractModel
|
|||||||
return true;
|
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
|
public static function recordMentionsFromMessage(WebSocketDialogMsg $msg): void
|
||||||
{
|
{
|
||||||
if ($msg->type !== 'text') {
|
if ($msg->type !== 'text') {
|
||||||
|
|||||||
@ -376,6 +376,10 @@
|
|||||||
class="related-status archived">
|
class="related-status archived">
|
||||||
{{$L('已归档')}}
|
{{$L('已归档')}}
|
||||||
</span>
|
</span>
|
||||||
|
<Icon
|
||||||
|
type="md-close"
|
||||||
|
class="related-remove"
|
||||||
|
@click.native.stop="removeRelatedTask(item)"/>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
@ -1597,6 +1601,26 @@ export default {
|
|||||||
this.$store.dispatch('openTask', item.related_task_id);
|
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) {
|
onTaskRelationUpdate(taskId) {
|
||||||
if (!taskId || taskId !== this.taskId) {
|
if (!taskId || taskId !== this.taskId) {
|
||||||
return;
|
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
|
* @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 {
|
.ivu-tag {
|
||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user