feat: add kuaidi100 logistics sync

This commit is contained in:
wushumin
2026-05-26 17:08:33 +08:00
parent 09d9fcbe69
commit a5f00d7e31
31 changed files with 2596 additions and 67 deletions

View File

@@ -448,6 +448,30 @@ class SystemConfigsController
['config_key' => 'endpoint', 'title' => '短信 Endpoint', 'field_type' => 'text', 'placeholder' => '默认可留空', 'remark' => '如不填写则按 SDK 默认规则解析', 'is_secret' => false],
],
],
'kuaidi100' => [
'group_name' => '快递100',
'group_desc' => '配置快递100实时查询与物流订阅推送用于订单寄送和回寄物流轨迹同步。',
'items' => [
[
'config_key' => 'enabled',
'title' => '同步开关',
'field_type' => 'select',
'placeholder' => '请选择是否启用',
'remark' => '启用后新提交的运单会尝试订阅快递100推送后台进程会定时补查轨迹。',
'is_secret' => false,
'default_value' => 'disabled',
'options' => [
['label' => '停用', 'value' => 'disabled'],
['label' => '启用', 'value' => 'enabled'],
],
],
['config_key' => 'customer', 'title' => 'Customer', 'field_type' => 'text', 'placeholder' => '请输入快递100 Customer', 'remark' => '实时查询接口签名使用的 Customer。', 'is_secret' => false, 'visible_when' => ['config_key' => 'enabled', 'equals' => 'enabled']],
['config_key' => 'key', 'title' => 'Key', 'field_type' => 'password', 'placeholder' => '请输入快递100 Key', 'remark' => '用于实时查询签名和订阅推送。请妥善保管。', 'is_secret' => true, 'visible_when' => ['config_key' => 'enabled', 'equals' => 'enabled']],
['config_key' => 'callback_url', 'title' => '推送回调地址', 'field_type' => 'text', 'placeholder' => '例如 https://api.example.com/api/open/kuaidi100/callback', 'remark' => '需公网可访问;生产建议填本系统 /api/open/kuaidi100/callback 的完整地址。', 'is_secret' => false, 'visible_when' => ['config_key' => 'enabled', 'equals' => 'enabled']],
['config_key' => 'callback_salt', 'title' => '回调 Salt', 'field_type' => 'password', 'placeholder' => '可选需与快递100订阅参数保持一致', 'remark' => '用于快递100推送签名增强如账号未配置可留空。', 'is_secret' => true, 'visible_when' => ['config_key' => 'enabled', 'equals' => 'enabled']],
['config_key' => 'query_min_interval_minutes', 'title' => '最小查询间隔(分钟)', 'field_type' => 'text', 'placeholder' => '默认 30', 'remark' => '定时补查同一运单的最小间隔,允许 5-1440。', 'is_secret' => false, 'default_value' => '30', 'visible_when' => ['config_key' => 'enabled', 'equals' => 'enabled']],
],
],
];
}
@@ -467,6 +491,7 @@ class SystemConfigsController
{
$driver = (new FileStorageConfigService())->normalizeDriver((string)($configValueMap['file_storage.driver'] ?? 'local'));
if ($driver === 'local') {
$this->validateKuaidi100Config($configValueMap);
return;
}
@@ -489,10 +514,12 @@ class SystemConfigsController
throw new \RuntimeException('直传文件大小上限需填写 1-2048 之间的整数');
}
$this->validateKuaidi100Config($configValueMap);
return;
}
if ($driver !== 'qiniu') {
$this->validateKuaidi100Config($configValueMap);
return;
}
@@ -513,6 +540,35 @@ class SystemConfigsController
if ($publicBaseUrl === '' && $bucketDomain === '') {
throw new \RuntimeException('当前已切换为七牛云存储,请至少填写公开访问域名或七牛公网访问域名');
}
$this->validateKuaidi100Config($configValueMap);
}
private function validateKuaidi100Config(array $configValueMap): void
{
$enabled = (string)($configValueMap['kuaidi100.enabled'] ?? 'disabled');
if (!in_array($enabled, ['enabled', 'disabled'], true)) {
throw new \RuntimeException('快递100同步开关配置无效');
}
if ($enabled !== 'enabled') {
return;
}
$required = [
'kuaidi100.customer' => '快递100 Customer',
'kuaidi100.key' => '快递100 Key',
'kuaidi100.callback_url' => '快递100推送回调地址',
];
foreach ($required as $key => $label) {
if (trim((string)($configValueMap[$key] ?? '')) === '') {
throw new \RuntimeException(sprintf('当前已启用快递100请先填写 %s', $label));
}
}
$interval = trim((string)($configValueMap['kuaidi100.query_min_interval_minutes'] ?? '30'));
if ($interval !== '' && (!ctype_digit($interval) || (int)$interval < 5 || (int)$interval > 1440)) {
throw new \RuntimeException('快递100最小查询间隔需填写 5-1440 之间的整数');
}
}
private function applyDerivedConfigValues(array &$configValueMap): void