fix: 取消OA付款待核实中间状态

This commit is contained in:
yueyang 2026-10-29 20:20:57 +08:00
parent 6d3b75bf6d
commit 263bf5bd51
7 changed files with 39 additions and 40 deletions

View File

@ -18,15 +18,15 @@ class DingProcessDetailMirrorRepository
public const PAYMENT_STATES = [
'待付款',
'已付款',
'付款待核实',
'不涉及付款',
];
public const LEGACY_PAYMENT_STATE = '未确认';
public const LEGACY_PAYMENT_STATE_MAP = [
'未确认' => '付款待核实',
'出纳状态待同步' => '付款待核实',
'付款待核实' => '待付款',
'未确认' => '待付款',
'出纳状态待同步' => '待付款',
'出纳未开始' => '待付款',
'出纳待打款' => '待付款',
'出纳退回' => '待付款',
@ -375,10 +375,8 @@ class DingProcessDetailMirrorRepository
AND {$sourceState} <> 'not_applicable'
THEN '已付款'
WHEN {$cashierState} IN ('pending', 'returned', 'not_started') THEN '待付款'
WHEN {$workflowStatus} = '审批中'
AND NOT ({$paymentFacts})
THEN '待付款'
ELSE '付款待核实'
WHEN {$workflowStatus} = '审批中' AND ({$paymentFacts}) THEN '已付款'
ELSE '待付款'
END";
}

View File

@ -23,9 +23,11 @@ class DingProcessDetailMirrorSynchronizer
private const SOURCE = 'operations_replica';
private const APPROVAL_API_FALLBACK_LIMIT = 50;
private const APPROVAL_API_DRAIN_LIMIT = 750;
private const APPROVAL_API_BACKLOG_BATCH_LIMIT = 25;
private const APPROVAL_API_BACKLOG_BATCH_LIMIT = 750;
private const BUSINESS_ID_SYNC_LIMIT = 50;
private readonly ConnectionInterface $connection;
@ -164,7 +166,7 @@ class DingProcessDetailMirrorSynchronizer
if ($businessIds === []) {
throw new RuntimeException('至少需要一个审批编号。');
}
if (count($businessIds) > self::APPROVAL_API_FALLBACK_LIMIT) {
if (count($businessIds) > self::BUSINESS_ID_SYNC_LIMIT) {
throw new RuntimeException('单次最多按审批编号补取 50 个流程。');
}
@ -496,7 +498,7 @@ class DingProcessDetailMirrorSynchronizer
'ding_process_detail_mirror',
'cashier_checked_at',
);
$remainingAttempts = self::APPROVAL_API_FALLBACK_LIMIT - $this->approvalApiAttempts;
$remainingAttempts = self::APPROVAL_API_DRAIN_LIMIT - $this->approvalApiAttempts;
if (! $this->approvalApiAvailable || $remainingAttempts <= 0) {
return [];
}
@ -1279,7 +1281,7 @@ class DingProcessDetailMirrorSynchronizer
}
if (! $this->approvalClient->isConfigured()
|| ! $this->approvalApiAvailable
|| $this->approvalApiAttempts >= self::APPROVAL_API_FALLBACK_LIMIT) {
|| $this->approvalApiAttempts >= self::APPROVAL_API_DRAIN_LIMIT) {
return null;
}

View File

