This commit is contained in:
Your Name
2026-04-07 18:13:03 +08:00
parent a780356908
commit fdf714f833
397 changed files with 15086 additions and 1043 deletions
+214 -28
View File
@@ -7,6 +7,9 @@ namespace app\adminapi\logic\order;
use app\common\model\Order;
use app\common\model\OrderDetail;
use app\common\model\auth\Admin;
use app\common\model\tcm\Diagnosis;
use app\common\model\tcm\PrescriptionOrder;
use app\common\model\tcm\PrescriptionOrderPayOrder;
use app\common\service\wechat\WechatWorkExternalPayService;
use think\facade\Db;
use think\facade\Log;
@@ -73,7 +76,7 @@ class OrderLogic
/**
* @notes 从企业微信对外收款账单同步订单(员工直接在企业微信发起收款,未经过后台创建)
* 拉取 get_bill_list 接口的已支付记录,创建或更新本地订单
* 拉取 get_bill_listtrade_state 1=已完成(已支付) 3=已完成有退款;会创建订单,并在状态变化时更新(如已支付→已退款)
* @param int $beginTime 开始时间戳(秒)
* @param int $endTime 结束时间戳(秒)
* @return array ['created' => int, 'updated' => int, 'skipped' => int, 'errors' => string[]]
@@ -108,10 +111,13 @@ class OrderLogic
foreach ($billList as $bill) {
$tradeState = (int)($bill['trade_state'] ?? 0);
// 1:已完成(已支付) 3:已完成有退款 — 见企业微信 get_bill_list 文档
if (!in_array($tradeState, [1, 3], true)) {
$result['skipped']++;
continue;
}
$targetStatus = $tradeState === 3 ? 4 : 2; // 4=已退款 2=已支付
$orderNo = (string)($bill['out_trade_no'] ?? $bill['trade_no'] ?? '');
$totalFee = (int)($bill['total_fee'] ?? $bill['total_amount'] ?? 0);
$tradeNo = (string)($bill['transaction_id'] ?? $bill['trade_no'] ?? '');
@@ -134,34 +140,76 @@ class OrderLogic
}
$payerExternalUserid = (string)($bill['external_userid'] ?? '');
$paymentTimeStr = $payTime
? (is_numeric($payTime) ? date('Y-m-d H:i:s', (int)$payTime) : (string)$payTime)
: date('Y-m-d H:i:s');
$order = Order::where('order_no', $orderNo)->find();
if ($order) {
if ($order->status == 1) {
$order->status = 2;
$order->payment_method = 'wechat';
$order->payment_time = $payTime ? (is_numeric($payTime) ? date('Y-m-d H:i:s', (int)$payTime) : $payTime) : date('Y-m-d H:i:s');
$needSave = false;
$currentStatus = (int)$order->status;
if ($currentStatus !== $targetStatus) {
// 待支付:随账单变为已支付或已退款(含未同步到「已支付」即发生退款)
if ($currentStatus === 1) {
$order->status = $targetStatus;
$needSave = true;
} elseif ($currentStatus === 2 && $targetStatus === 4) {
$order->status = 4;
$needSave = true;
} elseif ($currentStatus === 4 && $targetStatus === 2) {
// 账单从「有退款」变回「已完成」等异常纠偏
$order->status = 2;
$needSave = true;
}
// 已取消(3) 不自动改支付状态,避免覆盖后台取消
}
if ($currentStatus === 1 || $targetStatus === 2) {
if ($order->payment_method !== 'wechat') {
$order->payment_method = 'wechat';
$needSave = true;
}
if ($paymentTimeStr !== '' && (string)$order->payment_time !== $paymentTimeStr) {
$order->payment_time = $paymentTimeStr;
$needSave = true;
}
}
if ($tradeNo !== '' && (string)$order->trade_no !== $tradeNo) {
$order->trade_no = $tradeNo;
$needSave = true;
}
if (abs((float)$order->amount - $amount) > 0.000001) {
$order->amount = $amount;
$needSave = true;
}
$defaultCreatorIdInt = (int)$defaultCreatorId;
if ($billPayeeUserid && $creatorId !== $defaultCreatorIdInt && (int)$order->creator_id === $defaultCreatorIdInt) {
$order->payee_userid = $billPayeeUserid;
$order->payer_external_userid = $payerExternalUserid;
$order->creator_id = $creatorId;
$order->order_type = $orderType;
$needSave = true;
} elseif ($billPayeeUserid !== '' && (string)$order->payee_userid !== $billPayeeUserid) {
$order->payee_userid = $billPayeeUserid;
$needSave = true;
}
if ($payerExternalUserid !== '' && (string)$order->payer_external_userid !== $payerExternalUserid) {
$order->payer_external_userid = $payerExternalUserid;
$needSave = true;
}
if ($amount == 5.00 && (int)$order->order_type !== 1) {
$order->order_type = 1;
$needSave = true;
}
if ($needSave) {
$order->save();
$result['updated']++;
} else {
$needSave = false;
if ($billPayeeUserid && $creatorId !== $defaultCreatorId && (int)$order->creator_id === $defaultCreatorId) {
$order->payee_userid = $billPayeeUserid;
$order->payer_external_userid = $payerExternalUserid;
$order->creator_id = $creatorId;
$needSave = true;
}
if ($amount == 5.00 && (int)$order->order_type !== 1) {
$order->order_type = 1;
$needSave = true;
}
if ($needSave) {
$order->save();
}
$result['skipped']++;
}
} else {
@@ -172,11 +220,18 @@ class OrderLogic
$order->creator_id = $creatorId;
$order->order_type = $orderType;
$order->amount = $amount;
$order->status = 2;
$order->status = $targetStatus;
$order->payment_method = 'wechat';
$order->payment_time = $payTime ? (is_numeric($payTime) ? date('Y-m-d H:i:s', (int)$payTime) : $payTime) : date('Y-m-d H:i:s');
$order->payment_time = $paymentTimeStr;
$order->trade_no = $tradeNo;
$order->remark = '企业微信直接收款同步,待关联患者';
$remark = '企业微信直接收款同步,待关联患者';
if ($tradeState === 3) {
$refundCent = (int)($bill['total_refund_fee'] ?? 0);
if ($refundCent > 0) {
$remark .= '(账单含退款' . round($refundCent / 100, 2) . '元)';
}
}
$order->remark = $remark;
$order->payee_userid = $billPayeeUserid;
$order->payer_external_userid = $payerExternalUserid;
$order->save();
@@ -652,15 +707,17 @@ class OrderLogic
/**
* @notes 订单统计(按订单类型或退款)
* @param array $params order_type(0退款,1挂号费,2问诊费,3药品费用,4首付,5尾款,6其他), days(0今天,7,30)
* @param array $params order_type(-1全部已支付类型合计,0退款,1挂号费,2问诊费,3药品费用,4首付,5尾款,6其他), days(0今天,7,30)
* @return array
*/
public static function orderStats(array $params = [])
{
$orderType = isset($params['order_type']) ? (int)$params['order_type'] : 1;
if (!array_key_exists($orderType, self::$orderTypeNames)) {
$allPaidOrderTypes = [1, 2, 3, 4, 5, 6];
$orderType = array_key_exists('order_type', $params) ? (int) $params['order_type'] : 1;
if ($orderType !== -1 && $orderType !== 0 && !array_key_exists($orderType, self::$orderTypeNames)) {
$orderType = 1;
}
$orderTypeName = $orderType === -1 ? '全部(已支付)' : self::$orderTypeNames[$orderType];
$days = isset($params['days']) ? (int)$params['days'] : 7;
$endTime = !empty($params['end_time']) ? strtotime($params['end_time']) : time();
@@ -682,6 +739,8 @@ class OrderLogic
->whereNull('delete_time');
if ($orderType === 0) {
$query->where('status', 4);
} elseif ($orderType === -1) {
$query->whereIn('order_type', $allPaidOrderTypes)->where('status', 2);
} else {
$query->where('order_type', $orderType)->where('status', 2);
}
@@ -696,7 +755,7 @@ class OrderLogic
if (empty($creatorIds)) {
return [
'order_type' => $orderType,
'order_type_name' => self::$orderTypeNames[$orderType],
'order_type_name' => $orderTypeName,
'date_range' => [date('Y-m-d', $startTime), date('Y-m-d', $endTime)],
'today_total' => 0,
'today_amount' => '0.00',
@@ -738,6 +797,8 @@ class OrderLogic
->whereNull('delete_time');
if ($orderType === 0) {
$todayQuery->where('status', 4);
} elseif ($orderType === -1) {
$todayQuery->whereIn('order_type', $allPaidOrderTypes)->where('status', 2);
} else {
$todayQuery->where('order_type', $orderType)->where('status', 2);
}
@@ -835,7 +896,7 @@ class OrderLogic
return [
'order_type' => $orderType,
'order_type_name' => self::$orderTypeNames[$orderType],
'order_type_name' => $orderTypeName,
'date_range' => [date('Y-m-d', $startTime), date('Y-m-d', $endTime)],
'today_total' => $todayTotal,
'today_amount' => number_format($todayAmount, 2, '.', ''),
@@ -848,4 +909,129 @@ class OrderLogic
],
];
}
/**
* 与订单列表一致:超管或主管角色可见他人创建的订单
*/
public static function isOrderListSupervisor(int $adminId, array $adminInfo): bool
{
if (!empty($adminInfo['root']) && (int) $adminInfo['root'] === 1) {
return true;
}
$supervisorRoles = [0, 3];
$myRoles = array_map('intval', $adminInfo['role_id'] ?? []);
return count(array_intersect($myRoles, $supervisorRoles)) > 0;
}
/**
* 某诊单下已支付支付单,供关联业务订单多选(主管/诊单医助看该诊单全部;否则仅本人创建)
* 已占用(关联到未撤回/未取消的业务订单)的支付单会排除;编辑某业务订单时传 $exceptPrescriptionOrderId 以保留当前单已选中的项
*
* @return array<int, array<string, mixed>>
*/
public static function listPaidOrdersForDiagnosis(int $diagnosisId, int $adminId, array $adminInfo, ?int $exceptPrescriptionOrderId = null): array
{
if ($diagnosisId <= 0) {
return [];
}
$exists = Diagnosis::where('id', $diagnosisId)->whereNull('delete_time')->count() > 0;
if (!$exists) {
return [];
}
$q = Order::where('patient_id', $diagnosisId)
->where('status', 2)
->whereNull('delete_time');
if (!self::isOrderListSupervisor($adminId, $adminInfo)) {
$assistantId = (int) Diagnosis::where('id', $diagnosisId)->value('assistant_id');
if ($assistantId !== $adminId) {
$q->where('creator_id', $adminId);
}
}
$rows = $q
->field(['id', 'order_no', 'order_type', 'amount', 'status', 'create_time', 'creator_id', 'remark'])
->order('id', 'desc')
->select()
->toArray();
$activePoIds = PrescriptionOrder::whereNull('delete_time')
->where('fulfillment_status', '<>', 4)
->column('id');
$busyPayIds = [];
if ($activePoIds !== []) {
$busyPayIds = PrescriptionOrderPayOrder::whereIn('prescription_order_id', $activePoIds)
->column('pay_order_id');
$busyPayIds = array_unique(array_map('intval', $busyPayIds));
}
$whiteList = [];
if ($exceptPrescriptionOrderId !== null && $exceptPrescriptionOrderId > 0) {
$whiteList = array_map(
'intval',
PrescriptionOrderPayOrder::where('prescription_order_id', $exceptPrescriptionOrderId)->column('pay_order_id')
);
}
$out = [];
foreach ($rows as $row) {
$oid = (int) ($row['id'] ?? 0);
if ($oid <= 0) {
continue;
}
$busy = in_array($oid, $busyPayIds, true);
$allowed = in_array($oid, $whiteList, true);
if ($busy && ! $allowed) {
continue;
}
$out[] = $row;
}
return $out;
}
/**
* 校验支付单均可关联到指定诊单(已支付、归属与权限)
*
* @param int[] $ids zyt_order.id
*/
public static function assertPayOrdersLinkable(array $ids, int $diagnosisId, int $adminId, array $adminInfo): ?string
{
$ids = array_values(array_unique(array_filter(array_map('intval', $ids), static fn (int $v): bool => $v > 0)));
if ($diagnosisId <= 0) {
return '诊单无效';
}
if ($ids === []) {
return null;
}
$diagExists = Diagnosis::where('id', $diagnosisId)->whereNull('delete_time')->count() > 0;
if (!$diagExists) {
return '诊单不存在';
}
$supervisor = self::isOrderListSupervisor($adminId, $adminInfo);
$assistantId = (int) Diagnosis::where('id', $diagnosisId)->value('assistant_id');
$isDiagAssistant = $assistantId === $adminId;
$orders = Order::whereIn('id', $ids)->whereNull('delete_time')->select();
if (count($orders) !== count($ids)) {
return '部分支付单不存在或已删除';
}
foreach ($orders as $o) {
if ((int) $o->patient_id !== $diagnosisId) {
return '支付单与诊单不匹配';
}
if ((int) $o->status !== 2) {
return '仅能关联已支付订单';
}
if (! $supervisor && ! $isDiagAssistant && (int) $o->creator_id !== $adminId) {
return '无权限关联所选支付单';
}
}
return null;
}
}