Merge branch 'master' into kpi-statis

This commit is contained in:
2026-04-22 16:46:09 +08:00
26 changed files with 1659 additions and 301 deletions
@@ -124,6 +124,22 @@ class PrescriptionOrderLogic
return self::roleIntersect($adminInfo, is_array($allow) ? $allow : []);
}
/**
* 列表顶栏金额统计:与「关联支付单」审核白名单同档的角色可见「全量」统计(不缩小到本人/医助诊单域)
*/
public static function canViewOrderListStatsAllScope(array $adminInfo): bool
{
if (!empty($adminInfo['root']) && (int) $adminInfo['root'] === 1) {
return true;
}
$allow = Config::get('project.prescription_order_payment_audit_roles', [0, 3, 4, 9, 6]);
if (!is_array($allow)) {
$allow = [0, 3];
}
return self::roleIntersect($adminInfo, $allow);
}
/**
* @param array<string,mixed> $row
*/
@@ -424,6 +440,12 @@ class PrescriptionOrderLogic
return false;
}
if ((int) ($rx['void_status'] ?? 0) === 1) {
self::$error = '已作废处方不可创建业务订单';
return false;
}
if (PrescriptionOrder::where('prescription_id', $rxId)->whereNull('delete_time')->where('fulfillment_status', '<>', 4)->count() > 0) {
self::$error = '该处方已存在有效业务订单(未撤回前不可重复创建)';
@@ -1513,14 +1535,25 @@ class PrescriptionOrderLogic
return $out;
}
/** 完成订单时可选的履约终态:3=已完成,7-12=业务结案类状态 */
private const COMPLETE_FULFILLMENT_TARGETS = [3, 7, 8, 9, 10, 11, 12];
/** 完成时是否按「实付=关联支付单金额」重算并清空诊单医助(与 clearDiagnosisAssistantOnComplete 的终态判断一致) */
private const COMPLETE_FULFILLMENT_TERMINAL = [3, 8, 9, 10, 11, 12];
/**
* 将「已发货」(fulfillment_status=5) 且支付审核已通过的订单标记为「已完成」(3)
* 将「已发货/已签收」且支付审核已通过的订单结案:可选「已完成」或 7-12 业务状态
*
* @return array<string,mixed>|false
*/
public static function complete(int $id, int $adminId, array $adminInfo)
public static function complete(int $id, int $adminId, array $adminInfo, int $targetFulfillmentStatus = 3)
{
self::$error = '';
if (!in_array($targetFulfillmentStatus, self::COMPLETE_FULFILLMENT_TARGETS, true)) {
self::$error = '无效的完成状态';
return false;
}
$order = PrescriptionOrder::where('id', $id)->whereNull('delete_time')->find();
if (!$order) {
self::$error = '订单不存在';
@@ -1530,8 +1563,9 @@ class PrescriptionOrderLogic
self::$error = '无权限操作';
return false;
}
if ((int) $order->fulfillment_status !== 5) {
self::$error = '仅「已发货」状态可标记为已完成';
$curFs = (int) $order->fulfillment_status;
if ($curFs !== 5 && $curFs !== 6) {
self::$error = '仅「已发货」或「已签收」状态可完成订单';
return false;
}
if ((int) $order->payment_slip_audit_status !== 1) {
@@ -1539,17 +1573,22 @@ class PrescriptionOrderLogic
return false;
}
// 计算关联订单总额
$linkedPayOrderIds = self::linkedPayOrderIdList($id);
$linkedPayOrders = self::linkedPayOrdersPayload($linkedPayOrderIds);
$label = self::fulfillmentStatusLabel($targetFulfillmentStatus);
$linkedPayOrderIds = self::linkedPayOrderIdList($id);
$linkedPayOrders = self::linkedPayOrdersPayload($linkedPayOrderIds);
$linkedPayPaidTotal = 0.0;
foreach ($linkedPayOrders as $o) {
$linkedPayPaidTotal += (float) ($o['amount'] ?? 0);
}
$linkedPayPaidTotal = round($linkedPayPaidTotal, 2);
$order->fulfillment_status = 3;
$order->paid = $linkedPayPaidTotal;
if ($targetFulfillmentStatus === 3) {
$order->fulfillment_status = 3;
$order->paid = $linkedPayPaidTotal;
} else {
$order->fulfillment_status = $targetFulfillmentStatus;
}
try {
$order->save();
@@ -1558,14 +1597,22 @@ class PrescriptionOrderLogic
return false;
}
$unassignSummary = self::clearDiagnosisAssistantOnComplete((int) $order->diagnosis_id);
$unassignSummary = '';
if (in_array($targetFulfillmentStatus, self::COMPLETE_FULFILLMENT_TERMINAL, true)) {
$unassignSummary = self::clearDiagnosisAssistantOnComplete((int) $order->diagnosis_id);
}
if ($targetFulfillmentStatus === 3) {
$logLine = '订单完成,状态变更为「' . $label . '」,实付金额更新为 ¥' . $linkedPayPaidTotal . $unassignSummary;
} else {
$logLine = '订单处理完成,状态变更为「' . $label . '」' . $unassignSummary;
}
self::writeLog(
$id,
$adminId,
$adminInfo,
'complete',
'订单完成,状态变更为「已完成」,实付金额更新为 ¥' . $linkedPayPaidTotal . $unassignSummary
$logLine
);
$out = $order->toArray();
@@ -1575,6 +1622,26 @@ class PrescriptionOrderLogic
return $out;
}
private static function fulfillmentStatusLabel(int $fs): string
{
$m = [
1 => '待双审通过',
2 => '待发货',
3 => '已完成',
4 => '已取消',
5 => '已发货',
6 => '已签收',
7 => '进行中',
8 => '暂不制药',
9 => '拒收',
10 => '退款',
11 => '保留药方',
12 => '制药缓发',
];
return $m[$fs] ?? ('状态' . (string) $fs);
}
/**
* 完成订单时把关联诊单的 assistant_id 清空,让患者回到「待分配」状态
* 仅当该患者没有其它进行中的处方订单时才清空,避免误覆盖
@@ -1600,7 +1667,7 @@ class PrescriptionOrderLogic
// 同一诊单下若仍有未完成/未取消的处方订单,则不清空
$pendingCount = PrescriptionOrder::where('diagnosis_id', $diagnosisId)
->whereNull('delete_time')
->whereNotIn('fulfillment_status', [3, 4])
->whereNotIn('fulfillment_status', [3, 4, 8, 9, 10, 11, 12])
->count();
if ($pendingCount > 0) {
return '';
@@ -1635,7 +1702,7 @@ class PrescriptionOrderLogic
if ($pa !== 1) {
return false;
}
if ($fs === 3 || $fs === 4) {
if (in_array($fs, [3, 4, 8, 9, 10, 11, 12], true)) {
return false;
}
if (trim((string) ($item['gancao_reciperl_order_no'] ?? '')) !== '') {