@ -25,13 +25,12 @@
};
$paymentStateClass = static fn (string $state): string => match ($state) {
'已付款' => 'is-success',
'待付款', '付款待核实', '未确认' => 'is-warning',
'待付款', '未确认' => 'is-warning',
'不涉及付款' => 'is-neutral',
default => 'is-neutral',
};
$paymentSummaryLabel = match ($filters['payment_state'] ?? '') {
'已付款' => '已确认付款合计',
'付款待核实' => '待核实付款明细合计',
default => '付款明细合计',
};
$dateTimeText = static function (mixed $value): string {
@ -85,14 +84,14 @@
return $node;
}
return ($row->status ?? '') === '审批中' ? '未核验' : '-';
return '-';
};
$cashierNodeText = static function (object $row): string {
if (($row->payment_state ?? '') === '不涉及付款') {
return '-';
}
$node = trim((string) ($row->cashier_task_name ?? '')) ?: '出纳节点';
$node = trim((string) ($row->cashier_task_name ?? '')) ?: '出纳打款';
$status = match ((string) ($row->cashier_status ?? '')) {
'completed' => '已完成',
'pending' => '处理中',
@ -100,7 +99,12 @@
'not_started' => '未开始',
'terminated' => '已终止',
'not_applicable' => '不涉及',
default => '待核验',
'pending_sync' => (float) ($row->payment_fact_amount ?? 0) > 0
? '已完成'
: '待付款',
default => (float) ($row->payment_fact_amount ?? 0) > 0
? '已完成'
: '待付款',
};
return $node . ' · ' . $status;
@ -819,11 +823,8 @@
金额合计按审批费用明细汇总,付款明细合计按审批表单中的结构化付款明细汇总,不等同于出纳已确认付款;
同一笔付款不会因关联多条费用而重复计算。
付款状态按钉钉“出纳打款”节点判断;付款差额按“费用合计 − 付款明细合计”单独计算,不参与付款状态判断。
审批中的流程如果尚未出现付款明细,默认显示“待付款”;已有付款明细但尚未取得可靠出纳节点时,才显示“付款待核实”。
当前节点、节点进入时间和出纳节点来自最近一次成功读取的钉钉任务;尚未取得任务结果显示“未核验”。
@if (in_array('付款待核实', $paymentStates, true))
“付款待核实”仅表示已有付款明细但尚未取得可靠的出纳节点任务。
@endif
审批中的流程在出纳节点完成或出现结构化付款事实前显示“待付款”;已完成流程或已确认出纳打款显示“已付款”。
当前节点、节点进入时间和出纳节点来自钉钉任务同步,后台会持续补查未完成的在途流程。
当前展示的是当前账号权限范围内可读取的钉钉OA审批流程;审批中的金额和行项目仍可能随流程变化。
企业级全量数据待领导开通 OA 权限后切换。
</p>

View File

@ -63,7 +63,6 @@ class ProcessDetailsPageTest extends FeatureTestCase
'payment_states' => [
'待付款',
'已付款',
'付款待核实',
'不涉及付款',
],
]);
@ -80,7 +79,7 @@ class ProcessDetailsPageTest extends FeatureTestCase
'section' => 'process-data',
'page' => 'oa-process',
'per_page' => 100,
'payment_state' => '付款待核实',
'payment_state' => '待付款',
]))->assertOk()
->assertSee('流程数据')
->assertSee('OA流程')
@ -105,9 +104,10 @@ class ProcessDetailsPageTest extends FeatureTestCase
->assertSee('财务用途审批')
->assertSee('1小时30分钟')
->assertSee('出纳打款 · 已完成')
->assertSee('待核实付款明细合计')
->assertSee('付款明细合计')
->assertSee('已付款')
->assertSee('付款待核实')
->assertDontSee('付款待核实')
->assertDontSee('未核验')
->assertSee('付款明细金额')
->assertSee('付款差额')
->assertSee('0.20')

View File

@ -177,7 +177,7 @@ class DingProcessDetailMirrorRepositoryTest extends TestCase
);
}
public function test_pending_cashier_status_with_payment_facts_remains_unverified(): void
public function test_pending_cashier_status_with_payment_facts_is_paid(): void
{
DB::connection('business_mirror')
->table('ding_process_detail_mirror')
@ -185,14 +185,14 @@ class DingProcessDetailMirrorRepositoryTest extends TestCase
->update(['cashier_status' => 'pending_sync', 'cashier_checked_at' => null]);
$result = $this->repository->paginate(
['payment_state' => '付款待核实'],
['payment_state' => '已付款'],
1,
50,
);
$this->assertSame(2, $result['total']);
$this->assertSame(4, $result['total']);
$this->assertSame(
['付款待核实'],
['已付款'],
collect($result['data'])->pluck('payment_state')->unique()->values()->all(),
);
}

View File

@ -532,7 +532,7 @@ class DingProcessDetailMirrorSynchronizerTest extends TestCase
);
}
public function test_incremental_sync_reserves_api_quota_for_cashier_backlog(): void
public function test_incremental_sync_drains_cashier_backlog_before_changed_workflows(): void
{
$connection = DB::connection('business_mirror');
$now = now();
@ -624,20 +624,20 @@ class DingProcessDetailMirrorSynchronizerTest extends TestCase
$expectedBacklog = array_map(
static fn (array $workflow): string => (string) $workflow['processInstanceId'],
array_slice($backlog, 0, 25),
$backlog,
);
$this->assertCount(50, $this->approvalClient->calls);
$this->assertSame($expectedBacklog, array_slice($this->approvalClient->calls, 0, 25));
$this->assertCount(90, $this->approvalClient->calls);
$this->assertSame($expectedBacklog, array_slice($this->approvalClient->calls, 0, 30));
$this->assertSame(
'backlog-024',
'backlog-029',
json_decode((string) $connection->table('business_mirror_table_states')
->value('cursor'), true)['approval_api_cursor'],
);
$this->assertSame('completed', $connection->table('ding_process_detail_mirror')
->where('process_instance_id', 'backlog-024')
->where('process_instance_id', 'backlog-029')
->value('cashier_status'));
$this->assertNotNull($connection->table('ding_process_detail_mirror')
->where('process_instance_id', 'backlog-024')
->where('process_instance_id', 'backlog-029')
->value('cashier_checked_at'));
}

View File

@ -76,7 +76,6 @@ class ProcessDetailsPageDataTest extends TestCase
'payment_states' => [
'待付款',
'已付款',
'付款待核实',
'不涉及付款',
],
]);
@ -106,7 +105,6 @@ class ProcessDetailsPageDataTest extends TestCase
[
'待付款',
'已付款',
'付款待核实',
'不涉及付款',
],
$data['paymentStates'],
@ -140,7 +138,7 @@ class ProcessDetailsPageDataTest extends TestCase
->method('filterOptions')
->with($this->callback(static fn (array $filters): bool =>
$filters['status'] === '已完成'
&& $filters['payment_state'] === '付款待核实'
&& $filters['payment_state'] === '待付款'
))
->willReturn([
'document_types' => ['公摊日常报销'],