From 3891941058076459b733bd75618b844f20f18589 Mon Sep 17 00:00:00 2001 From: limeng <1131177064@qq.com> Date: Thu, 15 Oct 2026 17:35:38 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=8D=8F=E8=AE=AE=E7=AD=BE=E7=BD=B2?= =?UTF-8?q?=E4=B8=9A=E5=8A=A1=E6=93=8D=E4=BD=9C=E6=8E=88=E6=9D=83=E4=B8=8E?= =?UTF-8?q?=E6=8C=89=E9=92=AE=E6=9D=83=E9=99=90=E4=B8=80=E8=87=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Business/CourierAgreementSignatures.php | 21 +-- app/Http/Controllers/SystemSettings/Users.php | 8 ++ app/Utilities/AgreementSigningPermissions.php | 58 ++++++++ .../agreement-signing.blade.php | 34 ++++- .../system_settings/users/form.blade.php | 9 ++ .../AgreementSigningPermissionsTest.php | 128 ++++++++++++++++++ .../CourierAgreementSignatureWorkflowTest.php | 39 ++++++ .../SystemSettings/UserPermissionsTest.php | 23 ++++ 8 files changed, 307 insertions(+), 13 deletions(-) create mode 100644 app/Utilities/AgreementSigningPermissions.php create mode 100644 tests/Feature/Business/AgreementSigningPermissionsTest.php diff --git a/app/Http/Controllers/Business/CourierAgreementSignatures.php b/app/Http/Controllers/Business/CourierAgreementSignatures.php index fdf9d6b4..9abc2d11 100644 --- a/app/Http/Controllers/Business/CourierAgreementSignatures.php +++ b/app/Http/Controllers/Business/CourierAgreementSignatures.php @@ -13,7 +13,7 @@ use App\Support\CourierAgreementSignatureService; use App\Support\CourierQuoteConfirmation; use App\Support\CourierQuoteSignatureService; use App\Support\SupplierCooperationTemplates; -use App\Utilities\SystemAccess; +use App\Utilities\AgreementSigningPermissions; use Illuminate\Http\RedirectResponse; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; @@ -224,7 +224,7 @@ class CourierAgreementSignatures extends Controller */ public function storeSubject(Request $request): JsonResponse { - $this->ensureCanManage(); + $this->ensureCanAdminister(); if ($response = $this->subjectsTableUnavailable()) { return $response; @@ -251,7 +251,7 @@ class CourierAgreementSignatures extends Controller public function updateSubject(Request $request, CourierSigningSubject $subject): JsonResponse { - $this->ensureCanManage(); + $this->ensureCanAdminister(); $this->ensureSubjectBelongsToCurrentCompany($subject); if ($response = $this->subjectsTableUnavailable()) { @@ -272,7 +272,7 @@ class CourierAgreementSignatures extends Controller public function setDefaultSubject(CourierSigningSubject $subject): JsonResponse { - $this->ensureCanManage(); + $this->ensureCanAdminister(); $this->ensureSubjectBelongsToCurrentCompany($subject); if ($response = $this->subjectsTableUnavailable()) { @@ -299,7 +299,7 @@ class CourierAgreementSignatures extends Controller public function destroySubject(Request $request, CourierSigningSubject $subject): JsonResponse { - $this->ensureCanManage(); + $this->ensureCanAdminister(); $this->ensureSubjectBelongsToCurrentCompany($subject); if ($response = $this->subjectsTableUnavailable()) { @@ -371,7 +371,7 @@ class CourierAgreementSignatures extends Controller private function deleteTask(Request $request, CourierAgreementSignature|CourierQuoteSignature $task): JsonResponse|RedirectResponse { - $this->ensureCanManage(); + $this->ensureCanAdminister(); abort_unless($task->company_id === (int) company_id(), 404); $request->validate(['delete_confirmed' => ['required', 'accepted']]); @@ -608,12 +608,17 @@ class CourierAgreementSignatures extends Controller private function ensureCanManage(): void { abort_unless( - in_array(SystemAccess::roleName(user()), [SystemAccess::SUPER_ADMIN, SystemAccess::ADMIN], true), + AgreementSigningPermissions::canOperate(), 403, - '当前账号没有协议签署管理权限。', + '当前账号没有协议签署操作权限,请联系管理员授权。', ); } + private function ensureCanAdminister(): void + { + abort_unless(AgreementSigningPermissions::canAdminister(), 403, '当前账号没有协议签署管理权限。'); + } + private function subjectData(Request $request): array { $data = $request->validate([ diff --git a/app/Http/Controllers/SystemSettings/Users.php b/app/Http/Controllers/SystemSettings/Users.php index ab984b2b..568ec513 100644 --- a/app/Http/Controllers/SystemSettings/Users.php +++ b/app/Http/Controllers/SystemSettings/Users.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers\SystemSettings; use App\Models\Auth\Role; use App\Models\Auth\User; use App\Models\Auth\UserAccessGroup; +use App\Utilities\AgreementSigningPermissions; use App\Utilities\SystemAccess; use Illuminate\Http\Request; use Illuminate\Routing\Controller; @@ -66,6 +67,9 @@ class Users extends Controller $created->roles()->attach($role->id); $created->companies()->attach(company_id()); + if (array_key_exists('agreement_signing_allowed', $data)) { + AgreementSigningPermissions::setGranted($created, (bool) $data['agreement_signing_allowed']); + } }); flash('用户已新增。')->success(); @@ -122,6 +126,9 @@ class Users extends Controller $managedUser->update($attributes); $managedUser->syncRoles([$role->id]); + if (array_key_exists('agreement_signing_allowed', $data)) { + AgreementSigningPermissions::setGranted($managedUser, (bool) $data['agreement_signing_allowed']); + } }); $managedUser->flushCache(); @@ -182,6 +189,7 @@ class Users extends Controller 'role' => ['required', Rule::in($assignable)], 'password' => [$managedUser ? 'nullable' : 'required', 'string', 'min:8', 'confirmed'], 'enabled' => ['nullable', 'boolean'], + 'agreement_signing_allowed' => ['sometimes', 'boolean'], ]); } diff --git a/app/Utilities/AgreementSigningPermissions.php b/app/Utilities/AgreementSigningPermissions.php new file mode 100644 index 00000000..3fa533fd --- /dev/null +++ b/app/Utilities/AgreementSigningPermissions.php @@ -0,0 +1,58 @@ +id])); + if ($granted) { + $ids[] = (int) $target->id; + } + setting()->set(self::SETTING_KEY, json_encode($ids)); + setting()->save(); + } + + public static function canOperate(?User $actor = null): bool + { + $actor ??= user(); + if (! $actor || ! $actor->enabled) { + return false; + } + + $role = SystemAccess::roleName($actor); + $granted = in_array($role, [SystemAccess::SUPER_ADMIN, SystemAccess::ADMIN], true) + || ($role === SystemAccess::USER && in_array((int) $actor->id, self::grantedUserIds(), true)); + if (! $granted || ! $actor->companies()->where('companies.id', company_id())->exists()) { + return false; + } + + $section = collect(SidebarPermissions::navigationFor($actor))->firstWhere('slug', 'courier-payables'); + + return collect($section['pages'] ?? []) + ->flatMap(fn (array $page): array => [$page, ...($page['children'] ?? [])]) + ->contains('slug', 'agreement-signing'); + } + + public static function canAdminister(?User $actor = null): bool + { + $actor ??= user(); + + return $actor && SystemAccess::canOpenSettings($actor) && self::canOperate($actor); + } +} diff --git a/resources/views/business/pages/courier-payables/agreement-signing.blade.php b/resources/views/business/pages/courier-payables/agreement-signing.blade.php index b7ebe95c..f6993334 100644 --- a/resources/views/business/pages/courier-payables/agreement-signing.blade.php +++ b/resources/views/business/pages/courier-payables/agreement-signing.blade.php @@ -13,6 +13,8 @@ @php($agreementCompanyName = $agreementDefaultSubject?->name ?: company()?->name ?: '当前公司') @php($agreementSubjectPayload = $agreementSubjects->map(fn ($subject) => ['id' => $subject->id, 'name' => $subject->name, 'unified_social_credit_code' => $subject->unified_social_credit_code, 'is_default' => (bool) $subject->is_default])->values()) @php($esignConfigured = \App\Services\Esign\EsignClient::configured()) +@php($agreementCanOperate = \App\Utilities\AgreementSigningPermissions::canOperate()) +@php($agreementCanAdminister = \App\Utilities\AgreementSigningPermissions::canAdminister()) @php($agreementSearch = trim((string) request('agreement_search', ''))) @php($agreementStatus = trim((string) request('agreement_status', ''))) @php($agreementType = trim((string) request('agreement_type', ''))) @@ -1344,6 +1346,10 @@ + @unless ($agreementCanOperate) +
当前账号仅可查看协议签署,尚未获签署操作授权,请联系管理员。
+ @endunless +