You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
4.6 KiB
PHP

<?php
namespace App\Services;
use Illuminate\Support\Facades\DB;
/**
* 综合校验服务
* 整合互斥校验和项目规则校验
*/
class ComprehensiveValidationService
{
private ExclusionValidationService $exclusionService;
private ItemRuleValidationService $itemRuleService;
public function __construct(
ExclusionValidationService $exclusionService,
ItemRuleValidationService $itemRuleService
) {
$this->exclusionService = $exclusionService;
$this->itemRuleService = $itemRuleService;
}
/**
* 综合校验入口
*
* @param int $patientId 患者ID
* @param array $itemCodes 预约的项目code数组
* @param int $planId 号源ID
* @return array ['valid' => bool, 'conflicts' => [...], 'details' => [...]]
*/
public function validate(int $patientId, array $itemCodes, int $planId): array
{
$allConflicts = [];
// 0. 根据 planId 查询预约日期,传给互斥校验
$planDate = null;
$plan = DB::table('plan as p')
->join('plan_batch as pb', 'p.batch_id', '=', 'pb.id')
->where('p.id', $planId)
->select('pb.plan_date')
->first();
if ($plan) {
$planDate = $plan->plan_date;
}
// 1. 执行互斥校验
$exclusionResult = $this->exclusionService->validate($patientId, $itemCodes, $planDate);
if (!empty($exclusionResult['conflicts'])) {
foreach ($exclusionResult['conflicts'] as $conflict) {
$allConflicts[] = [
'type' => 'EXCLUSION',
'rule_type' => $conflict['exclusion_type'],
'item_code' => $conflict['source_code'],
'message' => $conflict['message'],
'details' => [
'source_code' => $conflict['source_code'],
'target_code' => $conflict['target_code'],
'appointment_date' => $conflict['appointment_date'],
],
];
}
}
// 2. 执行项目规则校验
$itemRuleResult = $this->itemRuleService->validate($itemCodes, $patientId, $planId);
if (!empty($itemRuleResult['conflicts'])) {
foreach ($itemRuleResult['conflicts'] as $conflict) {
$allConflicts[] = [
'type' => 'ITEM_RULE',
'rule_type' => $conflict['rule_type'],
'item_code' => $conflict['item_code'],
'message' => $conflict['message'],
'details' => [
'item_code' => $conflict['item_code'],
'rule_type' => $conflict['rule_type'],
],
];
}
}
// 3. 统计各类型冲突数量
$summary = $this->buildSummary($exclusionResult, $itemRuleResult);
return [
'valid' => empty($allConflicts),
'conflicts' => $allConflicts,
'summary' => $summary,
'details' => [
'exclusion_valid' => $exclusionResult['valid'] ?? true,
'exclusion_conflicts' => $exclusionResult['conflicts'] ?? [],
'item_rule_valid' => $itemRuleResult['valid'] ?? true,
'item_rule_conflicts' => $itemRuleResult['conflicts'] ?? [],
'patient_info' => $itemRuleResult['patient_info'] ?? null,
'appointment_time' => $itemRuleResult['appointment_time'] ?? null,
],
];
}
/**
* 构建冲突汇总信息
*/
private function buildSummary(array $exclusionResult, array $itemRuleResult): array
{
$exclusionCount = count($exclusionResult['conflicts'] ?? []);
$itemRuleCount = count($itemRuleResult['conflicts'] ?? []);
$summary = [
'total_conflicts' => $exclusionCount + $itemRuleCount,
'exclusion_conflicts' => $exclusionCount,
'item_rule_conflicts' => $itemRuleCount,
];
// 按规则类型分组统计
$ruleTypeCount = [];
foreach ($exclusionResult['conflicts'] ?? [] as $conflict) {
$type = $conflict['exclusion_type'];
$ruleTypeCount["EXCLUSION_{$type}"] = ($ruleTypeCount["EXCLUSION_{$type}"] ?? 0) + 1;
}
foreach ($itemRuleResult['conflicts'] ?? [] as $conflict) {
$type = $conflict['rule_type'];
$ruleTypeCount["ITEM_RULE_{$type}"] = ($ruleTypeCount["ITEM_RULE_{$type}"] ?? 0) + 1;
}
$summary['by_type'] = $ruleTypeCount;
return $summary;
}
}