diff --git a/app/Http/Controllers/Api/ProjectController.php b/app/Http/Controllers/Api/ProjectController.php index bb78bfe4..06857f0e 100755 --- a/app/Http/Controllers/Api/ProjectController.php +++ b/app/Http/Controllers/Api/ProjectController.php @@ -170,19 +170,6 @@ class ProjectController extends AbstractController } ], - "project_flow_item": [ // 工作流 - { - "id": 9, - "project_id": 2, - "flow_id": 3, - "name": "待处理", - "status": "start", - "turns": [9,10,11,12], - "userids": [], - "sort": 0 - } - ], - "task_num": 9, "task_complete": 0, "task_percent": 0, @@ -200,7 +187,6 @@ class ProjectController extends AbstractController $project = Project::userProject($project_id); $data = array_merge($project->toArray(), $project->getTaskStatistics($user->userid), [ 'project_user' => $project->projectUser, - 'project_flow_item' => $project->projectFlowItem ]); // return Base::retSuccess('success', $data); @@ -1216,6 +1202,7 @@ class ProjectController extends AbstractController * @apiParam {String} [p_name] 优先级相关(子任务不支持) * @apiParam {String} [p_color] 优先级相关(子任务不支持) * + * @apiParam {Number} [flow_item_id] 任务状态,工作流状态ID * @apiParam {String|false} [complete_at] 完成时间(如:2020-01-01 00:00,false表示未完成) * * @apiSuccess {Number} ret 返回状态码(1正确、0错误) @@ -1442,26 +1429,73 @@ class ProjectController extends AbstractController // $task_id = intval(Request::input('task_id')); // - $projectTask = ProjectTask::select(['id', 'flow_item_id', 'flow_item_name', 'project_id'])->find($task_id); + $projectTask = ProjectTask::select(['id', 'project_id', 'complete_at', 'flow_item_id', 'flow_item_name'])->find($task_id); if (empty($projectTask)) { return Base::retError('任务不存在', [ 'task_id' => $task_id ], -4002); } // - $projectFlowItem = []; - $turnBuilder = ProjectFlowItem::select(['id', 'name']); - if ($projectTask->flow_item_id) { - $projectFlowItem = ProjectFlowItem::select(['id', 'name', 'turns'])->find($projectTask->flow_item_id); + $projectFlowItem = $projectTask->flow_item_id ? ProjectFlowItem::with(['projectFlow'])->find($projectTask->flow_item_id) : null; + if ($projectFlowItem?->projectFlow) { + $projectFlow = $projectFlowItem->projectFlow; + } else { + $projectFlow = ProjectFlow::whereProjectId($projectTask->project_id)->first(); } + if (empty($projectFlow)) { + return Base::retSuccess('success', [ + 'task_id' => $projectTask->id, + 'flow_item_id' => 0, + 'flow_item_name' => '', + 'turns' => [], + ]); + } + // + $turns = ProjectFlowItem::select(['id', 'name', 'status', 'turns'])->whereFlowId($projectFlow->id)->orderBy('sort')->get(); if (empty($projectFlowItem)) { $data = [ - 'id' => 0, - 'name' => '', - 'turns' => $turnBuilder->whereProjectId($projectTask->project_id)->get() + 'task_id' => $projectTask->id, + 'flow_item_id' => 0, + 'flow_item_name' => '', + 'turns' => $turns, ]; + $assign = null; + if ($projectTask->complete_at) { + // 赋一个结束状态 + foreach ($turns as $turn) { + if ($turn->status == 'end' || preg_match("/complete|done|完成/i", $turn->name)) { + $assign = $turn; + break; + } + } + if (empty($data['flow_item_id'])) { + foreach ($turns as $turn) { + if ($turn->status == 'end') { + $assign = $turn; + break; + } + } + } + } else { + // 赋一个开始状态 + foreach ($turns as $turn) { + if ($turn->status == 'start') { + $assign = $turn; + break; + } + } + } + if ($assign) { + $data['flow_item_id'] = $assign->id; + $data['flow_item_name'] = $assign->name; + } } else { - $data = $projectFlowItem->toArray(); - $data['turns'] = $turnBuilder->whereIn('id', $data['turns'])->get(); + $data = [ + 'task_id' => $projectTask->id, + 'flow_item_id' => $projectFlowItem->id, + 'flow_item_name' => $projectFlowItem->name, + 'turns' => $turns, + ]; } + // return Base::retSuccess('success', $data); } diff --git a/app/Models/Project.php b/app/Models/Project.php index 5b3e6d06..33046da3 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -26,8 +26,6 @@ use Request; * @property-read int $owner_userid * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectColumn[] $projectColumn * @property-read int|null $project_column_count - * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectFlowItem[] $projectFlowItem - * @property-read int|null $project_flow_item_count * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectLog[] $projectLog * @property-read int|null $project_log_count * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectUser[] $projectUser @@ -101,14 +99,6 @@ class Project extends AbstractModel return $this->hasMany(ProjectUser::class, 'project_id', 'id')->orderBy('id'); } - /** - * @return \Illuminate\Database\Eloquent\Relations\HasMany - */ - public function projectFlowItem(): \Illuminate\Database\Eloquent\Relations\HasMany - { - return $this->hasMany(projectFlowItem::class, 'project_id', 'id')->orderBy('sort'); - } - /** * 查询所有项目(与正常查询多返回owner字段) * @param self $query diff --git a/app/Models/ProjectFlowItem.php b/app/Models/ProjectFlowItem.php index fa06ed91..19869af7 100644 --- a/app/Models/ProjectFlowItem.php +++ b/app/Models/ProjectFlowItem.php @@ -17,6 +17,7 @@ use App\Module\Base; * @property int|null $sort 排序 * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at + * @property-read \App\Models\ProjectFlow|null $projectFlow * @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem newQuery() * @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem query() @@ -63,6 +64,14 @@ class ProjectFlowItem extends AbstractModel return Base::json2array($value); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasOne + */ + public function projectFlow(): \Illuminate\Database\Eloquent\Relations\HasOne + { + return $this->hasOne(ProjectFlow::class, 'id', 'flow_id'); + } + /** * @return bool|null */ diff --git a/app/Models/ProjectTask.php b/app/Models/ProjectTask.php index 028fdd21..0e4f5ad8 100644 --- a/app/Models/ProjectTask.php +++ b/app/Models/ProjectTask.php @@ -473,6 +473,45 @@ class ProjectTask extends AbstractModel public function updateTask($data, &$updateProject = false, &$updateContent = false, &$updateSubTask = false) { AbstractModel::transaction(function () use ($data, &$updateProject, &$updateContent, &$updateSubTask) { + // 工作流 + if (Arr::exists($data, 'flow_item_id')) { + if ($this->flow_item_id == $data['flow_item_id']) { + throw new ApiException('任务状态未发生改变'); + } + $currentFlowItem = null; + $newFlowItem = ProjectFlowItem::whereProjectId($this->project_id)->find(intval($data['flow_item_id'])); + if (empty($newFlowItem) || empty($newFlowItem->projectFlow)) { + throw new ApiException('任务状态不存在'); + } + if ($this->flow_item_id) { + // 判断符合流转 + $currentFlowItem = ProjectFlowItem::find($this->flow_item_id); + if ($currentFlowItem && !in_array($currentFlowItem->id, $newFlowItem->turns)) { + throw new ApiException("当前状态[{$currentFlowItem->name}]不可流转到[{$newFlowItem->name}]"); + } + } + if ($newFlowItem->status == 'end') { + // 判断自动完成 + if (!$this->complete_at) { + $data['complete_at'] = date("Y-m-d H:i"); + } + } else { + // 判断自动打开 + if ($this->complete_at) { + $data['complete_at'] = false; + } + } + if ($newFlowItem->userids) { + // 判断自动添加负责人 + if (!Arr::exists($data, 'owner')) { + $data['owner'] = $this->taskUser->pluck('userid')->toArray(); + } + $data['owner'] = array_values(array_unique(array_merge($data['owner'], $newFlowItem->userids))); + } + $this->flow_item_id = $newFlowItem->id; + $this->flow_item_name = $newFlowItem->status . "|" . $newFlowItem->name; + $this->addLog("修改{任务}状态:{$currentFlowItem?->name} => {$newFlowItem->name}"); + } // 状态 if (Arr::exists($data, 'complete_at')) { if (Base::isDate($data['complete_at'])) { diff --git a/resources/assets/js/pages/manage.vue b/resources/assets/js/pages/manage.vue index 32cf95b4..2aed9390 100644 --- a/resources/assets/js/pages/manage.vue +++ b/resources/assets/js/pages/manage.vue @@ -151,7 +151,7 @@ :mask-closable="false" :styles="{ width: '90%', - maxWidth: taskData.dialog_id ? '1200px' : '640px' + maxWidth: taskData.dialog_id ? '1200px' : '700px' }" @on-visible-change="taskVisibleChange" footer-hide> diff --git a/resources/assets/js/pages/manage/calendar.vue b/resources/assets/js/pages/manage/calendar.vue index b0e30fd7..b696f848 100644 --- a/resources/assets/js/pages/manage/calendar.vue +++ b/resources/assets/js/pages/manage/calendar.vue @@ -125,6 +125,9 @@ export default { if (data.sub_top === true) { task.title = `[${this.$L('子任务')}] ${task.title}` } + if (data.flow_item_name) { + task.title = `[${data.flow_item_name}] ${task.title}` + } if (data.overdue) { task.title = `[${this.$L('超期')}] ${task.title}` task.color = "#f56c6c" diff --git a/resources/assets/js/pages/manage/components/ProjectList.vue b/resources/assets/js/pages/manage/components/ProjectList.vue index 31177f06..dc58f06f 100644 --- a/resources/assets/js/pages/manage/components/ProjectList.vue +++ b/resources/assets/js/pages/manage/components/ProjectList.vue @@ -151,9 +151,14 @@ :style="item.color ? {backgroundColor: item.color} : {}" @click="openTask(item)">
-
{{item.name}}
+
+ + {{item.flow_item_name}} + +
{{item.name}}
+
- +
@@ -1108,6 +1113,13 @@ export default { } }, + openMenu(task) { + const el = this.$refs[`taskMenu_${task.id}`]; + if (el) { + el[0].show() + } + }, + taskIsHidden(task) { const {name, desc, complete_at} = task; const {searchText} = this; diff --git a/resources/assets/js/pages/manage/components/TaskDetail.vue b/resources/assets/js/pages/manage/components/TaskDetail.vue index f65db90f..8fcf8e06 100644 --- a/resources/assets/js/pages/manage/components/TaskDetail.vue +++ b/resources/assets/js/pages/manage/components/TaskDetail.vue @@ -2,7 +2,10 @@
  • - + +
    +
    + {{taskDetail.flow_item_name}}
    - + +
    + {{taskDetail.flow_item_name}} +