fix: sync material tag on report publish

This commit is contained in:
wushumin
2026-06-05 15:42:16 +08:00
parent 65d8f93410
commit ed87ea1541
3 changed files with 122 additions and 8 deletions

View File

@@ -484,6 +484,102 @@ class MaterialTagService
return $this->formatTagCode($tag, $report ?: null);
}
public function syncBoundTagForReport(array $report, ?Request $request = null): ?array
{
$reportId = (int)($report['id'] ?? 0);
$orderId = (int)($report['order_id'] ?? 0);
$reportNo = trim((string)($report['report_no'] ?? ''));
if ($reportId <= 0 || $orderId <= 0 || $reportNo === '' || ($report['report_type'] ?? 'appraisal') !== 'appraisal') {
return null;
}
$tag = Db::name('material_tag_codes')->where('report_id', $reportId)->find();
if (!$tag) {
$tag = Db::name('material_tag_codes')
->where('bound_order_id', $orderId)
->where('bind_status', 'bound')
->where('status', '<>', 'invalid')
->order('bound_at', 'desc')
->order('id', 'desc')
->find();
}
if (!$tag && $reportNo !== '') {
$tag = Db::name('material_tag_codes')
->where('report_no', $reportNo)
->where('bind_status', 'bound')
->where('status', '<>', 'invalid')
->order('id', 'desc')
->find();
}
if (!$tag) {
return null;
}
$batch = Db::name('material_batches')->where('id', (int)$tag['batch_id'])->find();
if (($tag['status'] ?? 'active') === 'invalid' || ($batch && ($batch['status'] ?? 'active') === 'invalid')) {
return null;
}
$now = date('Y-m-d H:i:s');
$payload = [
'report_id' => $reportId,
'report_no' => $reportNo,
'bind_status' => 'bound',
'bound_order_id' => $orderId,
'updated_at' => $now,
];
if (empty($tag['bound_by'])) {
$payload['bound_by'] = $request ? ((int)$request->header('x-admin-id', 0) ?: null) : null;
}
if (trim((string)($tag['bound_by_name'] ?? '')) === '') {
$payload['bound_by_name'] = $request ? trim((string)$request->header('x-admin-name', '')) : '';
}
if (empty($tag['bound_at'])) {
$payload['bound_at'] = $now;
}
Db::name('material_tag_codes')->where('id', (int)$tag['id'])->update($payload);
$fresh = Db::name('material_tag_codes')->where('id', (int)$tag['id'])->find();
return $this->formatTagCode($fresh ?: array_merge($tag, $payload), $report);
}
private function findPublishedReportForTag(array $tag): ?array
{
if ((int)($tag['report_id'] ?? 0) > 0) {
$report = Db::name('reports')
->where('id', (int)$tag['report_id'])
->where('report_status', 'published')
->find();
if ($report) {
return $report;
}
}
$reportNo = trim((string)($tag['report_no'] ?? ''));
if ($reportNo !== '') {
$report = Db::name('reports')
->where('report_no', $reportNo)
->where('report_status', 'published')
->find();
if ($report) {
return $report;
}
}
$orderId = (int)($tag['bound_order_id'] ?? 0);
if ($orderId <= 0) {
return null;
}
return Db::name('reports')
->where('order_id', $orderId)
->where('report_type', 'appraisal')
->where('report_status', 'published')
->order('publish_time', 'desc')
->order('id', 'desc')
->find() ?: null;
}
public function showPublicTag(string $token, Request $request): array
{
$tag = Db::name('material_tag_codes')->where('qr_token', $token)->find();
@@ -521,6 +617,14 @@ class MaterialTagService
$report = (int)($tag['report_id'] ?? 0) > 0
? Db::name('reports')->where('id', (int)$tag['report_id'])->find()
: null;
$publishedReport = $this->findPublishedReportForTag($tag);
if ($publishedReport && (!$report || ($report['report_status'] ?? '') !== 'published' || (int)$report['id'] !== (int)$publishedReport['id'])) {
$this->syncBoundTagForReport($publishedReport, $request);
$tag = Db::name('material_tag_codes')->where('id', (int)$tag['id'])->find() ?: $tag;
$tag['scan_count'] = max((int)$tag['scan_count'], 1);
$tag['last_scanned_at'] = $now;
$report = $publishedReport;
}
if (!$report) {
return [
@@ -597,6 +701,12 @@ class MaterialTagService
$report = (int)($tag['report_id'] ?? 0) > 0
? Db::name('reports')->where('id', (int)$tag['report_id'])->find()
: null;
$publishedReport = $this->findPublishedReportForTag($tag);
if ($publishedReport && (!$report || ($report['report_status'] ?? '') !== 'published' || (int)$report['id'] !== (int)$publishedReport['id'])) {
$this->syncBoundTagForReport($publishedReport, $request);
$tag = Db::name('material_tag_codes')->where('id', (int)$tag['id'])->find() ?: $tag;
$report = $publishedReport;
}
$passed = $report
&& ($report['report_status'] ?? '') === 'published'
@@ -963,8 +1073,7 @@ class MaterialTagService
$tag = Db::name('material_tag_codes')->where('qr_token', $token)->find();
if (
!$tag
|| (int)($tag['report_id'] ?? 0) <= 0
|| ($tag['bind_status'] ?? '') !== 'bound'
|| ((int)($tag['report_id'] ?? 0) <= 0 && (int)($tag['bound_order_id'] ?? 0) <= 0 && trim((string)($tag['report_no'] ?? '')) === '')
|| ($tag['status'] ?? 'active') === 'invalid'
) {
return '';
@@ -975,10 +1084,10 @@ class MaterialTagService
return '';
}
$report = Db::name('reports')
->where('id', (int)$tag['report_id'])
->where('report_status', 'published')
->find();
$report = $this->findPublishedReportForTag($tag);
if ($report) {
$this->syncBoundTagForReport($report);
}
return $report ? (string)$report['report_no'] : '';
}