master
lion 5 days ago
parent 08855e66ce
commit 697560708c

@ -13,7 +13,7 @@ use Throwable;
class VerifyQccEnterprisePackInfo extends Command
{
protected $signature = 'qcc:verify-pack-info
{company_id : 候选或已占额企业的本地企业 ID}
{company_id : 候选、已占额或待人工确认企业的本地企业 ID}
{--timeout=60 : 请求超时时间(秒,正整数)}
{--raw : 兼容旧用法,默认即输出完整响应}';
@ -34,9 +34,9 @@ class VerifyQccEnterprisePackInfo extends Command
}
$account = $company->qccAccount;
if (!$account || !in_array($account->status, [CompanyQccAccount::STATUS_SELECTED, CompanyQccAccount::STATUS_OCCUPIED], true)) {
if (!$account || !in_array($account->status, [CompanyQccAccount::STATUS_SELECTED, CompanyQccAccount::STATUS_OCCUPIED, CompanyQccAccount::STATUS_UNKNOWN], true)) {
$status = $account ? $account->status : 'none';
$this->error("企业必须处于候选(selected)或已占额(occupied)状态,当前状态:{$status}。");
$this->error("企业必须处于候选(selected)、已占额(occupied)或待人工确认(unknown)状态,当前状态:{$status}。");
return self::FAILURE;
}

@ -7,7 +7,7 @@
- 点击“获取更新”创建一个全量候选和已占额企业快照,不受新闻列表筛选和分页影响;仅 `company_qcc_accounts.status` 为 `selected` 或 `occupied` 的企业进入批次,按公司 ID 顺序执行。
- 执行前再次检查企业是否仍为候选或已占额;不符合的任务记录失败/跳过,不调用元禾。
- 单次请求使用元禾 `enterprise/packInfo`,连接超时 10 秒、总超时 60 秒;只有外层 `code=200` 且 `data.news` 是数组或 null 才进行处理。null/空数组记成功、0 新增;缺字段、非数组记失败。
- 本功能直接调用 Repository:code=200 且 data 中存在非空业务内容(新闻、股东等)时,仅将 selected 转为 occupied,记录首次成功时间、来源和引用;已占额及首次成功记录不重复改写。空数据、失败、超时不改状态。占额记录独立于新闻入库事务,避免本地保存失败丢失上游成功事实。`qcc:verify-pack-info` 诊断命令仅查询候选或已占额企业,按 code=200 判断成功,不修改企业状态,也不导入新闻。默认超时 60 秒,可用 `--timeout=120` 指定秒数;始终输出完整响应,保留 `--raw` 兼容旧用法。例如:`php artisan qcc:verify-pack-info 2280 --timeout=120 --raw`。成功退出码为 0,业务失败、超时或参数校验失败为 1。
- 本功能直接调用 Repository:code=200 且 data 中存在非空业务内容(新闻、股东等)时,仅将 selected 转为 occupied,记录首次成功时间、来源和引用;已占额及首次成功记录不重复改写。空数据、失败、超时不改状态。占额记录独立于新闻入库事务,避免本地保存失败丢失上游成功事实。`qcc:verify-pack-info` 诊断命令仅查询候选、已占额或待人工确认(unknown)企业,按 code=200 判断成功,不修改企业状态,也不导入新闻。默认超时 60 秒,可用 `--timeout=120` 指定秒数;始终输出完整响应,保留 `--raw` 兼容旧用法。例如:`php artisan qcc:verify-pack-info 2280 --timeout=120 --raw`。成功退出码为 0,业务失败、超时或参数校验失败为 1。
- 按企业、数据提供方及去重键建立唯一约束。去重键按 NewsId、Id、原文 URL 的优先级生成 SHA-256;来源标识必须跨次稳定。同一新闻关联不同公司分别保存。
- 重复采集只更新来源字段、原始 JSON 与最近采集信息,不覆盖标题、人工正文和人工留存结论;自动判断的记录会按本批次分类设置重新判断,始终不展示。不留存是逻辑状态,不删除记录。
- 原文 HTML 使用现有 TinyMCE 组件编辑,并通过服务端 HTMLPurifier 清理。来源 Content 独立保存,接口正文为空时不会伪造原文。

@ -39,7 +39,7 @@ class VerifyQccEnterprisePackInfoTest extends TestCase
DB::table('companies')->insert(['id' => 333, 'company_name' => '测试企业', 'credit_code' => 'test-credit']);
DB::table('company_qcc_accounts')->insert([
'company_id' => 333, 'status' => $status, 'first_success_ref' => 'original-ref',
'updated_at' => '2026-01-01 00:00:00',
'updated_at' => '2026-01-01 00:00:00', 'unknown_note' => '原有诊断备注',
]);
}
@ -64,6 +64,8 @@ class VerifyQccEnterprisePackInfoTest extends TestCase
return [
['selected', ['code' => 200, 'data' => ['news' => [['Title' => '<info>标题</info>']]]], [], 60, 0],
['occupied', ['code' => '200', 'data' => []], ['--timeout' => '120', '--raw' => true], 120, 0],
['unknown', ['code' => 200, 'data' => ['news' => []]], [], 60, 0],
['unknown', ['code' => 500], ['--timeout' => '120'], 120, 1],
['selected', ['code' => 0], [], 60, 1],
['occupied', ['code' => 500, 'msg' => '失败'], [], 60, 1],
['selected', ['data' => []], [], 60, 1],
@ -71,9 +73,9 @@ class VerifyQccEnterprisePackInfoTest extends TestCase
}
/** @dataProvider exceptionCases */
public function test_exception_leaves_account_unchanged(?string $raw): void
public function test_exception_leaves_account_unchanged(string $status, ?string $raw): void
{
$this->company('selected');
$this->company($status);
$before = DB::table('company_qcc_accounts')->get()->toJson();
$mock = Mockery::mock(YuanheRepository::class);
$mock->shouldReceive('enterprisePackInfo')->once()->andThrow(new YuanhePackInfoException('请求超时', null, null, $raw));
@ -85,7 +87,7 @@ class VerifyQccEnterprisePackInfoTest extends TestCase
public static function exceptionCases(): array
{
return [[null], ['<html>Bad Gateway</html>']];
return [['selected', null], ['selected', '<html>Bad Gateway</html>'], ['unknown', null], ['unknown', '<html>Bad Gateway</html>']];
}
/** @dataProvider rejectedCases */
@ -102,7 +104,7 @@ class VerifyQccEnterprisePackInfoTest extends TestCase
public static function rejectedCases(): array
{
return [
['unknown', []], ['non_occupying', []], ['selected', ['--timeout' => '0']],
['none', []], ['non_occupying', []], ['selected', ['--timeout' => '0']],
['selected', ['--timeout' => '-1']], ['selected', ['--timeout' => '1.5']],
['selected', ['--timeout' => 'abc']],
];

Loading…
Cancel
Save