true, // 优惠券抵扣 'is_use_points' => true, // 是否使用积分抵扣 'force_points' => false, // 强制使用积分,积分兑换 'is_user_grade' => true, // 会员等级折扣 'is_agent' => true, // 商品是否开启分销,最终还是支付成功后判断分销活动是否开启 'is_reduce' => true, //是否满减 ]; /** * 订单结算数据 */ protected $commonOrderData = []; /** * 订单结算数据 */ protected $orderData = []; /** * 订单来源 */ protected $orderSource; /** * 构造函数 */ public function __construct($user, $supplierData, $params) { $this->model = new OrderModel; $this->app_id = OrderModel::$app_id; $this->user = $user; $this->supplierData = $supplierData; $this->params = $params; $this->orderSource = [ 'source' => OrderSourceEnum::BRANCHACTIVITY, 'activity_id' => 0 ]; } /** * 订单确认-结算台 */ public function settlement() { // 验证商品状态, 是否允许购买 $this->validateProductList(); $orderTotalNum = 0; $orderTotalPrice = 0; $orderPayPrice = 0; $expressPrice = 0; $totalPointsMoney = 0; $totalPoints = 0; $totalProductReduce = 0; $totalServicePrice = 0; $totalConsumptionMoney = 0; $totalConsumption = 0; $this->commonOrderData = $this->getCommonOrderData(); // 供应商 foreach ($this->supplierData as &$supplier) { // 整理订单数据 $this->orderData = $this->getOrderData($supplier['shop_supplier_id'], $supplier['productList']); // 订单商品总数量 $orderTotalNum += helper::getArrayColumnSum($supplier['productList'], 'total_num'); // 设置订单商品总服务费用 $totalServicePrice += $this->setProductService($supplier['productList']); //总服务费用 $this->orderData['total_service_price'] = $totalServicePrice; // 设置订单商品总金额(不含优惠折扣) $this->setOrderTotalPrice($supplier['productList']); $orderTotalPrice += $this->orderData['order_total_price']; // 计算积分商城抵扣 $this->setOrderPoints($supplier['productList'], $this->settledRule['force_points']); // 计算积分商城抵扣 $this->setOrderConsumption($supplier['productList']); // 计算订单商品的实际付款金额 $this->setOrderProductPayPrice($supplier['productList']); // 设置默认配送方式 if (!isset($this->params['supplier'])) { $deliveryType = SettingModel::getItem('store')['delivery_type']; $delivery = $this->params['delivery']; if (in_array($delivery, $deliveryType)) { $delivery = $delivery; } else if (in_array("10", $deliveryType)) { $delivery = 10; } else if (in_array("40", $deliveryType)) { $delivery = 40; } else { $delivery = $deliveryType[0]; } $this->orderData['delivery'] = $supplier['productList'][0]['is_virtual'] == 1 || $supplier['productList'][0]['is_virtual'] == 2 || $supplier['productList'][0]['is_virtual'] == 3 ? 30 : $delivery; } else { if ($supplier['productList'][0]['is_virtual'] == 1 || $supplier['productList'][0]['is_virtual'] == 2 || $supplier['productList'][0]['is_virtual'] == 3) { $this->orderData['delivery'] = 30; } else { $this->orderData['delivery'] = $this->params['supplier'][$supplier['shop_supplier_id']]['delivery']; } $this->orderData['store_id'] = $this->params['supplier'][$supplier['shop_supplier_id']]['store_id']; } // 处理配送方式 if ($this->orderData['delivery'] == DeliveryTypeEnum::EXPRESS) { $this->setOrderExpress($supplier['productList']); $expressPrice += $this->orderData['express_price']; } elseif ($this->orderData['delivery'] == DeliveryTypeEnum::EXTRACT) { $this->orderData['store_id'] > 0 && $this->orderData['extract_store'] = StoreModel::detail($this->params['supplier'][$supplier['shop_supplier_id']]['store_id']); } elseif ($this->orderData['delivery'] == DeliveryTypeEnum::STORESS) { $this->orderData['extract_store_id'] = isset($this->params['delivery_store']) ? $this->params['delivery_store'] : $this->orderData['store_id']; } // 计算订单最终金额 $this->setOrderPayPrice($supplier['productList']); $orderPayPrice += $this->orderData['order_pay_price']; $supplier['orderData'] = $this->orderData; //核销数据 $verify_data = $this->orderData["verify_data"]; //预约的数据 $booking_data = empty($this->params["booking_data"]) ? [] : $this->params["booking_data"]; } //最终价格 $orderPayPrice = $this->setOrderFinalPrice(); // 计算完成后再计算积分可抵扣 foreach ($this->supplierData as &$supplier) { $this->orderData = $supplier['orderData']; // 计算积分抵扣 $this->setOrderPoints($supplier['productList'], $this->settledRule['force_points']); $totalPointsMoney += $this->orderData['points_money']; $totalPoints += $this->orderData['points_num']; // 计算可用消费券抵扣 $this->setOrderConsumption($supplier['productList']); $totalConsumptionMoney += $this->orderData['consumption_money']; $totalConsumption += $this->orderData['consumption_num']; // 商品总价 - 积分抵扣 foreach ($supplier['productList'] as &$product) { $value = $product['total_pay_price']; // 减去积分抵扣金额 if ($this->orderData['is_allow_points'] && $this->commonOrderData['is_use_points'] && !$this->settledRule['force_points']) { $value = helper::bcsub($product['total_pay_price'], $product['points_money']); }// 减去消费券抵扣金额 if ($this->orderData['is_allow_consumption'] && $this->commonOrderData['is_use_consumption'] && !$this->settledRule['force_points']) { $value = helper::bcsub($value, $product['consumption_money']); } $product['total_pay_price'] = helper::number2($value); } // 计算订单最终金额 $this->setOrderPayPrice($supplier['productList']); $supplier['orderData'] = $this->orderData; } $this->commonOrderData['is_use_points'] && $orderPayPrice = $orderPayPrice - $totalPointsMoney; // 计算订单积分赠送数量 $this->setOrderPointsBonus(); // 计算订单消费券赠送数量 $this->setOrderConsumptionBonus(); //订单数据 $this->commonOrderData = array_merge([ 'order_total_num' => $orderTotalNum, // 商品总数量 'order_total_price' => helper::number2($orderTotalPrice), // 商品总价 'order_pay_price' => helper::number2($orderPayPrice), // 商品总价,最终支付 'total_service_price' => helper::number2($totalServicePrice), // 商品总服务费 'coupon_list' => [], 'coupon_id_sys' => '', 'coupon_money_sys' => 0, 'points_money' => $totalPointsMoney, 'points_num' => $totalPoints, 'is_real_use_points' => $this->params['is_use_points'], 'is_real_use_consumption' => $this->params['is_use_consumption'], 'product_reduce_money' => $totalProductReduce, 'consumption_money' => $totalConsumptionMoney, 'consumption_num' => $totalConsumption, 'verify_data' => $verify_data, 'booking_data' => $booking_data, 'last_extract' => UserService::getLastExtract($this->user['user_id']), // 房间id 'room_id' => isset($this->params['room_id']) && $this->params['room_id'] > 0 ? $this->params['room_id'] : 0, // 计次卡 'counting_id' => 0, 'user_counting_data' => [], 'activity_id' => $this->params['activity_id'], //活动id ], $this->commonOrderData, $this->settledRule); // 返回订单数据 return [ 'supplierList' => $this->supplierData, 'orderData' => $this->commonOrderData ]; } /** * 整理订单数据(结算台初始化),公共部分 */ private function getCommonOrderData() { // 积分设置 $pointsSetting = SettingModel::getItem('points'); return [ // 默认地址 'address' => $this->user['address_default'], // 是否存在收货地址 'exist_address' => $this->user['address_id'] > 0, // 是否允许使用积分抵扣 'is_allow_points' => true, // 是否使用积分抵扣 'is_use_points' => $this->params['is_use_points'], // 是否允许使用消费抵扣 'is_allow_consumption' => true, // 是否使用消费券抵扣 'is_use_consumption' => $this->params['is_use_consumption'], // 是否使用计次卡 'counting_id' => isset($this->params['counting_id']) ? $this->params['counting_id'] : '', // 支付方式 'pay_type' => isset($this->params['pay_type']) ? $this->params['pay_type'] : OrderPayTypeEnum::WECHAT, 'pay_source' => isset($this->params['pay_source']) ? $this->params['pay_source'] : '', // 系统设置 'setting' => [ 'points_name' => $pointsSetting['points_name'], // 积分名称 ], ]; } /** * 验证订单商品的状态 */ public function validateProductList() { foreach ($this->supplierData as $supplier) { foreach ($supplier['productList'] as $product) { // 判断商品是否下架 if ($product['product_status']['value'] != 10) { $this->error = "很抱歉,商品 [{$product['product_name']}] 已下架"; return false; } // 判断商品库存 if ($product['total_num'] > $product['product_sku']['stock_num']) { $this->error = "很抱歉,商品 [{$product['product_name']}] 库存不足"; return false; } // 判断是否超过限购数量 if ($product['limit_num'] > 0) { $hasNum = OrderModel::getHasBuyOrderNum($this->user['user_id'], $product['product_id']); if ($hasNum + $product['total_num'] > $product['limit_num']) { $this->error = "很抱歉,购买超过此商品最大限购数量"; return false; } } } } return true; } /** * 创建新订单 */ public function createOrder($order) { // 表单验证 if (!$this->validateOrderForm($order, $this->params)) { return false; } $order_arr = []; // 创建新的订单 foreach ($order['supplierList'] as $supplier) { if ($supplier['orderData']['delivery'] == DeliveryTypeEnum::EXTRACT) { if (empty($supplier['orderData']['extract_store'])) { $this->error = '请先选择自提门店'; return false; } } $this->model = new OrderModel; $this->model->transaction(function () use ($order, $supplier) { // 创建订单事件 $this->createOrderEvent($order['orderData'], $supplier); }); array_push($order_arr, $this->model); } if (count($order_arr) > 1) { $orderNo = $this->model->orderNo(); $trade_list = []; foreach ($order_arr as $order) { $trade_model = new OrderTradeModel; $trade_list[] = [ 'out_trade_no' => $orderNo, 'order_id' => $order['order_id'], 'app_id' => $this->app_id ]; $trade_model->saveAll($trade_list); } } $order_id = helper::getArrayColumn($order_arr, 'order_id'); return $order_id; } /** * 设置订单的商品总金额(不含优惠折扣) */ private function setOrderTotalPrice($productList) { // 订单商品的总金额(不含优惠券折扣) $this->orderData['order_total_price'] = helper::number2(helper::getArrayColumnSum($productList, 'total_price')); } /** * 计算订单商品的实际付款金额 */ private function setOrderProductPayPrice($productList) { // 商品总价 - 优惠抵扣 foreach ($productList as &$product) { // 减去优惠券抵扣金额 $value = helper::bcsub($product['total_price'], $product['coupon_money']); // 减去积分抵扣金额 if ($this->orderData['is_allow_points'] && $this->commonOrderData['is_use_points'] && !$this->settledRule['force_points']) { $value = helper::bcsub($value, $product['points_money']); } // 减去消费券抵扣金额 if ($this->orderData['is_allow_consumption'] && $this->commonOrderData['is_use_consumption'] && !$this->settledRule['force_points']) { $value = helper::bcsub($value, $product['consumption_money']); } $product['total_pay_price'] = helper::number2($value); } return true; } /** * 整理订单数据(结算台初始化) */ private function getOrderData($shop_supplier_id, $productList = []) { // 系统支持的配送方式 (后台设置) $deliveryType = SettingModel::getItem('store')['delivery_type']; // 积分设置 $pointsSetting = SettingModel::getItem('points'); if (isset($this->params['supplier'])) { $delivery = $this->params['supplier'][$shop_supplier_id]['delivery']; } else { if (in_array("10", $deliveryType)) { $delivery = 10; } else if (in_array("40", $deliveryType)) { $delivery = 40; } else { $delivery = $deliveryType[0]; } } if (!empty($productList) && ($productList[0]['is_virtual'] == 1 || $productList[0]['is_virtual'] == 3)) { //虚拟商品核销 by yj $verify_data = [ 'is_verify' => $productList[0]['is_verify'] && empty($productList[0]['virtual_auto']) ? 1 : 0, //必须是手动发货并且支持核销 'verify_type' => $productList[0]['verify_type'], 'verify_day' => $productList[0]['verify_day'], 'verify_store_ids' => $productList[0]['verify_store_ids'], 'verify_store_force' => 0 //预留,是否必须选择核销门店 ]; if ($verify_data['verify_type'] == 20) { $verify_data['verify_start_time'] = date('Y-m-d', $productList[0]['verify_start_time']); $verify_data['verify_end_time'] = date('Y-m-d', $productList[0]['verify_end_time']); } } else { $verify_data = []; } //通过收货地址获取最近的门店 if (!empty($this->user['address_default'])) { $address = $this->user['address_default']; $store_list = (new storeModel())->getList(false, $address["longitude"], $address["latitude"], false, $shop_supplier_id); if (!empty($store_list)) { $sell_store_id = $store_list[0]["store_id"]; } } return [ //虚拟商品核销数据 'verify_data' => $verify_data, // 配送类型 'delivery' => $delivery, // 默认地址 'address' => $this->user['address_default'], // 是否存在收货地址 'exist_address' => $this->user['address_id'] > 0, // 配送费用 'express_price' => 0.00, // 当前用户收货城市是否存在配送规则中 'intra_region' => true, // 自提门店信息 'extract_store' => [], // 是否允许使用积分抵扣 'is_allow_points' => false, // 是否允许使用消费券抵扣 'is_allow_consumption' => false, // 是否使用积分抵扣 'is_use_points' => $this->params['is_use_points'], // 支付方式 'pay_type' => isset($this->params['pay_type']) ? $this->params['pay_type'] : OrderPayTypeEnum::WECHAT, // 系统设置 'setting' => [ 'delivery' => $deliveryType, // 支持的配送方式 'points_name' => $pointsSetting['points_name'], // 积分名称 ], // 记忆的自提联系方式 //'last_extract' => UserService::getLastExtract($this->user['user_id']), 'deliverySetting' => $deliveryType, //门店id 'store_id' => 0, //优惠券id 'coupon_id' => 0, //优惠金额 'coupon_money' => 0, //总服务费用金额 'total_service_price' => 0, // 通过收货地址获取最近的门店出货 'sell_store_id' => empty($sell_store_id) ? 0 : $sell_store_id, ]; } /** * 订单配送-快递配送 */ private function setOrderExpress($productList) { // 设置默认数据:配送费用 helper::setDataAttribute($productList, [ 'express_price' => 0, ], true); // 当前用户收货城市id $cityId = $this->user['address_default'] ? $this->user['address_default']['city_id'] : null; /*if( $this->user['user_id'] == 8743){ print_r("a".$cityId);exit; }*/ /* if(empty($cityId)){ $this->error = "请先完善您的收货地址再提交订单"; return false; }*/ // 初始化配送服务类 $ExpressService = new ExpressService( $this->app_id, $cityId, $productList, OrderTypeEnum::MASTER, $this->user ); // 获取不支持当前城市配送的商品 $notInRuleProduct = $ExpressService->getNotInRuleProduct(); // 验证商品是否在配送范围 $this->orderData['intra_region'] = ($notInRuleProduct === false); if (!$this->orderData['intra_region']) { $notInRuleProductName = $notInRuleProduct['product_name']; $this->error = "很抱歉,您的收货地址不在商品 [{$notInRuleProductName}] 的配送范围内"; return false; } else { // 计算配送金额 $ExpressService->setExpressPrice(); } // 订单总运费金额 $this->orderData['express_price'] = helper::number2($ExpressService->getTotalFreight()); return true; } /** * 设置订单的实际支付金额(含配送费+安装费) */ private function setOrderPayPrice($productList) { // 订单金额(含优惠折扣) $this->orderData['order_price'] = helper::number2(helper::getArrayColumnSum($productList, 'total_pay_price')); // 订单实付款金额(订单金额 + 运费) $this->orderData['order_pay_price'] = helper::number2(helper::bcadd($this->orderData['order_price'], $this->orderData['express_price'])); // 订单实付款金额(订单金额 + 服务费) $this->orderData['order_pay_price'] = helper::number2(helper::bcadd($this->orderData['order_pay_price'], $this->orderData['total_service_price'])); } /** * 表单验证 (订单提交) */ private function validateOrderForm(&$order) { //如果是积分兑换,判断用户积分是否足够 if ($this->settledRule['force_points']) { //因为积分会过期问题 所以现在读取现在有的积分 $points = (new PointsLogModel())->getUserPoints($this->user['user_id']); if ($points < $order['orderData']['points_num']) { $this->error = '用户积分不足,无法使用积分兑换'; return false; } } return true; } /** * 创建订单事件 */ private function createOrderEvent($commomOrder, $supplier) { // 新增订单记录 $status = $this->add($commomOrder, $supplier); if ($supplier['orderData']['delivery'] == DeliveryTypeEnum::EXPRESS || $supplier['orderData']['delivery'] == DeliveryTypeEnum::STORESS) { // 记录收货地址 $this->saveOrderAddress($commomOrder['address'], $status); } elseif ($supplier['orderData']['delivery'] == DeliveryTypeEnum::EXTRACT) { // 记录自提信息 if (!empty($this->params['linkman']) && !empty($this->params['phone'])) { $this->saveOrderExtract($this->params['linkman'], $this->params['phone']); } else { $this->saveOrderExtract($commomOrder['address']['name'], $commomOrder['address']['phone']); } } //如果虚拟商品支持核销,保存核销信息 by yj if ($supplier['productList'][0]['is_verify'] == 1) { $this->saveOrderVerify($supplier['productList'][0]); } // 保存订单商品信息 $this->saveOrderProduct($supplier, $status, $commomOrder); // 更新商品库存 (针对下单减库存的商品) if (!empty($commomOrder["extract_store_id"])) { //自提门店 $sell_store_id = $commomOrder["extract_store_id"]; } elseif (!empty($commomOrder["sell_store_id"])) { //没有自提门店,判断出货门店 $sell_store_id = $supplier['orderData']["sell_store_id"]; } else { $sell_store_id = 0; } // 减库存 ProductFactory::getFactory($this->orderSource['source'])->updateProductStock($supplier['productList']); // 积分兑换扣除用户积分 if ($commomOrder['force_points']) { $describe = "用户积分兑换消费:{$this->model['order_no']}"; $this->user->setIncPoints(-$commomOrder['points_num'], $describe, 0, true, $status); } else { // 积分抵扣情况下扣除用户积分 if ($commomOrder['is_allow_points'] && $commomOrder['is_real_use_points'] && $commomOrder['points_num'] > 0) { $describe = "用户消费:{$this->model['order_no']}"; $this->user->setIncPoints(-$commomOrder['points_num'], $describe, 0, true, $status); } if ($commomOrder['is_allow_consumption'] && $commomOrder['is_real_use_consumption'] && $commomOrder['consumption_num'] > 0) { $describe = "用户消费:{$this->model['order_no']}"; $this->user->setIncConsumption(-$commomOrder['consumptions_num'], $describe, 0, true, $status); } } return $status; } /** * 新增订单记录 */ private function add($commomOrder, $supplier) { $order = $supplier['orderData']; //没有门店id且物流为快递配送 // $sell_store_id = $order['sell_store_id']; // if(empty($sell_store_id) && $supplier['orderData']['delivery'] == 10){ // //如没有发货门店,获取一个收货门店 // $sell_store_id = storeModel::getDeliverStore($supplier["shop_supplier_id"]); // } // 订单数据 $data = [ 'user_id' => $this->user['user_id'], 'order_no' => $this->model->orderNo(), 'trade_no' => $this->model->orderNo(), 'total_price' => $order['order_total_price'], 'order_price' => $order['order_price'], 'coupon_id' => 0, 'coupon_money' => $supplier['orderData']['coupon_money'], 'coupon_id_sys' => 0, 'coupon_money_sys' => 0, 'points_money' => $commomOrder['is_real_use_points'] == 1 ? $supplier['orderData']['points_money'] : 0, 'points_num' => $commomOrder['is_real_use_points'] == 1 ? $supplier['orderData']['points_num'] : 0, 'pay_price' => $order['order_pay_price'], 'delivery_type' => $supplier['orderData']['delivery'], 'pay_type' => $commomOrder['pay_type'], 'pay_source' => empty($commomOrder['pay_source']) ? 'wx' : $commomOrder['pay_source'], 'buyer_remark' => $this->params['supplier'][$supplier['shop_supplier_id']]['remark'], 'order_source' => $this->orderSource['source'], 'points_bonus' => $supplier['orderData']['points_bonus'], 'is_agent' => $this->settledRule['is_agent'] ? 1 : 0, 'shop_supplier_id' => $supplier['shop_supplier_id'], 'supplier_money' => $order['supplier_money'], 'sys_money' => $order['sys_money'], 'app_id' => $this->app_id, 'room_id' => $commomOrder['room_id'], 'virtual_auto' => $supplier['productList'][0]['virtual_auto'], 'is_verify' => isset($supplier['productList'][0]['is_verify']) ? $supplier['productList'][0]['is_verify'] : 0, //是否支持核销 by yj 'is_virtual' => $supplier['productList'][0]['is_virtual'], //是否是服务商品 by yj 'product_reduce_money' => 0, 'user_counting_id' => empty($commomOrder['user_counting_data']) ? 0 : $commomOrder['user_counting_data']["order_id"], 'total_service_price' => empty($order['total_service_price']) ? 0 : $order['total_service_price'], // 'sell_store_id' => empty($sell_store_id) ? 0 : $sell_store_id, 'activity_id' => $commomOrder['activity_id'], //分会活动的id ]; if ($supplier['orderData']['delivery'] == DeliveryTypeEnum::EXPRESS) { $data['express_price'] = $order['express_price']; } elseif ($supplier['orderData']['delivery'] == DeliveryTypeEnum::EXTRACT) { $data['extract_store_id'] = $order['extract_store']['store_id']; } elseif ($supplier['orderData']['delivery'] == DeliveryTypeEnum::STORESS) { //配送门店 $data['delivery_store'] = isset($this->params['delivery_store']) ? $this->params['delivery_store'] : $order['extract_store_id']; $data['extract_store_id'] = isset($this->params['delivery_store']) ? $this->params['delivery_store'] : $order['extract_store_id']; } //随主订单配置 $config = SettingModel::getItem('trade'); $closeDays = $config['order']['close_days']; $closeDays != 0 && $data['pay_end_time'] = time() + ((int)$closeDays * 86400); // 保存订单记录 $this->model->save($data); $order_id = $this->model['order_id']; $activity_order = new BranchActivityOrderModel(); $activity_order->save(['order_id' => $order_id, 'activity_id' => $commomOrder['activity_id'], 'app_id' => $this->app_id, 'shop_supplier_id' => $supplier['shop_supplier_id']]); return $order_id; } /** * 记录收货地址 */ private function saveOrderAddress($address, $order_id) { $model = new OrderAddress(); if ($address['region_id'] == 0 && !empty($address['district'])) { $address['detail'] = $address['district'] . ' ' . $address['detail']; } return $model->save([ 'order_id' => $order_id, 'user_id' => $this->user['user_id'], 'app_id' => $this->app_id, 'name' => $address['name'], 'phone' => $address['phone'], 'province_id' => $address['province_id'], 'city_id' => $address['city_id'], 'region_id' => $address['region_id'], 'detail' => $address['detail'], // 增加坐标和门牌用于openLocation by lyzflash 'longitude' => $address['longitude'], 'latitude' => $address['latitude'], 'house_number' => $address['house_number'] ]); } /** * 保存上门自提联系人 */ private function saveOrderExtract($linkman, $phone) { // 记忆上门自提联系人(缓存),用于下次自动填写 UserService::setLastExtract($this->model['user_id'], trim($linkman), trim($phone)); // 保存上门自提联系人(数据库) return $this->model->extract()->save([ 'linkman' => trim($linkman), 'phone' => trim($phone), 'user_id' => $this->model['user_id'], 'app_id' => $this->app_id, ]); } /** * 保存订单商品信息 */ private function saveOrderProduct($supplier, $status, $commomOrder) { // 获取出货门店 by yj 2024.1.24 // if(!empty($commomOrder["extract_store_id"])){ // //自提门店 // $sell_store_id = $commomOrder["extract_store_id"]; // }elseif(!empty($commomOrder["sell_store_id"])){ // //没有自提门店,判断是不是扫门店码 // $sell_store_id = $commomOrder["sell_store_id"]; // }else{ // //如没有发货门店,获取一个收货门店 // $sell_store_id = storeModel::getDeliverStore($supplier["shop_supplier_id"]); // } // 订单商品列表 $productList = []; foreach ($supplier['productList'] as $product) { $item = [ 'order_id' => $status, 'user_id' => $this->user['user_id'], 'app_id' => $this->app_id, 'product_id' => $product['product_id'], 'product_name' => $product['product_name'], 'image_id' => empty($product['product_sku']['image_id']) ? $product['image'][0]['image_id'] : $product['product_sku']['image_id'], 'deduct_stock_type' => $product['deduct_stock_type'], 'spec_type' => $product['spec_type'], 'spec_sku_id' => $product['product_sku']['spec_sku_id'], 'product_sku_id' => $product['product_sku']['product_sku_id'], 'product_attr' => $product['product_sku']['product_attr'], 'content' => $product['content'], 'product_no' => $product['product_sku']['product_no'], 'product_price' => $product['product_sku']['product_price'], 'line_price' => $product['product_sku']['line_price'], 'product_weight' => empty($product['product_sku']['product_weight']) ? 0 : $product['product_sku']['product_weight'], 'is_user_grade' => (int)$product['is_user_grade'], 'grade_ratio' => $product['grade_ratio'] ?? 0, 'grade_product_price' => isset($product['grade_product_price']) ? $product['grade_product_price'] : 0, 'grade_total_money' => $product['grade_total_money'] ?? 0, 'coupon_money' => isset($product['coupon_money']) ? $product['coupon_money'] : 0, 'points_money' => isset($product['points_money']) && $commomOrder['is_real_use_points'] ? $product['points_money'] : 0, 'points_num' => isset($product['points_num']) && $commomOrder['is_real_use_points'] ? $product['points_num'] : 0, 'points_bonus' => isset($product['points_bonus']) ? $product['points_bonus'] : 0, 'total_num' => $product['total_num'], 'total_price' => $product['total_price'], 'total_pay_price' => $product['total_pay_price'], 'supplier_money' => $product['supplier_money'], 'is_agent' => $product['is_agent'], 'is_enable_team' => $product['is_enable_team'], 'is_ind_agent' => $product['is_ind_agent'], 'agent_money_type' => $product['agent_money_type'], 'first_money' => $product['first_money'], 'second_money' => $product['second_money'], 'third_money' => $product['third_money'], 'fullreduce_money' => isset($product['fullreduce_money']) ? $product['fullreduce_money'] : 0, 'virtual_content' => $product['virtual_content'], 'is_alone_team' => $product['is_alone_team'], 'alone_team_equity' => $product['alone_team_equity'], 'product_reduce_money' => $product['product_reduce_money'], 'is_verify' => $product['is_verify'], 'verify_type' => $product['verify_type'], 'verify_day' => $product['verify_day'], 'service_name' => !empty($product['service_name']) ? $product['service_name'] : '', 'service_price' => !empty($product['service_price']) ? $product['service_price'] : 0, ]; // 记录订单商品来源id $item['product_source_id'] = isset($product['product_source_id']) ? $product['product_source_id'] : 0; // 记录订单商品sku来源id $item['sku_source_id'] = isset($product['sku_source_id']) ? $product['sku_source_id'] : 0; // 记录拼团类的商品来源id $item['bill_source_id'] = isset($product['bill_source_id']) ? $product['bill_source_id'] : 0; // 自定义表单数据id,直接读取最新的那条记录 by lyzflash $item['table_record_id'] = RecordModel::getLastRecordId($this->user['user_id'], 'product_' . $product['product_id'] . '_' . $product['product_sku']['spec_sku_id']); $productList[] = $item; } $model = new OrderProduct(); return $model->saveAll($productList); } /** * 计算订单可用积分抵扣 * $force_points true:积分商城 false:普通商品 */ private function setOrderPoints($productList, $force_points = true) { $this->orderData['points_money'] = 0; // 积分抵扣总数量 $this->orderData['points_num'] = 0; // 允许积分抵扣 $this->orderData['is_allow_points'] = false; // 积分商城兑换 if (isset($this->settledRule['force_points']) && $this->settledRule['force_points'] && $force_points) { // 积分抵扣金额,商品价格-兑换金额 $this->orderData['points_money'] = $productList[0]['points_money']; // 积分抵扣总数量 $this->orderData['points_num'] = $productList[0]['points_num']; // 允许积分抵扣 $this->orderData['is_allow_points'] = true; //因为积分会过期问题 所以现在读取现在有的积分 $points = (new PointsLogModel())->getUserPoints($this->user['user_id']); if ($points < $productList[0]['points_num']) { $this->error = '用户积分不足,无法使用积分兑换'; return false; } /* if ($this->user['points'] < $productList[0]['points_num']) { $this->error = '积分不足,去多赚点积分吧!'; return false; }*/ return true; } if ($force_points) { return true; } // 积分设置 $setting = SettingModel::getItem('points'); // 条件:后台开启下单使用积分抵扣 if (!$setting['is_shopping_discount']) { return false; } // 条件:订单金额满足[?]元 if (helper::bccomp($setting['discount']['full_order_price'], $this->orderData['order_total_price']) === 1) { return false; } // 计算订单商品最多可抵扣的积分数量 $this->setOrderProductMaxPointsNum($productList); // 订单最多可抵扣的积分总数量 $maxPointsNumCount = helper::getArrayColumnSum($productList, 'max_points_num'); // 实际可抵扣的积分数量 $actualPointsNum = min($maxPointsNumCount, $this->user['points']); if ($actualPointsNum < 1) { $this->orderData['points_money'] = 0; // 积分抵扣总数量 $this->orderData['points_num'] = 0; // 允许积分抵扣 $this->orderData['is_allow_points'] = true; return false; } // 计算订单商品实际抵扣的积分数量和金额 $ProductDeduct = new PointsDeductService($productList); $ProductDeduct->setProductPoints($maxPointsNumCount, $actualPointsNum); // 积分抵扣总金额 $orderPointsMoney = helper::getArrayColumnSum($productList, 'points_money'); $this->orderData['points_money'] = helper::number2($orderPointsMoney); // 积分抵扣总数量 $this->orderData['points_num'] = $actualPointsNum; // 允许积分抵扣 $this->orderData['is_allow_points'] = true; return true; } /** * 计算订单商品最多可抵扣的积分数量 */ private function setOrderProductMaxPointsNum($productList) { // 积分设置 $setting = SettingModel::getItem('points'); foreach ($productList as &$product) { // 积分兑换 if ($this->settledRule['force_points']) { $product['max_points_num'] = $product['points_num']; } else { // 商品不允许积分抵扣 if (!$product['is_points_discount']) continue; // 积分抵扣比例 $deductionRatio = helper::bcdiv($setting['discount']['max_money_ratio'], 100); // 最多可抵扣的金额 $maxPointsMoney = helper::bcmul($product['total_pay_price'], $deductionRatio); // 最多可抵扣的积分数量 $product['max_points_num'] = helper::bcdiv($maxPointsMoney, $setting['discount']['discount_ratio'], 0); // 如果超过商品最大抵扣数量 if ($product['max_points_discount'] > 0 && $product['max_points_num'] > $product['max_points_discount'] * $product['total_num']) { $product['max_points_num'] = $product['max_points_discount'] * $product['total_num']; } } } return true; } /** * 计算订单积分赠送数量 */ private function setOrderPointsBonus() { // 初始化商品积分赠送数量 foreach ($this->supplierData as &$supplier) { foreach ($supplier['productList'] as $product) { $product['points_bonus'] = 0; } $supplier['orderData']['points_bonus'] = 0; } // 积分设置 $setting = SettingModel::getItem('points'); // 条件:后台开启开启购物送积分 if (!$setting['is_shopping_gift']) { return false; } // 设置商品积分赠送数量 foreach ($this->supplierData as &$supplier) { foreach ($supplier['productList'] as &$product) { // 积分赠送比例 $ratio = $setting['gift_ratio'] / 100; // 计算抵扣积分数量 $product['points_bonus'] = !$product['is_points_gift'] ? 0 : helper::bcmul($product['total_pay_price'], $ratio, 0); } // 订单积分赠送数量 $supplier['orderData']['points_bonus'] = helper::getArrayColumnSum($supplier['productList'], 'points_bonus'); } return true; } /** * 计算订单可用消费券抵扣 */ private function setOrderConsumption($productList) { $this->orderData['consumption_money'] = 0; // 消费券抵扣总数量 $this->orderData['consumption_num'] = 0; // 允许消费券抵扣 $this->orderData['is_allow_consumption'] = false; // 消费券设置 $setting = SettingModel::getItem('consumption'); // 条件:后台开启下单使用消费券抵扣 if (!$setting['is_shopping_discount']) { return false; } // 条件:订单金额满足[?]元 if (helper::bccomp($setting['discount']['full_order_price'], $this->orderData['order_total_price']) === 1) { return false; } // 计算订单商品最多可抵扣的消费券数量 $this->setOrderConsumptionMaxPointsNum($productList); // 订单最多可抵扣的消费券总数量 $maxConsumptionNumCount = helper::getArrayColumnSum($productList, 'max_consumption_num'); // 实际可抵扣的消费券数量 $actualConsumptionNum = min($maxConsumptionNumCount, $this->user['consumer_coupon']); if ($actualConsumptionNum < 1) { $this->orderData['consumption_money'] = 0; // 消费券抵扣总数量 $this->orderData['consumption_num'] = 0; // 允许消费券抵扣 $this->orderData['is_allow_consumption'] = true; return false; } // 计算订单商品实际抵扣的消费券数量和金额 $ProductDeduct = new ConsumptionDeductService($productList); $ProductDeduct->setProductConsumption($maxConsumptionNumCount, $actualConsumptionNum); // 消费券抵扣总金额 $orderConsumptionMoney = helper::getArrayColumnSum($productList, 'consumption_money'); $this->orderData['consumption_money'] = helper::number2($orderConsumptionMoney); // 消费券抵扣总数量 $this->orderData['consumption_num'] = $actualConsumptionNum; // 允许消费券抵扣 $this->orderData['is_allow_consumption'] = true; return true; } /** * 计算订单商品最多可抵扣的消费券数量 */ private function setOrderConsumptionMaxPointsNum($productList) { // 消费券设置 $setting = SettingModel::getItem('consumption'); foreach ($productList as &$product) { // 商品不允许消费券抵扣 if (!$product['is_consumption_discount'] || $product['is_repurchase'] || $product['is_newcomer'] || $product['is_vip']) continue; // 消费券抵扣比例 $deductionRatio = helper::bcdiv($setting['discount']['max_money_ratio'], 100); // 最多可抵扣的金额 $maxPointsMoney = helper::bcmul($product['total_price'], $deductionRatio); // 最多可抵扣的消费券数量 $product['max_consumption_num'] = helper::bcdiv($maxPointsMoney, $setting['discount']['discount_ratio'], 0); // 如果超过商品最大抵扣数量 if ($product['max_consumption_discount'] > 0 && $product['max_consumption_num'] > $product['max_consumption_discount'] * $product['total_num']) { $product['max_consumption_num'] = $product['max_consumption_discount'] * $product['total_num']; } } return true; } /** * 计算订单消费券赠送数量 */ private function setOrderConsumptionBonus() { // 初始化商品消费券赠送数量 foreach ($this->supplierData as &$supplier) { foreach ($supplier['productList'] as $product) { $product['consumption_bonus'] = 0; } $supplier['orderData']['consumption_bonus'] = 0; } // 消费券设置 $setting = SettingModel::getItem('consumption'); // 条件:后台开启开启购物送消费券 if (!$setting['is_shopping_gift']) { return false; } // 设置商品消费券赠送数量 foreach ($this->supplierData as &$supplier) { foreach ($supplier['productList'] as &$product) { // 消费券赠送比例 $ratio = $setting['gift_ratio'] / 100; // 计算抵扣的消费券数量 $product['consumption_bonus'] = !$product['is_consumption_gift'] ? 0 : helper::bcmul($product['total_pay_price'], $ratio, 0); } // 订单消费券赠送数量 $supplier['orderData']['consumption_bonus'] = helper::getArrayColumnSum($supplier['productList'], 'consumption_bonus'); } return true; } /** * 设置订单商品服务费用 */ private function setProductService($productList) { // 计算服务费用 $servicePrice = 0; foreach ($productList as $product) { if (!empty($product['service_price']) && $product['service_price'] > 0) { $servicePrice += $product['service_price'] * $product['total_num']; } } return $servicePrice; } /** * 设置订单满减抵扣信息 */ private function setOrderFullreduceMoney($reduce, $productList) { // 计算订单商品满减抵扣金额 $productListTemp = helper::getArrayColumns($productList, ['total_price']); $service = new FullDeductService; $completed = $service->setProductFullreduceMoney($productListTemp, $reduce['reduced_price']); if ($completed) { // 分配订单商品优惠券抵扣金额 foreach ($productList as $key => &$product) { $product['fullreduce_money'] = $completed[$key]['fullreduce_money'] / 100; } } return true; } /** * 获取所有支付价格 */ private function setOrderFinalPrice() { foreach ($this->supplierData as &$supplier) { //商户独立抽成 $config = SettingModel::getSupplierCommissionRate($supplier["shop_supplier_id"]); $sys_percent = intval($config['commission_rate']); $supplier_percent = 100 - $sys_percent; // 供应商结算金额,包括运费 $supplier['orderData']['supplier_money'] = helper::number2($supplier['orderData']['order_price'] * $supplier_percent / 100 + $supplier['orderData']['express_price']); // 平台分佣金额 $supplier['orderData']['sys_money'] = helper::number2($supplier['orderData']['order_price'] * $sys_percent / 100); // 产品价格 // 结算金额不包括运费 foreach ($supplier['productList'] as &$product) { $product['supplier_money'] = helper::number2($product['total_pay_price'] * $supplier_percent / 100); $product['sys_money'] = helper::number2($product['total_pay_price'] * $sys_percent / 100); } } $price = 0; foreach ($this->supplierData as &$supplier) { $price += $supplier['orderData']['order_pay_price']; } return $price; } /** * 保存虚拟商品核销信息 */ private function saveOrderVerify($product) { return $this->model->verify()->save([ 'verify_type' => $product['verify_type'], 'verify_day' => $product['verify_day'], 'verify_start_time' => $product['verify_start_time'], 'verify_end_time' => $product['verify_end_time'], 'verify_store_ids' => implode(',', $product['verify_store_ids']), 'app_id' => $product['app_id'], ]); } }