223 lines
8.8 KiB
PHP
223 lines
8.8 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @author Any
|
|
* @description KISS
|
|
* @date 2021年10月13日
|
|
* @version 1.0.0
|
|
*
|
|
* _____LOG_____
|
|
*
|
|
*/
|
|
namespace app\models\common\integral\mall;
|
|
|
|
use app\models\common\CommonGoodsListForm;
|
|
use app\models\integral\mall\IntegralMallGoods;
|
|
use app\models\integral\mall\IntegralMallGoodsAttr;
|
|
use app\models\integral\Integral;
|
|
use app\models\integral\mall\IntegralMallOrder;
|
|
use app\models\Goods;
|
|
use app\models\GoodsHub;
|
|
use app\models\Order;
|
|
use app\models\OrderDetail;
|
|
use app\models\Address;
|
|
use app\models\Model;
|
|
use app\models\UniqueOrderNo;
|
|
use app\components\SiteHelper;
|
|
use app\components\SysConst;
|
|
use app\components\Serializer;
|
|
use app\components\FlashStorage;
|
|
use app\models\PaymentTypes;
|
|
use app\models\common\payment\Payment;
|
|
use app\models\common\payment\PaymentOrder;
|
|
|
|
|
|
class CommonIntegralMallOrderSubmitForm extends Model
|
|
{
|
|
public $cx_mch_id;
|
|
public $goods_info;
|
|
public $user_id;
|
|
public $address_id;
|
|
|
|
public $pay_type;
|
|
public $remark;
|
|
|
|
|
|
|
|
public function rules()
|
|
{
|
|
return [
|
|
[['pay_type', 'remark'], 'trim'],
|
|
[['pay_type', 'remark'], 'string'],
|
|
[['goods_info'], 'safe'],
|
|
[['cx_mch_id', 'user_id', 'address_id'], 'integer'],
|
|
[['pay_type'], 'default' , 'value' => 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();
|
|
}
|
|
}
|
|
|