diff --git a/app/Helpers/Function.php b/app/Helpers/Function.php index 3c338456..13f4fc58 100644 --- a/app/Helpers/Function.php +++ b/app/Helpers/Function.php @@ -10,7 +10,7 @@ if (!function_exists('asset_main')) { if (!function_exists('seeders_at')) { function seeders_at($data) { - $diff = time() - strtotime("2021-07-01"); + $diff = time() - strtotime("2021-07-02"); $time = strtotime($data) + $diff; return date("Y-m-d H:i:s", $time); } diff --git a/app/Http/Controllers/Api/ProjectController.php b/app/Http/Controllers/Api/ProjectController.php index 02a99d53..dbd95c30 100755 --- a/app/Http/Controllers/Api/ProjectController.php +++ b/app/Http/Controllers/Api/ProjectController.php @@ -1405,6 +1405,60 @@ class ProjectController extends AbstractController return Base::retSuccess('删除成功', ['id' => $task->id]); } + /** + * @api {get} api/project/task/resetfromlog 29. 根据日志重置任务 + * + * @apiDescription 需要token身份(限:项目、任务负责人) + * @apiVersion 1.0.0 + * @apiGroup project + * @apiName task__resetfromlog + * + * @apiParam {Number} task_id 任务ID + * + * @apiSuccess {Number} ret 返回状态码(1正确、0错误) + * @apiSuccess {String} msg 返回信息(错误描述) + * @apiSuccess {Object} data 返回数据 + */ + public function task__resetfromlog() + { + User::auth(); + // + $id = intval(Request::input('id')); + // + $projectLog = ProjectLog::find($id); + if (empty($projectLog) || empty($projectLog->task_id)) { + return Base::retError('记录不存在'); + } + $record = $projectLog->record; + // + $task = ProjectTask::userTask($projectLog->task_id, null, true); + // + if ($record['type'] == 'flow') { + $newFlowItem = ProjectFlowItem::find(intval($record['flow_item_id'])); + if (empty($newFlowItem)) { + return Base::retError('流程不存在或已被删除'); + } + return AbstractModel::transaction(function() use ($record, $task, $newFlowItem) { + $data = array_intersect_key($record, array_flip(['complete_at', 'owner', 'assist'])); + $currentFlowItem = $task->flow_item_id ? ProjectFlowItem::find($task->flow_item_id) : null; + // 更新任务 + $task->flow_item_id = $newFlowItem->id; + $task->flow_item_name = $newFlowItem->name; + $updateMarking = []; + $task->addLog("重置{任务}状态:{$currentFlowItem?->name} => {$newFlowItem->name}"); + $task->updateTask($data, $updateMarking); + // + $data = ProjectTask::oneTask($task->id)->toArray(); + $data['update_marking'] = $updateMarking ?: json_decode('{}'); + $task->pushMsg('update', $data); + // + return Base::retSuccess('重置成功', $data); + }); + } else { + return Base::retError('暂不支持此操作'); + } + } + /** * @api {get} api/project/task/flow 29. 任务工作流信息 * @@ -1574,6 +1628,7 @@ class ProjectController extends AbstractController 'sort' => intval($item['sort']), 'turns' => $turns, 'userids' => $userids, + 'usertype' => $item['usertype'], ]); if ($flow) { $ids[] = $flow->id; diff --git a/app/Models/ProjectFlowItem.php b/app/Models/ProjectFlowItem.php index 19869af7..9d358710 100644 --- a/app/Models/ProjectFlowItem.php +++ b/app/Models/ProjectFlowItem.php @@ -14,6 +14,7 @@ use App\Module\Base; * @property string|null $status 状态 * @property array $turns 可流转 * @property array $userids 自动负责人ID + * @property string|null $usertype 流转模式 * @property int|null $sort 排序 * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at @@ -31,6 +32,7 @@ use App\Module\Base; * @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereTurns($value) * @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereUpdatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereUserids($value) + * @method static \Illuminate\Database\Eloquent\Builder|ProjectFlowItem whereUsertype($value) * @mixin \Eloquent */ class ProjectFlowItem extends AbstractModel diff --git a/app/Models/ProjectLog.php b/app/Models/ProjectLog.php index cebc2319..b41dbfb4 100644 --- a/app/Models/ProjectLog.php +++ b/app/Models/ProjectLog.php @@ -2,6 +2,8 @@ namespace App\Models; +use App\Module\Base; + /** * App\Models\ProjectLog * @@ -11,6 +13,7 @@ namespace App\Models; * @property int|null $task_id 项目ID * @property int|null $userid 会员ID * @property string|null $detail 详细信息 + * @property string|null $record 记录数据 * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at * @property-read \App\Models\User|null $user @@ -22,6 +25,7 @@ namespace App\Models; * @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereDetail($value) * @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereId($value) * @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereProjectId($value) + * @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereRecord($value) * @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereTaskId($value) * @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereUpdatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|ProjectLog whereUserid($value) @@ -30,6 +34,18 @@ namespace App\Models; class ProjectLog extends AbstractModel { + /** + * @param $value + * @return array + */ + public function getRecordAttribute($value) + { + if (is_array($value)) { + return $value; + } + return Base::json2array($value); + } + /** * @return \Illuminate\Database\Eloquent\Relations\HasOne */ diff --git a/app/Models/ProjectTask.php b/app/Models/ProjectTask.php index 85910780..8d9ec0c0 100644 --- a/app/Models/ProjectTask.php +++ b/app/Models/ProjectTask.php @@ -495,6 +495,11 @@ class ProjectTask extends AbstractModel if ($this->flow_item_id == $data['flow_item_id']) { throw new ApiException('任务状态未发生改变'); } + $recordData = [ + 'type' => 'flow', + 'flow_item_id' => $this->flow_item_id, + 'flow_item_name' => $this->flow_item_name, + ]; $currentFlowItem = null; $newFlowItem = ProjectFlowItem::whereProjectId($this->project_id)->find(intval($data['flow_item_id'])); if (empty($newFlowItem) || empty($newFlowItem->projectFlow)) { @@ -510,24 +515,38 @@ class ProjectTask extends AbstractModel if ($newFlowItem->status == 'end') { // 判断自动完成 if (!$this->complete_at) { + $recordData['complete_at'] = $this->complete_at; $data['complete_at'] = date("Y-m-d H:i"); } } else { // 判断自动打开 if ($this->complete_at) { + $recordData['complete_at'] = $this->complete_at; $data['complete_at'] = false; } } if ($newFlowItem->userids) { // 判断自动添加负责人 - if (!Arr::exists($data, 'owner')) { - $data['owner'] = $this->taskUser->pluck('userid')->toArray(); + $recordData['owner'] = $data['owner'] = $this->taskUser->where('owner', 1)->pluck('userid')->toArray(); + if ($newFlowItem->usertype == "replace") { + // 流转模式 + if ($this->parent_id === 0) { + $recordData['assist'] = $data['assist'] = $this->taskUser->where('owner', 0)->pluck('userid')->toArray(); + $data['assist'] = array_merge($data['assist'], $data['owner']); + } + $data['owner'] = $newFlowItem->userids; + } else { + // 添加模式 + $data['owner'] = array_merge($data['owner'], $newFlowItem->userids); + } + $data['owner'] = array_values(array_unique($data['owner'])); + if (isset($data['assist'])) { + $data['assist'] = array_values(array_unique(array_diff($data['assist'], $data['owner']))); } - $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}"); + $this->addLog("修改{任务}状态:{$currentFlowItem?->name} => {$newFlowItem->name}", 0, $recordData); } // 状态 if (Arr::exists($data, 'complete_at')) { @@ -559,7 +578,7 @@ class ProjectTask extends AbstractModel } // 负责人 if (Arr::exists($data, 'owner')) { - $count = $this->taskUser->count(); + $count = $this->taskUser->where('owner', 1)->count(); $array = []; $owner = is_array($data['owner']) ? $data['owner'] : [$data['owner']]; if (count($owner) > 10) { @@ -947,18 +966,23 @@ class ProjectTask extends AbstractModel * 添加任务日志 * @param string $detail * @param int $userid + * @param $record * @return ProjectLog */ - public function addLog($detail, $userid = 0) + public function addLog($detail, $userid = 0, $record = null) { $detail = str_replace("{任务}", $this->parent_id > 0 ? "子任务" : "任务", $detail); - $log = ProjectLog::createInstance([ + $array = [ 'project_id' => $this->project_id, 'column_id' => $this->column_id, 'task_id' => $this->parent_id ?: $this->id, 'userid' => $userid ?: User::userid(), 'detail' => $detail, - ]); + ]; + if ($record) { + $array['record'] = $record; + } + $log = ProjectLog::createInstance($array); $log->save(); return $log; } diff --git a/app/Models/User.php b/app/Models/User.php index 1cefc9e4..9f70632b 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -55,6 +55,7 @@ use Carbon\Carbon; * @method static \Illuminate\Database\Eloquent\Builder|User whereUserid($value) * @method static \Illuminate\Database\Eloquent\Builder|User whereUserimg($value) * @mixin \Eloquent + * @method static \Database\Factories\UserFactory factory(...$parameters) */ class User extends AbstractModel { diff --git a/database/migrations/2022_01_11_182830_project_flow_items_add_usertype.php b/database/migrations/2022_01_11_182830_project_flow_items_add_usertype.php new file mode 100644 index 00000000..9140e279 --- /dev/null +++ b/database/migrations/2022_01_11_182830_project_flow_items_add_usertype.php @@ -0,0 +1,42 @@ +string('usertype', 10)->nullable()->default('')->after('userids')->comment('流转模式'); + } + }); + if ($isAdd) { + ProjectFlowItem::where("usertype", "")->update([ + 'usertype' => 'add', + ]); + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('project_flow_items', function (Blueprint $table) { + $table->dropColumn("usertype"); + }); + } +} diff --git a/database/migrations/2022_01_11_191703_project_logs_add_record.php b/database/migrations/2022_01_11_191703_project_logs_add_record.php new file mode 100644 index 00000000..c285dee2 --- /dev/null +++ b/database/migrations/2022_01_11_191703_project_logs_add_record.php @@ -0,0 +1,34 @@ +text('record')->nullable()->after('detail')->comment('记录数据'); + } + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('project_logs', function (Blueprint $table) { + $table->dropColumn("record"); + }); + } +} diff --git a/resources/assets/js/pages/manage/components/ProjectLog.vue b/resources/assets/js/pages/manage/components/ProjectLog.vue index c1b5dc29..f4736b36 100644 --- a/resources/assets/js/pages/manage/components/ProjectLog.vue +++ b/resources/assets/js/pages/manage/components/ProjectLog.vue @@ -14,6 +14,9 @@
{{item.user ? item.user.nickname : $L('系统')}} {{$L(item.detail)}} + + + {{item.time.ymd}} {{item.time.segment}} {{item.time.hi}}
@@ -123,6 +126,44 @@ export default { this.listPage++; this.getLists(); }, + + operationList({id, record}) { + let list = []; + if (!$A.isJson(record)) { + return list + } + if (this.taskId > 0 && record.type === 'flow') { + list.push({ + id, + button: '重置', + content: `确定重置为【${record.flow_item_name}】吗?`, + }) + } + return list; + }, + + onOperation(item) { + $A.modalConfirm({ + content: item.content, + loading: true, + onOk: () => { + this.$store.dispatch("call", { + url: 'project/task/resetfromlog', + data: { + id: item.id + } + }).then(({data, msg}) => { + $A.messageSuccess(msg); + this.$Modal.remove(); + this.$store.dispatch("saveTask", data); + this.getLists(true); + }).catch(({msg}) => { + $A.modalError(msg, 301); + this.$Modal.remove(); + }); + } + }); + } } } diff --git a/resources/assets/js/pages/manage/components/ProjectWorkflow.vue b/resources/assets/js/pages/manage/components/ProjectWorkflow.vue index db7ab057..9210b76e 100644 --- a/resources/assets/js/pages/manage/components/ProjectWorkflow.vue +++ b/resources/assets/js/pages/manage/components/ProjectWorkflow.vue @@ -144,7 +144,14 @@
-
{{$L('任务流转到此流程时自动添加负责人')}}
+
+ + + {{$L('添加模式')}} + {{$L('流转模式')}} + +
{{$L('流转到此流程时改变负责人,原本的负责人移至协助人员。')}}
+
{{$L('流转到此流程时添加负责人。')}}
@@ -259,6 +266,7 @@ export default { "status": "start", "turns": [-10, -11, -12, -13], "userids": [], + "usertype": 'add', }, { "id": -11, @@ -266,6 +274,7 @@ export default { "status": "progress", "turns": [-10, -11, -12, -13], "userids": [], + "usertype": 'add', }, { "id": -12, @@ -273,6 +282,7 @@ export default { "status": "end", "turns": [-10, -11, -12, -13], "userids": [], + "usertype": 'add', }, { "id": -13, @@ -280,6 +290,7 @@ export default { "status": "end", "turns": [-10, -11, -12, -13], "userids": [], + "usertype": 'add', } ] }) @@ -331,6 +342,7 @@ export default { this.$set(this.userData, 'id', item.id); this.$set(this.userData, 'name', item.name); this.$set(this.userData, 'userids', item.userids); + this.$set(this.userData, 'usertype', item.usertype); this.userShow = true; break; @@ -350,6 +362,7 @@ export default { let item = data.project_flow_item.find(item => item.id == this.userData.id) if (item) { this.$set(item, 'userids', this.userData.userids) + this.$set(item, 'usertype', this.userData.usertype) } }) }, @@ -395,6 +408,7 @@ export default { status: 'end', turns, userids: [], + usertype: 'add', }) data.project_flow_item.some(item => { item.turns.push(id) diff --git a/resources/assets/sass/pages/components/project-log.scss b/resources/assets/sass/pages/components/project-log.scss index bcc9cdfc..37b6c03d 100644 --- a/resources/assets/sass/pages/components/project-log.scss +++ b/resources/assets/sass/pages/components/project-log.scss @@ -88,6 +88,14 @@ .log-text { color: rgba(0,0,0,.54); } + .log-operation { + > button { + font-size: 12px; + } + > button + button { + margin-left: 4px; + } + } .log-time { color: rgba(0,0,0,.3); font-size: 12px;