diff --git a/app/Http/Controllers/Api/ProjectController.php b/app/Http/Controllers/Api/ProjectController.php index bb4242856..1db3a301a 100755 --- a/app/Http/Controllers/Api/ProjectController.php +++ b/app/Http/Controllers/Api/ProjectController.php @@ -16,6 +16,7 @@ use App\Models\ProjectLog; use App\Models\ProjectTask; use App\Models\ProjectTaskFile; use App\Models\ProjectTaskFlowChange; +use App\Models\ProjectTaskUser; use App\Models\ProjectUser; use App\Models\User; use App\Models\WebSocketDialog; @@ -880,8 +881,17 @@ class ProjectController extends AbstractController public function task__lists() { $user = User::auth(); - // + + // 任务可见性 + $project_ids = Project::whereUserid($user->userid)->pluck('id')->toArray(); // 负责人项目ids + $main_task_ids = ProjectTask::whereIn('project_id', $project_ids)->pluck('id')->toArray(); // 负责人项目任务ids + $other_task_ids = ProjectTaskUser::whereUserid($user->userid)->whereColumn('task_id', '=', 'task_pid')->whereNotIn('project_id', $project_ids)->pluck('task_id')->toArray(); // 非负责人项目任务ids + $all_visible_task_ids = ProjectTask::whereIsAllVisible(1)->pluck('id')->toArray(); // 所有人可见项目ids + $one_task_ids = array_merge($main_task_ids, $other_task_ids); + $visibility_task_ids = array_merge($one_task_ids, $all_visible_task_ids); + $builder = ProjectTask::with(['taskUser', 'taskTag']); + $builder->whereIn("project_tasks.id", $visibility_task_ids); // $parent_id = intval(Request::input('parent_id')); $project_id = intval(Request::input('project_id')); @@ -1326,17 +1336,26 @@ class ProjectController extends AbstractController */ public function task__one() { - User::auth(); + $user = User::auth(); // $task_id = intval(Request::input('task_id')); $archived = Request::input('archived', 'no'); // $isArchived = str_replace(['all', 'yes', 'no'], [null, false, true], $archived); $task = ProjectTask::userTask($task_id, $isArchived, true, false, ['taskUser', 'taskTag']); + // 项目可见性 + $project_userid = Project::whereId($task->project_id)->value('userid'); // 项目负责人 + if ($task->is_all_visible != 1 && $user->userid != $project_userid) { + $visibleUserids = ProjectTaskUser::whereTaskId($task_id)->pluck('userid')->toArray(); + if (!in_array($user->userid, $visibleUserids)) { + return Base::retError('无任务权限'); + } + } // $data = $task->toArray(); $data['project_name'] = $task->project?->name; $data['column_name'] = $task->projectColumn?->name; + $data['visibility_appointor'] = $task->is_all_visible==1 ? [0] : ProjectTaskUser::whereTaskId($task_id)->whereOwner(2)->pluck('userid'); return Base::retSuccess('success', $data); } @@ -1542,7 +1561,7 @@ class ProjectController extends AbstractController */ public function task__add() { - User::auth(); + $user = User::auth(); // $data = Request::input(); $project_id = intval($data['project_id']); @@ -1587,6 +1606,17 @@ class ProjectController extends AbstractController $data = $data->toArray(); $data['new_column'] = $newColumn; } + + + if ($data['is_all_visible'] == 1) { + $data['is_visible'] = 1; + } else { + $projectOwner = Project::whereId($data['project_id'])->pluck('userid')->toArray(); // 项目负责人 + $taskOwnerAndAssists = ProjectTaskUser::select(['userid', 'owner'])->whereTaskId($data['id'])->pluck('userid')->toArray(); + $visibleIds = array_merge($projectOwner, $taskOwnerAndAssists); + $data['is_visible'] = in_array($user->userid, $visibleIds) ? 1 : 0; + } + $task->pushMsg('add', $data); $task->taskPush(null, 0); return Base::retSuccess('添加成功', $data); @@ -1648,6 +1678,7 @@ class ProjectController extends AbstractController * @apiParam {String} [content] 任务详情(子任务不支持) * @apiParam {String} [color] 背景色(子任务不支持) * @apiParam {Array} [assist] 修改协助人员(子任务不支持) + * @apiParam {Array} [visibility_appointor] 修改可见性人员 * * @apiParam {Number} [p_level] 优先级相关(子任务不支持) * @apiParam {String} [p_name] 优先级相关(子任务不支持) @@ -1664,17 +1695,31 @@ class ProjectController extends AbstractController { User::auth(); // - $data = Request::input(); - $task_id = intval($data['task_id']); + $param = Request::input(); + $task_id = intval($param['task_id']); // $task = ProjectTask::userTask($task_id, true, true, 2); // 更新任务 $updateMarking = []; - $task->updateTask($data, $updateMarking); + $task->updateTask($param, $updateMarking); // $data = ProjectTask::oneTask($task->id)->toArray(); $data['update_marking'] = $updateMarking ?: json_decode('{}'); + $data['visibility_appointor'] = $data['is_all_visible'] == 1 ? [0] : ProjectTaskUser::whereTaskId($task->id)->whereOwner(2)->pluck('userid'); $task->pushMsg('update', $data); + // 可见性推送 + if (Arr::exists($param, 'visibility_appointor')) { + if ($data['is_all_visible'] == 1) { + $task->pushMsgVisibleAdd($data); + } + if ($data['is_all_visible'] == 0) { + if ($param['visibility_appointor']) { + $task->pushMsgVisibleUpdate($data); + } else { + $task->pushMsgVisibleRemove(); + } + } + } // return Base::retSuccess('修改成功', $data); } diff --git a/app/Models/ProjectTask.php b/app/Models/ProjectTask.php index 6b319bfa5..3ac4e0e62 100644 --- a/app/Models/ProjectTask.php +++ b/app/Models/ProjectTask.php @@ -370,6 +370,18 @@ class ProjectTask extends AbstractModel $p_color = $data['p_color']; $top = intval($data['top']); $userid = User::userid(); + $visibility_appoint = $data['visibility_appoint']; + $visibility_appointor = $data['visibility_appointor']; + // 可见性 + $visibility_userids = []; + $is_all_visible = 0; + if ($visibility_appoint) { + if (in_array(0, $visibility_appointor)) { + $is_all_visible = 1; + } else { + $visibility_userids = $visibility_appointor; + } + } // if (ProjectTask::whereProjectId($project_id) ->whereNull('project_tasks.complete_at') @@ -398,6 +410,7 @@ class ProjectTask extends AbstractModel 'p_level' => $p_level, 'p_name' => $p_name, 'p_color' => $p_color, + 'is_all_visible' => $is_all_visible ]); if ($content) { $task->desc = Base::getHtml($content, 100); @@ -462,7 +475,7 @@ class ProjectTask extends AbstractModel } } // - return AbstractModel::transaction(function() use ($assist, $times, $subtasks, $content, $owner, $task) { + return AbstractModel::transaction(function() use ($assist, $times, $subtasks, $content, $owner, $task, $visibility_userids) { $task->save(); $owner = array_values(array_unique($owner)); foreach ($owner as $uid) { @@ -484,6 +497,17 @@ class ProjectTask extends AbstractModel 'owner' => 0, ])->save(); } + + foreach ($visibility_userids as $uid) { + ProjectTaskUser::createInstance([ + 'project_id' => $task->project_id, + 'task_id' => $task->id, + 'task_pid' => $task->parent_id ?: $task->id, + 'userid' => $uid, + 'owner' => 2, + ])->save(); + } + if ($content) { ProjectTaskContent::createInstance([ 'project_id' => $task->project_id, @@ -691,6 +715,26 @@ class ProjectTask extends AbstractModel $updateMarking['is_update_project'] = true; $this->syncDialogUser(); } + // 可见性 + if (Arr::exists($data, 'visibility_appointor')) { + if (in_array(0, $data['visibility_appointor'])) { + ProjectTask::whereId($data['task_id'])->update(['is_all_visible' => 1]); + } else { + ProjectTask::whereId($data['task_id'])->update(['is_all_visible' => 0]); + // 覆盖 + ProjectTaskUser::whereTaskId($data['task_id'])->whereOwner(2)->delete(); + foreach ($data['visibility_appointor'] as $uid) { + ProjectTaskUser::createInstance([ + 'project_id' => $this->project_id, + 'task_id' => $this->id, + 'task_pid' => $this->parent_id ?: $this->id, + 'userid' => $uid, + 'owner' => 2, + ])->save(); + } + + } + } // 计划时间(原则:子任务时间在主任务时间内) if (Arr::exists($data, 'times')) { $oldAt = [Carbon::parse($this->start_at), Carbon::parse($this->end_at)]; @@ -1372,6 +1416,8 @@ class ProjectTask extends AbstractModel $userids = $this->project->relationUserids(); } elseif (!is_array($userid)) { $userids = [$userid]; + } elseif (is_array($userid)) { + $userids = $userid; } // $array = []; @@ -1391,8 +1437,10 @@ class ProjectTask extends AbstractModel ]; } // 协助人 - $assists = $taskUser->pluck('userid')->toArray(); - $assists = array_intersect($userids, array_diff($assists, $owners)); +// $assists = $taskUser->pluck('userid')->toArray(); +// $assists = array_intersect($userids, array_diff($assists, $owners)); + $assists = $taskUser->where('owner', 0)->pluck('userid')->toArray(); + $assists = array_intersect($userids, $assists); if ($assists) { $array[] = [ 'userid' => array_values($assists), @@ -1403,13 +1451,21 @@ class ProjectTask extends AbstractModel ]; } // 项目成员(其他人) - $userids = array_diff($userids, $owners, $assists); + if ($data['is_all_visible'] == 1) { + // 全部可见 + $userids = array_diff($userids, $owners, $assists); + } else { + // 指定可见 + $visible = $taskUser->where('owner', 2)->pluck('userid')->toArray(); + $userids = $visible; + } $data = array_merge($data, [ 'owner' => 0, 'assist' => 0, ]); } } + // $array[] = [ 'userid' => array_values($userids), 'data' => $data @@ -1430,6 +1486,116 @@ class ProjectTask extends AbstractModel } } + /** + * 添加可见性任务 推送 + * @param array|self $data 发送内容,默认为[id, parent_id, project_id, column_id, dialog_id] + */ + public function pushMsgVisibleAdd($data = null) + { + if (!$this->project) { + return; + } + if ($data === null) { + $data = [ + 'id' => $this->id, + 'parent_id' => $this->parent_id, + 'project_id' => $this->project_id, + 'column_id' => $this->column_id, + 'dialog_id' => $this->dialog_id, + ]; + } elseif ($data instanceof self) { + $data = $data->toArray(); + } + // + $array = []; + if ($this->is_all_visible == 0) { + $userids = ProjectTaskUser::select(['userid', 'owner'])->whereTaskId($this->id)->pluck('userid')->toArray(); + } else { + $userids = ProjectUser::whereProjectId($this->project_id)->pluck('userid')->toArray(); // 项目成员 + } + // + $array[] = [ + 'userid' => array_values($userids), + 'data' => $data + ]; + // + foreach ($array as $item) { + $params = [ +// 'ignoreFd' => Request::header('fd'), + 'ignoreFd' => '0', + 'userid' => array_values($item), + 'msg' => [ + 'type' => 'projectTask', + 'action' => 'add', + 'data' => $item['data'], + ] + ]; + $task = new PushTask($params, false); + Task::deliver($task); + } + } + + /** + * 删除可见性任务 推送 + * @param string $action + * @param array|self $data 发送内容,默认为[id, parent_id, project_id, column_id, dialog_id] + */ + public function pushMsgVisibleRemove($data = null) + { + if (!$this->project) { + return; + } + if ($data === null) { + $data = [ + 'id' => $this->id, + 'parent_id' => $this->parent_id, + 'project_id' => $this->project_id, + 'column_id' => $this->column_id, + 'dialog_id' => $this->dialog_id, + ]; + } elseif ($data instanceof self) { + $data = $data->toArray(); + } + // + $array = []; + // 项目成员 与 项目负责人,任务负责人、协助人的差集 + $projectUserids = ProjectUser::whereProjectId($this->project_id)->pluck('userid')->toArray(); // 项目成员 + $projectOwner = Project::whereId($this->project_id)->pluck('userid')->toArray(); // 项目负责人 + $taskOwnerAndAssists = ProjectTaskUser::select(['userid', 'owner'])->whereIn('owner', [0, 1])->whereTaskId($this->id)->pluck('userid')->toArray(); + $userids = array_diff($projectUserids, $projectOwner, $taskOwnerAndAssists); + // + $array[] = [ + 'userid' => array_values($userids), + 'data' => $data + ]; + // + foreach ($array as $item) { + $params = [ +// 'ignoreFd' => Request::header('fd'), + 'ignoreFd' => '0', + 'userid' => array_values($item), + 'msg' => [ + 'type' => 'projectTask', + 'action' => 'delete', + 'data' => $item['data'], + ] + ]; + $task = new PushTask($params, false); + Task::deliver($task); + } + } + + /** + * 更新可见性任务 推送 + * @param array|self $data 发送内容,默认为[id, parent_id, project_id, column_id, dialog_id] + */ + public function pushMsgVisibleUpdate($data) + { + $this->pushMsgVisibleRemove(); + usleep(300); + $this->pushMsgVisibleAdd($data); + } + /** * 任务提醒 * @param $userids diff --git a/app/Tasks/PushTask.php b/app/Tasks/PushTask.php index 6f506f734..2e02d0acf 100644 --- a/app/Tasks/PushTask.php +++ b/app/Tasks/PushTask.php @@ -149,7 +149,7 @@ class PushTask extends AbstractTask if (!is_array($userid)) { $userid = [$userid]; } - foreach ($userid as $uid) { + foreach ($userid[0] as $uid) { $row = WebSocket::select(['fd'])->whereUserid($uid)->pluck('fd'); if ($row->isNotEmpty()) { $array = array_merge($array, $row->toArray()); @@ -162,6 +162,8 @@ class PushTask extends AbstractTask $ignoreFd = is_array($ignoreFd) ? $ignoreFd : [$ignoreFd]; } // 开始发送 + \Log::info('fd'); + \Log::info($array); foreach ($array as $fid) { if ($ignoreFd) { if (in_array($fid, $ignoreFd)) continue; diff --git a/database/migrations/2023_06_15_093619_add_project_tasks_is_all_visible.php b/database/migrations/2023_06_15_093619_add_project_tasks_is_all_visible.php new file mode 100644 index 000000000..ac95cf314 --- /dev/null +++ b/database/migrations/2023_06_15_093619_add_project_tasks_is_all_visible.php @@ -0,0 +1,36 @@ +tinyInteger('is_all_visible')->nullable()->default(1)->after('is_default')->comment('是否所有人可见'); + } + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + Schema::table('project_tasks', function (Blueprint $table) { + $table->dropColumn("avatar"); + }); + } +} diff --git a/resources/assets/js/pages/manage/components/TaskAdd.vue b/resources/assets/js/pages/manage/components/TaskAdd.vue index 8062266e2..0d61dc532 100644 --- a/resources/assets/js/pages/manage/components/TaskAdd.vue +++ b/resources/assets/js/pages/manage/components/TaskAdd.vue @@ -92,6 +92,25 @@ + + {{$L('项目负责人')}} + {{$L('项目协助人')}} + {{$L('指定人员')}} + + + +
@@ -185,6 +204,11 @@ export default { p_level: 0, p_name: '', p_color: '', + // 可见性 + visibility_principal: 1, + visibility_assist: 1, + visibility_appoint: 1, + visibility_appointor: [0], }, cascaderShow: false, diff --git a/resources/assets/js/pages/manage/components/TaskAddSimple.vue b/resources/assets/js/pages/manage/components/TaskAddSimple.vue index eedb13a4a..3bb6ca84d 100644 --- a/resources/assets/js/pages/manage/components/TaskAddSimple.vue +++ b/resources/assets/js/pages/manage/components/TaskAddSimple.vue @@ -113,6 +113,11 @@ export default { p_level: 0, p_name: '', p_color: '', + // 可见性 + visibility_principal: 1, + visibility_assist: 1, + visibility_appoint: 1, + visibility_appointor: [0], }, active: false, @@ -217,6 +222,11 @@ export default { p_level: 0, p_name: '', p_color: '', + // 可见性 + visibility_principal: 1, + visibility_assist: 1, + visibility_appoint: 1, + visibility_appointor: [0], } }).catch(({msg}) => { $A.modalError(msg); diff --git a/resources/assets/js/pages/manage/components/TaskDetail.vue b/resources/assets/js/pages/manage/components/TaskDetail.vue index 34121853e..69f836464 100644 --- a/resources/assets/js/pages/manage/components/TaskDetail.vue +++ b/resources/assets/js/pages/manage/components/TaskDetail.vue @@ -1,73 +1,89 @@