getError(): 错误消息 */ public function apply(Checkable $subject, Employee $user) { if ($subject->check_status === CheckStatus::Success->value) { return $this->setError('已经审核通过'); } if ($subject->check_status === CheckStatus::Processing->value) { return $this->setError('正在审核中'); } $workflow = Workflow::where('key', $subject->getCheckKey())->first(); // 没有配置审核流程, 直接通过 if (!$workflow || !$workflow->config) { $subject->checkSuccess(); return true; } $jobs = Keyword::where('parent_key', 'job')->get(); $config = collect($workflow->config)->sortBy('sort'); $batchId = WorkflowLog::where('subject_type', $subject->getMorphClass())->where('subject_id', $subject->id)->max('batch_id') + 1; $subjectData = $subject->toArray(); foreach($config as $item) { $checkValue = ''; $checkName = ''; // 职位审核 if ($item['type'] == CheckType::Job->value) { // 没有门店, 则跳过 if (!$user->store_id) { continue; } // 所属门店的职位审核 $store = Store::findOrFail($user->store_id); $job = $jobs->firstWhere('key', $item['value']); $checkValue = $store->id . '-' . $job->key; $checkName = $store->title . '-' . $job->name; } // 指定用户审核 else if ($item['type'] == CheckType::User->value) { $checkUser = Employee::findOrFail($item['value']); $checkValue = $checkUser->id; $checkName = $checkUser->name; } else { return $this->setError('未知的审核类型: ' . $item['type']); break; } $subject->workflows()->create([ 'batch_id' => $batchId, 'check_type' => $item['type'], 'check_value' => $checkValue, 'check_name' => $checkName, 'user_id' => $user->id, 'subject_data' => $subjectData, 'sort' => $item['sort'] ]); } $subject->checkApply(); // 开启第一个审核流程 $this->next($subject); return true; } /** * 取消审核 * 1. 删除未审核的流程 * 2. 更新申请记录的状态 * */ public function cancel(Checkable $subject) { $subject->workflows()->whereIn('check_status', [CheckStatus::None, CheckStatus::Processing])->delete(); $subject->checkCancel(); return true; } /** * 审核单个流程 * * @param Employee $user 审核人 * @param WorkflowLog $log 审核流水记录 * @param boolean $status 通过/不通过 * @param array $options {remarks: 不通过原因, time: 审核时间(默认当前时间)} * @return boolean */ public function check(Employee $user, WorkflowLog $log, $status, $options = []) { if ($log->check_status != CheckStatus::Processing) { return $this->setError('不可操作, 等待前面的审核完成'); } if (!$this->authCheck($user, $log)) { return $this->setError('没有权限'); } $attributes = ['check_status' => $status ? CheckStatus::Success : CheckStatus::Fail]; $attributes['checked_at'] = data_get($options, 'time', now()); $attributes['remarks'] = data_get($options, 'remarks'); $attributes['check_user_id'] = $user->id; $log->update($attributes); $subject = $log->subject; // 审核未通过, 删除剩下的流程 if (!$status) { WorkflowLog::where('subject_type', $log->subject_type)->where('subject_id', $log->subject_id)->where('check_status', CheckStatus::None)->delete(); $subject->checkFail($options); return true; } return $this->next($subject); } /** * 开启下一个审核流程 * * @param Checkable $subject * @return boolean */ public function next(Checkable $subject) { $log = $subject->workflows()->where('check_status', CheckStatus::None)->orderBy('sort')->first(); if ($log) { $log->update(['check_status' => CheckStatus::Processing]); // 申请人自动审核通过 if ($this->authCheck($subject->employee, $log)) { return $this->check($subject->employee, $log, true); } } else { // 没有审核流程了 $subject->checkSuccess(); } return true; } /** * 员工是否有权限审核 */ public function authCheck(Employee $user, WorkflowLog $log) { if ($user->adminUser?->isAdministrator()) { return true; } if ($log->check_type == CheckType::User && $log->check_value == $user->id) { return true; } else if ($log->check_type == CheckType::Job) { $jobs = $user->jobs; foreach($jobs as $job) { if ($log->check_value == $user->store_id . '-' . $job->key) { return true; } } } return false; } public function resloveData($data, $model = null) { if (isset($data['config'])) { foreach ($data['config'] as $key => &$item) { if (!$item) { $data['config'] = null; break; } $item['title'] = match ($item['type']) { CheckType::Job->value => CheckType::Job->text(), CheckType::User->value => CheckType::User->text(), }; $item['subTitle'] = match ($item['type']) { CheckType::Job->value => Keyword::where('key', $item['job'])->value('name'), CheckType::User->value => Employee::where('id', $item['user'])->value('name'), }; $item['value'] = match ($item['type']) { CheckType::Job->value => $item['job'], CheckType::User->value => $item['user'], }; $item['sort'] = $key + 1; } } return $data; } public function validate($data, $model = null) { $createRules = [ 'key' => ['required', Rule::unique('workflows', 'key')], 'name' => ['required'], 'config' => ['required', 'array'], ]; $updateRules = [ 'key' => [Rule::unique('workflows', 'key')->ignore($model?->id)], ]; $validator = Validator::make($data, $model ? $updateRules : $createRules, [ 'key.unique' => ':input 已经存在', ]); if ($validator->fails()) { return $validator->errors()->first(); } return true; } }