From 2ead3b7fd2bfe01e55d8c8ad59e206aef1e3ab5e Mon Sep 17 00:00:00 2001 From: liu <1873441552@qq.com> Date: Fri, 7 Jun 2024 15:38:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8B=86=E5=8D=95=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/controller/order/OrderController.php | 22 +- app/api/lists/order/OrderList.php | 2 +- app/api/logic/order/OrderLogic.php | 208 ++++++++++++++++++- app/api/validate/OrderValidate.php | 17 ++ app/functions.php | 16 ++ 5 files changed, 255 insertions(+), 10 deletions(-) diff --git a/app/api/controller/order/OrderController.php b/app/api/controller/order/OrderController.php index b52cf9ef..431c3568 100644 --- a/app/api/controller/order/OrderController.php +++ b/app/api/controller/order/OrderController.php @@ -475,16 +475,26 @@ class OrderController extends BaseApiController return $this->success('ok', ['order_count' => $res]); } - - //订单退款申请 + + #[ + ApiDoc\Title('订单退款申请'), + ApiDoc\url('/api/order/order/apply_refund'), + ApiDoc\Method('POST'), + ApiDoc\Param(name: "refund_message", type: "string", require: true, desc: "退款原因"), + ApiDoc\Param(name: "refund_num", type: "int", require: true, desc: "退款数量"), + ApiDoc\Param(name: "id", type: "int", require: true, desc: "订单id"), + ApiDoc\Param(name: "old_cart_id", type: "int", require: true, desc: "购物车id"), + ApiDoc\NotHeaders(), + ApiDoc\Header(name: "token", type: "string", require: true, desc: "token"), + ApiDoc\ResponseSuccess("data", type: "array"), + ] public function apply_refund() { $params = (new OrderValidate())->post()->goCheck('add'); $uid = $this->userId; -// OrderLogic::dealRefund($uid,$params); - - - + //拆单逻辑 + OrderLogic::dealRefund($uid,$params); + return $this->success('申请成功'); } diff --git a/app/api/lists/order/OrderList.php b/app/api/lists/order/OrderList.php index 2d1857f9..d4d9f4e3 100644 --- a/app/api/lists/order/OrderList.php +++ b/app/api/lists/order/OrderList.php @@ -51,7 +51,7 @@ class OrderList extends BaseAdminDataLists implements ListsSearchInterface ->each(function($item){ $item['goods_list']=StoreOrderCartInfo::where('oid',$item['id'])->with(['goodsName'=> function ($query) { $query->withTrashed(); - }])->field('product_id,cart_num,verify_code,is_writeoff,writeoff_time')->limit(3)->select(); + }])->field('product_id,cart_num,verify_code,is_writeoff,writeoff_time,old_cart_id')->limit(3)->select(); $item['goods_count']=count(explode(',',$item['cart_id'])); }) ->toArray(); diff --git a/app/api/logic/order/OrderLogic.php b/app/api/logic/order/OrderLogic.php index c4667865..42e288ea 100644 --- a/app/api/logic/order/OrderLogic.php +++ b/app/api/logic/order/OrderLogic.php @@ -23,10 +23,12 @@ use app\common\model\system_store\SystemStoreStaff; use app\common\model\user\User; use app\common\model\user\UserAddress; use app\common\model\user\UserShip; +use support\exception\BusinessException; use support\Log; use taoser\exception\ValidateException; use think\Exception; use think\facade\Db; +use Workerman\Events\Select; use Yansongda\Pay\Event\PayEnd; /** @@ -47,7 +49,7 @@ class OrderLogic extends BaseLogic { $where = ['is_pay' => 0]; - $cart_select = Cart::whereIn('id', $cartId)->where($where)->field('product_id as goods,cart_num')->select()->toArray(); + $cart_select = Cart::whereIn('id', $cartId)->where($where)->field('id,product_id as goods,cart_num')->select()->toArray(); if (empty($cart_select)) { self::setError('购物车为空'); return false; @@ -63,12 +65,18 @@ class OrderLogic extends BaseLogic $cart_select[$k]['total'] = bcmul($v['cart_num'], $find['price'], 2);//钱 $cart_select[$k]['price'] = $find['price']; $cart_select[$k]['product_id'] = $v['goods']; - $cart_select[$k]['old_cart_id'] = implode(',', $cartId); + $cart_select[$k]['old_cart_id'] = $v['id']; $cart_select[$k]['cart_num'] = $v['cart_num']; $cart_select[$k]['verify_code'] = $params['verify_code'] ?? ''; $cartInfo = $cart_select[$k]; $cartInfo['name'] = $find['store_name']; $cartInfo['image'] = $find['image']; + //计算好vip价格 + $vipPrice = self::dealVip($find['price']); + if($vipPrice){ + $cartInfo['price'] = $vipPrice; + } + $cartInfo['vip_price'] = $cart_select[$k]['total'] - $vipPrice??0; $cart_select[$k]['cart_info'] = json_encode($cartInfo); //理论上每笔都是拆分了 $cart_select[$k]['name'] = $find['store_name']; @@ -141,7 +149,7 @@ class OrderLogic extends BaseLogic */ static public function createOrder($cartId, $addressId, $user = null, $params = []) { - $verify_code = generateUniqueVerificationCode(); + $verify_code = verificationCode(); $params['verify_code'] = $verify_code; $orderInfo = self::cartIdByOrderInfo($cartId, $addressId, $user, $params); if (!$orderInfo) { @@ -585,4 +593,198 @@ class OrderLogic extends BaseLogic 'count'=>$count ]; } + + public static function dealRefund($uid,$params) + { + //todo 单子不是完成的不允许退款 + //单笔不拆单子直接修改状态 + $order = StoreOrder::where('id',$params['id'])->withTrashed()->findOrEmpty(); + if(count($params['old_cart_id']) ==1){ + $order->refund_status = OrderEnum::REFUND_STATUS_YES; + $order->status = OrderEnum::ALREADY_REFUND; + $order->refund_reason_wap_explain =$params['refund_message']??''; + $order->refund_num = $params['refund_num']; + $refund_price_cart = StoreOrderCartInfo::where('oid',$params['id']) + ->field('id,oid,cart_info') + ->find()->toArray(); + $vipPrice = $order['vip_price']; + $price = $refund_price_cart['cart_info']['price'] * $params['refund_num']; + $onePrice = 0; + bcscale(2); + if($vipPrice){ + //每单的vip价格 + $onePrice = bcdiv($vipPrice, $refund_price_cart['cart_info']['cart_num']); + } + if($price > $onePrice){ + $price =bcsub($price, $onePrice); + } + $order->refund_price = $price; + $order->save(); + }else{ + // 多单的情况 拆主订单为新的2单 修改新的2单的核销码 修改cart_info的核销码 和订单id 退款直接退一单的钱 + $order->delete_time = time(); + $order->save(); + Db::startTrans(); + try { + $order = $order->toArray(); + $cart_info = StoreOrderCartInfo::where('oid',$params['id']) + ->whereNotIn('old_cart_id',$params['old_cart_id']) + ->select()->toArray(); + if($cart_info){ + $leftOrder = self::dealCreateLeftOrder($order,$cart_info); + self::dealChangeCartInfo($leftOrder); + } + $refundOrder = self::dealCreateRefundOrder($order,$params); + self::dealChangeCartInfo($refundOrder); +// d($leftOrder,$refundOrder); + Db::commit(); + } catch (\Exception $e) { + // 回滚事务 + Db::rollback(); + throw new BusinessException($e->getMessage()); + } + + } + + return 1; + } + + + public static function dealChangeCartInfo($leftOrder) + { + $code = $leftOrder->verify_code; + $new_oid = $leftOrder->id; + $old_id = $leftOrder->pid; + $car_id = explode(',',$leftOrder->cart_id); + return StoreOrderCartInfo::where('oid',$old_id) + ->whereIn('old_cart_id',$car_id) + ->update([ + 'oid'=>$new_oid, + 'verify_code'=>$code + ]); + } + + + + public static function dealCreateLeftOrder($order,$cart_info) + { + //查出不在这个退货中的数据 + $order['order_id'] = $order['order_id'].'-2'; + $order['pid'] = $order['id']; + unset($order['id']); + $allOldCartIds =[]; + $totalTotal = 0; + $totalPrice = 0; + $totalVipPrice = 0; + foreach ($cart_info as $value){ + if (isset($value['old_cart_id'])) { + $allOldCartIds[] = $value['old_cart_id']; + } + if (isset($value['cart_info'])) { + if (isset($value['cart_info']['total'])) { + $totalTotal += floatval($value['cart_info']['total']); + } + if (isset($value['cart_info']['price'])) { + $totalPrice += floatval($value['cart_info']['price']); + } + if (isset($value['cart_info']['vip_price'])) { + $totalVipPrice += floatval($value['cart_info']['vip_price']); + } + } + } + $order['cart_id'] = implode(',',$allOldCartIds); + $order['total_num'] = count($cart_info); + $order['total_price'] = number_format($totalTotal, 2); + $order['pay_price'] = number_format($totalPrice, 2); + $order['vip_price'] = number_format($totalVipPrice, 2); + $order['verify_code'] = verificationCode(); + $order['create_time'] = time(); + $order['update_time'] = null; + $order['delete_time'] = null; + return StoreOrder::create($order); + } + + + + public static function dealCreateRefundOrder($order,$params) + { + $order['order_id'] = $order['order_id'].'-1'; + $order['pid'] = $order['id']; + unset($order['id']); + $order['cart_id'] = implode(',',$params['old_cart_id']); + + $order['refund_status'] = OrderEnum::REFUND_STATUS_YES; + $order['status'] = OrderEnum::ALREADY_REFUND; + $order['refund_num'] = $params['refund_num'];//按数量整单退剩余的 + $order['refund_reason_wap_explain'] = $params['refund_message']??''; + $order['total_num'] = count($params['old_cart_id']); + $refund_price_cart = StoreOrderCartInfo::whereIn('old_cart_id',$params['old_cart_id']) + ->field('id,oid,cart_info') + ->select()->toArray(); + $totalTotals = array_column(array_column($refund_price_cart, 'cart_info'), 'total'); + $totalTotal = array_reduce($totalTotals, function ($carry, $item) { + return $carry + $item; + }, 0); + $totalPrices = array_column(array_column($refund_price_cart, 'cart_info'), 'price'); + $totalPrice = array_reduce($totalPrices, function ($carry, $item) { + return $carry + $item; + }, 0); + + $totalVipPrices = array_column(array_column($refund_price_cart, 'cart_info'), 'vip_price'); + $totalVipPrices = array_reduce($totalVipPrices, function ($carry, $item) { + return $carry + $item; + }, 0); + + $order['total_price'] = number_format($totalTotal, 2); + $order['pay_price'] = number_format($totalPrice, 2); + $order['vip_price'] = number_format($totalVipPrices, 2); + $order['refund_price'] = number_format($totalPrice, 2); + $order['verify_code'] = verificationCode(); + $order['create_time'] = time()+1; + $order['update_time'] = null; + $order['delete_time'] = null; + return StoreOrder::create($order); + + } + + + public static function dealVip($pay_price) + { + $check = DictType::where('type','activities')->find(); + if(isset($check) && $check['status'] == 1){ +// $discountRate = '0.99';//首单逻辑 + $discountRate = $check['remark']; + $discountRate = bcdiv($discountRate, '100', 2); + $pay_price = bcdiv(bcmul($pay_price, $discountRate, 4), '1', 2); + }else{ + $userVip = User::where('id',\request()->userId)->value('user_ship'); + if($userVip){ + switch ($userVip){ + case UserShipEnum::VIP1: + $discountRate = UserShip::where('id',UserShipEnum::VIP1)->value('discount'); + break; + case UserShipEnum::VIP2: + $discountRate = UserShip::where('id',UserShipEnum::VIP2)->value('discount'); + break; + case UserShipEnum::VIP3: + $discountRate = UserShip::where('id',UserShipEnum::VIP3)->value('discount'); + break; + case UserShipEnum::VIP4: + $discountRate = UserShip::where('id',UserShipEnum::VIP4)->value('discount'); + break; + case UserShipEnum::VIP5: + $discountRate = UserShip::where('id',UserShipEnum::VIP5)->value('discount'); + break; + default: + $discountRate = 1; + } + $discountRate = bcdiv($discountRate, '100', 2); + $pay_price = bcdiv(bcmul($pay_price, $discountRate, 4), '1', 2); + } + } + return $pay_price; + + } + + } diff --git a/app/api/validate/OrderValidate.php b/app/api/validate/OrderValidate.php index d400659f..b1bb8a59 100644 --- a/app/api/validate/OrderValidate.php +++ b/app/api/validate/OrderValidate.php @@ -18,6 +18,10 @@ class OrderValidate extends BaseValidate */ protected $rule = [ 'verify_code' => 'require', + 'refund_message' => 'require', + 'refund_num' => 'require|number', + 'id' => 'require|number', + 'old_cart_id' => 'require|array', ]; @@ -27,6 +31,10 @@ class OrderValidate extends BaseValidate */ protected $field = [ 'verify_code' => '验证码', + 'refund_message' => '退款原因', + 'refund_num' => '退款数量', + 'id' => '订单id', + 'old_cart_id' => '购物车id', ]; @@ -41,6 +49,15 @@ class OrderValidate extends BaseValidate return $this->only(['verify_code']); } + /** + * @notes 退款场景 + * @return OrderValidate + */ + public function sceneAdd() + { + return $this->only(['refund_message','refund_num','id','old_cart_id']); + } + } diff --git a/app/functions.php b/app/functions.php index 7a23401f..8ad59b47 100644 --- a/app/functions.php +++ b/app/functions.php @@ -360,6 +360,22 @@ if (!function_exists('generateUniqueVerificationCode')) { } + +if (!function_exists('verificationCode')) { + function verificationCode() { + $sec = time(); + // 将前缀、秒时间戳和随机数连接起来 + $type = rand(1, 10); // 生成一个1-10之间的随机数作为前缀 + $code = $type .'-'. $sec; + $check = \app\common\model\store_order\StoreOrder::where('verify_code',$code)->count(); + if($check){ + verificationCode(); + } + return $code; + } +} + + if (!function_exists('haversineDistance')) { function haversineDistance($latitude1, $longitude1, $latitude2, $longitude2) { $earthRadius = 6371; // 地球平均半径,单位是千米