// +---------------------------------------------------------------------- namespace app\services\order; use app\dao\order\StoreOrderRefundDao; use app\services\BaseServices; use app\services\pay\PayServices; use crmeb\exceptions\AdminException; use crmeb\exceptions\ApiException; use crmeb\services\HttpService; use think\facade\Log; /** * 售后单 * Class OutStoreOrderRefundServices * @package app\services\order */ class OutStoreOrderRefundServices extends BaseServices { /** * 订单services * @var StoreOrderServices */ protected $storeOrderServices; /** * 构造方法 * OutStoreOrderRefundServices constructor. * @param StoreOrderRefundDao $dao */ public function __construct(StoreOrderRefundDao $dao, OutStoreOrderServices $storeOrderServices) { $this->dao = $dao; $this->storeOrderServices = $storeOrderServices; } /** * 售后单列表 * @param array $where * @return void */ public function refundList(array $where) { [$page, $limit] = $this->getPageValue(); $field = 'id, store_order_id, uid, order_id, refund_type, refund_num, refund_price, refunded_price, refund_phone, refund_express, refund_express_name, refund_explain, refund_img, refund_reason, refuse_reason, remark, refunded_time, cart_info, is_cancel, is_del, is_pink_cancel, add_time'; $list = $this->dao->getList($where, $page, $limit, $field); $count = $this->dao->count($where); foreach ($list as $key => &$item) { $item['pay_price'] = $item['refund_price']; unset($item['refund_price']); $item['items'] = $this->tidyCartList($item['cart_info']); unset($list[$key]['cart_info']); } return compact('list', 'count'); } /** * 格式化订单商品 * @param array $carts * @return array */ public function tidyCartList(array $carts): array { $list = []; foreach ($carts as $cart) { $list[] = [ 'store_name' => $cart['productInfo']['store_name'] ?? '', 'suk' => $cart['productInfo']['attrInfo']['suk'] ?? '', 'image' => $cart['productInfo']['attrInfo']['image'] ?: $cart['productInfo']['image'], 'price' => sprintf("%.2f", $cart['truePrice'] ?? '0.00'), 'cart_num' => $cart['cart_num'] ?? 0 ]; } return $list; } /** * 退款订单详情 * @param string $orderId 售后单号 * @param int $id 售后单ID * @return mixed */ public function getInfo(string $orderId = '', int $id = 0) { $field = ['id', 'store_order_id', 'order_id', 'uid', 'refund_type', 'refund_num', 'refund_price', 'refunded_price', 'refund_phone', 'refund_express', 'refund_express_name', 'refund_explain', 'refund_img', 'refund_reason', 'refuse_reason', 'remark', 'refunded_time', 'cart_info', 'is_cancel', 'is_pink_cancel', 'is_del', 'add_time']; if ($id > 0) { $where = $id; } else { $where = ['order_id' => $orderId]; } $refund = $this->dao->get($where, $field, ['orderData']); if (!$refund) throw new ApiException(410173); $refund = $refund->toArray(); //核算优惠金额 $totalPrice = 0; $vipTruePrice = 0; foreach ($refund['cart_info'] ?? [] as $key => &$cart) { $cart['sum_true_price'] = sprintf("%.2f", $cart['sum_true_price'] ?? bcmul((string)$cart['truePrice'], (string)$cart['cart_num'], 2)); $cart['vip_sum_truePrice'] = bcmul($cart['vip_truePrice'], $cart['cart_num'] ?: 1, 2); $vipTruePrice = bcadd((string)$vipTruePrice, $cart['vip_sum_truePrice'], 2); if (isset($order['split']) && $order['split']) { $refund['cart_info'][$key]['cart_num'] = $cart['surplus_num']; if (!$cart['surplus_num']) unset($refund['cart_info'][$key]); } $totalPrice = bcadd($totalPrice, $cart['sum_true_price'], 2); } $refund['vip_true_price'] = $vipTruePrice; /** @var StoreOrderRefundServices $refundServices */ $refundServices = app()->make(StoreOrderRefundServices::class); $refund['use_integral'] = $refundServices->getOrderSumPrice($refund['cart_info'], 'use_integral', false); $refund['coupon_price'] = $refundServices->getOrderSumPrice($refund['cart_info'], 'coupon_price', false); $refund['deduction_price'] = $refundServices->getOrderSumPrice($refund['cart_info'], 'integral_price', false); $refund['pay_postage'] = $refundServices->getOrderSumPrice($refund['cart_info'], 'postage_price', false); $refund['total_price'] = bcadd((string)$totalPrice, bcadd((string)$refund['deduction_price'], (string)$refund['coupon_price'], 2), 2); $refund['items'] = $this->tidyCartList($refund['cart_info']); if (in_array($refund['refund_type'], [1, 2, 4, 5])) { $title = '申请退款中'; } elseif ($refund['refund_type'] == 3) { $title = '拒绝退款'; } else { $title = '已退款'; } $refund['refund_type_name'] = $title; $refund['pay_type_name'] = PayServices::PAY_TYPE[$refund['pay_type']] ?? '其他方式'; unset($refund['cart_info']); return $refund; } /** * 修改售后单备注 * @param string $orderId 售后单号 * @param string $remark 备注 * @return bool * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function remark(string $orderId, string $remark): bool { $order = $this->dao->get(['order_id' => $orderId]); if (!$order) { throw new ApiException(410173); } /** @var StoreOrderRefundServices $refundServices */ $refundServices = app()->make(StoreOrderRefundServices::class); return $refundServices->updateRemark((int)$order['id'], $remark); } /** * 订单退款 * @param string $orderId 售后单号 * @param string $refundPrice 退款金额 * @return bool * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function refundPrice(string $orderId, string $refundPrice): bool { $orderRefund = $this->dao->get(['order_id' => $orderId]); if (!$orderRefund) { throw new ApiException(100026); } if ($orderRefund['is_cancel'] == 1) { throw new ApiException(400118); } $order = $this->storeOrderServices->get((int)$orderRefund['store_order_id']); if (!$order) { throw new ApiException(100026); } if (!in_array($orderRefund['refund_type'], [1, 5])) { throw new ApiException(400144); } $data['refund_type'] = 6; $data['refunded_time'] = time(); /** @var StoreOrderRefundServices $refundServices */ $refundServices = app()->make(StoreOrderRefundServices::class); //0元退款 if ($orderRefund['refund_price'] == 0 && in_array($orderRefund['refund_type'], [1, 5])) { $refundPrice = 0; } else { if (!$refundPrice) { throw new ApiException(400146); } if ($orderRefund['refund_price'] == $orderRefund['refunded_price']) { throw new ApiException(400147); } $data['refunded_price'] = bcadd($refundPrice, $orderRefund['refunded_price'], 2); $bj = bccomp((string)$orderRefund['refund_price'], $data['refunded_price'], 2); if ($bj < 0) { throw new ApiException(400148); } } $refundData['pay_price'] = $order['pay_price']; $refundData['refund_price'] = $refundPrice; if ($order['refund_price'] > 0) { mt_srand(); $refundData['refund_id'] = $order['order_id'] . rand(100, 999); } $refundData['order_id'] = $orderId; //修改订单退款状态 if ($refundServices->agreeRefund((int)$orderRefund['id'], $refundData)) { $refundServices->update((int)$orderRefund['id'], $data); return true; } else { $refundServices->storeProductOrderRefundYFasle((int)$orderRefund['id'], $refundPrice); throw new ApiException(400150); } } /** * 同意退款 * @param string $orderId 售后单号 * @return bool * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function agree(string $orderId): bool { $orderRefund = $this->dao->get(['order_id' => $orderId]); if (!$orderRefund) { throw new ApiException(100026); } /** @var StoreOrderRefundServices $refundServices */ $refundServices = app()->make(StoreOrderRefundServices::class); return $refundServices->agreeExpress((int)$orderRefund['id']); } /** * 拒绝退款 * @param string $orderId 售后单号 * @param string $refundReason 不退款原因 * @return bool * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function refuse(string $orderId, string $refundReason): bool { $orderRefund = $this->dao->get(['order_id' => $orderId]); if (!$orderRefund) { throw new ApiException(100026); } /** @var StoreOrderRefundServices $refundServices */ $refundServices = app()->make(StoreOrderRefundServices::class); $refundServices->refuse((int)$orderRefund['id'], $refundReason); return true; } /** * 售后单生成 * @param int $id * @param string $pushUrl * @return bool */ public function refundCreatePush(int $id, string $pushUrl): bool { $refundInfo = $this->getInfo('', $id); /** @var OutStoreOrderServices $orderServices */ $orderServices = app()->make(OutStoreOrderServices::class); $orderInfo = $orderServices->get($refundInfo['store_order_id'], ['id', 'order_id']); if (!$orderInfo) { throw new AdminException(400118); } $refundInfo['order'] = $orderInfo->toArray(); return out_push($pushUrl, $refundInfo, '售后单'); } /** * 售后单取消 * @param int $id * @param string $pushUrl * @return bool */ public function cancelApplyPush(int $id, string $pushUrl): bool { $refundInfo = $this->getInfo('', $id); /** @var OutStoreOrderServices $orderServices */ $orderServices = app()->make(OutStoreOrderServices::class); $orderInfo = $orderServices->get($refundInfo['store_order_id'], ['id', 'order_id']); if (!$orderInfo) { throw new AdminException(400118); } $refundInfo['order'] = $orderInfo->toArray(); return out_push($pushUrl, $refundInfo, '取消售后单'); } }