middleware(function ($request, $next) { abort_unless(SystemAccess::canOpenSettings(), 403); return $next($request); }); } public function index() { $eligibleUsers = $this->eligibleUsers()->with('roles')->orderBy('name')->get(); $eligibleUserIds = $eligibleUsers->pluck('id'); $bindingRequests = DingTalkBindingRequest::query()->with(['matchedUser', 'reviewer']); $identities = DingTalkIdentity::query()->with('user'); $audits = DingTalkAuthAudit::query()->with(['user', 'actor']); if (! SystemAccess::isSuperAdmin()) { $bindingRequests->whereIn('matched_user_id', $eligibleUserIds); $identities->whereIn('user_id', $eligibleUserIds); $audits->whereIn('user_id', $eligibleUserIds); } return view('system_settings.dingtalk_bindings.index', [ 'bindingRequests' => $bindingRequests->latest('last_attempted_at')->get(), 'identities' => $identities->latest('bound_at')->get(), 'eligibleUsers' => $eligibleUsers, 'audits' => $audits->latest('created_at')->limit(50)->get(), ]); } public function approve(DingTalkBindingRequest $bindingRequest, Request $request, DingTalkClosedAccess $access) { $data = $request->validate(['user_id' => ['required', 'integer']]); $managedUser = $this->eligibleUsers()->findOrFail((int) $data['user_id']); abort_unless(SystemAccess::canManageUser(user(), $managedUser) || $managedUser->id === user()->id, 403); abort_unless( SystemAccess::isSuperAdmin() || ((int) $bindingRequest->matched_user_id === (int) $managedUser->id), 403 ); if (DingTalkIdentity::query()->where('union_id', $bindingRequest->union_id)->exists()) { throw ValidationException::withMessages(['binding' => '该钉钉账号已经完成绑定。']); } if (DingTalkIdentity::query()->where('user_id', $managedUser->id)->exists()) { throw ValidationException::withMessages(['user_id' => '该财务账号已经绑定其他钉钉账号。']); } DB::transaction(function () use ($bindingRequest, $managedUser, $request, $access): void { DingTalkIdentity::query()->create([ 'user_id' => $managedUser->id, 'union_id' => $bindingRequest->union_id, 'open_id' => $bindingRequest->open_id, 'dingtalk_user_id' => $bindingRequest->dingtalk_user_id, 'nickname' => $bindingRequest->nickname, 'bound_by' => user()->id, 'bound_at' => now(), ]); $bindingRequest->forceFill([ 'status' => DingTalkBindingRequest::APPROVED, 'matched_user_id' => $managedUser->id, 'match_reason' => 'administrator_approved', 'reviewed_by' => user()->id, 'reviewed_at' => now(), ])->save(); $access->audit('binding_admin_approved', 'success', $managedUser->id, user()->id, $bindingRequest->union_id, $request); }); flash('钉钉账号已绑定。')->success(); return redirect()->route('system-settings.dingtalk-bindings.index'); } public function reject(DingTalkBindingRequest $bindingRequest, Request $request, DingTalkClosedAccess $access) { abort_unless( SystemAccess::isSuperAdmin() || ($bindingRequest->matchedUser && SystemAccess::canManageUser(user(), $bindingRequest->matchedUser)), 403 ); abort_if(DingTalkIdentity::query()->where('union_id', $bindingRequest->union_id)->exists(), 422, '已绑定身份不能直接拒绝。'); $bindingRequest->forceFill([ 'status' => DingTalkBindingRequest::REJECTED, 'matched_user_id' => null, 'match_reason' => 'administrator_rejected', 'reviewed_by' => user()->id, 'reviewed_at' => now(), ])->save(); $access->audit('binding_rejected', 'denied', null, user()->id, $bindingRequest->union_id, $request); flash('钉钉绑定申请已拒绝。')->success(); return redirect()->route('system-settings.dingtalk-bindings.index'); } public function destroy(DingTalkIdentity $identity, Request $request, DingTalkClosedAccess $access) { $managedUser = $identity->user()->firstOrFail(); abort_unless(SystemAccess::canManageUser(user(), $managedUser) || $managedUser->id === user()->id, 403); DB::transaction(function () use ($identity, $managedUser, $request, $access): void { $unionId = $identity->union_id; $identity->delete(); DingTalkBindingRequest::query()->where('union_id', $unionId)->update([ 'status' => DingTalkBindingRequest::REVOKED, 'match_reason' => 'administrator_revoked', 'reviewed_by' => user()->id, 'reviewed_at' => now(), ]); $access->audit('binding_revoked', 'success', $managedUser->id, user()->id, $unionId, $request); }); flash('钉钉账号绑定已解除。')->success(); return redirect()->route('system-settings.dingtalk-bindings.index'); } private function eligibleUsers() { $query = User::query() ->where('enabled', true) ->whereHas('companies', fn ($company) => $company->where('companies.id', company_id())->where('companies.enabled', true)); if (! SystemAccess::isSuperAdmin()) { $query->whereHas('roles', fn ($roles) => $roles->where('roles.name', SystemAccess::USER)); } return $query; } }