chore: prepare release build

This commit is contained in:
wushumin
2026-05-16 16:32:56 +08:00
parent dd56e0861b
commit deecb5d33e
28 changed files with 4396 additions and 361 deletions

View File

@@ -75,6 +75,7 @@ class AppraisalTasksController
->select()
->toArray();
$this->applyTaskScopeFilterRows($allRows, $request, $scope);
$this->attachTransferFlowToRows($allRows);
$list = $this->buildGroupedTaskList($allRows, $reportMap);
$total = count($list);
@@ -166,6 +167,7 @@ class AppraisalTasksController
$report = $this->findLatestAppraisalReport((int)$task['order_id']);
$materialTag = $report ? (new MaterialTagService())->findBoundTagForReport((int)$report['id']) : null;
$transferFlow = $this->latestTransferFlowForOrder((int)$task['order_id']);
$effectiveStatus = $this->effectiveTaskStatus($task, $report);
if ($effectiveStatus !== $task['status']) {
Db::name('appraisal_tasks')->where('id', (int)$task['id'])->update([
@@ -232,6 +234,7 @@ class AppraisalTasksController
->order('t.id', 'asc')
->select()
->toArray();
$this->attachTransferFlowToRows($stageTaskRows);
$stageTasks = array_map(function (array $item) use ($id, $stageReportMap) {
$row = $this->normalizeTaskListRow($item, $stageReportMap[(int)$item['order_id']] ?? null);
@@ -305,6 +308,7 @@ class AppraisalTasksController
'submitted_at' => $task['submitted_at'],
'sla_deadline' => $task['sla_deadline'],
'is_overtime' => (bool)$task['is_overtime'],
'internal_tag_no' => (string)($transferFlow['internal_tag_no'] ?? ''),
],
'report_summary' => $report ? [
'id' => (int)$report['id'],
@@ -373,10 +377,6 @@ class AppraisalTasksController
if (!$task) {
return api_error('任务不存在', 404);
}
if (($task['service_provider'] ?? '') === 'zhongjian') {
return api_error('中检订单不使用平台验真吊牌', 422);
}
$operatorGuard = $this->guardTaskOperator($request, $task);
if ($operatorGuard['error']) {
return $operatorGuard['error'];
@@ -426,23 +426,25 @@ class AppraisalTasksController
if (!$task) {
return api_error('任务不存在', 404);
}
if (($task['service_provider'] ?? '') === 'zhongjian') {
return api_error('中检订单不使用平台验真吊牌', 422);
}
Db::startTrans();
try {
$tag = (new MaterialTagService())->bindTagToReportByTask($id, $qrInput, $request);
$report = $this->findLatestAppraisalReport((int)$task['order_id']);
if (!$report) {
Db::rollback();
return api_error('请先提交鉴定结论生成报告草稿', 422);
}
$publish = $this->publishReportRecord($report, $request);
$publish = $this->publishReportRecord($report, $request, false);
(new FulfillmentFlowService())->markReportPublished((int)$task['order_id'], $request);
Db::commit();
} catch (\InvalidArgumentException $e) {
Db::rollback();
return api_error($e->getMessage(), 422);
} catch (\RuntimeException $e) {
Db::rollback();
return api_error($e->getMessage(), $e->getCode() ?: 404);
} catch (\Throwable $e) {
Db::rollback();
return api_error('验真吊牌绑定或报告发布失败', 500, ['detail' => $e->getMessage()]);
}
@@ -457,6 +459,7 @@ class AppraisalTasksController
{
$id = (int)$request->input('id', 0);
$reportNo = trim((string)$request->input('zhongjian_report_no', ''));
$qrInput = trim((string)$request->input('qr_input', ''));
$files = $this->evidenceService()->normalize($request->input('report_files', []), $request, true);
if ($id <= 0) {
return api_error('任务 ID 不能为空', 422);
@@ -467,6 +470,9 @@ class AppraisalTasksController
if (!$files) {
return api_error('请至少上传 1 个中检报告文件', 422);
}
if ($qrInput === '') {
return api_error('请扫描验真吊牌二维码', 422);
}
$task = Db::name('appraisal_tasks')->where('id', $id)->find();
if (!$task) {
@@ -475,6 +481,20 @@ class AppraisalTasksController
if (($task['service_provider'] ?? '') !== 'zhongjian') {
return api_error('非中检订单不能录入中检报告', 422);
}
$order = Db::name('orders')->where('id', (int)$task['order_id'])->find() ?: [];
$task['order_status'] = $order['order_status'] ?? '';
$report = $this->findLatestAppraisalReport((int)$task['order_id']);
$effectiveStatus = $this->effectiveTaskStatus($task, $report);
if ($effectiveStatus !== $task['status']) {
Db::name('appraisal_tasks')->where('id', $id)->update([
'status' => $effectiveStatus,
'updated_at' => date('Y-m-d H:i:s'),
]);
$task['status'] = $effectiveStatus;
}
if (in_array($effectiveStatus, ['submitted', 'completed'], true)) {
return api_error('当前任务已流转完成,不能再录入中检报告', 422);
}
$operatorGuard = $this->guardTaskOperator($request, $task);
if ($operatorGuard['error']) {
@@ -565,22 +585,25 @@ class AppraisalTasksController
'created_at' => $now,
]);
Db::commit();
$freshReport = $this->findLatestAppraisalReport((int)$task['order_id']);
$publish = $this->publishReportRecord($freshReport, $request);
if (!$freshReport) {
Db::rollback();
return api_error('中检报告草稿生成失败', 500);
}
$tag = (new MaterialTagService())->bindTagToReportByTask($id, $qrInput, $request);
$publish = $this->publishReportRecord($freshReport, $request, false);
(new FulfillmentFlowService())->markReportPublished((int)$task['order_id'], $request);
Db::commit();
return api_success([
'id' => $id,
'material_tag' => $tag,
'report' => $publish,
], '中检报告已录入并发布');
], '验真吊牌已绑定,报告已发布');
} catch (\Throwable $e) {
try {
Db::rollback();
} catch (\Throwable $rollbackError) {
// Transaction may already be committed before publishing.
}
Db::rollback();
return api_error('中检报告录入失败', 500, ['detail' => $e->getMessage()]);
}
}
@@ -640,6 +663,7 @@ class AppraisalTasksController
{
$id = (int)$request->input('id', 0);
$action = trim((string)$request->input('action', 'save'));
$qrInput = trim((string)$request->input('qr_input', ''));
if (!$id) {
return api_error('任务 ID 不能为空', 422);
@@ -675,6 +699,9 @@ class AppraisalTasksController
if ($action !== 'save' && $resultText === '') {
return api_error('鉴定结论不能为空', 422);
}
if ($action !== 'save' && $qrInput === '') {
return api_error('请扫描验真吊牌二维码', 422);
}
$productInput = $request->input('product_info', null);
$productPayload = is_array($productInput) ? $this->normalizeProductInput($productInput) : null;
$attachments = $this->evidenceService()->normalize($request->input('attachments', []), $request, true);
@@ -774,6 +801,14 @@ class AppraisalTasksController
]);
$this->createOrUpdateReportDraft((int)$task['order_id'], $task, $payload, $now);
$report = $this->findLatestAppraisalReport((int)$task['order_id']);
if (!$report) {
Db::rollback();
return api_error('报告草稿生成失败', 500);
}
$tag = (new MaterialTagService())->bindTagToReportByTask($id, $qrInput, $request);
$publish = $this->publishReportRecord($report, $request, false);
(new FulfillmentFlowService())->markReportPublished((int)$task['order_id'], $request);
Db::commit();
(new EnterpriseWebhookService())->recordOrderEvent((int)$task['order_id'], 'appraisal_finished', [
@@ -781,7 +816,11 @@ class AppraisalTasksController
'task_stage' => $task['task_stage'],
'finished_at' => $now,
]);
return api_success(['id' => $id], '鉴定已完成,报告草稿已生成');
return api_success([
'id' => $id,
'material_tag' => $tag,
'report' => $publish,
], '验真吊牌已绑定,报告已发布');
} catch (\Throwable $e) {
Db::rollback();
return api_error('结论保存失败', 500, [
@@ -976,6 +1015,15 @@ class AppraisalTasksController
public function uploadEvidenceFile(Request $request)
{
$taskId = (int)$request->input('task_id', 0);
if ($taskId <= 0) {
return api_error('任务 ID 不能为空', 422);
}
$editableGuard = $this->guardTaskEditable($taskId, '当前任务已流转完成,不能再上传附件');
if ($editableGuard) {
return $editableGuard;
}
try {
$asset = $this->evidenceService()->upload($request);
return api_success($asset);
@@ -986,6 +1034,15 @@ class AppraisalTasksController
public function deleteEvidenceFile(Request $request)
{
$taskId = (int)$request->input('task_id', 0);
if ($taskId <= 0) {
return api_error('任务 ID 不能为空', 422);
}
$editableGuard = $this->guardTaskEditable($taskId, '当前任务已流转完成,不能再删除附件');
if ($editableGuard) {
return $editableGuard;
}
$fileUrl = trim((string)$request->input('file_url', ''));
if ($fileUrl === '') {
return api_error('文件地址不能为空', 422);
@@ -1093,9 +1150,86 @@ class AppraisalTasksController
'sla_deadline' => $item['sla_deadline'],
'is_overtime' => (bool)$item['is_overtime'],
'display_status' => $item['display_status'],
'internal_tag_no' => (string)($item['internal_tag_no'] ?? ''),
];
}
private function attachTransferFlowToRows(array &$rows): void
{
$orderIds = array_values(array_unique(array_filter(array_map(fn (array $item) => (int)($item['order_id'] ?? 0), $rows))));
if (!$orderIds) {
return;
}
$flowMap = $this->latestTransferFlowMap($orderIds);
foreach ($rows as &$row) {
$orderId = (int)($row['order_id'] ?? 0);
$row['internal_tag_no'] = (string)($flowMap[$orderId]['internal_tag_no'] ?? '');
}
unset($row);
}
private function latestTransferFlowForOrder(int $orderId): ?array
{
if ($orderId <= 0) {
return null;
}
return Db::name('order_transfer_flows')
->where('order_id', $orderId)
->order('id', 'desc')
->find() ?: null;
}
private function latestTransferFlowMap(array $orderIds): array
{
$orderIds = array_values(array_unique(array_filter(array_map('intval', $orderIds))));
if (!$orderIds) {
return [];
}
$rows = Db::name('order_transfer_flows')
->whereIn('order_id', $orderIds)
->order('id', 'desc')
->select()
->toArray();
$map = [];
foreach ($rows as $row) {
$orderId = (int)($row['order_id'] ?? 0);
if ($orderId > 0 && !isset($map[$orderId])) {
$map[$orderId] = [
'internal_tag_no' => (string)($row['internal_tag_no'] ?? ''),
];
}
}
return $map;
}
private function guardTaskEditable(int $taskId, string $message)
{
$task = Db::name('appraisal_tasks')->where('id', $taskId)->find();
if (!$task) {
return api_error('任务不存在', 404);
}
$order = Db::name('orders')->where('id', (int)$task['order_id'])->find() ?: [];
$task['order_status'] = $order['order_status'] ?? '';
$report = $this->findLatestAppraisalReport((int)$task['order_id']);
$effectiveStatus = $this->effectiveTaskStatus($task, $report);
if ($effectiveStatus !== (string)$task['status']) {
Db::name('appraisal_tasks')->where('id', $taskId)->update([
'status' => $effectiveStatus,
'updated_at' => date('Y-m-d H:i:s'),
]);
}
return in_array($effectiveStatus, ['submitted', 'completed'], true)
? api_error($message, 422)
: null;
}
private function formatResultInfo(array $task, ?Request $request = null): array
{
$resultId = 0;
@@ -1866,7 +2000,7 @@ class AppraisalTasksController
return $admin;
}
private function publishReportRecord(array $report, Request $request): array
private function publishReportRecord(array $report, Request $request, bool $wrapTransaction = true): array
{
if (!$report) {
throw new \RuntimeException('报告不存在', 404);
@@ -1878,10 +2012,11 @@ class AppraisalTasksController
$operatorId = (int)$request->header('x-admin-id', 0);
$now = date('Y-m-d H:i:s');
$effectivePublishTime = $report['publish_time'] ?: $now;
$usesPlatformVerify = (string)($report['service_provider'] ?? '') !== 'zhongjian';
$verify = [];
Db::startTrans();
if ($wrapTransaction) {
Db::startTrans();
}
try {
if (($report['report_status'] ?? '') !== 'published') {
Db::name('reports')->where('id', (int)$report['id'])->update([
@@ -1893,9 +2028,7 @@ class AppraisalTasksController
$report['publish_time'] = $effectivePublishTime;
}
if ($usesPlatformVerify) {
$verify = $this->createOrUpdateVerifyRecord($report, $now);
}
$verify = $this->createOrUpdateVerifyRecord($report, $now);
if (($report['report_type'] ?? 'appraisal') === 'appraisal' && (int)($report['order_id'] ?? 0) > 0) {
Db::name('orders')->where('id', (int)$report['order_id'])->update([
@@ -1933,15 +2066,19 @@ class AppraisalTasksController
'report_title' => (string)$report['report_title'],
'product_name' => $product['product_name'] ?? '',
'publish_time' => $effectivePublishTime,
'verify_url' => $usesPlatformVerify ? (string)($verify['verify_url'] ?? '') : '',
'verify_url' => (string)($verify['verify_url'] ?? ''),
'fallback_title' => '报告已出具',
'fallback_content' => '您的正式报告已生成,可前往报告中心查看。',
]);
}
Db::commit();
if ($wrapTransaction) {
Db::commit();
}
} catch (\Throwable $e) {
Db::rollback();
if ($wrapTransaction) {
Db::rollback();
}
throw $e;
}
@@ -1951,8 +2088,8 @@ class AppraisalTasksController
'report_no' => (string)$report['report_no'],
'report_title' => (string)$report['report_title'],
'publish_time' => $effectivePublishTime,
'verify_url' => $usesPlatformVerify ? (string)($verify['verify_url'] ?? '') : '',
'report_page_url' => $usesPlatformVerify ? (string)($verify['report_page_url'] ?? '') : '',
'verify_url' => (string)($verify['verify_url'] ?? ''),
'report_page_url' => (string)($verify['report_page_url'] ?? ''),
]);
}
@@ -1960,8 +2097,8 @@ class AppraisalTasksController
'id' => (int)$report['id'],
'report_status' => 'published',
'publish_time' => $effectivePublishTime,
'verify_url' => $usesPlatformVerify ? (string)($verify['verify_url'] ?? '') : '',
'report_page_url' => $usesPlatformVerify ? (string)($verify['report_page_url'] ?? '') : '',
'verify_url' => (string)($verify['verify_url'] ?? ''),
'report_page_url' => (string)($verify['report_page_url'] ?? ''),
];
}