diff --git a/app/Http/Controllers/Api/ApproveController.php b/app/Http/Controllers/Api/ApproveController.php index 5e3cdfa8d..555e7ecf4 100755 --- a/app/Http/Controllers/Api/ApproveController.php +++ b/app/Http/Controllers/Api/ApproveController.php @@ -952,6 +952,7 @@ class ApproveController extends AbstractController $data = [ 'id' => $process['id'], 'nickname' => User::userid2nickname($type == 'approve_submitter' ? $toUser['userid'] : $process['start_user_id']), + 'start_nickname' => User::userid2nickname($process['start_user_id']), 'proc_def_name' => $process['proc_def_name'], 'department' => $process['department'], 'type' => $process['var']['type'], diff --git a/app/Http/Controllers/Api/ProjectController.php b/app/Http/Controllers/Api/ProjectController.php index 2889500b9..30631bd80 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; @@ -895,8 +896,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')); @@ -1341,17 +1351,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); } @@ -1557,7 +1576,7 @@ class ProjectController extends AbstractController */ public function task__add() { - User::auth(); + $user = User::auth(); // $data = Request::input(); $project_id = intval($data['project_id']); @@ -1602,6 +1621,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); @@ -1663,6 +1693,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] 优先级相关(子任务不支持) @@ -1679,17 +1710,47 @@ 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); + $taskUser = ProjectTaskUser::select(['userid', 'owner'])->whereTaskId($task_id)->whereIn('owner', [0, 1])->get(); + $owners = $taskUser->where('owner', 1)->pluck('userid')->toArray(); // 负责人 + $assist = $taskUser->where('owner', 0)->pluck('userid')->toArray(); // 协助人 + // 更新任务 $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(); + } + } + } + if (Arr::exists($param, 'owner') && $data['is_all_visible'] == 0) { + $diff = array_diff($owners, $param['owner']); + if ($diff) { + $task->pushMsgVisibleRemove($diff); + } + } + if (Arr::exists($param, 'assist') && $data['is_all_visible'] == 0) { + $diff = array_diff($owners, $param['assist']); + if ($diff) { + $task->pushMsgVisibleRemove($diff); + } + } // return Base::retSuccess('修改成功', $data); } diff --git a/app/Models/ProjectTask.php b/app/Models/ProjectTask.php index 0d6970f93..7b7f786b4 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 @@ -1418,7 +1474,7 @@ class ProjectTask extends AbstractModel foreach ($array as $item) { $params = [ 'ignoreFd' => Request::header('fd'), - 'userid' => array_values($item), + 'userid' => $item['userid'], 'msg' => [ 'type' => 'projectTask', 'action' => $action, @@ -1430,6 +1486,114 @@ 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 array $userids + * @return void + */ + public function pushMsgVisibleRemove(array $userids = []) + { + if (!$this->project) { + return; + } + $data = [ + 'id' => $this->id, + 'parent_id' => $this->parent_id, + 'project_id' => $this->project_id, + 'column_id' => $this->column_id, + 'dialog_id' => $this->dialog_id, + ]; + // + $array = []; + if (empty($userids)) { + // 默认 项目成员 与 项目负责人,任务负责人、协助人的差集 + $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/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..e0200036c --- /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('userid')->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/approve/details.vue b/resources/assets/js/pages/manage/approve/details.vue index e935328a1..f0b3e08c1 100644 --- a/resources/assets/js/pages/manage/approve/details.vue +++ b/resources/assets/js/pages/manage/approve/details.vue @@ -159,8 +159,8 @@