diff --git a/app/Http/Controllers/Api/ProjectController.php b/app/Http/Controllers/Api/ProjectController.php index 93d44b0dd..bdd150b0b 100755 --- a/app/Http/Controllers/Api/ProjectController.php +++ b/app/Http/Controllers/Api/ProjectController.php @@ -576,6 +576,8 @@ class ProjectController extends AbstractController $project = Project::userProject($project_id); // if ($only_column) { + // + ProjectPermission::userTaskPermission($project, ProjectPermission::TASK_LIST_SORT); // 排序列表 $index = 0; foreach ($sort as $item) { @@ -761,6 +763,8 @@ class ProjectController extends AbstractController // 项目 $project = Project::userProject($project_id); // + ProjectPermission::userTaskPermission($project, ProjectPermission::TASK_LIST_ADD); + // if (empty($name)) { return Base::retError('列表名称不能为空'); } @@ -810,7 +814,9 @@ class ProjectController extends AbstractController return Base::retError('列表不存在'); } // 项目 - Project::userProject($column->project_id); + $project = Project::userProject($column->project_id); + // + ProjectPermission::userTaskPermission($project, ProjectPermission::TASK_LIST_UPDATE); // if (Arr::exists($data, 'name') && $column->name != $data['name']) { $column->addLog("修改列表名称:{$column->name} => {$data['name']}"); @@ -850,7 +856,9 @@ class ProjectController extends AbstractController return Base::retError('列表不存在'); } // 项目 - Project::userProject($column->project_id, true, true); + $project = Project::userProject($column->project_id); + // + ProjectPermission::userTaskPermission($project, ProjectPermission::TASK_LIST_REMOVE); // $column->deleteColumn(); return Base::retSuccess('删除成功', ['id' => $column->id]); @@ -1005,10 +1013,6 @@ class ProjectController extends AbstractController $builder->whereNull('project_tasks.archived_at'); } // - if (ProjectPermission::getPermission($project_id, ProjectPermission::PANEL_SHOW_TASK_COMPLETE) == 0) { - $builder->whereNull('project_tasks.complete_at'); - } - // if ($deleted == 'all') { $builder->withTrashed(); } elseif ($deleted == 'yes') { @@ -1512,7 +1516,7 @@ class ProjectController extends AbstractController $archived = Request::input('archived', 'no'); // $isArchived = str_replace(['all', 'yes', 'no'], [null, false, true], $archived); - $task = ProjectTask::userTask($task_id, $isArchived, true, '', ['taskUser', 'taskTag']); + $task = ProjectTask::userTask($task_id, $isArchived, true, ['taskUser', 'taskTag']); // 项目可见性 $project_userid = ProjectUser::whereProjectId($task->project_id)->whereOwner(1)->value('userid'); // 项目负责人 if ($task->visibility != 1 && $user->userid != $project_userid) { @@ -1608,7 +1612,9 @@ class ProjectController extends AbstractController return Base::retError('文件不存在或已被删除'); } // - $task = ProjectTask::userTask($file->task_id, true, true, ProjectPermission::TASK_REMOVE); + $task = ProjectTask::userTask($file->task_id); + // + ProjectPermission::userTaskPermission(Project::userProject($task->project_id), ProjectPermission::TASK_UPDATE, $task); // $task->pushMsg('filedelete', $file); $file->delete(); @@ -1737,7 +1743,8 @@ class ProjectController extends AbstractController $column_id = $data['column_id']; // 项目 $project = Project::userProject($project_id); - ProjectTask::userTaskPermission(ProjectPermission::TASK_ADD, $project); + // + ProjectPermission::userTaskPermission($project, ProjectPermission::TASK_ADD); // 列表 $column = null; $newColumn = null; @@ -1814,11 +1821,13 @@ class ProjectController extends AbstractController $task_id = intval(Request::input('task_id')); $name = Request::input('name'); // - $task = ProjectTask::userTask($task_id, true, true, ProjectPermission::TASK_ADD); + $task = ProjectTask::userTask($task_id); if ($task->complete_at) { return Base::retError('主任务已完成无法添加子任务'); } // + ProjectPermission::userTaskPermission(Project::userProject($task->project_id), ProjectPermission::TASK_ADD); + // $task = ProjectTask::addTask([ 'name' => $name, 'parent_id' => $task->id, @@ -1873,11 +1882,18 @@ class ProjectController extends AbstractController $param = Request::input(); $task_id = intval($param['task_id']); // - $task = ProjectTask::userTask($task_id, true, true, ProjectPermission::TASK_UPDATE); + $task = ProjectTask::userTask($task_id); + // + $project = Project::userProject($task->project_id); + if (Arr::exists($param, 'flow_item_id')) { + ProjectPermission::userTaskPermission($project, ProjectPermission::TASK_STATUS, $task); + }else{ + ProjectPermission::userTaskPermission($project, ProjectPermission::TASK_UPDATE, $task); + } + // $taskUser = ProjectTaskUser::select(['userid', 'owner'])->whereTaskId($task_id)->get(); $owners = $taskUser->where('owner', 1)->pluck('userid')->toArray(); // 负责人 $assists = $taskUser->where('owner', 0)->pluck('userid')->toArray(); // 协助人 - // 更新任务 $updateMarking = []; $task->updateTask($param, $updateMarking); @@ -2009,12 +2025,15 @@ class ProjectController extends AbstractController $task_id = intval(Request::input('task_id')); $type = Request::input('type', 'add'); // - $task = ProjectTask::userTask($task_id, $type == 'add', true, ProjectPermission::TASK_ARCHIVED); + $task = ProjectTask::userTask($task_id, $type == 'add'); // if ($task->parent_id > 0) { return Base::retError('子任务不支持此功能'); } // + $project = Project::userProject($task->project_id); + ProjectPermission::userTaskPermission($project, ProjectPermission::TASK_ARCHIVED, $task); + // if ($type == 'recovery') { $task->archivedTask(null); } elseif ($type == 'add') { @@ -2051,7 +2070,11 @@ class ProjectController extends AbstractController $task_id = intval(Request::input('task_id')); $type = Request::input('type', 'delete'); // - $task = ProjectTask::userTask($task_id, null, $type !== 'recovery', ProjectPermission::TASK_REMOVE); + $task = ProjectTask::userTask($task_id, null, $type !== 'recovery'); + // + $project = Project::userProject($task->project_id); + ProjectPermission::userTaskPermission($project, ProjectPermission::TASK_REMOVE, $task); + // if ($type == 'recovery') { $task->restoreTask(); return Base::retSuccess('操作成功', ['id' => $task->id]); @@ -2086,7 +2109,7 @@ class ProjectController extends AbstractController return Base::retError('记录不存在'); } // - $task = ProjectTask::userTask($projectLog->task_id, true, true, ProjectPermission::TASK_UPDATE); + $task = ProjectTask::userTask($projectLog->task_id); // $record = $projectLog->record; if ($record['flow'] && is_array($record['flow'])) { @@ -2226,7 +2249,10 @@ class ProjectController extends AbstractController $project_id = intval(Request::input('project_id')); $column_id = intval(Request::input('column_id')); // - $task = ProjectTask::userTask($task_id, true, true, ProjectPermission::TASK_MOVE); + $task = ProjectTask::userTask($task_id); + // + $project = Project::userProject($task->project_id); + ProjectPermission::userTaskPermission($project, ProjectPermission::TASK_MOVE, $task); // if( $task->project_id == $project_id && $task->column_id == $column_id){ return Base::retSuccess('移动成功', ['id' => $task_id]); @@ -2459,7 +2485,6 @@ class ProjectController extends AbstractController * @apiParam {Array} task_update_complete 标记完成权限 * @apiParam {Array} task_archived 归档任务权限 * @apiParam {Array} task_move 移动任务权限 - * @apiParam {Number} panel_show_task_complete 是否显示已完成任务 1显示 0不显示 * * @apiSuccess {Number} ret 返回状态码(1正确、0错误) * @apiSuccess {String} msg 返回信息(错误描述) @@ -2473,7 +2498,18 @@ class ProjectController extends AbstractController if (!$projectUser) { return Base::retError("项目不存在"); } - $permissions = Request::only([ProjectPermission::TASK_ADD, ProjectPermission::TASK_UPDATE, ProjectPermission::TASK_REMOVE, ProjectPermission::TASK_UPDATE_COMPLETE, ProjectPermission::TASK_ARCHIVED, ProjectPermission::TASK_MOVE, ProjectPermission::PANEL_SHOW_TASK_COMPLETE]); + $permissions = Request::only([ + ProjectPermission::TASK_LIST_ADD, + ProjectPermission::TASK_LIST_UPDATE, + ProjectPermission::TASK_LIST_REMOVE, + ProjectPermission::TASK_LIST_SORT, + ProjectPermission::TASK_ADD, + ProjectPermission::TASK_UPDATE, + ProjectPermission::TASK_REMOVE, + ProjectPermission::TASK_STATUS, + ProjectPermission::TASK_ARCHIVED, + ProjectPermission::TASK_MOVE, + ]); $projectPermission = ProjectPermission::updatePermissions($projectId, Base::newArrayRecursive('intval', $permissions)); return Base::retSuccess("success", $projectPermission); } diff --git a/app/Models/Project.php b/app/Models/Project.php index 36956af85..3a6c9fc66 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -172,8 +172,6 @@ class Project extends AbstractModel $array['task_my_complete'] = $builder->whereNotNull('project_tasks.complete_at')->count(); $array['task_my_percent'] = $array['task_my_num'] ? intval($array['task_my_complete'] / $array['task_my_num'] * 100) : 0; // - $array['panel_show_task_complete'] = ProjectPermission::getPermission($this->id, ProjectPermission::PANEL_SHOW_TASK_COMPLETE); - // return $array; } diff --git a/app/Models/ProjectPermission.php b/app/Models/ProjectPermission.php index 2619fd5e4..fff4e117f 100644 --- a/app/Models/ProjectPermission.php +++ b/app/Models/ProjectPermission.php @@ -27,13 +27,32 @@ use App\Module\Base; class ProjectPermission extends AbstractModel { - const TASK_ADD = 'task_add'; // 任务添加 - const TASK_UPDATE = 'task_update'; // 任务更新 - const TASK_REMOVE = 'task_remove'; // 任务删除 - const TASK_UPDATE_COMPLETE = 'task_update_complete'; // 任务完成 - const TASK_ARCHIVED = 'task_archived'; // 任务归档 - const TASK_MOVE = 'task_move'; // 任务移动 - const PANEL_SHOW_TASK_COMPLETE = 'panel_show_task_complete'; // 显示已完成任务 + const TASK_LIST_ADD = 'task_list_add'; // 添加列 + const TASK_LIST_UPDATE = 'task_list_update'; // 修改列 + const TASK_LIST_REMOVE = 'task_list_remove'; // 删除列 + const TASK_LIST_SORT = 'task_list_sort'; // 列表排序 + const TASK_ADD = 'task_add'; // 任务添加 + const TASK_UPDATE = 'task_update'; // 任务更新 + const TASK_STATUS = 'task_status'; // 任务状态 + const TASK_REMOVE = 'task_remove'; // 任务删除 + const TASK_ARCHIVED = 'task_archived'; // 任务归档 + const TASK_MOVE = 'task_move'; // 任务移动 + + // 权限列表 + const PERMISSIONS = [ + 'project_leader' => 1, // 项目负责人 + 'project_member' => 2, // 项目成员 + 'task_leader' => 3, // 任务负责人 + 'task_assist' => 4, // 任务协助人 + ]; + + // 权限描述 + const PERMISSIONS_DESC = [ + 1 => "项目负责人", + 2 => "项目成员", + 3 => "任务负责人", + 4 => "任务协助人", + ]; /** * The attributes that are mass assignable. @@ -63,7 +82,7 @@ class ProjectPermission extends AbstractModel { $projectPermission = self::initPermissions($projectId); $currentPermissions = $projectPermission->permissions; - if ($key){ + if ($key) { if (!isset($currentPermissions[$key])) { throw new ApiException('项目权限设置不存在'); } @@ -81,13 +100,16 @@ class ProjectPermission extends AbstractModel public static function initPermissions($projectId) { $permissions = [ - self::TASK_ADD => [1,3], - self::TASK_UPDATE => [1,2], - self::TASK_REMOVE => [1,2], - self::TASK_UPDATE_COMPLETE => [1,2], - self::TASK_ARCHIVED => [1,2], - self::TASK_MOVE => [1,2], - self::PANEL_SHOW_TASK_COMPLETE => 1, + self::TASK_LIST_ADD => $projectTaskList = [self::PERMISSIONS['project_leader'], self::PERMISSIONS['project_member']], + self::TASK_LIST_UPDATE => $projectTaskList, + self::TASK_LIST_REMOVE => [self::PERMISSIONS['project_leader']], + self::TASK_LIST_SORT => $projectTaskList, + self::TASK_ADD => $projectTaskList, + self::TASK_UPDATE => $taskUpdate = [self::PERMISSIONS['project_leader'], self::PERMISSIONS['task_leader'], self::PERMISSIONS['task_assist']], + self::TASK_STATUS => [self::PERMISSIONS['project_leader'], self::PERMISSIONS['task_leader']], + self::TASK_REMOVE => $taskUpdate, + self::TASK_ARCHIVED => $taskUpdate, + self::TASK_MOVE => $taskUpdate ]; return self::firstOrCreate( ['project_id' => $projectId], @@ -113,4 +135,68 @@ class ProjectPermission extends AbstractModel return $projectPermission; } + + /** + * 检查用户是否有执行特定动作的权限 + * @param string $action 动作名称 + * @param Project $project 项目实例 + * @param ProjectTask $task 任务实例 + * @return bool + */ + public static function userTaskPermission(Project $project, $action, ProjectTask $task = null) + { + $userid = User::userid(); + $permissions = self::getPermission($project->id, $action); + switch ($action) { + // 任务添加,任务更新, 任务状态, 任务删除, 任务完成, 任务归档, 任务移动 + case self::TASK_LIST_ADD: + case self::TASK_LIST_UPDATE: + case self::TASK_LIST_REMOVE: + case self::TASK_LIST_SORT: + case self::TASK_ADD: + case self::TASK_UPDATE: + case self::TASK_STATUS: + case self::TASK_REMOVE: + case self::TASK_ARCHIVED: + case self::TASK_MOVE: + $verify = false; + // 项目负责人 + if (in_array(self::PERMISSIONS['project_leader'], $permissions)) { + if ($project->owner) { + $verify = true; + } + } + // 项目成员 + if (!$verify && in_array(self::PERMISSIONS['project_member'], $permissions)) { + $user = ProjectUser::whereProjectId($project->id)->whereUserid(intval($userid))->first(); + if (!empty($user)) { + $verify = true; + } + } + // 任务负责人 + if (!$verify && $task && in_array(self::PERMISSIONS['task_leader'], $permissions)) { + if ($task->isOwner()) { + $verify = true; + } + } + // 任务协助人 + if (!$verify && $task && in_array(self::PERMISSIONS['task_assist'], $permissions)) { + if ($task->isAssister()) { + $verify = true; + } + } + // + if (!$verify) { + $desc = []; + rsort($permissions); + foreach ($permissions as $permission) { + $desc[] = self::PERMISSIONS_DESC[$permission]; + } + $desc = array_reverse($desc); + throw new ApiException(sprintf("仅限%s操作", implode('、', $desc))); + } + break; + } + return true; + } } diff --git a/app/Models/ProjectTask.php b/app/Models/ProjectTask.php index c4201e641..813f73c06 100644 --- a/app/Models/ProjectTask.php +++ b/app/Models/ProjectTask.php @@ -551,15 +551,12 @@ class ProjectTask extends AbstractModel */ public function updateTask($data, &$updateMarking = []) { + // AbstractModel::transaction(function () use ($data, &$updateMarking) { // 主任务 $mainTask = $this->parent_id > 0 ? self::find($this->parent_id) : null; // 工作流 if (Arr::exists($data, 'flow_item_id')) { - $isProjectOwner = $this->useridInTheProject(User::userid()) === 2; - if (!$isProjectOwner && !$this->isOwner()) { - throw new ApiException('仅限项目或任务负责人修改任务状态'); - } if ($this->flow_item_id == $data['flow_item_id']) { throw new ApiException('任务状态未发生改变'); } @@ -580,6 +577,7 @@ class ProjectTask extends AbstractModel throw new ApiException("当前状态[{$currentFlowItem->name}]不可流转到[{$newFlowItem->name}]"); } if ($currentFlowItem->userlimit) { + $isProjectOwner = $this->useridInTheProject(User::userid()) === 2; if (!$isProjectOwner && !in_array(User::userid(), $currentFlowItem->userids)) { throw new ApiException("当前状态[{$currentFlowItem->name}]仅限状态负责人或项目负责人修改"); } @@ -1730,11 +1728,10 @@ class ProjectTask extends AbstractModel * @param int $task_id * @param bool $archived true:仅限未归档, false:仅限已归档, null:不限制 * @param bool $trashed true:仅限未删除, false:仅限已删除, null:不限制 - * @param string $action 动作名称 * @param array $with * @return self */ - public static function userTask($task_id, $archived = true, $trashed = true, $action = '', $with = []) + public static function userTask($task_id, $archived = true, $trashed = true, $with = []) { $builder = self::with($with)->allData()->where("project_tasks.id", intval($task_id)); if ($trashed === false) { @@ -1757,7 +1754,7 @@ class ProjectTask extends AbstractModel try { $project = Project::userProject($task->project_id); } catch (\Throwable $e) { - if ($task->owner !== null || (empty($action) && $task->permission(4))) { + if ($task->owner !== null || $task->permission(4)) { $project = Project::find($task->project_id); if (empty($project)) { throw new ApiException('项目不存在或已被删除', [ 'task_id' => $task_id ], -4002); @@ -1766,52 +1763,7 @@ class ProjectTask extends AbstractModel throw new ApiException($e->getMessage(), [ 'task_id' => $task_id ], -4002); } } - if ($action) { - self::userTaskPermission($action, $project, $task); - } // return $task; } - - /** - * 检查用户是否有执行特定动作的权限 - * @param string $action 动作名称 - * @param Project $project 项目实例 - * @param Task $task 任务实例 - * @return bool - */ - public static function userTaskPermission($action, $project, $task = null) - { - $permissions = ProjectPermission::getPermission($project->id, $action); - foreach ($permissions as $permission) { - switch ($permission) { - case 1: - // 项目负责人 - if (!$project->owner) { - throw new ApiException('仅限项目负责人操作', [ 'project_id' => $project->id ]); - } - break; - case 2: - // 任务负责人 - if (!$task->isOwner()) { - throw new ApiException('仅限任务负责人操作', [ 'project_id' => $project->id ]); - } - break; - case 3: - // 项目成员 - $instance = new self(); - if (!($instance->useridInTheProject(User::userid()) === 1)) { - throw new ApiException('仅限项目成员操作', [ 'project_id' => $project->id ]); - } - break; - case 4: - // 任务成员(任务成员 = 任务创建人+任务协助人+任务负责人) - if ($task->isCreater()) { - throw new ApiException('仅限任务成员操作', [ 'project_id' => $project->id ]); - } - break; - } - } - return true; - } } diff --git a/resources/assets/js/pages/manage/components/ProjectPanel.vue b/resources/assets/js/pages/manage/components/ProjectPanel.vue index 21ff6bd8f..b204efe1f 100644 --- a/resources/assets/js/pages/manage/components/ProjectPanel.vue +++ b/resources/assets/js/pages/manage/components/ProjectPanel.vue @@ -304,7 +304,7 @@ -
+
diff --git a/resources/assets/js/pages/manage/components/ProjectPermission.vue b/resources/assets/js/pages/manage/components/ProjectPermission.vue index f00cc581b..bc6c49c5a 100644 --- a/resources/assets/js/pages/manage/components/ProjectPermission.vue +++ b/resources/assets/js/pages/manage/components/ProjectPermission.vue @@ -8,64 +8,86 @@
-
+ + +
{{$L('任务列权限')}}:
+ + + {{ $L('项目负责人') }} + {{ $L('项目成员') }} + + + + + {{ $L('项目负责人') }} + {{ $L('项目成员') }} + + + + + {{ $L('项目负责人') }} + {{ $L('项目成员') }} + + + + + {{ $L('项目负责人') }} + {{ $L('项目成员') }} + +
{{$L('任务权限')}}:
{{ $L('项目负责人') }} - {{ $L('项目成员') }} + {{ $L('项目成员') }} {{ $L('项目负责人') }} - {{ $L('任务负责人') }} - {{ $L('项目成员') }} + {{ $L('任务负责人') }} + {{ $L('任务协助人') }} + {{ $L('项目成员') }} - - + + {{ $L('项目负责人') }} - {{ $L('任务负责人') }} - {{ $L('项目成员') }} + {{ $L('任务负责人') }} + {{ $L('任务协助人') }} + {{ $L('项目成员') }} {{ $L('项目负责人') }} - {{ $L('任务负责人') }} - {{ $L('项目成员') }} + {{ $L('任务负责人') }} + {{ $L('任务协助人') }} + {{ $L('项目成员') }} {{ $L('项目负责人') }} - {{ $L('任务负责人') }} - {{ $L('项目成员') }} + {{ $L('任务负责人') }} + {{ $L('任务协助人') }} + {{ $L('项目成员') }} - + {{ $L('项目负责人') }} - {{ $L('任务负责人') }} - {{ $L('项目成员') }} + {{ $L('任务负责人') }} + {{ $L('任务协助人') }} + {{ $L('项目成员') }} - -
{{$L('面板显示')}}:
- - - {{ $L('默认显示') }} - {{ $L('默认不显示') }} - -
{{ $L('项目面板默认显示已完成的任务') }}
-
- +
+ @@ -82,14 +104,15 @@ export default { }, data() { return { + loadIng: 0, formData: { - task_add: [1,3], - task_update: [1,2], - task_update_complete: [1,2], - task_archived: [1,2], - task_remove: [1,2], - task_move: [1,2], - panel_show_task_complete: 1 + project_task_list: [], + task_add: [], + task_update: [], + task_status: [], + task_archived: [], + task_remove: [], + task_move: [] } } }, diff --git a/resources/assets/sass/pages/components/project-permission.scss b/resources/assets/sass/pages/components/project-permission.scss index 5c1c4fbf4..486ebc4a9 100644 --- a/resources/assets/sass/pages/components/project-permission.scss +++ b/resources/assets/sass/pages/components/project-permission.scss @@ -11,7 +11,6 @@ font-size: 20px; font-weight: 500; line-height: 1; - // style="font-weight: bold;line-height: 40px;" padding: 20px 20px 24px; display: flex; align-items: center; @@ -33,6 +32,7 @@ overflow: auto; margin-bottom: 20px; height: 100%; + position: relative; .project-permission-title{ font-weight: 500; @@ -49,4 +49,29 @@ } } + .project-permission-footer{ + flex-shrink: 0; + position: static; + padding: 16px 26px; + border-top: 1px solid #F4F4F5; + display: flex; + align-items: center; + gap: 16px; + button { + min-width: 120px; + height: 38px; + line-height: 36px; + } + } +} + + +body.window-portrait { + .project-permission { + .project-permission-footer{ + button { + width: 50%; + } + } + } }