完善生产异常维修与备件管理功能
This commit is contained in:
@@ -40,6 +40,7 @@ final class DataEntryController extends Base
|
||||
{
|
||||
protected ?BaseValidate $validate = null;
|
||||
protected ?BaseValidate $productRecordValidate = null;
|
||||
private ?array $repairFlowCache = null;
|
||||
|
||||
public function __construct(
|
||||
protected CurrentMember $currentMember,
|
||||
@@ -124,6 +125,61 @@ final class DataEntryController extends Base
|
||||
]);
|
||||
}
|
||||
|
||||
#[OA\Get(path: '/produce/material/options', summary: '获取维修备件选项', tags: ['produce-web'])]
|
||||
#[DataResponse(description: '获取成功')]
|
||||
#[AllowAnonymous(requireToken: false, requirePermission: false, description: '公共接口')]
|
||||
public function materialOptions(Request $request): Response
|
||||
{
|
||||
$productCode = trim((string) $request->input('product_code', ''));
|
||||
$productName = trim((string) $request->input('product_name', ''));
|
||||
$categoryId = (int) $request->input('category_id', 0);
|
||||
$page = max(1, (int) $request->input('page', 1));
|
||||
$limit = min(50, max(1, (int) $request->input('limit', 10)));
|
||||
|
||||
$query = Material::query()->with('category:id,category_name');
|
||||
$query->when($productCode !== '', static fn ($builder) => $builder->where('product_code', 'like', "%{$productCode}%"));
|
||||
$query->when($productName !== '', static fn ($builder) => $builder->where('product_name', 'like', "%{$productName}%"));
|
||||
$query->when($categoryId > 0, static fn ($builder) => $builder->where('category_id', $categoryId));
|
||||
|
||||
$usageCounts = $this->materialUsageCounts();
|
||||
$materials = $query->get(['id', 'category_id', 'product_code', 'product_name'])
|
||||
->sort(function (Material $left, Material $right) use ($usageCounts): int {
|
||||
$leftCount = $usageCounts[(string) $left->product_code] ?? 0;
|
||||
$rightCount = $usageCounts[(string) $right->product_code] ?? 0;
|
||||
return $leftCount === $rightCount
|
||||
? strcmp((string) $left->product_code, (string) $right->product_code)
|
||||
: $rightCount <=> $leftCount;
|
||||
});
|
||||
$total = $materials->count();
|
||||
$items = $materials->forPage($page, $limit)
|
||||
->map(static fn (Material $material): array => [
|
||||
'id' => (string) $material->id,
|
||||
'category_id' => (string) $material->category_id,
|
||||
'category_name' => (string) $material->category_name,
|
||||
'product_code' => (string) $material->product_code,
|
||||
'product_name' => (string) $material->product_name,
|
||||
])
|
||||
->values()
|
||||
->all();
|
||||
|
||||
return Json::success('获取成功', compact('items', 'total', 'page', 'limit'));
|
||||
}
|
||||
|
||||
private function materialUsageCounts(): array
|
||||
{
|
||||
$counts = [];
|
||||
RepairRecord::query()->without('exception')->whereNotNull('parts')->get(['parts'])->each(function (RepairRecord $record) use (&$counts): void {
|
||||
foreach ((array) $record->parts as $part) {
|
||||
$code = trim((string) ($part['product_code'] ?? ''));
|
||||
if ($code === '') {
|
||||
continue;
|
||||
}
|
||||
$counts[$code] = ($counts[$code] ?? 0) + max(1, (int) ($part['quantity'] ?? 1));
|
||||
}
|
||||
});
|
||||
return $counts;
|
||||
}
|
||||
|
||||
#[OA\Get(path: '/produce/scanapp/material-category', summary: '获取扫码端物料分类选项', tags: ['produce-web'])]
|
||||
#[DataResponse(description: '获取成功')]
|
||||
#[AllowAnonymous(requireToken: false, requirePermission: false, description: '公共接口')]
|
||||
@@ -644,7 +700,7 @@ final class DataEntryController extends Base
|
||||
$query = match ($recordType) {
|
||||
'scan' => ScanData::query()->with(['process', 'step', 'status']),
|
||||
'product' => ProductRecord::query()->with(['process', 'step', 'status']),
|
||||
'exception' => ExceptionRecord::query(),
|
||||
'exception' => ExceptionRecord::query()->with(['process', 'step']),
|
||||
'repair' => RepairRecord::query()->with('exception'),
|
||||
};
|
||||
|
||||
@@ -731,7 +787,7 @@ final class DataEntryController extends Base
|
||||
ProductRecord::query()->with(['process', 'step', 'status'])->where('process_order_no', $orderNo)->get()->each(function (ProductRecord $item) use ($timeline): void {
|
||||
$timeline->push($this->formatTimelineRecord('product', $item, (int) $item->created_at));
|
||||
});
|
||||
ExceptionRecord::query()->where('order_no', $orderNo)->get()->each(function (ExceptionRecord $item) use ($timeline): void {
|
||||
ExceptionRecord::query()->with(['process', 'step'])->where('order_no', $orderNo)->get()->each(function (ExceptionRecord $item) use ($timeline): void {
|
||||
$timeline->push($this->formatTimelineRecord('exception', $item, (int) $item->reported_at));
|
||||
});
|
||||
RepairRecord::query()->with('exception')->where('order_no', $orderNo)->get()->each(function (RepairRecord $item) use ($timeline): void {
|
||||
@@ -1063,6 +1119,22 @@ final class DataEntryController extends Base
|
||||
return Json::fail('用户编码不存在');
|
||||
}
|
||||
|
||||
$config = $this->getConfigGroupData('basic_setting');
|
||||
$processId = (int) ($config['exception_process_id'] ?? 0);
|
||||
$stepId = (int) ($config['exception_step_id'] ?? 0);
|
||||
if ($processId <= 0 || $stepId <= 0) {
|
||||
return Json::fail('异常提报工序步骤尚未配置,请联系管理员');
|
||||
}
|
||||
|
||||
$step = ProcessStep::query()
|
||||
->whereKey($stepId)
|
||||
->where('process_id', $processId)
|
||||
->where('status', 1)
|
||||
->first();
|
||||
if (!$step) {
|
||||
return Json::fail('异常提报工序步骤配置无效,请联系管理员');
|
||||
}
|
||||
|
||||
$type = ExceptionSetting::query()
|
||||
->whereKey($typeId)
|
||||
->where('setting_type', 'type')
|
||||
@@ -1099,24 +1171,26 @@ final class DataEntryController extends Base
|
||||
return is_string($image) && preg_match('/^https?:\/\//', $image) === 1;
|
||||
}));
|
||||
$record = ExceptionRecord::query()->create([
|
||||
'order_no' => $orderNo,
|
||||
'user_code' => $userCode,
|
||||
'reporter' => (string) ($member->nickname ?: $member->username),
|
||||
'reporter_id' => (int) $member->id,
|
||||
'type_id' => $type->id,
|
||||
'type_code' => $type->code,
|
||||
'type_name' => $type->name,
|
||||
'reason_id' => $reason->id,
|
||||
'reason_code' => $reason->code,
|
||||
'reason_name' => $reason->name,
|
||||
'issue_id' => $issue?->id,
|
||||
'issue_code' => $issue?->code,
|
||||
'issue_name' => $issue?->name,
|
||||
'images' => $images,
|
||||
'remark' => trim((string) ($data['remark'] ?? '')),
|
||||
'status' => 0,
|
||||
'reported_at' => time(),
|
||||
]);
|
||||
'order_no' => $orderNo,
|
||||
'process_id' => $processId,
|
||||
'step_id' => $stepId,
|
||||
'user_code' => $userCode,
|
||||
'reporter' => (string) ($member->nickname ?: $member->username),
|
||||
'reporter_id' => (int) $member->id,
|
||||
'type_id' => $type->id,
|
||||
'type_code' => $type->code,
|
||||
'type_name' => $type->name,
|
||||
'reason_id' => $reason->id,
|
||||
'reason_code' => $reason->code,
|
||||
'reason_name' => $reason->name,
|
||||
'issue_id' => $issue?->id,
|
||||
'issue_code' => $issue?->code,
|
||||
'issue_name' => $issue?->name,
|
||||
'images' => $images,
|
||||
'remark' => trim((string) ($data['remark'] ?? '')),
|
||||
'status' => 0,
|
||||
'reported_at' => time(),
|
||||
]);
|
||||
|
||||
return Json::success('提交成功', ['id' => $record->id]);
|
||||
}
|
||||
@@ -1223,13 +1297,13 @@ final class DataEntryController extends Base
|
||||
'record_type_name' => '异常提报',
|
||||
'order_no' => (string) $item->order_no,
|
||||
'product_code' => '',
|
||||
'process_name' => '',
|
||||
'step_name' => '',
|
||||
'process_name' => (string) $item->process_name,
|
||||
'step_name' => (string) $item->step_name,
|
||||
'status_name' => (string) $item->status_name,
|
||||
'result_name' => (string) $item->type_name,
|
||||
'operator' => (string) $item->reporter,
|
||||
'user_code' => (string) $item->user_code,
|
||||
'quantity' => null,
|
||||
'quantity' => 1,
|
||||
'exception_reason' => (string) $item->reason_name,
|
||||
'exception_content' => (string) $item->issue_name,
|
||||
'event_at' => (int) $item->reported_at,
|
||||
@@ -1242,13 +1316,13 @@ final class DataEntryController extends Base
|
||||
'record_type_name' => '维修记录',
|
||||
'order_no' => (string) $item->order_no,
|
||||
'product_code' => (string) $item->product_code,
|
||||
'process_name' => '',
|
||||
'step_name' => '',
|
||||
'process_name' => $this->getRepairFlowNodeNames()['process_name'],
|
||||
'step_name' => $this->getRepairFlowNodeNames()['step_name'],
|
||||
'status_name' => '已维修',
|
||||
'result_name' => (string) $item->repair_result_name,
|
||||
'operator' => (string) $item->operator,
|
||||
'user_code' => '',
|
||||
'quantity' => null,
|
||||
'user_code' => (string) ($item->exception?->user_code ?? ''),
|
||||
'quantity' => 1,
|
||||
'material_category' => (string) ($item->category_name ?: $item->category_names),
|
||||
'fault_description' => (string) ($item->fault_description_name ?: $item->fault_description),
|
||||
'event_at' => (int) ($item->repaired_at ?: $item->created_at),
|
||||
@@ -1258,6 +1332,28 @@ final class DataEntryController extends Base
|
||||
};
|
||||
}
|
||||
|
||||
/** 获取维修记录配置的工序与步骤名称。 */
|
||||
private function getRepairFlowNodeNames(): array
|
||||
{
|
||||
if ($this->repairFlowCache !== null) {
|
||||
return $this->repairFlowCache;
|
||||
}
|
||||
|
||||
$basic = $this->getConfigGroupData('basic_setting');
|
||||
$flow = $this->getConfigGroupData('repair_flow');
|
||||
$processId = (int) ($basic['repair_process_id'] ?? 0);
|
||||
$stepId = (int) ($basic['repair_step_id'] ?? 0);
|
||||
$processId = $processId > 0 ? $processId : (int) ($flow['repair_process_id'] ?? 0);
|
||||
$stepId = $stepId > 0 ? $stepId : (int) ($flow['repair_step_id'] ?? 0);
|
||||
$process = $processId > 0 ? Process::query()->withTrashed()->find($processId) : null;
|
||||
$step = $stepId > 0 ? ProcessStep::query()->withTrashed()->find($stepId) : null;
|
||||
|
||||
return $this->repairFlowCache = [
|
||||
'process_name' => (string) ($process?->process_name ?? ''),
|
||||
'step_name' => (string) ($step?->step_name ?? ''),
|
||||
];
|
||||
}
|
||||
|
||||
private function formatTimelineRecord(string $recordType, object $item, int $eventAt): array
|
||||
{
|
||||
$record = $this->formatQueryRecord($recordType, $item);
|
||||
|
||||
Reference in New Issue
Block a user