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
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;
|
|
}
|
|
}
|