purchaseId ?? 0); if (!empty($purchaseId)) { $purchaseIds[] = $purchaseId; } } $cgMap = []; if (!empty($purchaseIds)) { $cgList = PurchaseClass::getByIds(array_unique($purchaseIds)); if (!empty($cgList)) { $cgMap = array_column($cgList, null, 'id'); } } $pairs = []; foreach ($orderList as $order) { $orderId = is_array($order) ? ($order['id'] ?? 0) : ($order->id ?? 0); $orderSn = is_array($order) ? ($order['orderSn'] ?? '') : ($order->orderSn ?? ''); $amount = self::resolveDebtAmount($order); $cgId = intval(is_array($order) ? ($order['purchaseId'] ?? 0) : ($order->purchaseId ?? 0)); $cgSn = ''; if ($cgId > 0 && isset($cgMap[$cgId])) { $cgSn = $cgMap[$cgId]['orderSn'] ?? ''; } $pairs[] = [ 'orderId' => intval($orderId), 'orderSn' => $orderSn, 'cgId' => $cgId, 'cgSn' => $cgSn, 'amount' => $amount, ]; } return $pairs; } public static function buildPairsFromPurchases($purchaseList) { if (empty($purchaseList)) { return []; } $saleIds = []; foreach ($purchaseList as $purchase) { $saleId = is_array($purchase) ? ($purchase['saleId'] ?? 0) : ($purchase->saleId ?? 0); if (!empty($saleId)) { $saleIds[] = $saleId; } } $orderMap = []; if (!empty($saleIds)) { $orderList = OrderClass::getByIds(array_unique($saleIds)); if (!empty($orderList)) { $orderMap = array_column($orderList, null, 'id'); } } $pairs = []; foreach ($purchaseList as $purchase) { $cgId = is_array($purchase) ? ($purchase['id'] ?? 0) : ($purchase->id ?? 0); $cgSn = is_array($purchase) ? ($purchase['orderSn'] ?? '') : ($purchase->orderSn ?? ''); $amount = self::resolveDebtAmount($purchase); $orderId = intval(is_array($purchase) ? ($purchase['saleId'] ?? 0) : ($purchase->saleId ?? 0)); $orderSn = ''; if ($orderId > 0 && isset($orderMap[$orderId])) { $orderSn = $orderMap[$orderId]['orderSn'] ?? ''; } $pairs[] = [ 'orderId' => $orderId, 'orderSn' => $orderSn, 'cgId' => intval($cgId), 'cgSn' => $cgSn, 'amount' => $amount, ]; } return $pairs; } public static function bindRelations($clear, $pairs, $status = self::STATUS_AWAIT_PAY) { $clearId = is_object($clear) ? ($clear->id ?? 0) : ($clear['id'] ?? 0); $clearSn = is_object($clear) ? ($clear->orderSn ?? '') : ($clear['orderSn'] ?? ''); if (empty($clearId) || empty($pairs)) { return; } foreach ($pairs as $pair) { $orderId = intval($pair['orderId'] ?? 0); $cgId = intval($pair['cgId'] ?? 0); if ($orderId <= 0 && $cgId <= 0) { continue; } $exists = self::getByCondition([ 'clearId' => $clearId, 'orderId' => $orderId, 'cgId' => $cgId, ], true); $newAmount = self::normalizeAmount($pair['amount'] ?? 0); if (!empty($exists)) { self::patchAmountIfEmpty($exists, $newAmount); continue; } self::add([ 'clearId' => $clearId, 'clearSn' => $clearSn, 'orderId' => $orderId, 'orderSn' => $pair['orderSn'] ?? '', 'cgId' => $cgId, 'cgSn' => $pair['cgSn'] ?? '', 'amount' => $newAmount, 'status' => $status, ]); } } public static function markDoneByClearId($clearId) { self::markStatusByClearId($clearId, self::STATUS_HAS_PAY); } /** * 更新关联表中的结账单号 (clearSn) * 用途:当微信/支付宝支付由于拉卡拉规则需要生成新的结账单号时,同步更新关联表中的单号,保持数据一致性 * 谁用:PurchaseClearController 微信/支付宝支付接口 */ public static function updateClearSnByClearId($clearId, $newClearSn) { $clearId = intval($clearId); if ($clearId <= 0 || empty($newClearSn)) { return; } $list = self::getAllByCondition(['clearId' => $clearId], null, '*', null, true); if (empty($list)) { return; } foreach ($list as $item) { $item->clearSn = $newClearSn; $item->save(); } } public static function markExpireByClearId($clearId) { self::markStatusByClearId($clearId, self::STATUS_EXPIRE); } public static function markStatusByClearId($clearId, $status) { $clearId = intval($clearId); $status = intval($status); if ($clearId <= 0) { return; } $list = self::getAllByCondition(['clearId' => $clearId], null, '*', null, true); if (empty($list)) { return; } foreach ($list as $item) { $item->status = $status; $item->save(); } } public static function getOrderIdsByClearId($clearId) { $clearId = intval($clearId); if ($clearId <= 0) { return []; } $list = self::getAllByCondition(['clearId' => $clearId, 'orderId>' => 0], null, 'orderId', null); return array_values(array_unique(array_filter(array_map('intval', array_column($list, 'orderId'))))); } public static function getCgIdsByClearId($clearId) { $clearId = intval($clearId); if ($clearId <= 0) { return []; } $list = self::getAllByCondition(['clearId' => $clearId, 'cgId>' => 0], null, 'cgId', null); return array_values(array_unique(array_filter(array_map('intval', array_column($list, 'cgId'))))); } public static function getPendingClearIdByOrderId($orderId, $customId) { $orderId = intval($orderId); $customId = intval($customId); if ($orderId <= 0) { return 0; } $list = self::getAllByCondition([ 'orderId' => $orderId, 'status' => self::STATUS_AWAIT_PAY, ], null, 'clearId', null); if (empty($list)) { return 0; } $clearIds = array_unique(array_map('intval', array_column($list, 'clearId'))); $now = date("Y-m-d H:i:s"); foreach ($clearIds as $clearId) { $clear = ClearClass::getById($clearId, true); if (empty($clear)) { continue; } if (($clear->status ?? 0) != PurchaseClearClass::STATUS_AWAIT_PAY) { continue; } if ($customId > 0 && ($clear->customId ?? 0) != $customId) { continue; } $deadline = $clear->deadline ?? ''; if (!empty($deadline) && $deadline < $now) { continue; } return intval($clearId); } return 0; } protected static function resolveDebtAmount($entity) { return self::normalizeAmount(self::readField($entity, 'actPrice')); } protected static function readField($entity, $key) { return is_array($entity) ? ($entity[$key] ?? 0) : ($entity->$key ?? 0); } protected static function normalizeAmount($amount) { if ($amount === '' || $amount === null) { return '0.00'; } return bcadd((string)$amount, '0', 2); } protected static function patchAmountIfEmpty($row, $amount) { $amount = self::normalizeAmount($amount); if (bccomp($amount, '0', 2) <= 0) { return false; } $current = self::normalizeAmount(is_object($row) ? ($row->amount ?? 0) : ($row['amount'] ?? 0)); if (bccomp($current, '0', 2) > 0) { return false; } if (is_object($row)) { $row->amount = $amount; return $row->save(false); } return false; } }