all(); $list = VisitAudit::with('visit')->where(function ($query) use ($all) { if (isset($all['myself_audit']) && !empty($all['myself_audit'])) { $query->where('audit_admin_id', $this->getUserId()); } $query->whereHas('visit', function ($q) use ($all) { if (isset($all['audit_status'])) { $q->where('audit_status', $all['audit_status']); } if (isset($all['type'])) { $q->where('type', $all['type']); } if (isset($all['myself_accept']) && !empty($all['myself_accept'])) { $q->where('accept_admin_id', $this->getUserId()); } }); })->orderBy($all['sort_name'] ?? 'id', $all['sort_type'] ?? 'desc') ->paginate($all['page_size'] ?? 20); return $this->success($list); } /** * @OA\Get( * path="/api/admin/visit_audit/show", * tags={"拜访审核"}, * summary="详情", * description="", * @OA\Parameter(name="id", in="query", @OA\Schema(type="string"), required=true, description="id"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", * description="暂无" * ) * ) */ public function show() { $all = \request()->all(); $messages = [ 'id.required' => 'Id必填', ]; $validator = Validator::make($all, [ 'id' => 'required' ], $messages); if ($validator->fails()) { return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]); } $detail = VisitAudit::find($all['id']); return $this->success($detail); } /** * @OA\Post( * path="/api/admin/visit_audit/save", * tags={"拜访审核"}, * summary="更新", * description="", * @OA\Parameter(name="id", in="query", @OA\Schema(type="int"), required=true, description="Id(存在更新,不存在新增)"), * @OA\Parameter(name="admin_id", in="query", @OA\Schema(type="string"), required=false, description="不用填"), * @OA\Parameter(name="department_id", in="query", @OA\Schema(type="string"), required=false, description="不用填"), * @OA\Parameter(name="visit_id", in="query", @OA\Schema(type="string"), required=true, description="参观id"), * @OA\Parameter(name="audit_admin_id", in="query", @OA\Schema(type="string"), required=true, description="审核人员id"), * @OA\Parameter(name="status", in="query", @OA\Schema(type="string"), required=false, description="状态0待审核1通过2驳回"), * @OA\Parameter(name="reason", in="query", @OA\Schema(type="string"), required=false, description="原因"), * @OA\Parameter(name="level", in="query", @OA\Schema(type="string"), required=false, description="审核次序"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", * description="暂无" * ) * ) */ public function save() { $all = \request()->all(); $messages = [ 'visit_id.required' => '参观id必填' ]; $validator = Validator::make($all, [ 'visit_id' => 'required' ], $messages); if ($validator->fails()) { return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]); } DB::beginTransaction(); try { if (isset($all['id'])) { $model = VisitAudit::find($all['id']); } else { $model = new VisitAudit(); $all['admin_id'] = $this->getUserId(); $all['department_id'] = $this->getUser()->department_id; } $model->fill($all); $model->save(); // 获取必要数据 $visit = Visit::find($all['visit_id']); // 短信通知下一个审核人,如果当前通过的话 if ($all['status'] == 1) { VisitAudit::smsNextAudit($visit, $model->level); } $user = User::find($visit->user_id); $visitTime = VisitTime::find($visit->visit_time_id); $acceptAdmin = Admin::find($visit->accept_admin_id); // 如果全部审核通过则拜访通过 $waitCount = VisitAudit::where('visit_id', $all['visit_id'])->whereIn('status', [0])->count(); $noPassCount = VisitAudit::where('visit_id', $all['visit_id'])->whereIn('status', [2])->count(); if ($noPassCount || (empty($noPassCount) && empty($waitCount))) { $auditResult = ''; if ($noPassCount) { // 不通过 $auditResult = '驳回'; // 修改状态 Visit::where('id', $all['visit_id'])->update(['audit_status' => 2]); } if (empty($noPassCount) && empty($waitCount)) { // 通过 $auditResult = '通过'; Visit::where('id', $all['visit_id'])->update(['audit_status' => 1]); // 发短信 if (!empty($acceptAdmin->mobile)) { $vars = ['date' => $visit->date, 'name' => $visit->name, 'phone_number' => $visit->mobile]; $template_id = '5wReg1'; sms($acceptAdmin->mobile, $vars, $template_id); } } if ($auditResult) { // 发通知订阅消息:通过与驳回共用「审核结果」模板(Caa0…)。 // 驳回若单独使用另一模板,易出现后台字段不一致或用户未授权该模板导致发送失败。 $subMsgTemplateId = 'Caa0O6pPtQDHQMPsqE6PHyzueeI11JvlpenbgwkYC0s'; $templateData = [ 'date1' => [ 'value' => $visit->date ], 'name3' => [ 'value' => $acceptAdmin->name ?? '', ], 'thing4' => [ 'value' => $this->clipSubscribeThing($visit->name) ], 'thing13' => [ 'value' => $this->clipSubscribeThing($auditResult, 20), ], 'thing9' => [ 'value' => $this->clipSubscribeThing($visit->company_name ?? '-') ], ]; if ($user && !empty($user->openid)) { try { $sendResult = Visit::subMsg($subMsgTemplateId, $user->openid, $templateData, $all['visit_id']); if (is_array($sendResult) && isset($sendResult['errcode']) && (int) $sendResult['errcode'] !== 0) { Log::warning('visit audit subscribe message send failed', [ 'visit_id' => $all['visit_id'], 'audit_result' => $auditResult, 'errcode' => $sendResult['errcode'] ?? null, 'errmsg' => $sendResult['errmsg'] ?? null, ]); } } catch (\Throwable $e) { Log::warning('visit audit subscribe message exception', [ 'visit_id' => $all['visit_id'], 'message' => $e->getMessage(), ]); } } // 发通知短信消息 $vars = ['result' => $auditResult]; $template_id = 'G5W6Y3'; sms($visit->mobile, $vars, $template_id); } } // 审核记录 $auditAdmin = Admin::find($model->audit_admin_id); VisitLog::add($this->getUser(), '', $all['visit_id'], $auditAdmin->name . '审核' . ($all['status'] == 1 ? '通过' : '驳回')); DB::commit(); return $this->success('更新成功'); } catch (\Exception $exception) { DB::rollBack(); return $this->fail([$exception->getCode(), $exception->getMessage()]); } } /** * @OA\Get( * path="/api/admin/visit_audit/destroy", * tags={"拜访审核"}, * summary="删除", * description="", * @OA\Parameter(name="id", in="query", @OA\Schema(type="string"), required=true, description="id"), * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", * description="暂无" * ) * ) */ public function destroy() { $all = \request()->all(); $messages = [ 'id.required' => 'Id必填', ]; $validator = Validator::make($all, [ 'id' => 'required' ], $messages); if ($validator->fails()) { return $this->fail([ResponseCode::ERROR_PARAMETER, implode(',', $validator->errors()->all())]); } VisitAudit::where('id', $all['id'])->delete(); return $this->success('删除成功'); } /** * 订阅消息 thing 类字段长度限制较严,避免微信接口因超长拒绝发送。 */ private function clipSubscribeThing(?string $text, int $maxLen = 20): string { $text = trim((string) $text); if ($text === '') { return '-'; } if (function_exists('mb_strlen') && function_exists('mb_substr')) { if (mb_strlen($text) > $maxLen) { return mb_substr($text, 0, $maxLen - 1) . '…'; } } elseif (strlen($text) > $maxLen) { return substr($text, 0, $maxLen - 1) . '…'; } return $text; } }