修复协议文件签字盖章区域过小 #293

Merged
limeng merged 1 commits from fix/limeng-esign-sign-field-size into main 2026-10-11 10:17:33 +08:00
6 changed files with 252 additions and 37 deletions

View File

@ -1153,7 +1153,8 @@
.agreement-preview-signature {
margin-top: 2.5rem;
text-align: right;
padding: 0;
text-align: left;
}
.agreement-preview-signature--split {
@ -1163,6 +1164,9 @@
text-align: left;
}
.agreement-preview-signature-slot { padding: 0.75rem; }
.agreement-preview-signature-blank { height: 15rem; }
.agreement-preview-handwriting-blank { height: 6.25rem; }
.agreement-preview-list {
margin: 0.75rem 0;
padding-left: 1.4rem;
@ -1872,6 +1876,7 @@
<p>以上收款账户的变更,以我司的盖章为有效。</p>
<div class="agreement-preview-signature">
<p><span data-preview-bind="proofSigner">待填写</span>:</p>
<div class="agreement-preview-signature-blank"></div>
<p>日期:<span data-preview-bind="signatureDate">{{ now()->format('Y年n月j日') }}</span></p>
</div>
<p class="agreement-preview-page-number">第 1 页 / 共 1 页</p>
@ -1890,6 +1895,7 @@
<p>以上收款账户的变更,以我司的盖章为有效。</p>
<div class="agreement-preview-signature">
<p><span data-preview-bind="changeSigner">待填写</span>:</p>
<div class="agreement-preview-signature-blank"></div>
<p>日期:<span data-preview-bind="signatureDate">{{ now()->format('Y年n月j日') }}</span></p>
</div>
<p class="agreement-preview-page-number">第 1 页 / 共 1 页</p>
@ -1902,11 +1908,25 @@
<p data-entity-person-description hidden>原合作主体 <span class="agreement-preview-value" data-preview-bind="formerCompanyName">待填写</span> 已注销,由原公司法人 <span class="agreement-preview-value" data-preview-bind="formerLegalRepresentative">待填写</span> 以个人身份确认本证明。自 <span class="agreement-preview-value" data-preview-bind="changedCompanyStartDate">待填写</span> 起,改由 <span class="agreement-preview-value" data-preview-bind="changedCompanyName">待填写</span> 与贵公司开展业务。</p>
<p>变更后,原公司的各项事宜由变更后的公司继续执行。原公司的结算未付款项,由变更之后的公司提供的收款账户收款。原公司的业务和款项若出现法律上的纠纷,由变更后的公司承担责任。</p>
<p>特此证明!</p>
<div class="agreement-preview-signature">
<p data-entity-organization-signatures>变更前公司法人签字盖公章:</p>
<p data-entity-person-signature hidden>原公司法人个人签字:<span class="agreement-preview-value" data-preview-bind="formerLegalRepresentative">待填写</span></p>
<p>变更后公司法人签字盖公章:<span class="agreement-preview-value" data-preview-bind="changedCompanyName">待填写</span>(签署人:<span class="agreement-preview-value" data-preview-bind="changedLegalRepresentative">待填写</span>)</p>
<p>日期:<span data-preview-bind="signatureDate">{{ now()->format('Y年n月j日') }}</span></p>
<div class="agreement-preview-signature agreement-preview-signature--split">
<div class="agreement-preview-signature-slot">
<p data-entity-organization-signatures>变更前公司法人签字盖公章:<span class="agreement-preview-value" data-preview-bind="formerCompanyName">待填写</span></p>
<p data-entity-organization-signatures>签署人:<span class="agreement-preview-value" data-preview-bind="formerLegalRepresentative">待填写</span></p>
<p data-entity-person-signature hidden>原公司法人个人签字:<span class="agreement-preview-value" data-preview-bind="formerLegalRepresentative">待填写</span></p>
<div class="agreement-preview-signature-blank"></div>
<div data-entity-organization-signatures>
<p>法人签字:</p>
<div class="agreement-preview-handwriting-blank"></div>
</div>
<p>日期:<span data-preview-bind="signatureDate">{{ now()->format('Y年n月j日') }}</span></p>
</div>
<div class="agreement-preview-signature-slot">
<p>变更后公司法人签字盖公章:<span class="agreement-preview-value" data-preview-bind="changedCompanyName">待填写</span>(签署人:<span class="agreement-preview-value" data-preview-bind="changedLegalRepresentative">待填写</span>)</p>
<div class="agreement-preview-signature-blank"></div>
<p>法人签字:</p>
<div class="agreement-preview-handwriting-blank"></div>
<p>日期:<span data-preview-bind="signatureDate">{{ now()->format('Y年n月j日') }}</span></p>
</div>
</div>
<p class="agreement-preview-page-number">第 1 页 / 共 1 页</p>
</article>
@ -1919,6 +1939,7 @@
<div class="agreement-preview-signature">
<p><span data-preview-bind="sharedSignerLabel">确认企业</span>:<span class="agreement-preview-value" data-preview-bind="contractPartnerName">待填写</span></p>
<p data-shared-organization-signature>法人签字并公司盖章:</p>
<div class="agreement-preview-signature-blank"></div>
<p>日期:<span data-preview-bind="signatureDate">{{ now()->format('Y年n月j日') }}</span></p>
</div>
<p class="agreement-preview-page-number">第 1 页 / 共 1 页</p>
@ -1947,11 +1968,20 @@
</ol>
<p>委托代签以上事项时效性,以委托书上签的有效期为准,委托有效期:从 <span class="agreement-preview-value" data-preview-bind="authorizationStartDate">待填写</span> 至 <span class="agreement-preview-value" data-preview-bind="authorizationEndDate">待填写</span> 止。</p>
<div class="agreement-preview-signature agreement-preview-signature--split">
<p>委托方:<span data-preview-bind="principalName">待填写</span></p>
<p>受托方:<span data-preview-bind="trusteeName">待填写</span></p>
</div>
<div class="agreement-preview-signature">
<p>日期:<span data-preview-bind="signatureDate">{{ now()->format('Y年n月j日') }}</span></p>
<div class="agreement-preview-signature-slot">
<p>委托方:<span data-preview-bind="principalName">待填写</span></p>
<div class="agreement-preview-signature-blank"></div>
<p>签字:</p>
<div class="agreement-preview-handwriting-blank"></div>
<p>日期:<span data-preview-bind="signatureDate">{{ now()->format('Y年n月j日') }}</span></p>
</div>
<div class="agreement-preview-signature-slot">
<p>受托方:<span data-preview-bind="trusteeName">待填写</span></p>
<div class="agreement-preview-signature-blank"></div>
<p>签字:</p>
<div class="agreement-preview-handwriting-blank"></div>
<p>日期:<span data-preview-bind="signatureDate">{{ now()->format('Y年n月j日') }}</span></p>
</div>
</div>
<p class="agreement-preview-page-number">第 1 页 / 共 1 页</p>
</article>
@ -1971,7 +2001,7 @@
</div>
<p>双方确认以下报价版本作为快递服务结算依据。报价版本一经签署即形成独立留档,后续变价须生成新版本并重新签署。</p>
<div class="agreement-preview-quote-matrix" data-preview-bind="quoteMatrix">请选择报价版本后查看报价明细</div>
<div class="agreement-preview-signature"><p>乙方(快递方)签章:</p><p>日期:<span data-preview-bind="signatureDate">{{ now()->format('Y年n月j日') }}</span></p></div>
<div class="agreement-preview-signature"><p>乙方(快递方)签章:</p><div class="agreement-preview-signature-blank"></div><p>日期:<span data-preview-bind="signatureDate">{{ now()->format('Y年n月j日') }}</span></p></div>
<p class="agreement-preview-page-number">报价确认单 · 快递方单方签署</p>
</article>
</div>

View File

@ -124,14 +124,45 @@
@if ($preview)
<div class="agreement-preview-signature agreement-preview-signature--split">
<p>甲 方:<span class="agreement-preview-value" data-preview-bind="cooperationPartyAName">待填写</span></p>
<p>乙 方:<span class="agreement-preview-value" data-preview-bind="cooperationPartyBName">待填写</span></p>
<p>代表人:</p>
<p>代表人:</p>
<p>日 期:<span data-preview-bind="signatureDate">待填写</span></p>
<p>日 期:<span data-preview-bind="signatureDate">待填写</span></p>
<p>签约地:常州市</p>
<div class="agreement-preview-signature-slot">
<p>甲 方:<span class="agreement-preview-value" data-preview-bind="cooperationPartyAName">待填写</span></p>
<div class="agreement-preview-signature-blank"></div>
<p>代表人:</p>
<div class="agreement-preview-handwriting-blank"></div>
<p>日 期:<span data-preview-bind="signatureDate">待填写</span></p>
<p>签约地:常州市</p>
</div>
<div class="agreement-preview-signature-slot">
<p>乙 方:<span class="agreement-preview-value" data-preview-bind="cooperationPartyBName">待填写</span></p>
<div class="agreement-preview-signature-blank"></div>
<p>代表人:</p>
<div class="agreement-preview-handwriting-blank"></div>
<p>日 期:<span data-preview-bind="signatureDate">待填写</span></p>
<p>签约地:常州市</p>
</div>
</div>
@else
<div class="sign"><p>甲 方:{!! $mixedText($payload['cooperation_party_a_name'] ?? '') !!}</p><p>乙 方:{!! $mixedText($payload['cooperation_party_b_name'] ?? '') !!}</p><p>代表人:</p><p>代表人:</p><p>日 期:{!! $mixedText($signatureDate) !!}</p><p>日 期:{!! $mixedText($signatureDate) !!}</p><p>签约地:常州市</p></div>
<section class="contract-signatures">
<h4 class="contract-signatures__heading">签署及盖章</h4>
<table class="contract-signatures__table">
<tr>
<td>
<p class="contract-signatures__title">甲 方:{!! $mixedText($payload['cooperation_party_a_name'] ?? '') !!}</p>
<div class="contract-signatures__blank"></div>
<p class="contract-signatures__line">代表人:</p>
<div class="contract-signatures__handwriting"></div>
<p class="contract-signatures__line">日 期:{!! $mixedText($signatureDate) !!}</p>
<p class="contract-signatures__line">签约地:常州市</p>
</td>
<td>
<p class="contract-signatures__title">乙 方:{!! $mixedText($payload['cooperation_party_b_name'] ?? '') !!}</p>
<div class="contract-signatures__blank"></div>
<p class="contract-signatures__line">代表人:</p>
<div class="contract-signatures__handwriting"></div>
<p class="contract-signatures__line">日 期:{!! $mixedText($signatureDate) !!}</p>
<p class="contract-signatures__line">签约地:常州市</p>
</td>
</tr>
</table>
</section>
@endif

View File

@ -14,12 +14,28 @@
.meta { color: #595959; font-size: 11px; text-align: right; margin-bottom: 20px; }
.account { margin: 14px 0 20px 28px; }
.account div { margin: 6px 0; }
.sign { margin-top: 36px; text-align: right; page-break-inside: avoid; }
.sign p { margin: 8px 0; }
.authorization-list { margin: 0 0 12px; }
.authorization-item { display: table; width: 100%; padding-bottom: 4px; }
.authorization-item__number { display: table-cell; width: 24px; padding-right: 4px; vertical-align: top; white-space: nowrap; }
.authorization-item__text { display: table-cell; vertical-align: top; }
.sign { margin: 36px 0 0 auto; padding: 0; page-break-inside: avoid; text-align: left; }
.sign p { margin: 10px 0; min-height: 24px; }
.sign--single { width: 68%; }
.sign--split { width: 100%; margin-top: 30px; padding: 0; border: 0; }
.sign-grid { width: 100%; table-layout: fixed; border-collapse: separate; border-spacing: 14px 0; }
.sign-grid td { padding: 16px; vertical-align: top; }
.sign-grid__title { margin: 0 0 12px; font-weight: 700; }
.sign-grid__blank { height: 240px; }
.sign-grid__handwriting { height: 100px; }
.sign-grid__line { margin: 0 0 10px; min-height: 24px; }
.contract-signatures { page-break-before: always; margin-top: 0; padding-top: 12px; }
.contract-signatures__heading { margin: 0 0 16px; font-size: 14px; }
.contract-signatures__table { width: 100%; table-layout: fixed; border-collapse: separate; border-spacing: 14px 0; }
.contract-signatures__table td { padding: 18px; vertical-align: top; }
.contract-signatures__title { margin: 0 0 12px; font-weight: 700; }
.contract-signatures__blank { height: 240px; }
.contract-signatures__handwriting { height: 100px; }
.contract-signatures__line { margin: 0 0 10px; min-height: 24px; }
.page { page-break-after: always; }
.cooperation-parties { margin: 14px 0 20px; }
.cooperation-parties div { margin: 6px 0; }
@ -60,7 +76,7 @@
</div>
<p>请贵公司按照上述汇款资料付款,如因我司提供收款银行帐户资料错误,导致相关款项支付不到位,则由此产生的一切经济纠纷和责任由我司承担。我司承诺若上述收款银行帐户资料发生变化及时书面通知贵公司。</p>
<p>以上收款账户的变更,以我司的盖章为有效。</p>
<div class="sign"><p>公司盖章:</p><p>日期:{!! $mixedText($signatureDate) !!}</p></div>
<div class="sign sign--single"><p>公司盖章:</p><div class="sign-grid__blank"></div><p>日期:{!! $mixedText($signatureDate) !!}</p></div>
@elseif ($type === 'account-change')
<p><span class="latin">TO</span> <strong>{!! $mixedText($payload['company_full_name']) !!}</strong>:</p>
<p>基于我公司正规化管理的需要,同时保证广大客户的汇款安全,我司收款账户将于 {!! $mixedText($payload['account_change_date']) !!} 变更账户,之前相应的账户(收款账户为:{!! $mixedText($payload['old_account_name']) !!},账号:{!! $mixedText($payload['old_account_number']) !!})于 {!! $mixedText($payload['old_account_stop_date']) !!} 停止使用,即日起我司收款的银行帐户进行变更,自 {!! $mixedText($payload['new_account_effective_date']) !!} 起我司与贵司往来款项请汇款至以下新账户,新汇款资料如下:</p>
@ -70,7 +86,7 @@
<div>银行账户:{!! $mixedText($payload['new_bank_account']) !!}</div>
</div>
<p>如因我司提供收款银行帐户资料错误导致相关款项支付不到位,由此产生的一切经济纠纷和责任由我司承担。以上收款账户的变更,以我司的盖章为有效。</p>
<div class="sign"><p>公司盖章:</p><p>日期:{!! $mixedText($signatureDate) !!}</p></div>
<div class="sign sign--single"><p>公司盖章:</p><div class="sign-grid__blank"></div><p>日期:{!! $mixedText($signatureDate) !!}</p></div>
@elseif ($type === 'entity-change')
<p>致 <strong>{!! $mixedText($payload['company_full_name']) !!}</strong>:</p>
@if (filter_var($payload['entity_change_old_company_deregistered'] ?? false, FILTER_VALIDATE_BOOLEAN))
@ -80,14 +96,35 @@
@endif
<p>变更后,原公司的各项事宜由变更后的公司继续执行。原公司的结算未付款项,由变更之后的公司提供的收款账户收款。原公司的业务和款项若出现法律上的纠纷,由变更后的公司承担责任。</p>
<p>特此证明!</p>
<div class="sign">
@if (filter_var($payload['entity_change_old_company_deregistered'] ?? false, FILTER_VALIDATE_BOOLEAN))
<p>原公司法人个人签字:{!! $mixedText($payload['former_legal_representative'] ?? '') !!}</p>
@else
<p>变更前公司法人签字盖公章:{!! $mixedText($payload['former_company_name']) !!}(签署人:{!! $mixedText($payload['former_legal_representative'] ?? '') !!})</p>
@endif
<p>变更后公司法人签字盖公章:{!! $mixedText($payload['changed_company_name']) !!}(签署人:{!! $mixedText($payload['secondary_operator_name'] ?? '') !!})</p>
<p>日期:{!! $mixedText($signatureDate) !!}</p>
<div class="sign sign--split">
<table class="sign-grid">
<tr>
<td>
<p class="sign-grid__title">变更前主体</p>
@if (filter_var($payload['entity_change_old_company_deregistered'] ?? false, FILTER_VALIDATE_BOOLEAN))
<p class="sign-grid__line">原公司法人个人签字:{!! $mixedText($payload['former_legal_representative'] ?? '') !!}</p>
@else
<p class="sign-grid__line">变更前公司法人签字盖公章:{!! $mixedText($payload['former_company_name']) !!}</p>
<p class="sign-grid__line">签署人:{!! $mixedText($payload['former_legal_representative'] ?? '') !!}</p>
@endif
<div class="sign-grid__blank"></div>
@if (! filter_var($payload['entity_change_old_company_deregistered'] ?? false, FILTER_VALIDATE_BOOLEAN))
<p class="sign-grid__line">法人签字:</p>
<div class="sign-grid__handwriting"></div>
@endif
<p class="sign-grid__line">日期:{!! $mixedText($signatureDate) !!}</p>
</td>
<td>
<p class="sign-grid__title">变更后主体</p>
<p class="sign-grid__line">变更后公司法人签字盖公章:{!! $mixedText($payload['changed_company_name']) !!}</p>
<p class="sign-grid__line">签署人:{!! $mixedText($payload['secondary_operator_name'] ?? '') !!}</p>
<div class="sign-grid__blank"></div>
<p class="sign-grid__line">法人签字:</p>
<div class="sign-grid__handwriting"></div>
<p class="sign-grid__line">日期:{!! $mixedText($signatureDate) !!}</p>
</td>
</tr>
</table>
</div>
@elseif ($type === 'shared-contract')
<p>与 {!! $mixedText($payload['company_full_name'] ?? $signature->company_full_name) !!} 合作的 {!! $mixedText($sharedCourierText) !!},均归属于 {!! $mixedText($payload['contract_partner_name'] ?? '') !!},共用一份合同及同一份打款资料,合同签署及结算主体均为 {!! $mixedText($payload['contract_partner_name'] ?? '') !!}。</p>
@ -95,13 +132,14 @@
@if (filled($payload['shared_note'] ?? null))
<p>备注:{!! $mixedText($payload['shared_note']) !!}</p>
@endif
<div class="sign">
<div class="sign sign--single">
@if (($payload['counterparty_signer_type'] ?? 'organization') === 'person')
<p>确认人(个人签字):{!! $mixedText($payload['contract_partner_name'] ?? '') !!}</p>
@else
<p>确认企业:{!! $mixedText($payload['contract_partner_name'] ?? '') !!}</p>
<p>法人签字并公司盖章:</p>
@endif
<div class="sign-grid__blank"></div>
<p>日期:{!! $mixedText($signatureDate) !!}</p>
</div>
@elseif ($type === 'cooperation-contract')
@ -121,7 +159,14 @@
<div class="authorization-item"><span class="authorization-item__number latin">4.</span><span class="authorization-item__text">代表委托方代收 {!! $mixedText($payload['payment_counterparty']) !!} 的往来货款。</span></div>
</div>
<p>委托有效期:从 {!! $mixedText($payload['authorization_start_date']) !!} 至 {!! $mixedText($payload['authorization_end_date']) !!} 止。</p>
<div class="sign"><p>委托方:{!! $mixedText($payload['principal_name']) !!}</p><p>受托方:{!! $mixedText($payload['trustee_name']) !!}</p><p>日期:{!! $mixedText($signatureDate) !!}</p></div>
<div class="sign sign--split">
<table class="sign-grid">
<tr>
<td><p class="sign-grid__title">委托方</p><p class="sign-grid__line">{!! $mixedText($payload['principal_name']) !!}</p><div class="sign-grid__blank"></div><p class="sign-grid__line">签字:</p><div class="sign-grid__handwriting"></div><p class="sign-grid__line">日期:{!! $mixedText($signatureDate) !!}</p></td>
<td><p class="sign-grid__title">受托方</p><p class="sign-grid__line">{!! $mixedText($payload['trustee_name']) !!}</p><div class="sign-grid__blank"></div><p class="sign-grid__line">签字:</p><div class="sign-grid__handwriting"></div><p class="sign-grid__line">日期:{!! $mixedText($signatureDate) !!}</p></td>
</tr>
</table>
</div>
@endif
</body>
</html>

View File

@ -35,7 +35,8 @@
.signature { page-break-before: always; }
.signature h2 { margin-top: 0; }
.signature__meta { margin-bottom: 18px; color: #555; }
.signature__box { width: 250px; height: 82px; margin-left: auto; border: 1px solid #777; padding: 8px; color: #666; }
.signature__box { width: 360px; margin-left: auto; padding: 14px 16px; color: #666; page-break-inside: avoid; }
.signature__blank { height: 240px; }
.document-control { margin-top: 22px; border-top: 1px solid #bbb; padding-top: 6px; color: #777; font-size: 7.5px; text-align: right; }
</style>
</head>
@ -134,7 +135,7 @@
<section class="signature">
<h2>签署确认</h2>
<div class="signature__meta">报价版本:{!! $mixedText($version->version_code) !!} 快递公司:{!! $mixedText($version->carrier_name) !!} 执行日期:{!! $mixedText($version->effective_date?->toDateString()) !!}</div>
<div class="signature__box">乙方(快递方)签章:{!! $mixedText($version->carrier_name) !!}<br><br>签署日期:{!! $mixedText($signatureDate) !!}</div>
<div class="signature__box"><div>乙方(快递方)签章:{!! $mixedText($version->carrier_name) !!}</div><div class="signature__blank"></div><div>签署日期:{!! $mixedText($signatureDate) !!}</div></div>
<div class="document-control">生成时间:{!! $mixedText($generatedAt->format('Y-m-d H:i:s')) !!} · 版本 {!! $mixedText($version->version_code) !!}</div>
</section>
</body>

View File

@ -267,7 +267,8 @@ class CourierAgreementSignatureWorkflowTest extends FeatureTestCase
'fontPath' => str_replace('\\', '/', resource_path('fonts/DroidSansFallback.ttf')),
])->render();
$this->assertStringContainsString('原公司法人个人签字:原法人', strip_tags($html));
$this->assertStringContainsString('变更后公司法人签字盖公章:新公司有限公司(签署人:新法人)', strip_tags($html));
$this->assertStringContainsString('变更后公司法人签字盖公章:新公司有限公司', strip_tags($html));
$this->assertStringContainsString('签署人:新法人', strip_tags($html));
$this->assertStringNotContainsString('变更前公司法人签字盖公章', $html);
Http::assertSent(function (ClientRequest $request): bool {

View File

@ -0,0 +1,107 @@
<?php
namespace Tests\Unit;
use App\Models\Business\CourierAgreementSignature;
use App\Support\CourierAgreementPdf;
use DOMElement;
use Illuminate\Foundation\Testing\TestCase;
use Tests\CreatesApplication;
class CourierAgreementSignatureLayoutTest extends TestCase
{
use CreatesApplication;
public function test_cooperation_signature_page_fits_two_seals_and_separate_handwritten_signatures(): void
{
[$frames, $pageCount] = $this->renderLayout('cooperation-contract');
$seals = array_values(array_filter($frames, fn ($frame) => $frame['class'] === 'contract-signatures__blank'));
$handwriting = array_values(array_filter($frames, fn ($frame) => $frame['class'] === 'contract-signatures__handwriting'));
$this->assertCount(2, $seals);
$this->assertCount(2, $handwriting);
$this->assertGreaterThan(1, $pageCount);
foreach ($seals as $index => $seal) {
$this->assertGreaterThanOrEqual(159, $seal['width']);
$this->assertGreaterThanOrEqual(159, $seal['height']);
$this->assertSame($pageCount, $seal['page']);
$this->assertGreaterThanOrEqual(75, $handwriting[$index]['height']);
$this->assertGreaterThanOrEqual($seal['y'] + $seal['height'], $handwriting[$index]['y']);
}
$this->assertLessThanOrEqual($seals[1]['x'], $seals[0]['x'] + $seals[0]['width']);
foreach ($frames as $frame) {
$this->assertSame($pageCount, $frame['page'], 'Both parties and their dates must stay on the signature page.');
$this->assertLessThan(806, $frame['y'] + $frame['height']);
}
}
public function test_other_agreements_keep_full_size_seal_spaces_and_dates_together(): void
{
foreach (['account-proof', 'account-change', 'entity-change', 'shared-contract', 'authorization'] as $type) {
[$frames, $pageCount] = $this->renderLayout($type);
$seals = array_values(array_filter($frames, fn ($frame) => $frame['class'] === 'sign-grid__blank'));
$this->assertCount(in_array($type, ['entity-change', 'authorization'], true) ? 2 : 1, $seals);
foreach ($seals as $seal) {
$this->assertGreaterThanOrEqual(159, $seal['width'], $type);
$this->assertGreaterThanOrEqual(159, $seal['height'], $type);
}
foreach ($frames as $frame) {
$this->assertSame($pageCount, $frame['page'], "$type signature spaces and dates must stay together.");
$this->assertLessThan(806, $frame['y'] + $frame['height'], $type);
}
}
}
private function renderLayout(string $type): array
{
$payload = [
'company_full_name' => '示例甲方公司', 'signature_date' => '2026-10-11',
'account_proof_effective_date' => '2026-10-11',
'account_proof_account_name' => '示例合作公司', 'account_proof_bank_name' => '示例银行',
'account_proof_bank_account' => '0000000000000000',
'account_change_date' => '2026-10-11', 'old_account_name' => '原收款人',
'old_account_number' => '0000000000000000', 'old_account_stop_date' => '2026-10-11',
'new_account_effective_date' => '2026-10-11', 'new_account_name' => '新收款人',
'new_bank_name' => '示例银行', 'new_bank_account' => '0000000000000000',
'former_company_name' => '示例原公司', 'former_legal_representative' => '原法人',
'entity_change_date' => '2026-10-11', 'changed_company_name' => '示例新公司',
'changed_company_start_date' => '2026-10-11', 'secondary_operator_name' => '新法人',
'contract_partner_name' => '示例合作公司', 'shared_courier_names' => ['示例快递'],
'cooperation_party_a_name' => '示例甲方公司', 'cooperation_party_a_phone' => '00000000000',
'cooperation_party_b_name' => '示例乙方公司', 'cooperation_party_b_phone' => '00000000000',
'cooperation_start_date' => '2026-10-11', 'cooperation_end_date' => '2027-10-10',
'principal_name' => '示例委托方', 'principal_id_number' => 'EXAMPLE-ID',
'trustee_name' => '示例受托方', 'trustee_id_number' => 'EXAMPLE-ID',
'authorization_items' => ['1', '2', '3', '4'], 'bill_counterparty' => '示例对账方',
'loan_counterparty' => '示例借支方', 'payment_counterparty' => '示例付款方',
'authorization_start_date' => '2026-10-11', 'authorization_end_date' => '2027-10-10',
];
$signature = new CourierAgreementSignature([
'business_no' => 'AGR-LAYOUT-TEST', 'template_code' => CourierAgreementSignature::DOCUMENTS[$type]['code'],
'document_type' => $type, 'payload' => $payload,
]);
$frames = [];
$pdf = app('dompdf.wrapper');
$this->app->instance('dompdf.wrapper', $pdf);
$pdf->getDomPDF()->setCallbacks([[
'event' => 'end_frame',
'f' => function ($frame) use (&$frames, $pdf): void {
$node = $frame->get_node();
if (! $node instanceof DOMElement || ! preg_match('/(?:blank|handwriting|sign-grid__line|contract-signatures__title|contract-signatures__line)/', $node->getAttribute('class'))) {
return;
}
$position = $frame->get_position();
$frames[] = [
'class' => $node->getAttribute('class'),
'page' => $pdf->getDomPDF()->getCanvas()->get_page_number(),
'x' => $position['x'], 'y' => $position['y'],
'width' => $frame->get_margin_width(), 'height' => $frame->get_margin_height(),
];
},
]]);
app(CourierAgreementPdf::class)->render($signature);
$this->app->forgetInstance('dompdf.wrapper');
return [$frames, $pdf->getDomPDF()->getCanvas()->get_page_count()];
}
}