SysConst::$cxPayTypeEnIntegral], [['cx_mch_id', 'goods_info', 'user_id', 'address_id'], 'required'], ]; } public function save() { if(!$this->validate()){ return $this->getModelError(); } //商品信息 $form = new CommonIntegralMallOrderDataForm(); $form->cx_mch_id = $this->cx_mch_id; $form->user_id = $this->user_id; $form->goods_info = $this->goods_info; $res = $form->search(); if($res['code'] != 0) return $res; $pay_data = $res['data']; $goods_list = $pay_data['goods_list']; $pay_types = $pay_data['pay_types']; //@TODO 并发情况 检查商品库存是否充足 $res = $this->checkGoodsStock($goods_list); if($res['code'] != 0) return $res; //收货地址 $address = Address::findOne(['user_id' => $this->user_id, 'cx_mch_id' => $this->cx_mch_id, 'is_delete' => 0, 'id' => $this->address_id]); if($address == null){ return $this->apiReturnError('所选收货地址不存在'); } //支付方式检查 $res = $this->checkPayType($goods_list, $pay_types); if($res['code'] != 0) return $res; //下订单 $t = \Yii::$app->db->beginTransaction(); $order = new Order(); $order->plugin_sign = SysConst::$cxPluginSceneIntegralMall; $order->cx_mch_id = $this->cx_mch_id; $order->user_id = $this->user_id; $order->order_no = UniqueOrderNo::generate(UniqueOrderNo::ORDER_TYPE_INTEGRAL_MALL_ORDER,"\\app\models\Order"); $express_price = 0; $coupon_discount_price = 0; $total_discount_price = $coupon_discount_price + 0; $use_user_coupon_id = 0; $total_goods_original_price = array_sum(array_column($goods_list, 'price')); $total_goods_original_price = sprintf('%.2f',$total_goods_original_price); $total_goods_price = $total_goods_original_price - $total_discount_price; $total_price = $express_price + $total_goods_price; $total_price = sprintf('%.2f',$total_price); $order->total_price = $total_price; $order->total_pay_price = 0; $order->express_original_price = $express_price; $order->express_price = $express_price; $order->total_goods_price = $total_goods_price; $order->total_goods_original_price = $total_goods_original_price; $order->use_user_coupon_id = $use_user_coupon_id; $order->coupon_discount_price = $coupon_discount_price; $order->name = $address->name; $order->mobile = $address->mobile; $order->address = $address->province.$address->city.$address->district.$address->detail; $order->location = $address->location; $order->remark = $this->remark; $order->is_pay = 0; $order->pay_type = 0; $support_pay_types = array_column($pay_types, 'short_name'); $order->support_pay_types = json_encode($support_pay_types,JSON_UNESCAPED_UNICODE); if(!$order->save()){ $t->rollBack(); return $this->getModelError($order); } //订单详情 $res = $this->saveOrderDetail($goods_list, $order->id); if($res['code'] != 0){ $t->rollBack(); return $res; } //积分订单 $integral_mall_order = IntegralMallOrder::findOne(['cx_mch_id' => $this->cx_mch_id, 'order_id' => $order->id, 'is_delete' => 0]); if($integral_mall_order == null){ $integral_mall_order = new IntegralMallOrder(); $integral_mall_order->cx_mch_id = $this->cx_mch_id; $integral_mall_order->order_id = $order->id; } $total_integral_num = array_sum(array_column($goods_list, 'total_integral_num')); $integral_mall_order->integral_num = $total_integral_num; if(!$integral_mall_order->save()){ $t->rollBack(); return $this->getModelError($integral_mall_order); } $title = "积分兑换".$goods_list[0]['name']; $paymentOrder = new PaymentOrder([ 'orderNo' => $order->order_no, 'amount' => (float)$order->total_price, 'title' => $title, 'notifyClass' => '\\app\\models\\common\\notify\\payment\\IntegralMallOrderPaymentNotify', 'supportPayTypes' => array_column($pay_types, 'short_name'), 'payType' => PaymentTypes::payTypeKeyToId($this->pay_type) ]); $payment = new Payment(); $paymentOrders[] = $paymentOrder; $res = $payment->createOrder($paymentOrders); if($res['code'] != 0){ $t->rollBack(); return $res; } $t->commit(); return $res; } private function checkGoodsStock($goods_list) { foreach ($goods_list as $index => $item){ if(!$item['has_stock']){ return $this->apiReturnError("{$item['name']}商品库存不足"); } } return $this->apiReturnSuccess(); } private function checkPayType($goods_list, $pay_types) { if(!in_array($this->pay_type, array_column($pay_types, 'short_name'))){ return $this->apiReturnError('无效支付方式'); } $total_integral_num = array_sum(array_column($goods_list, 'integral_num')); if($this->pay_type == SysConst::$cxPayTypeEnIntegral){ //积分账户余额是否充足 $integral_model = Integral::findOne(['user_id' => $this->user_id, 'scene' => Integral::SCENARIO_DEFAULT, 'cx_mch_id' => $this->cx_mch_id, 'is_delete' => 0]); if($integral_model == null || $integral_model->account_integral < $total_integral_num){ return $this->apiReturnError('积分账户余额不足'); } } return $this->apiReturnSuccess(); } private function saveOrderDetail($goods_list, $order_id) { foreach ($goods_list as $index => $item){ $order_detail = OrderDetail::findOne(['order_id' => $order_id, 'goods_id' => $item['id']]); if($order_detail == null){ $order_detail = new OrderDetail(); $order_detail->cx_mch_id = $this->cx_mch_id; $order_detail->order_id = $order_id; $order_detail->goods_id = $item['id']; } $order_detail->num = $item['goods_num']; $order_detail->unit_price = $item['price']; $order_detail->total_original_price = $item['total_original_price']; $order_detail->total_price = $item['total_original_price']; $order_detail->goods_attr_info = json_encode($item['goods_attr_info'], JSON_UNESCAPED_UNICODE); $order_detail->plugin_sign = SysConst::$cxPluginSceneIntegralMall; $order_detail->serial_no = $item['goods_attr_info']['serial_no']; $order_detail->goods_type = $item['type']; if(!$order_detail->save()){ return $this->getModelError($order_detail); } $res = Goods::handleStock($order_detail->goods_id, $item['goods_attr_info']['id'], $order_detail->num, Goods::STOCK_DECREASE, $this->cx_mch_id); if($res['code'] != 0) return $res; } return $this->apiReturnSuccess(); } }