You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
954 lines
37 KiB
954 lines
37 KiB
<?php |
|
/** |
|
* Created by IntelliJ IDEA. |
|
* User: luwei |
|
* Date: 2017/7/17 |
|
* Time: 11:48 |
|
*/ |
|
|
|
namespace app\modules\api\models; |
|
|
|
use app\models\Address; |
|
use app\models\Attr; |
|
use app\models\AttrGroup; |
|
use app\models\Cart; |
|
use app\models\Cat; |
|
use app\models\Coupon; |
|
use app\models\CouponAutoSend; |
|
use app\models\Form; |
|
use app\models\FreeDeliveryRules; |
|
use app\models\Goods; |
|
use app\models\GoodsCat; |
|
use app\models\Level; |
|
use app\models\Mch; |
|
use app\models\MiaoshaGoods; |
|
use app\models\Option; |
|
use app\models\PostageRules; |
|
use app\models\Shop; |
|
use app\models\Store; |
|
use app\models\TerritorialLimitation; |
|
use app\models\User; |
|
use app\models\UserCoupon; |
|
|
|
class OrderSubmitPreviewForm extends OrderData |
|
{ |
|
public $store; |
|
public $store_id; |
|
public $user_id; |
|
public $step_id; |
|
|
|
public $address_id; |
|
public $cart_list; |
|
|
|
public $cart_id_list; |
|
public $goods_info; |
|
|
|
public $longitude; |
|
public $latitude; |
|
|
|
public $type; //订单类型 s--商城订单 ms--秒杀订单 |
|
public $mch_list; |
|
|
|
public function rules() |
|
{ |
|
return [ |
|
[['cart_id_list', 'goods_info', 'cart_list', 'mch_list'], 'string'], |
|
[['address_id', 'step_id'], 'integer'], |
|
[['longitude', 'latitude'], 'trim'], |
|
]; |
|
} |
|
|
|
/** |
|
* @return array |
|
* [ |
|
* 'address'=>{}, |
|
* 'cart_id_list'=>[] 或 'goods_info'=>{} 或 'cart_list'=>[], |
|
* 'coupon_list'=>[], |
|
* 'express_price'=>"", |
|
* 'form_list'=>{}, |
|
* 'goods_card_list'=>[], |
|
* 'integral'=>{}, |
|
* 'is_payment'=>{}, |
|
* 'is_shop'=>'', |
|
* 'shop_list'=>[], |
|
* 'level'=>'', |
|
* 'list'=>[], |
|
* 'pay_type_list'=>[], |
|
* 'send_type'=>'', |
|
* total_price'=>'' |
|
* ] |
|
*/ |
|
public function search() |
|
{ |
|
$store = Store::findOne($this->store_id); |
|
$this->store = $store; |
|
if (!$this->validate()) { |
|
return $this->errorResponse; |
|
} |
|
|
|
// 快速购买 |
|
if ($this->cart_list) { |
|
$res = $this->getCartList($this->cart_list, $store); |
|
} |
|
//购物车(新增多商户的商品) |
|
if ($this->cart_id_list || $this->mch_list) { |
|
$res = $this->getDataByCartIdList($this->cart_id_list, $store); |
|
if ($this->mch_list) { |
|
$res['data']['mch_list'] = []; |
|
$mch_list = json_decode($this->mch_list, true); |
|
if (is_array($mch_list)) { |
|
foreach ($mch_list as $mch) { |
|
$mch_res = $this->getDataByCartIdList(json_encode($mch['cart_id_list'], JSON_UNESCAPED_UNICODE), $store); |
|
$mch = Mch::findOne($mch['id']); |
|
if ($mch_res['code'] == 0 && $mch) { |
|
$mch_res['data']['id'] = $mch->id; |
|
$mch_res['data']['name'] = $mch->name; |
|
$res['data']['mch_list'][] = $mch_res['data']; |
|
} |
|
} |
|
} |
|
if (count($res['data']['mch_list'])) { |
|
$res['code'] = 0; |
|
} |
|
} |
|
} |
|
|
|
//商品直接购买 |
|
if ($this->goods_info) { |
|
$res = $this->getDataByGoodsInfo($this->goods_info, $store); |
|
} |
|
|
|
if ($this->type == 'ms') { |
|
$buyMaxRes = $this->checkBuyMax($res['data']['list']); |
|
if ($buyMaxRes) { |
|
return $buyMaxRes; |
|
} |
|
} |
|
if ($res['code'] != 0) { |
|
return $res; |
|
} |
|
$this->address = $res['data']['address']; |
|
// 获取起送规则 |
|
$this->total_price = $res['data']['total_price']; // 暂时只计算商城价格(不包含多商户) |
|
$this->mch_list = $res['data']['mch_list']; |
|
$res['data']['offer_rule'] = $this->getOfferRule(); |
|
|
|
$goods_id = []; |
|
$goods_cat_id = []; |
|
$coupon_goods_id = []; |
|
foreach ($res['data']['list'] as $key => $value) { |
|
if ($res['data']['list'][$key]->cat_id == 0) { |
|
// 多分类商品id |
|
$goods_id[] = $res['data']['list'][$key]->goods_id; |
|
} else { |
|
// 单分类商品cat_id |
|
$goods_cat_id[] = $res['data']['list'][$key]->cat_id; |
|
} |
|
$coupon_goods_id[] = $res['data']['list'][$key]->goods_id; |
|
} |
|
$goods_cat_id = array_unique($goods_cat_id); //单分类商品cat_id |
|
$many_cat_goods = GoodsCat::find()->select('cat_id')->where(['is_delete' => 0, 'goods_id' => $goods_id])->asArray()->all(); |
|
$many_cat_id = []; |
|
foreach ($many_cat_goods as $key => $value) { |
|
$many_cat_id[] = $value['cat_id']; // 多分类商品cat_id |
|
} |
|
$cat_id = array_merge($goods_cat_id, $many_cat_id); |
|
|
|
$cat = Cat::find()->where(['is_delete' => 0, 'store_id' => $store->id, 'id' => $cat_id])->asArray()->all(); |
|
|
|
$goods_cat_ids = []; |
|
$many_cat_ids = []; |
|
foreach ($cat as $key2 => $value2) { |
|
$goods_cat_ids[] = $value2['id']; |
|
if ($value2['parent_id'] != 0) { |
|
$many_cat_ids[] = $value2['parent_id']; |
|
} |
|
} |
|
$cat_ids = array_merge($goods_cat_ids, $many_cat_ids); |
|
|
|
$res['data']['coupon_list'] = $this->getCouponList($res['data']['total_price'], array_unique($cat_ids), $coupon_goods_id); |
|
|
|
if ($store->send_type != 1) { |
|
$res['data']['shop_list'] = $this->getShopList(); |
|
$res['data']['is_shop'] = Shop::find()->where(['is_default' => 1, 'store_id' => $this->store_id])->asArray()->one(); |
|
} else { |
|
$res['data']['shop_list'] = []; |
|
$res['data']['is_shop'] = ''; |
|
} |
|
// } |
|
$level = Level::find()->select([ |
|
'name', 'level', 'discount', |
|
])->where(['level' => \Yii::$app->user->identity->level, 'store_id' => $this->store_id])->asArray()->one(); |
|
$res['data']['level'] = $level; |
|
//获取商城发货方式 |
|
$res['data']['send_type'] = $store->send_type; |
|
// 获取 店铺积分使用规则 |
|
if (!empty($res['data']['integral'])) { |
|
if (is_array($res['data']['integral'])) { |
|
$res['data']['integral']['integration'] = $store->integration; |
|
} |
|
|
|
if (is_object($res['data']['integral']) && isset($res['data']['integral']->integration)) { |
|
$res['data']['integral']->integration = $store->integration; |
|
} |
|
} |
|
// 获取用户当前积分 |
|
$user = User::findOne(['id' => $this->user_id, 'type' => 1, 'is_delete' => 0]); |
|
if ($user->integral < $res['data']['integral']['forehead_integral']) { |
|
$res['data']['integral']['forehead_integral'] = $user->integral; |
|
$res['data']['integral']['forehead'] = sprintf("%.2f", $user->integral / $store->integral); |
|
} |
|
$res['data']['form'] = $this->formData(); |
|
|
|
//包邮规则 |
|
if ($res['data']['express_price'] != 0) { |
|
$free = FreeDeliveryRules::find()->where(['store_id' => $this->store_id])->asArray()->all(); |
|
foreach ($free as $k => $v) { |
|
$city = json_decode($v['city'], true); |
|
foreach ($city as $v1) { |
|
if ($res['data']['address']['city_id'] == $v1['id'] && $res['data']['total_price'] >= $v['price'] && !$this->step_id) { |
|
$res['data']['express_price'] = 0; |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
//支付方式 |
|
$pay_str = Option::get('payment', $store->id, 'admin', '{"wechat":"1"}'); |
|
$is_payment = json_decode($pay_str, true); |
|
$res['data']['is_payment'] = $is_payment; |
|
$pay_type_list = OrderData::getPayType($this->store_id, $is_payment); |
|
$res['data']['pay_type_list'] = $pay_type_list; |
|
|
|
$res['data']['is_area'] = 0; |
|
$area = TerritorialLimitation::findOne([ |
|
'store_id' => $this->store_id, |
|
'is_delete' => 0, |
|
'is_enable' => 1, |
|
]); |
|
if ($area) { |
|
if (!$res['data']['address']) { |
|
$res['data']['is_area'] = 0; |
|
$res['data']['is_area_city_id'] = []; |
|
} |
|
$city_id = []; //限制的地区ID |
|
$detail = json_decode($area->detail); |
|
if (!is_array($detail)) { |
|
$detail = []; |
|
} |
|
|
|
foreach ($detail as $key => $value) { |
|
foreach ($value->province_list as $key2 => $value2) { |
|
$city_id[] = $value2->id; |
|
} |
|
} |
|
$addressArr = [ |
|
$res['data']['address']['province_id'], |
|
$res['data']['address']['city_id'], |
|
$res['data']['address']['district_id'] |
|
]; |
|
$addressArray = array_intersect($addressArr, $city_id); |
|
if (empty($addressArray)) { |
|
$res['data']['is_area'] = 1; |
|
} |
|
$res['data']['is_area_city_id'] = $city_id; |
|
} |
|
|
|
// 处理PHP浮点数计算产生的小数 |
|
if (!empty($res['data']['list']) && is_array($res['data']['list'])) { |
|
foreach ($res['data']['list'] as &$item) { |
|
if (is_object($item) && !empty($item->price)) { |
|
$item->price = sprintf('%.2f', $item->price); |
|
} |
|
} |
|
unset($item); |
|
} |
|
if (!empty($res['data']['integral']['forehead_integral'])) { |
|
$res['data']['integral']['forehead_integral'] = sprintf('%.2f', $res['data']['integral']['forehead_integral']); |
|
} |
|
if (!empty($res['data']['mch_list']) && is_array($res['data']['mch_list'])) { |
|
foreach ($res['data']['mch_list'] as &$mch) { |
|
if (!empty($mch['list']) && is_array($mch['list'])) { |
|
foreach ($mch['list'] as &$item) { |
|
if (is_object($item) && !empty($item->price)) { |
|
$item->price = sprintf('%.2f', $item->price); |
|
} |
|
} |
|
unset($item); |
|
} |
|
} |
|
unset($mch); |
|
} |
|
|
|
//处理只有多商户商品下单提示必须选择门店的问题 |
|
if (is_array($res['data']['list']) && count($res['data']['list']) == 0 && is_array($res['data']['mch_list']) && count($res['data']['mch_list']) > 0) { |
|
$res['data']['send_type'] = 0; |
|
} |
|
|
|
return $res; |
|
} |
|
|
|
private function getCouponList($goods_total_price, $cat_ids, $coupon_goods_id) |
|
{ |
|
$list = UserCoupon::find()->alias('uc') |
|
->leftJoin(['c' => Coupon::tableName()], 'uc.coupon_id=c.id') |
|
->leftJoin(['cas' => CouponAutoSend::tableName()], 'uc.coupon_auto_send_id=cas.id') |
|
->where([ |
|
'AND', |
|
['uc.is_delete' => 0], |
|
['uc.is_use' => 0], |
|
['uc.is_expire' => 0], |
|
['uc.user_id' => $this->user_id], |
|
['<=', 'c.min_price', $goods_total_price], |
|
]) |
|
->select('uc.id user_coupon_id,c.sub_price,c.min_price,cas.event,uc.begin_time,uc.end_time,uc.type,c.appoint_type,c.cat_id_list,c.goods_id_list') |
|
->asArray()->all(); |
|
$events = [ |
|
0 => '平台发放', |
|
1 => '分享红包', |
|
2 => '购物返券', |
|
3 => '领券中心', |
|
]; |
|
$new_list = []; |
|
foreach ($list as $i => $item) { |
|
if ($item['begin_time'] > (strtotime(date('Y-M-d')) + 86400) || $item['end_time'] < time()) { |
|
continue; |
|
} |
|
$list[$i]['status'] = 0; |
|
if ($item['is_use']) { |
|
$list[$i]['status'] = 1; |
|
} |
|
|
|
if ($item['is_expire']) { |
|
$list[$i]['status'] = 2; |
|
} |
|
|
|
$list[$i]['min_price_desc'] = $item['min_price'] == 0 ? '无门槛' : '满' . $item['min_price'] . '元可用'; |
|
$list[$i]['begin_time'] = date('Y.m.d H:i', $item['begin_time']); |
|
$list[$i]['end_time'] = date('Y.m.d H:i', $item['end_time']); |
|
if (!$item['event']) { |
|
if ($item['type'] == 2) { |
|
$list[$i]['event'] = $item['event'] = 3; |
|
} else { |
|
$list[$i]['event'] = $item['event'] = 0; |
|
} |
|
} |
|
$list[$i]['event_desc'] = $events[$item['event']]; |
|
$list[$i]['min_price'] = doubleval($item['min_price']); |
|
$list[$i]['sub_price'] = doubleval($item['sub_price']); |
|
|
|
if ($list[$i]['appoint_type'] == 1) { |
|
$list[$i]['cat_id_list'] = json_decode($list[$i]['cat_id_list']); |
|
if ($list[$i]['cat_id_list'] != null) { |
|
if (!array_intersect($list[$i]['cat_id_list'], $cat_ids)) { |
|
unset($list[$i]); |
|
continue; |
|
} |
|
} |
|
} elseif ($list[$i]['appoint_type'] == 2) { |
|
$list[$i]['goods_id_list'] = json_decode($list[$i]['goods_id_list']); |
|
if ($list[$i]['goods_id_list'] != null) { |
|
if (!array_intersect($list[$i]['goods_id_list'], $coupon_goods_id)) { |
|
unset($list[$i]); |
|
continue; |
|
} |
|
} |
|
} |
|
|
|
$new_list[] = $list[$i]; |
|
} |
|
return $new_list; |
|
} |
|
|
|
/** |
|
* @param $cart_list json eg:[{"id":"39","num":2,"attr":""},{"id":"140","num":2,"attr":[{"attr_group_id":1,"attr_group_name":"颜色","attr_id":1,"attr_name":"白色"},{"attr_group_id":2,"attr_group_name":"尺码","attr_id":4,"attr_name":"M"},{"attr_group_id":22,"attr_group_name":"机箱","attr_id":293,"attr_name":"外机"}]}] |
|
* @param $store object |
|
* @return array |
|
*/ |
|
private function getCartList($cart_list, $store) |
|
{ |
|
$cart_list = json_decode($cart_list); |
|
$list = []; |
|
$total_price = 0; |
|
$new_cart_id_list = []; |
|
$goodsList = []; |
|
$resIntegral = [ |
|
'forehead' => 0, |
|
'forehead_integral' => 0, |
|
]; |
|
$goodsIds = []; |
|
$goods_card_list = []; |
|
foreach ($cart_list as $item) { |
|
$goods = Goods::findOne([ |
|
'store_id' => $this->store_id, |
|
'id' => $item->id, |
|
'is_delete' => 0, |
|
'status' => 1, |
|
]); |
|
if (!$goods) { |
|
continue; |
|
} |
|
|
|
if (!$goods->use_attr) { |
|
$gf = new GoodsForm(); |
|
$gf->id = $goods->id; |
|
$gf->store_id = $goods->store_id; |
|
$gfr = $gf->search(); |
|
if ($gfr->code == 0) { |
|
$attr_group_list = $gfr->data['attr_group_list']; |
|
$item->attr = []; |
|
foreach ($attr_group_list as $attr_group) { |
|
$item->attr[] = (object)[ |
|
'attr_group_id' => $attr_group->attr_group_id, |
|
'attr_group_name' => $attr_group->attr_group_name, |
|
'attr_id' => $attr_group->attr_list[0]->attr_id, |
|
'attr_name' => $attr_group->attr_list[0]->attr_name, |
|
]; |
|
} |
|
} |
|
} |
|
$attr_id_list = []; |
|
foreach ($item->attr as $key => $value) { |
|
array_push($attr_id_list, $value->attr_id); |
|
} |
|
$goods_attr_info = $goods->getAttrInfo($attr_id_list); |
|
$attr_num = intval(empty($goods_attr_info['num']) ? 0 : $goods_attr_info['num']); |
|
$goods_pic = isset($goods_attr_info['pic']) ? $goods_attr_info['pic'] ?: $goods->getGoodsPic(0)->pic_url : $goods->getGoodsPic(0)->pic_url; |
|
if ($attr_num < $item->num) { |
|
continue; |
|
} |
|
|
|
$new_item = (object)[ |
|
'goods_id' => $goods->id, |
|
'goods_name' => $goods->name, |
|
'goods_pic' => $goods_pic, |
|
'num' => $item->num, |
|
'price' => doubleval(empty($goods_attr_info['price']) ? $goods->price : $goods_attr_info['price']) * $item->num, |
|
'attr_list' => $item->attr, |
|
'give' => 0, |
|
'single_price' => doubleval(empty($goods_attr_info['price']) ? $goods->price : $goods_attr_info['price']), |
|
'freight' => $goods->freight, |
|
'integral' => $goods->integral, |
|
'weight' => $goods->weight, |
|
'full_cut' => $goods->full_cut, |
|
'cat_id' => $goods->cat_id, |
|
]; |
|
|
|
$total_price += $new_item->price; |
|
$new_cart_id_list[] = $item->id; |
|
$list[] = $new_item; |
|
$goods_card = Goods::getGoodsCard($goods->id); |
|
$goods_card_list = array_merge($goods_card_list, $goods_card); |
|
$new_goods = [ |
|
'goods_id' => $goods->id, |
|
'goods_name' => $goods->name, |
|
'freight' => $goods->freight, |
|
'weight' => $goods->weight, |
|
'num' => $item->num, |
|
'full_cut' => $goods->full_cut, |
|
'price' => $new_item->price, |
|
]; |
|
|
|
|
|
$goodsList[] = $new_goods; |
|
// 单个商品积分计算 |
|
$arr = OrderData::integral($new_item, $store->integral, $goodsIds); |
|
$resIntegral['forehead_integral'] += $arr['resIntegral']['forehead_integral']; |
|
$resIntegral['forehead'] += $arr['resIntegral']['forehead']; |
|
$goodsIds[] = $goods->id; |
|
} |
|
$address = $this->getAddress(); |
|
$express_price = 0; |
|
if (count($list)) { |
|
if ($address) { |
|
$resGoodsList = Goods::cutFull($goodsList); |
|
$express_price = PostageRules::getExpressPriceMore($this->store_id, $address['city_id'], $resGoodsList, $address['province_id']); |
|
} |
|
} |
|
return [ |
|
'code' => 0, |
|
'msg' => 'success', |
|
'data' => [ |
|
'total_price' => $total_price, |
|
'list' => $list, |
|
'cart_list' => $cart_list, |
|
'address' => $address, |
|
'express_price' => $express_price, |
|
'integral' => $resIntegral, |
|
'goods_card_list' => $goods_card_list, |
|
], |
|
]; |
|
} |
|
|
|
/** |
|
* @param string $cart_id_list eg. [12,32,7] |
|
*/ |
|
private function getDataByCartIdList($cart_id_list, $store) |
|
{ |
|
/* @var Cart[] $cart_list */ |
|
$cart_list = Cart::find()->where([ |
|
'store_id' => $this->store_id, |
|
'user_id' => $this->user_id, |
|
'is_delete' => 0, |
|
'id' => json_decode($cart_id_list, true), |
|
])->all(); |
|
|
|
$list = []; |
|
$total_price = 0; |
|
$new_cart_id_list = []; |
|
$goodsList = []; |
|
$resIntegral = [ |
|
'forehead' => 0, |
|
'forehead_integral' => 0, |
|
]; |
|
$goodsIds = []; |
|
$goods_card_list = []; |
|
foreach ($cart_list as $item) { |
|
$goods = Goods::findOne([ |
|
'store_id' => $this->store_id, |
|
'id' => $item->goods_id, |
|
'is_delete' => 0, |
|
'status' => 1, |
|
]); |
|
if (!$goods) { |
|
continue; |
|
} |
|
|
|
$attr_list = Attr::find()->alias('a') |
|
->select('ag.attr_group_name,a.attr_name') |
|
->leftJoin(['ag' => AttrGroup::tableName()], 'a.attr_group_id=ag.id') |
|
->where(['a.id' => json_decode($item->attr, true)]) |
|
->asArray()->all(); |
|
$goods_attr_info = $goods->getAttrInfo(json_decode($item->attr, true)); |
|
$attr_num = intval(empty($goods_attr_info['num']) ? 0 : $goods_attr_info['num']); |
|
$goods_pic = isset($goods_attr_info['pic']) ? $goods_attr_info['pic'] ?: $goods->getGoodsPic(0)->pic_url : $goods->getGoodsPic(0)->pic_url; |
|
if ($attr_num < $item->num) { |
|
continue; |
|
} |
|
|
|
$goods_item = (object)[ |
|
'cart_id' => $item->id, |
|
'goods_id' => $goods->id, |
|
'goods_name' => $goods->name, |
|
'goods_pic' => $goods_pic, |
|
'num' => $item->num, |
|
'price' => doubleval(empty($goods_attr_info['price']) ? $goods->price : $goods_attr_info['price']) * $item->num, |
|
'single_price' => doubleval(empty($goods_attr_info['price']) ? $goods->price : $goods_attr_info['price']), |
|
'attr_list' => $attr_list, |
|
'give' => 0, |
|
'freight' => $goods->freight, |
|
'integral' => $goods->integral, |
|
'weight' => $goods->weight, |
|
'full_cut' => $goods->full_cut, |
|
'cat_id' => $goods->cat_id, |
|
'mch_id' => $goods->mch_id, |
|
]; |
|
|
|
$total_price += $goods_item->price; |
|
$new_cart_id_list[] = $item->id; |
|
$list[] = $goods_item; |
|
$goods_card = Goods::getGoodsCard($goods->id); |
|
$goods_card_list = array_merge($goods_card_list, $goods_card); |
|
$new_goods = [ |
|
'goods_id' => $goods->id, |
|
'goods_name' => $goods->name, |
|
'freight' => $goods->freight, |
|
'weight' => $goods->weight, |
|
'num' => $item->num, |
|
'full_cut' => $goods->full_cut, |
|
'price' => $goods_item->price, |
|
'mch_id' => $goods->mch_id, |
|
]; |
|
|
|
$goodsList[] = $new_goods; |
|
|
|
// 单个商品积分计算 |
|
$arr = OrderData::integral($goods_item, $store->integral, $goodsIds); |
|
$resIntegral['forehead_integral'] += $arr['resIntegral']['forehead_integral']; |
|
$resIntegral['forehead'] += $arr['resIntegral']['forehead']; |
|
|
|
$goodsIds[] = $goods->id; |
|
} |
|
//地区 |
|
$address = $this->getAddress(); |
|
$express_price = 0; |
|
if (count($list)) { |
|
//多件商品运费 |
|
if ($address) { |
|
//先计算单品满件包邮和满额包邮 |
|
$resGoodsList = Goods::cutFull($goodsList); |
|
//再通过运费规则计算运费 |
|
$express_price = PostageRules::getExpressPriceMore($this->store_id, $address['city_id'], $resGoodsList, $address['province_id']); |
|
} |
|
} |
|
|
|
return [ |
|
'code' => 0, |
|
'msg' => 'success', |
|
'data' => [ |
|
'total_price' => $total_price, |
|
'cart_id_list' => $new_cart_id_list, |
|
'list' => $list, |
|
'address' => $address, |
|
'express_price' => round($express_price, 2), |
|
'integral' => $resIntegral, |
|
'goods_card_list' => $goods_card_list, |
|
], |
|
]; |
|
} |
|
|
|
/** |
|
* @param string $goods_info |
|
* JSON,eg.{"goods_id":"22","attr":[{"attr_group_id":1,"attr_group_name":"颜色","attr_id":3,"attr_name":"橙色"},{"attr_group_id":2,"attr_group_name":"尺码","attr_id":7,"attr_name":"L"}],"num":1} |
|
*/ |
|
private function getDataByGoodsInfo($goods_info, $store) |
|
{ |
|
$goods_info = json_decode($goods_info); |
|
$goods = Goods::findOne([ |
|
'id' => $goods_info->goods_id, |
|
'is_delete' => 0, |
|
'store_id' => $this->store_id, |
|
'status' => 1, |
|
]); |
|
if (!$goods) { |
|
return [ |
|
'code' => 1, |
|
'msg' => '商品不存在或已下架', |
|
]; |
|
} |
|
|
|
$attr_id_list = []; |
|
foreach ($goods_info->attr as $item) { |
|
array_push($attr_id_list, $item->attr_id); |
|
} |
|
$total_price = 0; |
|
$goods_attr_info = $goods->getAttrInfo($attr_id_list); |
|
|
|
$attr_list = Attr::find()->alias('a') |
|
->select('ag.attr_group_name,a.attr_name') |
|
->leftJoin(['ag' => AttrGroup::tableName()], 'a.attr_group_id=ag.id') |
|
->where(['a.id' => $attr_id_list]) |
|
->asArray()->all(); |
|
$goods_pic = isset($goods_attr_info['pic']) ? $goods_attr_info['pic'] ?: $goods->getGoodsPic(0)->pic_url : $goods->getGoodsPic(0)->pic_url; |
|
$goods_item = (object)[ |
|
'goods_id' => $goods->id, |
|
'goods_name' => $goods->name, |
|
'goods_pic' => $goods_pic, |
|
'num' => $goods_info->num, |
|
'price' => doubleval(empty($goods_attr_info['price']) ? $goods->price : $goods_attr_info['price']) * $goods_info->num, |
|
'single_price' => doubleval(empty($goods_attr_info['price']) ? $goods->price : $goods_attr_info['price']), |
|
'attr_list' => $attr_list, |
|
'give' => 0, |
|
'freight' => $goods->freight, |
|
'integral' => $goods->integral, |
|
'weight' => $goods->weight, |
|
'full_cut' => $goods->full_cut, |
|
'cat_id' => $goods->cat_id, |
|
'mch_id' => $goods->mch_id, |
|
]; |
|
|
|
$list = []; |
|
$mch_list = []; |
|
//地址 |
|
$address = $this->getAddress(); |
|
$express_price = 0; |
|
$resIntegral = 0; |
|
$goods_card_list = []; |
|
|
|
if ($goods->mch_id) { //入驻商的商品 |
|
$mch = Mch::findOne($goods->mch_id); |
|
//运费 |
|
$express_price = $this->Express($goods_item, $address, $goods->full_cut); |
|
$mch_list[] = [ |
|
'id' => $mch->id, |
|
'name' => $mch->name, |
|
'logo' => $mch->logo, |
|
'express_price' => $express_price, |
|
'total_price' => $goods_item->price, |
|
'list' => [$goods_item], |
|
]; |
|
} else { //自营的商品 |
|
$total_price = $goods_item->price; |
|
//运费 |
|
$express_price = $this->Express($goods_item, $address, $goods->full_cut); |
|
//积分计算 |
|
$integral_res = OrderData::integral($goods_item, $store->integral); |
|
$resIntegral = $integral_res['resIntegral']; |
|
$goods_item->give = $integral_res['give']; |
|
$goods_card_list = Goods::getGoodsCard($goods->id); |
|
$list[] = $goods_item; |
|
} |
|
return [ |
|
'code' => 0, |
|
'msg' => 'success', |
|
'data' => [ |
|
'total_price' => $total_price, |
|
'goods_info' => $goods_info, |
|
'list' => $list, |
|
'address' => $address, |
|
'express_price' => $express_price, |
|
'integral' => $resIntegral, |
|
'goods_card_list' => $goods_card_list, |
|
'mch_list' => $mch_list, |
|
], |
|
]; |
|
} |
|
|
|
private function getShopList() |
|
{ |
|
$list = Shop::find()->select(['address', 'mobile', 'id', 'name', 'longitude', 'latitude']) |
|
->where(['store_id' => $this->store_id, 'is_delete' => 0])->asArray()->all(); |
|
$distance = array(); |
|
foreach ($list as $index => $item) { |
|
$list[$index]['distance'] = -1; |
|
if ($item['longitude'] && $this->longitude) { |
|
$from = [$this->longitude, $this->latitude]; |
|
$to = [$item['longitude'], $item['latitude']]; |
|
$list[$index]['distance'] = $this->get_distance($from, $to, false, 2); |
|
} |
|
$distance[] = $list[$index]['distance']; |
|
} |
|
array_multisort($distance, SORT_ASC, $list); |
|
$min = min(count($list), 30); |
|
$list_arr = array(); |
|
foreach ($list as $index => $item) { |
|
if ($index <= $min) { |
|
$list[$index]['distance'] = $this->distance($item['distance']); |
|
array_push($list_arr, $list[$index]); |
|
} |
|
} |
|
return $list; |
|
} |
|
|
|
/** |
|
* @param Goods $goods |
|
* @param array $attr_id_list eg.[12,34,22] |
|
* @return array ['attr_list'=>[],'miaosha_price'=>'秒杀价格','miaosha_num'=>'秒杀数量','sell_num'=>'已秒杀商品数量'] |
|
*/ |
|
private function getMiaoshaData($goods, $attr_id_list = []) |
|
{ |
|
$miaosha_goods = MiaoshaGoods::findOne([ |
|
'goods_id' => $goods->id, |
|
'is_delete' => 0, |
|
'open_date' => date('Y-m-d'), |
|
'start_time' => intval(date('H')), |
|
]); |
|
if (!$miaosha_goods) { |
|
return null; |
|
} |
|
|
|
$attr_data = json_decode($miaosha_goods->attr, true); |
|
sort($attr_id_list); |
|
$miaosha_data = null; |
|
foreach ($attr_data as $i => $attr_data_item) { |
|
$_tmp_attr_id_list = []; |
|
foreach ($attr_data_item['attr_list'] as $item) { |
|
$_tmp_attr_id_list[] = $item['attr_id']; |
|
} |
|
sort($_tmp_attr_id_list); |
|
if ($attr_id_list == $_tmp_attr_id_list) { |
|
$miaosha_data = $attr_data_item; |
|
break; |
|
} |
|
} |
|
return $miaosha_data; |
|
} |
|
|
|
/** |
|
* 获取商品秒杀价格,若库存不足则使用商品原价,若有部分库存,则部分数量使用秒杀价,部分使用商品原价,商品库存不足返回false |
|
* @param array $miaosha_data ['attr_list'=>[],'miaosha_price'=>'秒杀价格','miaosha_num'=>'秒杀数量','sell_num'=>'已秒杀商品数量'] |
|
* @param Goods $goods |
|
* @param array $attr_id_list eg.[12,34,22] |
|
* @param integer $buy_num 购买数量 |
|
* |
|
* @return false|float |
|
*/ |
|
private function getMiaoshaPrice($miaosha_data, $goods, $attr_id_list, $buy_num) |
|
{ |
|
$attr_data = json_decode($goods->attr, true); |
|
sort($attr_id_list); |
|
$goost_attr_data = null; |
|
foreach ($attr_data as $i => $attr_data_item) { |
|
$_tmp_attr_id_list = []; |
|
foreach ($attr_data_item['attr_list'] as $item) { |
|
$_tmp_attr_id_list[] = intval($item['attr_id']); |
|
} |
|
sort($_tmp_attr_id_list); |
|
if ($attr_id_list == $_tmp_attr_id_list) { |
|
$goost_attr_data = $attr_data_item; |
|
break; |
|
} |
|
} |
|
$goods_price = $goost_attr_data['price']; |
|
if (!$goods_price) { |
|
$goods_price = $goods->price; |
|
} |
|
|
|
$miaosha_price = min($miaosha_data['miaosha_price'], $goods_price); |
|
|
|
if ($buy_num > $goost_attr_data['num']) { //商品库存不足 |
|
\Yii::warning([ |
|
'res' => '库存不足', |
|
'm_data' => $miaosha_data, |
|
'g_data' => $goost_attr_data, |
|
'$attr_id_list' => $attr_id_list, |
|
]); |
|
return false; |
|
} |
|
|
|
if ($buy_num <= ($miaosha_data['miaosha_num'] - $miaosha_data['sell_num'])) { |
|
\Yii::warning([ |
|
'res' => '库存充足', |
|
'price' => $buy_num * $miaosha_price, |
|
'm_data' => $miaosha_data, |
|
]); |
|
return $buy_num * $miaosha_price; |
|
} |
|
|
|
$miaosha_num = ($miaosha_data['miaosha_num'] - $miaosha_data['sell_num']); |
|
$original_num = $buy_num - $miaosha_num; |
|
|
|
\Yii::warning([ |
|
'res' => '部分充足', |
|
'price' => $miaosha_num * $miaosha_price + $original_num * $goods_price, |
|
'm_data' => $miaosha_data, |
|
]); |
|
return $miaosha_num * $miaosha_price + $original_num * $goods_price; |
|
} |
|
|
|
private static function distance($distance) |
|
{ |
|
if ($distance == -1) { |
|
return -1; |
|
} |
|
if ($distance > 1000) { |
|
$distance = round($distance / 1000, 2) . 'km'; |
|
} else { |
|
$distance .= 'm'; |
|
} |
|
return $distance; |
|
} |
|
|
|
/** |
|
* 根据起点坐标和终点坐标测距离 |
|
* @param [array] $from [起点坐标(经纬度),例如:array(118.012951,36.810024)] |
|
* @param [array] $to [终点坐标(经纬度)] |
|
* @param [bool] $km 是否以公里为单位 false:米 true:公里(千米) |
|
* @param [int] $decimal 精度 保留小数位数 |
|
* @return [string] 距离数值 |
|
*/ |
|
public function get_distance($from, $to, $km = true, $decimal = 2) |
|
{ |
|
sort($from); |
|
sort($to); |
|
$EARTH_RADIUS = 6370.996; // 地球半径系数 |
|
|
|
$distance = $EARTH_RADIUS * 2 * asin(sqrt(pow(sin(($from[0] * pi() / 180 - $to[0] * pi() / 180) / 2), 2) + cos($from[0] * pi() / 180) * cos($to[0] * pi() / 180) * pow(sin(($from[1] * pi() / 180 - $to[1] * pi() / 180) / 2), 2))) * 1000; |
|
|
|
if ($km) { |
|
$distance = $distance / 1000; |
|
} |
|
|
|
return round($distance, $decimal); |
|
} |
|
|
|
/** |
|
* 检查订单中是否有秒杀商品并且限购 |
|
* @return null||array null表示无限购 |
|
*/ |
|
public function checkBuyMax($list) |
|
{ |
|
$goods_list = []; |
|
foreach ($list as $item) { |
|
if (empty($goods_list[$item->goods_id])) { |
|
$goods_list[$item->goods_id] = [ |
|
'goods_name' => $item->goods_name, |
|
'num' => $item->num, |
|
]; |
|
} else { |
|
$goods_list[$item->goods_id]['num'] += intval($item->num); |
|
} |
|
} |
|
|
|
foreach ($goods_list as $goods_id => $item) { |
|
$miaosha_goods = MiaoshaGoods::find()->where([ |
|
'AND', |
|
[ |
|
'goods_id' => $goods_id, |
|
'is_delete' => 0, |
|
'open_date' => date('Y-m-d'), |
|
'start_time' => intval(date('H')), |
|
], |
|
['!=', 'buy_max', 0], |
|
['<', 'buy_max', $item['num']], |
|
])->one(); |
|
if ($miaosha_goods) { |
|
return [ |
|
'code' => 1, |
|
'msg' => "购买数量超过限制! 商品“" . $item['goods_name'] . '”最多允许购买' . $miaosha_goods->buy_max . '件,请返回重新下单', |
|
]; |
|
} |
|
} |
|
return null; |
|
} |
|
|
|
//自定义表单 |
|
private function formData() |
|
{ |
|
$new_list = []; |
|
$new_list['is_form'] = Option::get('is_form', $this->store_id, 'admin', 0); |
|
$form_list = []; |
|
if ($new_list['is_form'] == 1) { |
|
$new_list['name'] = Option::get('form_name', $this->store_id, 'admin', '表单信息'); |
|
$form_list = Form::find()->where([ |
|
'store_id' => $this->store_id, 'is_delete' => 0, |
|
])->asArray()->all(); |
|
foreach ($form_list as $index => $value) { |
|
if (in_array($value['type'], ['radio', 'checkbox'])) { |
|
$default = str_replace(",", ",", $value['default']); |
|
$list = explode(',', $default); |
|
$default_list = []; |
|
foreach ($list as $k => $v) { |
|
$default_list[$k]['name'] = $v; |
|
if ($k == 0) { |
|
$default_list[$k]['is_selected'] = 1; |
|
} else { |
|
$default_list[$k]['is_selected'] = 0; |
|
} |
|
} |
|
$form_list[$index]['default_list'] = $default_list; |
|
} |
|
} |
|
} |
|
$new_list['list'] = $form_list; |
|
return $new_list; |
|
} |
|
|
|
//单个商品运费 |
|
|
|
/** |
|
* @param $goods_item object 重新编写的goods_item |
|
* @param $address object||null 地址 |
|
* @param null $full_cut 单商品运费规则(满件包邮及满额包邮) |
|
* @return float|int |
|
*/ |
|
private function Express($goods_item, $address, $full_cut = null) |
|
{ |
|
$express_price = 0; |
|
if ($address) { |
|
if ($full_cut) { |
|
$full_cut = json_decode($full_cut, true); |
|
} else { |
|
$full_cut = [ |
|
'pieces' => 0, |
|
'forehead' => 0, |
|
]; |
|
} |
|
|
|
if ((empty($full_cut['pieces']) || $goods_item->num < ($full_cut['pieces'] ?: 0)) && (empty($full_cut['forehead']) || $goods_item->price < ($full_cut['forehead'] ?: 0))) { |
|
$express_price = PostageRules::getExpressPrice($this->store_id, $address['city_id'], $goods_item, $goods_item->num, $address['province_id']); |
|
} |
|
} |
|
return $express_price; |
|
} |
|
}
|
|
|