0]; $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; } try { self::$total = 0; /** 计算价格 */ $check = DictType::where('type','activities')->find(); foreach ($cart_select as $k => $v) { $find = StoreBranchProduct::where(['id' => $v['goods']])->field('store_name,image,unit,price,product_id')->find(); if (!$find) { continue; } if(isset($check) && $check['status'] == 1){ $find['price'] = StoreProduct::where('product_id',$find['product_id'])->value('ot_price'); } $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'] = $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']; $cart_select[$k]['imgs'] = $find['image']; $cart_select[$k]['unit_name'] = StoreProductUnit::where(['id' => $find['unit']])->value('name'); self::$total = bcadd(self::$total, $cart_select[$k]['total'], 2); } //TODO 收单打9.9折 会员按照比例打折 等级按照充值去升级 $pay_price = self::$total; // $check = StoreOrder::where('uid',\request()->userId)->count();//首单逻辑 $vipPrice = 0; 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); } } if(!empty(self::$total) && !empty($pay_price)){ bcscale(2); $vipPrice = bcsub(self::$total, $pay_price, 2); } $order = [ 'create_time' => time(), 'order_id' => getNewOrderId('PF'), 'total_price' => self::$total,//总价 'pay_price' => $pay_price,//后期可能有降价抵扣 'vip_price'=>$vipPrice, 'total_num' => count($cart_select),//总数 'pay_type' => $params['pay_type'] ?? 0, 'reservation_time' => $params['reservation_time'] ?? '', 'cart_id' => implode(',', $cartId), 'store_id' => $params['store_id'] ?? 0, 'shipping_type' => $params['shipping_type'] ?? 1//配送方式 1=快递 ,2=门店自提 ]; } catch (\Exception $e) { self::setError($e->getMessage()); return false; } return ['order' => $order, 'cart_list' => $cart_select]; } /** * 创建新订单 * @return Object|bool|array */ static public function createOrder($cartId, $addressId, $user = null, $params = []) { $verify_code = verificationCode(); $params['verify_code'] = $verify_code; $orderInfo = self::cartIdByOrderInfo($cartId, $addressId, $user, $params); if (!$orderInfo) { return false; } $_order = $orderInfo['order']; $_order['deduction_price'] = 0; $_order['uid'] = request()->userId; $user = User::where('id', \request()->userId)->find(); $_order['real_name'] = $user['real_name']; $_order['mobile'] = $user['mobile']; $_order['pay_type'] = $orderInfo['order']['pay_type']; $_order['verify_code'] = $verify_code; if (isset($params['reservation_time'])) { $_order['reservation_time'] = $params['reservation_time']; $_order['reservation'] = YesNoEnum::YES; } if ($addressId > 0) { $address = UserAddress::where(['id' => $addressId, 'uid' => Request()->userId])->find(); if ($address) { $_order['real_name'] = $address['real_name']; $_order['user_phone'] = $address['phone']; $_order['user_address'] = $address['detail']; } } Db::startTrans(); try { $order = StoreOrder::create($_order); $goods_list = $orderInfo['cart_list']; foreach ($goods_list as $k => $v) { $goods_list[$k]['oid'] = $order->id; $goods_list[$k]['uid'] = request()->userId; $goods_list[$k]['cart_id'] = implode(',', $cartId); $goods_list[$k]['delivery_id'] = $params['store_id'];//商家id } (new StoreOrderCartInfo())->saveAll($goods_list); $where = ['is_pay' => 0]; Cart::whereIn('id', $cartId)->where($where)->update(['is_pay' => 1]); Db::commit(); return $order; } catch (\Exception $e) { Db::rollback(); self::setError($e->getMessage()); return false; } } /** * @notes 获取购货订单购物车商品信息 * @param $params * @return array */ static public function cartIdByPurchaseOrderInfo($user, $params) { if (!$user) { self::setError('没有用户信息,请先登录'); return false; } $mer_id = $user['merchant']['mer_id']; $where1 = ['paid' => 1, 'is_opurchase' => 0]; $where1[] = ['pay_type', '<>', 9]; $arrs = Cashierclass::where('merchant', $mer_id)->whereDay('create_time')->where($where1)->column('cart_id,id,address_id'); // $order_id = Cashierclass::where('merchant', $mer_id)->whereDay('create_time')->where($where1)->column('id'); $cart_arr = []; $order_id = []; foreach ($arrs as $k => $v) { if (empty($v['cart_id'])) { self::setError('没有购物车信息'); return false; } // if (empty($v['address_id'])) { // self::setError('请先设置配送地址'); // return false; // } $arr = explode(',', $v['cart_id']); foreach ($arr as $kk => $vv) { $cart_arr[] = $vv; } $order_id[] = $v['id']; } $where = ['is_pay' => 1, 'is_fail' => 0]; $cart_select = Cart::whereIn('cart_id', $cart_arr)->where($where)->field('goods_id as goods,cart_num')->select()->toArray(); if (empty($cart_select)) { self::setError('购物车为空'); return false; } /** 计算价格 */ foreach ($cart_select as $k => $v) { $sell = Goods::where(['id' => $v['goods']])->value('sell'); $cart_select[$k]['total'] = bcmul($v['cart_num'], $sell, 2); $cart_select[$k]['price'] = $sell; } $order = [ 'time' => time(), 'number' => static::getNewOrderId('CG'), 'total' => array_sum(array_column($cart_select, 'total')), 'pay_type' => $params['pay_type'] ?? 0, 'cart_id' => implode(',', $cart_arr), 'order_arr' => implode(',', $order_id) ]; return ['order' => $order, 'cart_list' => $cart_select]; } /** * 创建购货订单 * @return Object|bool */ static public function createOpurchaseOrder($user = null, $params = []) { if (!$user) { self::setError('没有用户信息,请先登录'); return false; } $mer_id = $user['merchant']['mer_id']; // $merchant = Merchant::where('mer_id', $mer_id)->find(); $orderInfo = self::cartIdByPurchaseOrderInfo($user, $params); if (!$orderInfo) { return false; } $_order = $orderInfo['order']; // if ($_order['total'] < $merchant['mer_money']) { // self::setError('商户余额不足'); // return false; // } $_order['merchant'] = $mer_id; $_order['money'] = $_order['total']; $_order['actual'] = $_order['total']; $_order['paid'] = 1; Db::startTrans(); try { $order = Opurchaseclass::create($_order); $goods_list = $orderInfo['cart_list']; foreach ($goods_list as $k => $v) { $goods_list[$k]['nums'] = $v['cart_num']; $goods_list[$k]['pid'] = $order->id; } (new Opurchaseinfo())->saveAll($goods_list); // $merchant->mer_money = bcsub($merchant->mer_money, $_order['total'], 2); $order_arr = explode(',', $_order['order_arr']); Cashierclass::where('id', 'in', $order_arr)->update(['is_opurchase' => 1]); Db::commit(); return $order; } catch (\Exception $e) { Db::rollback(); self::setError($e->getMessage()); return false; } } /** * @notes 获取订单号 * @param $type * @return string * @author likeadmin * @date 2021/7/28 17:05 */ static public function getNewOrderId($type) { list($msec, $sec) = explode(' ', microtime()); $msectime = number_format((floatval($msec) + floatval($sec)) * 1000, 0, '', ''); $orderId = $type . $msectime . mt_rand(10000, max(intval($msec * 10000) + 10000, 98369)); return $orderId; } /** * 余额订单支付 * @param User $user * @param $order * @return bool * @throws Exception * @throws ValidateException */ static public function payBalance(User $user, $order) { if ($user['now_money'] < $order['pay_price']) { self::setError('余额不足,请更换支付方式'); return false; } Db::startTrans(); try { $user->now_money = bcsub($user->now_money, $order['pay_price'], 2); $user->save(); $capitalFlowDao = new CapitalFlowLogic($user); $capitalFlowDao->userExpense('user_order_pay', 'order', $order['id'], $order['pay_price']); Db::commit(); return true; } catch (\Exception $e) { Db::rollback(); Log::error('余额支付失败' . $e->getMessage() . '。line:' . $e->getLine() . '。file:' . $e->getFile()); self::setError('余额支付失败' . $e->getMessage()); return false; } } /** * @notes 订单支付成功 * @param $order 订单 * @param $CallbackData 回调数据 * @date 2021/7/8 00:40 */ static function paySuccess($order, $CallbackData = []) { Db::startTrans(); try { $order->money = $CallbackData['money']; $order->paid = 1; $order->save(); Log::info('支付成功'); // 提交事务 Db::commit(); return true; } catch (\Exception $e) { // 回滚事务 Db::rollback(); Log::error('支付失败' . $e->getMessage() . '。like:' . $e->getLine()); self::setError('支付失败' . $e->getMessage()); return false; } } /** * 获取用户常用购买记录 */ public static function frequentlyPurchase($params) { try { $goods_id = StoreOrderCartInfo::where('uid', Request()->userId)->page($params['page_no'])->limit(50)->column('product_id'); if (!$goods_id) { return []; } $goods_arr = array_unique($goods_id); $select = StoreBranchProduct::where('id', 'in', $goods_arr)->with('unitName')->field('id,store_name,price,image,unit')->select(); return $select->toArray(); } catch (\Exception $e) { self::setError($e->getMessage()); return false; } } public static function purchaseAgain($order_id) { $arr = StoreOrderCartInfo::where('oid', $order_id)->field('product_id,cart_num,staff_id')->select(); $data = []; foreach ($arr as $k => $v) { $data[$k]['product_id'] = $v['product_id']; $unique = StoreProductAttrValue::where('product_id', $v['product_id'])->value('v'); $data[$k]['product_attr_unique'] = $unique; $data[$k]['cart_num'] = $v['cart_num']; $data[$k]['type'] = ''; $data[$k]['uid'] = Request()->userId; $store_id = StoreProduct::where('id', $v['product_id'])->value('store_id'); $data[$k]['store_id'] = $store_id; $data[$k]['staff_id'] = $v['staff_id']; $data[$k]['combination_id'] = 0; $data[$k]['seckill_id'] = 0; $data[$k]['bargain_id'] = 0; $data[$k]['discount_id'] = 0; $data[$k]['status'] = 1; $data[$k]['staff_id'] = 0; $data[$k]['is_new'] = 0; $data[$k]['is_del'] = 0; $data[$k]['is_pay'] = 0; } if ($data) { (new Cart())->saveAll($data); return true; } return false; } public static function detail($params): array { $find = StoreOrder::where($params)->findOrEmpty()->toArray(); if ($find) { $find['goods_list'] = StoreOrderCartInfo::where('oid', $find['id']) ->with('goodsName') ->field('product_id,cart_num nums')->select()->each(function ($item) { $item['msg'] = '预计48小时发货'; $item['unit_name'] = StoreProductUnit::where('id', $item['unit'])->value('name'); }); $store = SystemStore::where('id', $find['store_id'])->field('id,name,phone,address,detailed_address')->find(); $find['store_info'] = $store; } return $find; } //取消售后 public static function cancelSell($where) { return StoreOrder::where($where)->update( [ 'refund_status'=>OrderEnum::CANCEL_SALE, 'status'=>OrderEnum::CANCEL_ORDER, 'refund_cancle_time'=>date('Y-m-d H:i:s',time()) ] ); } //核销 /** * @param $params * @return bool * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException * @author: codeliu * @Time: 2024/6/3 22:42 */ public static function writeOff($params): bool { $data = StoreOrder::with('store')->where([ 'verify_code' => $params['verify_code'] ])->find(); if (empty($data)) { return false; } Db::startTrans(); try { StoreOrder::update([ 'status' => OrderEnum::RECEIVED_GOODS, 'is_writeoff' => OrderEnum::IS_OK, 'update_time' => time(), ], ['id' => $data['id']]); (new StoreOrderCartInfo())->update([ 'writeoff_time' => time(), 'is_writeoff' => YesNoEnum::YES, 'update_time' => time(), ], ['oid' => $data['id']]); $financeFlow = (new StoreFinanceFlowLogic)->getStoreOrder($data['id'], $data['store_id']); if (!empty($financeFlow)) { $capitalFlowLogic = new CapitalFlowLogic($data->store, 'store'); $capitalFlowLogic->storeIncome('store_order_income', 'order', $data['id'], $financeFlow['number']); } Db::commit(); return true; } catch (\Exception $e) { Db::rollback(); self::setError($e->getMessage()); return false; } } public static function write_count($info,$params) { $store_id = SystemStoreStaff::where('phone',$info['mobile'])->value('store_id'); if(empty($store_id)){ throw new \Exception('该用户未绑定店铺请查看'); } $query = StoreOrderCartInfo::alias('o') ->leftJoin('store_branch_product p','p.id = o.product_id') ->leftJoin('store_order s','s.id = o.oid') ->field('o.oid,p.store_name,s.order_id') ->where('o.store_id',$store_id); if(isset($params['name']) && $params['name']){ if($params['name'] && preg_match('/[\x{4e00}-\x{9fff}]+/u', $params['name'])==1){ $query->where('p.store_name','like','%'.$params['name'].'%'); }else{ $query->where('s.order_id',$params['name']); } } $product = $query->select(); if(empty($product)){ return [ 'no_send'=>0, 'send'=>0 ]; } $oids = array_column($product->toArray(), 'oid'); $uniqueOids = array_unique($oids); $no_send = StoreOrder::whereIn('id',$uniqueOids) ->where('status',1)->count(); $send = StoreOrder::whereIn('id',$uniqueOids) ->where('status',2)->count(); return [ 'no_send'=>$no_send, 'send'=>$send ]; } public static function getOne($code) { return StoreOrder::with(['store'])->where('verify_code',$code) ->select()->each(function ($item) { $item['goods_list']=StoreOrderCartInfo::where('oid',$item['id'])->with('goodsName')->field('product_id,cart_num,verify_code,is_writeoff,writeoff_time')->limit(3)->select(); $item['goods_count']=count(explode(',',$item['cart_id'])); return $item; //返回处理后的数据。 }) ->toArray(); } public static function write_list($info,$status,$params) { $store_id = SystemStoreStaff::where('phone',$info['mobile'])->value('store_id'); if(empty($store_id)){ throw new \Exception('该用户未绑定店铺请查看'); } //先查商品相似 $query = StoreOrderCartInfo::alias('o') ->leftJoin('store_branch_product p','p.id = o.product_id') ->leftJoin('store_order s','s.id = o.oid') ->field('o.oid,p.store_name,s.order_id') ->where('o.store_id',$store_id); if(isset($params['name']) && $params['name']){ if($params['name'] && preg_match('/[\x{4e00}-\x{9fff}]+/u', $params['name'])==1){ $query->where('p.store_name','like','%'.$params['name'].'%'); }else{ $query->where('s.order_id',$params['name']); } } $product = $query->select(); if(empty($product)){ return [ 'list'=>[], 'count'=>0 ]; } $oids = array_column($product->toArray(), 'oid'); $uniqueOids = array_unique($oids); $query = StoreOrder::with(['store']) ->whereIn('id',$uniqueOids) ->where('status',$status); $count = $query->count(); $list = $query ->page($params['page_no'], $params['page_size']) ->order(['id' => 'desc']) ->select() ->each(function($item){ $item['goods_list']=StoreOrderCartInfo::where('oid',$item['id'])->with('goodsName')->field('product_id,cart_num,verify_code,is_writeoff,writeoff_time')->limit(3)->select(); $item['goods_count']=count(explode(',',$item['cart_id'])); }) ->toArray(); return [ 'list'=>$list, '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->refund_type = $params['refund_type']; $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,$params); 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,$params) { //查出不在这个退货中的数据 $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['refund_type'] = $params['refund_type']; $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['refund_reason_time'] = time(); $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; } }