diff --git a/api/controllers/AddressController.php b/api/controllers/AddressController.php index 04890b5..27fe5fb 100644 --- a/api/controllers/AddressController.php +++ b/api/controllers/AddressController.php @@ -19,7 +19,7 @@ class AddressController extends CommonController /** * @return object - * @throws \yii\base\InvalidConfigException + * @throws yii\base\InvalidConfigException */ public function actionIndex() { diff --git a/api/controllers/SiteController.php b/api/controllers/SiteController.php index 53228f4..d47ced4 100644 --- a/api/controllers/SiteController.php +++ b/api/controllers/SiteController.php @@ -18,7 +18,7 @@ class SiteController extends Controller return ArrayHelper::merge(parent::behaviors(), [ 'authenticatior' => [ 'class' => HttpBearerAuth::className(), - 'except' => [], + 'except' => ['index'], ] ]); } diff --git a/api/logic/AddressLogic.php b/api/logic/AddressLogic.php index 6e1a98b..d6809f8 100644 --- a/api/logic/AddressLogic.php +++ b/api/logic/AddressLogic.php @@ -19,9 +19,17 @@ use yii\web\ServerErrorHttpException; class AddressLogic extends BaseObject { const SET_DEFAULT_ADDRESS = 1; - public $viewAction = 'view'; + /** + * @return Address|null + * 获取默认地址 + */ + public function getDefault() + { + return $this->findDefault(); + } + /** * @return Address * @throws BadRequestHttpException @@ -37,7 +45,7 @@ class AddressLogic extends BaseObject if (!$address->save()) { throw new ServerErrorHttpException('地址添加失败'); } - if (!$this->getDefaultAddress()) { + if (!$this->findDefault()) { $this->setDefaultAddress($address); } Helper::createdResponse($address, $this->viewAction); @@ -76,7 +84,7 @@ class AddressLogic extends BaseObject { $tra = Yii::$app->db->beginTransaction(); try { - $oldDefault = $this->getDefaultAddress(); + $oldDefault = $this->findDefault(); if ($oldDefault) { $oldDefault->status = Address::STATUS_NOT_DEFAULT; if (!$oldDefault->save()) { @@ -106,10 +114,10 @@ class AddressLogic extends BaseObject $data['phone'] = Yii::$app->request->getBodyParam('phone'); $data['province'] = Yii::$app->request->getBodyParam('province'); $data['city'] = Yii::$app->request->getBodyParam('city'); - $data['district'] = Yii::$app->request->getBodyParam('district'); + $data['area'] = Yii::$app->request->getBodyParam('area'); $data['address'] = Yii::$app->request->getBodyParam('address'); if (empty($data['consignee']) || empty($data['phone']) || empty($data['province']) || - empty($data['city']) || empty($data['district']) || empty($data['address'])) { + empty($data['city']) || empty($data['area']) || empty($data['address'])) { throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS); } return $data; @@ -135,7 +143,7 @@ class AddressLogic extends BaseObject /** * @return array|Address|null */ - private function getDefaultAddress() + private function findDefault() { return Address::find() ->where(['user_id' => Yii::$app->user->getId()]) diff --git a/api/logic/ExpressLogic.php b/api/logic/ExpressLogic.php index fc58234..7055d66 100644 --- a/api/logic/ExpressLogic.php +++ b/api/logic/ExpressLogic.php @@ -8,7 +8,6 @@ use backend\modules\shop\models\ars\ExpressArea; use backend\modules\shop\models\ars\ExpressTemplate; use backend\modules\shop\models\ars\Order; use backend\modules\shop\models\ars\OrderGoods; -use Yii; use yii\base\BaseObject; use yii\web\NotFoundHttpException; @@ -19,7 +18,6 @@ use yii\web\NotFoundHttpException; */ class ExpressLogic extends BaseObject { - public $viewAction = 'view'; /** * @var Order * 订单 @@ -87,66 +85,88 @@ class ExpressLogic extends BaseObject return $amount; } else { $extraPrice = 0; - $areasIds = []; + $areasIds = $basicGoods = []; foreach ($allGoods as $goods) { - $areasIds[] = $this->getAreaId($goods['object']->express_template); + $areasIds[] = $this->getAreaId($goods['object']->express_template);/*获取所有配送区域的id*/ } - /*获取首重运费和对应的计费规则id*/ - $basic = $this->getBasicPriceAndAreaId($areasIds); - foreach ($allGoods as $goods) { - /*计算增重运费*/ - $extraPrice += $this->countExtraAmount($goods['count'], $goods['weight'], $goods['object']->express_template, $basic['id']); + $basicId = $this->getBasicAreaId($areasIds);/*获取首重运费和对应的计费规则id*/ + foreach ($allGoods as $k => $goods) { + $res = $this->countExtraAmount($goods, $basicId);/*判断商品绑定的是否为基础模板并计算非基础模板商品的增重运费*/ + if (is_bool($res) && $res === true) { + $basicGoods[] = $allGoods[$k]; + continue; + } + $extraPrice += $res; } - return ($basic['price'] + $extraPrice); + $basicPrice = $this->countBasicPrice($basicGoods, $basicId);/*计算基础模板商品的运费*/ + return $extraPrice + $basicPrice; } } + /** + * @param $allGoods + * @param $areaId + * @return float|int + * @throws NotFoundHttpException + * 计算基础模板商品的运费价格 + */ + private function countBasicPrice($allGoods, $areaId) + { + $area = $this->findArea($areaId); + $count = $weight = 0; + $template = $this->findTemplate($area->express_template); + foreach ($allGoods as $goods) { + $count += $goods['count']; + $weight += $goods['weight']; + } + if ($template->calculation_type == ExpressTemplate::CALCULATION_TYPE_WEIGHT) { + $amount = $weight - $area->basic_count > 0 ? $weight - $area->basic_count : 0; + } else { + $amount = $weight - $area->basic_count > 0 ? $weight - $area->basic_count : 0; + } + return $area->basic_price + $area->extra_price * ceil($amount / $area->extra_count); + } /** * @param $areaIds - * @return array + * @return int * @throws NotFoundHttpException - * 获取基础运费 + * 获取基础运费的区域id */ - private function getBasicPriceAndAreaId($areaIds) + private function getBasicAreaId($areaIds) { $basePrice = $id = 0; foreach ($areaIds as $areasId) { $area = $this->findArea($areasId); - if (!$area->basic_price > $basePrice) { + if ($area->basic_price < $basePrice) { continue; } $basePrice = $area->basic_price; $id = $areasId; } - return ['price' => $basePrice, 'id' => $id]; + return $id; } /** - * @param $count - * @param $weight - * @param $templateId + * @param $goods * @param $areaId - * @return float|int + * @return bool|int * @throws NotFoundHttpException - * 计算增重运费 + * 计算非使用基础运费模板的商品按增重运费计算运费 */ - private function countExtraAmount($count, $weight, $templateId, $areaId) + private function countExtraAmount($goods, $areaId) { - $area = $this->findArea($this->getAreaId($templateId)); - $template = $this->findTemplate($templateId); + $count = $goods['count']; + $weight = $goods['weight']; + $area = $this->findArea($this->getAreaId($goods['object']->express_template)); + $template = $this->findTemplate($goods['object']->express_template); + if ($area->id == $areaId) { + return true; + } if ($template->calculation_type == ExpressTemplate::CALCULATION_TYPE_WEIGHT) { - if ($area->id == $areaId) { - $amount = $weight - $area->basic_count > 0 ? $weight - $area->basic_count : 0; - } else { - $amount = $weight; - } + $amount = $weight; } else { - if ($area->id == $areaId) { - $amount = $count - $area->basic_count > 0 ? $count - $area->basic_count : 0; - } else { - $amount = $count; - } + $amount = $count; } return $area->extra_price * ceil($amount / $area->extra_count); } @@ -155,12 +175,12 @@ class ExpressLogic extends BaseObject * @param $templateId * @return int * @throws NotFoundHttpException - * 根据运费模板和收货地址获取区域 + * 根据收货地址获取配送区域id */ private function getAreaId($templateId) { - $areas = ExpressArea::findALl(['express_template' => $templateId]); $city = $this->order->city; + $areas = ExpressArea::findALl(['express_template' => $templateId]); foreach ($areas as $area) { $allCity = explode(',', $area->city); if (in_array($city, $allCity)) { diff --git a/api/logic/Helper.php b/api/logic/Helper.php index 0c5db86..5d30418 100644 --- a/api/logic/Helper.php +++ b/api/logic/Helper.php @@ -8,7 +8,6 @@ use backend\modules\goods\models\ars\GoodsAttr; use backend\modules\goods\models\ars\GoodsSku; use backend\modules\shop\models\ars\Cart; use yii\data\ActiveDataProvider; -use yii\di\Instance; use yii\helpers\Url; use yii\web\BadRequestHttpException; use yii\web\NotFoundHttpException; @@ -25,6 +24,19 @@ class Helper { const REQUEST_BAD_PARAMS = '参数缺失或包含无效参数'; + + public static function timeRandomNum($digit, $Prefix = '') + { + $max = pow(10, $digit + 1); + return $Prefix . date('YmdHis', time()) . rand(0, $max - 1); + } + + /** + * @param $data + * @param $oid + * @param $type + * @throws ServerErrorHttpException + */ public static function saveFileMsg($data, $oid, $type) { $file = new File(); @@ -78,7 +90,7 @@ class Helper } /** - * @param array $ids 购物车id 数组 + * @param array $ids 购物车id 数组 * @throws NotFoundHttpException * @throws ServerErrorHttpException * @throws \Throwable @@ -104,26 +116,29 @@ class Helper * @param $goodsId * @param $count * @param null $skuId - * @throws BadRequestHttpException + * @return bool true代表无限库存,false代表有限库存需要进行增删库存操作 + * 判断库存 * @throws NotFoundHttpException - * 判断库存 + * @throws BadRequestHttpException */ public static function checkStock($goodsId, $count, $skuId = null) { $sku = GoodsSku::findOne($skuId); $goods = Goods::findOne($goodsId); if (!$goods) { - print_r($goodsId);exit; throw new NotFoundHttpException('商品未找到'); } - if (!$sku && $goods->stock == Goods::UNLIMITED_STOCK) { - return; + if ($goods->stock == Goods::UNLIMITED_STOCK) { + return true; + } + if ($sku && $sku->stock == Goods::UNLIMITED_STOCK) { + return true; } $stock = $sku ? $sku->stock : $goods->stock; if ($stock < $count) { throw new BadRequestHttpException("{$goods->name}库存不足"); } - return; + return false; } /** diff --git a/api/logic/OrderLogic.php b/api/logic/OrderLogic.php index cfad6b2..eb578e9 100644 --- a/api/logic/OrderLogic.php +++ b/api/logic/OrderLogic.php @@ -59,6 +59,9 @@ class OrderLogic extends Component $tra = Yii::$app->db->beginTransaction(); try { $order = new Order(); + $order->user_id = Yii::$app->user->getId(); + $order->type = Order::TYPE_SHOPPING; + $order->order_sn = Helper::timeRandomNum(3, 'W'); if (!$order->save()) { throw new ServerErrorHttpException('服务器创建订单失败'); } @@ -67,7 +70,11 @@ class OrderLogic extends Component } else { $this->addGoodsByCart($cartIds, $order->id);/*通过购物车添加订单商品*/ } + $this->getShippingType($order); $this->saveGoodsInfo($order);/*保存订单商品信息*/ + if (!$order->save()) { + throw new Exception('服务器创建订单失败'); + } $tra->commit(); Helper::createdResponse($order, $this->viewAction); return $order; @@ -110,6 +117,8 @@ class OrderLogic extends Component case self::TYPE_CHANGE_TAKING_SITE: $this->changeTakingSite($order, $data); break; + default: + throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS); } if (!$order->save()) { throw new ServerErrorHttpException('服务器更新订单失败'); @@ -123,6 +132,25 @@ class OrderLogic extends Component } /*----------------------------------------- 华丽的分割线 -----------------------------------------*/ + /** + * @param $order + * @return int + * @throws BadRequestHttpException + * @throws NotFoundHttpException + */ + private function getShippingType($order) + { + $allOrderGoods = $this->findOrderGoods($order->id); + $goods = $this->findGoods($allOrderGoods[0]->goods_id); + if ($goods->is_express) { + return Order::SHIPPING_TYPE_EXPRESS; + } + if ($goods->is_taking) { + return Order::SHIPPING_TYPE_PICKED_UP; + } + throw new BadRequestHttpException('配送方式异常'); + } + /** * @param Order $order * @param array $data @@ -138,6 +166,9 @@ class OrderLogic extends Component if ($order->shipping_type !== Order::SHIPPING_TYPE_EXPRESS) { throw new BadRequestHttpException('配送方式异常'); } + if ($order->status !== Order::STATUS_UNCONFIRMED) { + throw new BadRequestHttpException('该状态下不允许更改配送方式'); + } $address = Address::findOne(['id' => $data['address_id'], 'user_id' => Yii::$app->user->getId()]); if (!$address) { throw new NotFoundHttpException('收货地址未找到'); @@ -165,6 +196,9 @@ class OrderLogic extends Component if ($order->shipping_type !== Order::SHIPPING_TYPE_PICKED_UP) { throw new BadRequestHttpException('配送方式异常'); } + if ($order->status !== Order::STATUS_UNCONFIRMED) { + throw new BadRequestHttpException('该状态下不允许更改提货地址方式'); + } $site = TakingSite::findOne($data['taking_site_id']); if (!$site) { throw new NotFoundHttpException('自提点未找到'); @@ -181,12 +215,14 @@ class OrderLogic extends Component */ private function switchShippingType($order, $data) { - if (!isset($data['shipping_type'])) { + if (!isset($data['shipping_type']) || + !in_array($data['shipping_type'], [Order::SHIPPING_TYPE_PICKED_UP, Order::SHIPPING_TYPE_EXPRESS])) { throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS); } if ($order->status !== Order::STATUS_UNCONFIRMED) { - throw new BadRequestHttpException('订单状态异常'); + throw new BadRequestHttpException('该状态下不允许更改配送方式'); } + $order->shipping_type = $data['shipping_type']; } @@ -251,7 +287,7 @@ class OrderLogic extends Component private function cancel($order) { if ($order->status !== Order::STATUS_NONPAYMENT) { - throw new BadRequestHttpException('订单状态异常'); + throw new BadRequestHttpException('该状态下无法取消订单'); } $order->status = Order::STATUS_CANCEL; $this->updateStock($order, self::TYPE_ADD_STOCK);/*更新库存*/ @@ -265,7 +301,7 @@ class OrderLogic extends Component private function take($order) { if ($order->status !== Order::STATUS_SHIPMENT_ALL) { - throw new BadRequestHttpException('订单状态异常'); + throw new BadRequestHttpException('该状态下无法确认收货'); } $order->status = Order::STATUS_FINISH; } @@ -283,11 +319,13 @@ class OrderLogic extends Component $allOrderGoods = $this->findOrderGoods($id); foreach ($allOrderGoods as $orderGoods) { /*检查库存*/ - Helper::checkStock($orderGoods->goods_id, $orderGoods->goods_count, $orderGoods->sku_id); + if (Helper::checkStock($orderGoods->goods_id, $orderGoods->goods_count, $orderGoods->sku_id)) { + return; + } if ($orderGoods->sku_id) { $goods = GoodsSku::findOne($orderGoods->sku_id); } else { - $goods = Goods::findOne($orderGoods->goods_id); + $goods = $this->findGoods($orderGoods->goods_id); } if ($type) { $count = $orderGoods->goods_count; @@ -320,7 +358,6 @@ class OrderLogic extends Component /** * @param Order $order - * @throws Exception * 保存商品总价格和总数量信息到 */ private function saveGoodsInfo($order) @@ -330,9 +367,6 @@ class OrderLogic extends Component $order->goods_amount += $goods->price; $order->goods_count += $goods->goods_count; } - if (!$order->save()) { - throw new Exception('服务器创建订单失败'); - } } @@ -347,7 +381,7 @@ class OrderLogic extends Component */ private function addGoods($id, $goodsId, $skuId, $count) { - $goods = Goods::findOne($goodsId); + $goods = $this->findGoods($goodsId); $orderGoods = new OrderGoods(); $orderGoods->order_id = $id; $orderGoods->goods_id = $goodsId; @@ -364,6 +398,12 @@ class OrderLogic extends Component } } + /** + * @param $skuId + * @return int + * @throws NotFoundHttpException + * 获取sku重量 + */ private function skuWeight($skuId) { $sku = GoodsSku::findOne($skuId); @@ -398,5 +438,22 @@ class OrderLogic extends Component ->all(); } + /** + * @param int $goodsId + * @return Goods|null + * @throws NotFoundHttpException + */ + private function findGoods($goodsId) + { + $goods = Goods::find() + ->where(['id' => $goodsId]) + ->andWhere(['is_delete' => Goods::IS_DELETE_NO]) + ->andWhere(['is_sale' => Goods::IS_SALE_YES]) + ->one(); + if (!$goods) { + throw new NotFoundHttpException("商品[{$goodsId}]未找到"); + } + return $goods; + } } \ No newline at end of file diff --git a/backend/modules/shop/models/ars/Order.php b/backend/modules/shop/models/ars/Order.php index 196256c..aa61cd5 100755 --- a/backend/modules/shop/models/ars/Order.php +++ b/backend/modules/shop/models/ars/Order.php @@ -125,12 +125,14 @@ class Order extends \yii\db\ActiveRecord public function beforeSave($insert) { + $address = Yii::createObject([ + 'class' => 'api\logic\AddressLogic', + ]); if ($insert) { - $this->user_id = Yii::$app->user->getId(); - $this->type = Order::TYPE_SHOPPING; - //TODO 测试 - $this->city = '445100'; - $this->type = Order::TYPE_SHOPPING; + $default = $address->getDefault(); + $this->province = $default['province'] ?? ''; + $this->city = $default['city'] ?? ''; + $this->area = $default['area'] ?? ''; } if (!$insert && $this->status == self::STATUS_UNCONFIRMED && $this->type == self::TYPE_SHOPPING) { $express = Yii::createObject([