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

@@ -2150,6 +2150,8 @@ class AppraisalTasksController
$verify = $this->createOrUpdateVerifyRecord($report, $now);
if (($report['report_type'] ?? 'appraisal') === 'appraisal' && (int)($report['order_id'] ?? 0) > 0) {
(new MaterialTagService())->syncBoundTagForReport($report, $request);
Db::name('orders')->where('id', (int)$report['order_id'])->update([
'order_status' => 'report_published',
'display_status' => '报告已出具',

View File

@@ -435,8 +435,10 @@ class ReportsController
$effectivePublishTime = $report['publish_time'] ?: $now;
$isOrderAppraisalReport = ($report['report_type'] ?? 'appraisal') === 'appraisal' && (int)($report['order_id'] ?? 0) > 0;
$materialTag = null;
$materialTagService = new MaterialTagService();
if ($isOrderAppraisalReport) {
$materialTag = (new MaterialTagService())->findBoundTagForReport($id);
$materialTag = $materialTagService->findBoundTagForReport($id)
?: $materialTagService->syncBoundTagForReport($report, $request);
if (!$materialTag) {
if ($qrInput === '') {
Db::rollback();
@@ -452,7 +454,7 @@ class ReportsController
return api_error('报告未关联鉴定任务,不能绑定吊牌发布', 422);
}
$materialTag = (new MaterialTagService())->bindTagToReportByTask((int)$task['id'], $qrInput, $request);
$materialTag = $materialTagService->bindTagToReportByTask((int)$task['id'], $qrInput, $request);
}
}
@@ -476,6 +478,7 @@ class ReportsController
if ($isOrderAppraisalReport) {
$this->refreshAppraisalSnapshot((int)$report['id'], (int)$report['order_id'], $report['service_provider'], $now);
$materialTag = $materialTagService->syncBoundTagForReport($report, $request) ?: $materialTag;
}
$verify = $this->createOrUpdateVerifyRecord($report, $now);

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'] : '';
}