快递应付 → 快递报价 下新增「快递入驻」页:生成入驻二维码发给快递方,
对方免登录在手机上填写主体、联系人、结算账户、报价并上传资质,
内部对接人初审、管理员财务复审后生成首版报价,协议签署完成后开通。
- 新增三张表 business_courier_onboardings / _files / _events(纯新增,不改旧表)
- 免登录填报页 /onboarding/courier/{token}:40 位随机 token,可暂存、提交、退回后补件,
链接有效期可延长、可作废;银行账号加密存储;附件存 uploads 盘
- 内置纯 PHP 二维码生成(App\Support\QrCode,SVG 输出,无新增依赖)
- 财务复审:确认系统快递名称(唯一),快递所填报价写成报价管理的 CourierQuoteVersion,
可直接在协议签署页发起报价确认单;初审人不能复审
- 开通:需匹配到已签署的协议签署任务,或填写线下签署说明
- 快递资料页新增「入驻快递」页签,列出已开通的入驻快递
- 新增 CourierOnboardingWorkflowTest(8 个用例),更新快递报价目录顺序断言
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019gzfsnV3fJ89CoUy1D9V9g
49 lines
1.3 KiB
PHP
49 lines
1.3 KiB
PHP
<?php
|
|
|
|
namespace App\Models\Business;
|
|
|
|
use App\Abstracts\Model;
|
|
|
|
class CourierOnboardingFile extends Model
|
|
{
|
|
public const KINDS = [
|
|
'business_license' => '营业执照',
|
|
'legal_id_card' => '法人身份证(正反面)',
|
|
'bank_account_proof' => '开户许可证 / 银行账户证明',
|
|
'operating_permit' => '快递经营许可证',
|
|
'quote_sheet' => '盖章报价单',
|
|
'other' => '其他资料',
|
|
];
|
|
|
|
/** 提交审核前必须上传的资料。 */
|
|
public const REQUIRED_KINDS = ['business_license', 'bank_account_proof', 'quote_sheet'];
|
|
|
|
protected $table = 'business_courier_onboarding_files';
|
|
|
|
protected $fillable = ['company_id', 'onboarding_id', 'kind', 'original_name', 'path', 'mime', 'size'];
|
|
|
|
protected $casts = [
|
|
'company_id' => 'integer',
|
|
'onboarding_id' => 'integer',
|
|
'size' => 'integer',
|
|
'deleted_at' => 'datetime',
|
|
];
|
|
|
|
public function kindLabel(): string
|
|
{
|
|
return self::KINDS[$this->kind] ?? $this->kind;
|
|
}
|
|
|
|
public function isImage(): bool
|
|
{
|
|
return str_starts_with((string) $this->mime, 'image/');
|
|
}
|
|
|
|
public function sizeLabel(): string
|
|
{
|
|
$size = (int) $this->size;
|
|
|
|
return $size >= 1048576 ? sprintf('%.1f MB', $size / 1048576) : sprintf('%d KB', max(1, (int) ceil($size / 1024)));
|
|
}
|
|
}
|