Browse Source

feat: 商品,购物车,订单的业务逻辑

wechat_public_accounts
root 5 years ago
parent
commit
b555453cfc
  1. 15
      api/config/main.php
  2. 2
      api/config/params.php
  3. 47
      api/controllers/CartController.php
  4. 53
      api/controllers/CommonController.php
  5. 49
      api/controllers/GoodsController.php
  6. 55
      api/controllers/OrderController.php
  7. 18
      api/controllers/SiteController.php
  8. 9
      api/controllers/TestController.php
  9. 31
      api/controllers/UserController.php
  10. 144
      api/logic/CartLogic.php
  11. 114
      api/logic/Helper.php
  12. 349
      api/logic/OrderLogic.php
  13. 6
      backend/config/main.php
  14. 17
      backend/controllers/OrderController.php
  15. 1
      backend/controllers/SiteController.php
  16. 3
      backend/web/css/site.css
  17. 59
      common/models/ars/Order.php
  18. 21
      vendor/antgoods/goods/src/models/ars/Goods.php
  19. 1
      vendor/antgoods/goods/src/models/searchs/GoodsSearch.php
  20. 8
      vendor/iron/grid/GridView.php

15
api/config/main.php

@ -11,6 +11,8 @@ return [
'bootstrap' => ['log'], 'bootstrap' => ['log'],
'modules' => [], 'modules' => [],
'components' => [ 'components' => [
'cartLogic'=>['class'=>'api\logic\CartLogic'],
'orderLogic'=>['class'=>'api\logic\OrderLogic'],
'request' => [ 'request' => [
'parsers' => [ 'parsers' => [
'application/json' => 'yii\web\JsonParser', 'application/json' => 'yii\web\JsonParser',
@ -43,13 +45,24 @@ return [
'enableStrictParsing' => true, 'enableStrictParsing' => true,
'showScriptName' => false, 'showScriptName' => false,
'rules' => [ 'rules' => [
['class' => 'yii\rest\UrlRule',
['class' => 'yii\rest\UrlRule', 'controller' => 'goods', 'pluralize' => false,],
['class' => 'yii\rest\UrlRule', 'controller' => 'cart'],
['class' => 'yii\rest\UrlRule', 'controller' => 'order'],
[
'class' => 'yii\rest\UrlRule',
'controller' => 'user', 'controller' => 'user',
'extraPatterns' => [ 'extraPatterns' => [
'GET menu' => 'menu', 'GET menu' => 'menu',
'GET create' => 'create' 'GET create' => 'create'
] ]
], ],
[
'class' => 'yii\rest\UrlRule',
'controller' => 'site',
'extraPatterns' => [
'GET index' => 'index',
]
],
], ],
], ],
], ],

2
api/config/params.php

@ -52,7 +52,7 @@ return [
], ],
], ],
'商品管理' => [ '商品管理' => [
'icon' => 'fa-archive',
'icon' => 'fa-shopping-bag',
'items' => [ 'items' => [
['商城分类', '/antgoods/shop-category'], ['商城分类', '/antgoods/shop-category'],
['后台分类', '/antgoods/category'], ['后台分类', '/antgoods/category'],

47
api/controllers/CartController.php

@ -0,0 +1,47 @@
<?php
namespace api\controllers;
use yii\db\ActiveRecord;
use yii\rest\ActiveController;
use Yii;
/**
* @author iron
* @email weiriron@gmail.com
*/
class CartController extends CommonController
{
public $modelClass = 'common\models\ars\Cart';
/**
* @return bool
* 更新购物车(增/删商品)
*/
public function actionUpdate()
{
$type = Yii::$app->request->post('type');
return Yii::$app->cartLogic->addOrSubGoods($type);
}
/**
* @return ActiveRecord
* 创建商品
*/
public function actionCreate()
{
$goodsId = Yii::$app->request->getBodyParam('goodsId');
$count = Yii::$app->request->getBodyParam('count');
$skuId = Yii::$app->request->getBodyParam('skuId');
return Yii::$app->cartLogic->addGoods($goodsId, $count, $skuId);
}
/**
* 删除商品
*/
public function actionDelete()
{
Yii::$app->cartLogic->delete();
}
}

53
api/controllers/CommonController.php

@ -0,0 +1,53 @@
<?php
namespace api\controllers;
use yii\filters\auth\HttpBearerAuth;
use yii\helpers\ArrayHelper;
use yii\rest\ActiveController;
/**
* @author iron
* @email weiriron@gmail.com
*/
class CommonController extends ActiveController
{
// public function behaviors()
// {
// return ArrayHelper::merge(parent::behaviors(), [
// 'authenticatior' => [
// 'class' => HttpBearerAuth::className(),
// 'except' => [],
// ]
// ]);
// }
public function actions()
{
$action = parent::actions();
unset($action['delete']);
unset($action['create']);
unset($action['update']);
$action['index'] = [
'class' => 'yii\rest\IndexAction',
'checkAccess' => [$this, 'checkAccess'],
'modelClass' => $this->modelClass,
'dataFilter' => $this->getFilter()
];
return $action;
}
protected function getFilter()
{
$data = \Yii::$app->request->getBodyParams();
$data['user'] = true;
\Yii::$app->request->setBodyParams($data);
$filter = ['class' => 'yii\data\ActiveDataFilter',
'filter' => ['user_id' => \Yii::$app->user->getId()],
'searchModel' => ['class' => 'antgoods\goods\models\searchs\GoodsSearch']];
return $filter;
}
}

49
api/controllers/GoodsController.php

@ -0,0 +1,49 @@
<?php
namespace api\controllers;
use yii\filters\auth\HttpBearerAuth;
use yii\helpers\ArrayHelper;
use yii\rest\ActiveController;
/**
* @author iron
* @email weiriron@gmail.com
*/
class GoodsController extends ActiveController
{
public $modelClass = 'antgoods\goods\models\ars\Goods';
public function actions()
{
$action = parent::actions();
unset($action['delete']);
unset($action['create']);
$action['index'] = [
'class' => 'yii\rest\IndexAction',
'modelClass' => $this->modelClass,
'dataFilter' => $this->getFilter()
];
return $action;
}
protected function getFilter()
{
$keyword = \Yii::$app->request->getBodyParam('keyword');
$category = \Yii::$app->request->getBodyParam('category');
if (empty($keyword) && empty($category)) {
return null;
}
$array = [];
if ($keyword) {
$array['name'] = ['like' => $keyword];
}
if ($category) {
$array['cat_id'] = $category;
}
$filter = ['class' => 'yii\data\ActiveDataFilter',
'filter' => $array,
'searchModel' => ['class' => 'antgoods\goods\models\searchs\GoodsSearch']];
return $filter;
}
}

55
api/controllers/OrderController.php

@ -0,0 +1,55 @@
<?php
namespace api\controllers;
use yii\web\ForbiddenHttpException;
use Yii;
/**
* @author iron
* @email weiriron@gmail.com
*/
class OrderController extends CommonController
{
public $modelClass = 'common\models\ars\Order';
protected function getFilter()
{
$status = Yii::$app->request->getBodyParam('status');
$data = \Yii::$app->request->getBodyParams();
$data['user'] = true;
\Yii::$app->request->setBodyParams($data);
$array = ['user_id' => Yii::$app->user->getId()];
if ($status) {
$array['status'] = $status;
}
$filter = ['class' => 'yii\data\ActiveDataFilter',
'filter' => $array,
'searchModel' => ['class' => 'common\models\searchs\OrderSearch']];
return $filter;
}
public function actionCreate()
{
$originId = Yii::$app->request->getBodyParam('goodsId');
$count = Yii::$app->request->getBodyParam('count');
$skuId = Yii::$app->request->getBodyParam('skuId');
return Yii::$app->orderLogic->addGoods($originId, $count, $skuId);
}
/**
* @return mixed
* @throws \yii\base\InvalidConfigException
*/
public function actionUpdate()
{
$data = Yii::$app->request->getBodyParams();
return Yii::$app->orderLogic->update($data);
}
}

18
api/controllers/SiteController.php

@ -2,21 +2,25 @@
namespace api\controllers; namespace api\controllers;
use yii\web\Controller;
use antgoods\goods\models\ars\Goods;
use yii\rest\Controller;
/** /**
* Created by PhpStorm.
* User: iron
* Date: 2018/5/25
* Time: 16:42
* @author iron
* @email weiriron@gmail.com
*/ */
class SiteController extends Controller class SiteController extends Controller
{ {
public function actions() {
public function actions()
{
return [ return [
'error' => [ 'error' => [
'class' => 'yii\web\ErrorAction', 'class' => 'yii\web\ErrorAction',
], ],
]; ];
} }
public function actionIndex()
{
return Goods::findOne(1);
}
} }

9
api/controllers/TestController.php

@ -2,7 +2,6 @@
/* /*
* The MIT License * The MIT License
* *
* Copyright 2019 Blobt.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -29,8 +28,8 @@ namespace api\controllers;
* @email weiriron@gmail.com * @email weiriron@gmail.com
*/ */
use common\models\ars\Goods;
use common\models\searchs\GoodsSearch;
use antgoods\goods\models\ars\Goods;
use yii\data\ActiveDataProvider; use yii\data\ActiveDataProvider;
use yii\db\ActiveRecord; use yii\db\ActiveRecord;
use yii\rest\ActiveController; use yii\rest\ActiveController;
@ -38,7 +37,7 @@ use yii\web\NotFoundHttpException;
class TestController extends ActiveController class TestController extends ActiveController
{ {
public $modelClass = 'common\models\ars\Goods';
public $modelClass = 'antgoods\goods\models\ars\Goods';
public function actions() public function actions()
{ {
@ -52,7 +51,7 @@ class TestController extends ActiveController
return new ActiveDataProvider([ return new ActiveDataProvider([
'query' => Goods::find(), 'query' => Goods::find(),
'pagination' => [ 'pagination' => [
'pageSize' => 1,
'pageSize' => 10,
], ],
]); ]);
} }

31
api/controllers/UserController.php

@ -1,29 +1,6 @@
<?php <?php
namespace api\controllers; namespace api\controllers;
/*
* The MIT License
*
* Copyright 2019 Blobt.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
use common\models\ars\Config; use common\models\ars\Config;
use common\models\User; use common\models\User;
@ -48,13 +25,7 @@ class UserController extends ActiveController
public function actionIndex() public function actionIndex()
{ {
$key = $param = base64_encode(1 + date('Y')
+ date('m') - date('d') - date('h'));
$data = [];
Yii::$app->userLogic->createUser($data, $key);
$response = Yii::$app->getResponse();
$response->setStatusCode(201);
return ['status' => true];
} }

144
api/logic/CartLogic.php

@ -0,0 +1,144 @@
<?php
namespace api\logic;
use antgoods\goods\models\ars\Goods;
use common\models\ars\Cart;
use yii\base\Component;
use Yii;
use yii\db\ActiveRecord;
use yii\helpers\Url;
use yii\web\BadRequestHttpException;
use yii\web\NotFoundHttpException;
use yii\web\ServerErrorHttpException;
/**
* @author iron
* @email weiriron@gmail.com
* Class CartLogic
* @package api\logic
*/
class CartLogic extends Component
{
public $viewAction = 'view';
const TYPE_ADD = 1;
const TYPE_SUB = -1;
/**
* @param $goodsId
* @param $count
* @param $skuId
* @return array|\yii\db\ActiveRecord|null
* @throws BadRequestHttpException
* @throws NotFoundHttpException
* @throws ServerErrorHttpException
* 添加商品到购物车
*/
public function addGoods($goodsId, $count, $skuId)
{
if (empty($goodsId) || empty($count)) {
throw new BadRequestHttpException('无效参数');
}
//TODO 判断限购
//判断库存
Helper::checkStock($goodsId, $count, $skuId);
$cart = Cart::find()->where(['goods_id' => $goodsId])
->andWhere(['user_id' => Yii::$app->user->getId()])
->one();
if ($cart) {
if (!$cart->updateCounters(['goods_count' => $count])) {
throw new ServerErrorHttpException('服务器添加购物车商品失败');
}
} else {
$cart = $this->create($goodsId, $skuId, $count);
}
Helper::createdResponse($cart, $this->viewAction);
return $cart;
}
/**
* @param int $type
* @return bool
* @throws BadRequestHttpException
* @throws NotFoundHttpException
*/
public function addOrSubGoods($type)
{
if (empty($type) || ($type != self::TYPE_SUB && $type != self::TYPE_ADD)) {
throw new BadRequestHttpException('无效参数');
}
$cart = $this->findCart();
if (!$cart) {
throw new NotFoundHttpException('未找到该购物车');
}
if ($cart->goods_count == 1 && $type == self::TYPE_SUB) {
throw new BadRequestHttpException('购物商品需至少1件');
}
return $cart->updateCounters(['goods_count' => $type]);
}
/**
* @throws NotFoundHttpException
* @throws ServerErrorHttpException
* @throws \Throwable
* @throws \yii\db\StaleObjectException
* 删除购物车
*/
public function delete()
{
$cart = $this->findCart();
if (!$cart) {
throw new NotFoundHttpException('未找到该购物车');
}
if ($cart->delete()) {
Yii::$app->getResponse()->setStatusCode(204);
} else {
throw new ServerErrorHttpException('服务器无法删除购物车');
}
}
/**
* @param $goodsId
* @param $skuId
* @param $count
* @return Cart;
* 创建新购物车
* @throws ServerErrorHttpException
* @throws NotFoundHttpException
*/
private function create($goodsId, $skuId, $count)
{
$goods = Goods::findOne($goodsId);
if (!$goods) {
throw new NotFoundHttpException('商品未找到');
}
$cart = new Cart();
$cart->goods_id = $goods->id;
$cart->user_id = Yii::$app->user->getId();
$cart->goods_count = $count;
$cart->sku_id = $skuId ?: 0;
$cart->goods_img = $goods->image;
$cart->goods_name = $goods->name;
$cart->goods_price = Helper::countPrice($goodsId, $skuId);
if (!$cart->save()) {
throw new ServerErrorHttpException('服务器创建购物车失败');
}
return $cart;
}
/**
* @return ActiveRecord|null|Cart
* 获取购物车实例
*/
private function findCart()
{
$id = Yii::$app->request->getQueryParam('id');
return Cart::find()
->where(['id' => $id])
->andWhere(['user_id' => Yii::$app->user->getId()])
->one();
}
}

114
api/logic/Helper.php

@ -0,0 +1,114 @@
<?php
namespace api\logic;
use antgoods\goods\models\ars\Goods;
use antgoods\goods\models\ars\GoodsAttr;
use antgoods\goods\models\ars\GoodsSku;
use yii\di\Instance;
use yii\helpers\Url;
use yii\web\BadRequestHttpException;
use yii\web\NotFoundHttpException;
use Yii;
/**
* @author iron
* @email weiriron@gmail.com
* Class Helper
* @package api\logic
*/
class Helper
{
/**
* @param $array
* @return string
*/
public static function errorMessageStr($array): string
{
$data = [];
foreach ($array as $k => $v) {
$data[] = implode(' ', $v);
}
return implode(' ', $data);
}
/**
* @param $goodsId
* @param $count
* @param null $skuId
* @throws BadRequestHttpException
* @throws NotFoundHttpException
* 判断库存
*/
public static function checkStock($goodsId, $count, $skuId = null)
{
$sku = GoodsSku::findOne($skuId);
$goods = Goods::findOne($goodsId);
if (!$goods) {
throw new NotFoundHttpException('商品未找到');
}
if (!$sku && $goods->stock == Goods::UNLIMITED_STOCK) {
return;
}
$stock = $sku ? $sku->stock : $goods->stock;
if ($stock < $count) {
throw new BadRequestHttpException("商品{$goods->name}库存不足");
}
return;
}
public static function createdResponse($model, $view)
{
$response = Yii::$app->getResponse()->setStatusCode(201);
$id = implode(',', array_values($model->getPrimaryKey(true)));
$response->getHeaders()->set('Location', Url::toRoute([$view, 'id' => $id], true));
}
/**
* @param $goodsId
* @param $skuId
* @return int
* @throws NotFoundHttpException
* 计算商品价格
*/
public static function countPrice($goodsId, $skuId)
{
$goods = Goods::findOne($goodsId);
if (!$goods) {
throw new NotFoundHttpException('商品未找到');
}
$price = $goods->price;
$sku = GoodsSku::findOne($skuId);
if ($sku) {
$price = $sku->price;
}
return $price;
}
/**
* @param $skuId
* @return string
* @throws NotFoundHttpException
*/
public static function skuValue($skuId)
{
$sku = GoodsSku::findOne($skuId);
if ($sku) {
return '';
}
$data = [];
$goodsAttr = array_filter(explode(',', $sku->goods_attr));
if (empty($goodsAttr)) {
throw new NotFoundHttpException('sku无对应商品属性');
}
foreach ($goodsAttr as $k => $v) {
$attr = GoodsAttr::findOne($v);
if (!$attr) {
throw new NotFoundHttpException('商品属性未找到');
}
$data[] = $attr->attr_value;
}
return implode(',', $data);
}
}

349
api/logic/OrderLogic.php

@ -0,0 +1,349 @@
<?php
namespace api\logic;
use antgoods\goods\models\ars\Goods;
use antgoods\goods\models\ars\GoodsSku;
use common\models\ars\Address;
use common\models\ars\Cart;
use common\models\ars\Order;
use common\models\ars\OrderGoods;
use common\models\ars\TakingSite;
use yii\base\Component;
use Yii;
use yii\base\ErrorException;
use yii\db\ActiveRecord;
use yii\db\Exception;
use yii\helpers\Url;
use yii\web\BadRequestHttpException;
use yii\web\NotFoundHttpException;
use yii\web\ServerErrorHttpException;
/**
* @author iron
* @email weiriron@gmail.com
* Class CartLogic
* @package api\logic
*/
class OrderLogic extends Component
{
/*创建途径类型*/
const TYPE_ADD_GOODS_PURCHASE = 1;
const TYPE_ADD_GOODS_CART = 2;
/*订单操作类型*/
const TYPE_CONFIRM = 1;
const TYPE_CANCEL = 2;
const TYPE_TAKE = 3;
const TYPE_CHANGE_SHIPPING_TYPE = 4;
const TYPE_CHANGE_ADDRESS = 5;
const TYPE_CHANGE_TAKING_SITE = 6;
/*仓库类型*/
const TYPE_ADD_STOCK = 1;
const TYPE_SUB_STOCK = -1;
/**
* @param $data
* @return bool|\Exception|\yii\base\Exception
*/
public function update($data)
{
$type = Yii::$app->request->getQueryParam('type');
$order = $this->findOrder();
$tra = Yii::$app->db->beginTransaction();
try {
switch ($type) {
case self::TYPE_CONFIRM :
$this->confirm($order, $data);
break;
case self::TYPE_CANCEL:
$this->cancel($order);
break;
case self::TYPE_TAKE:
$this->take($order);
break;
case self::TYPE_CHANGE_SHIPPING_TYPE:
$this->updateShippingType($order, $data);
break;
case self::TYPE_CHANGE_ADDRESS:
$this->changeAddress($order, $data);
break;
case self::TYPE_CHANGE_TAKING_SITE:
$this->changeTakingSite($order, $data);
break;
}
if (!$order->save()) {
throw new ServerErrorHttpException('服务器更新订单失败');
}
$tra->commit();
return true;
} catch (\yii\base\Exception $e) {
$tra->rollBack();
return $e;
}
}
/**
* @param Order $order
* @param array $data
* @throws BadRequestHttpException
* @throws NotFoundHttpException
*/
private function changeAddress($order, $data)
{
if (!isset($data['address_id'])) {
throw new BadRequestHttpException('无效参数');
}
if ($order->shipping_type !== Order::SHIPPING_TYPE_EXPRESS) {
throw new BadRequestHttpException('配送方式异常');
}
$address = Address::find()
->where(['id' => $data['address_id'], 'user_id' => Yii::$app->user->getId()])
->one();
if (!$address) {
throw new NotFoundHttpException('收货地址未找到');
}
$order->consignee = $address->consignee;
$order->phone = $address->phone;
$order->city = $address->city;
$order->area = $address->area;
$order->province = $address->province;
$order->address = $address->address;
}
/**
* @param Order $order
* @param array $data
* @throws BadRequestHttpException
* @throws NotFoundHttpException
*/
private function changeTakingSite($order, $data)
{
if (!isset($data['taking_site_id']) || empty($data['taking_site_id'])) {
throw new BadRequestHttpException('无效参数');
}
if ($order->shipping_type !== Order::SHIPPING_TYPE_PICKED_UP) {
throw new BadRequestHttpException('配送方式异常');
}
$site = TakingSite::findOne($data['taking_site_id']);
if (!$site) {
throw new NotFoundHttpException('自提点未找到');
}
$order->taking_site = $data['taking_site_id'];
}
/**
* @param Order $order
* @param array $data
* @throws BadRequestHttpException
*/
private function updateShippingType($order, $data)
{
if (!isset($data['shipping_type'])) {
throw new BadRequestHttpException('无效参数');
}
if ($order->status !== Order::STATUS_UNCONFIRMED) {
throw new BadRequestHttpException('订单状态异常');
}
$order->shipping_type = $data['shipping_type'];
}
/**
* @param Order $order
* @param array $data
* @throws BadRequestHttpException
* @throws NotFoundHttpException
* @throws ServerErrorHttpException
*/
private function confirm($order, $data)
{
if ($order->status !== Order::STATUS_UNCONFIRMED) {
throw new BadRequestHttpException('订单状态异常');
}
if ($order->shipping_type === Order::SHIPPING_TYPE_PICKED_UP) {
if (!isset($data['consignee']) || !isset($data['phone'])
|| empty($data['consignee']) || empty($data['phone'])) {
throw new BadRequestHttpException('(联系人)参数无效');
}
}
if (isset($data['remarks'])) {
$order->remarks = $data['remarks'];
}
$order->status = Order::STATUS_NONPAYMENT;
$this->updateStock($order, self::TYPE_SUB_STOCK);
}
/**
* @param Order $order
* @throws BadRequestHttpException
* @throws NotFoundHttpException
* @throws ServerErrorHttpException
*/
private function cancel($order)
{
if ($order->status !== Order::STATUS_NONPAYMENT) {
throw new BadRequestHttpException('订单状态异常');
}
$order->status = Order::STATUS_CANCEL;
$this->updateStock($order, self::TYPE_ADD_STOCK);
}
/**
* @param Order $order
* @throws BadRequestHttpException
*/
private function take($order)
{
if ($order->status !== Order::STATUS_SHIPMENT_ALL) {
throw new BadRequestHttpException('订单状态异常');
}
$order->status = Order::STATUS_FINISH;
}
/**
* @param $id
* @param $type
* @throws BadRequestHttpException
* @throws NotFoundHttpException
* @throws ServerErrorHttpException
*/
private function updateStock($id, $type)
{
$allOrderGoods = $this->findOrderGoods($id);
foreach ($allOrderGoods as $orderGoods) {
/*检查库存*/
Helper::checkStock($orderGoods->goods_id, $orderGoods->goods_count, $orderGoods->sku_id);
if ($orderGoods->sku_id) {
$goods = GoodsSku::findOne($orderGoods->sku_id);
} else {
$goods = Goods::findOne($orderGoods->goods_id);
}
if ($type) {
$count = $orderGoods->goods_count;
} else {
$count = -$orderGoods->goods_count;
}
if (!$goods->updateCounters(['stock' => $count])) {
throw new ServerErrorHttpException('更新库存失败');
}
}
}
/**
* @param $originId
* @param $count
* @param $skuId
* @return \Exception|bool;
* @throws BadRequestHttpException
* @throws NotFoundHttpException
* 创建订单并添加商品
*/
public function addGoods($originId, $count, $skuId)
{
$type = Yii::$app->request->getQueryParam('type');
if (($type === self::TYPE_ADD_GOODS_CART && empty($originId)) ||
($type == self::TYPE_ADD_GOODS_PURCHASE && empty($count) && empty($originId))) {
throw new BadRequestHttpException('无效参数');
}
if ($type === self::TYPE_ADD_GOODS_PURCHASE) {
$goodsId = $originId;
} else {
$cart = Cart::findOne($originId);
if (!$cart) {
throw new NotFoundHttpException('购物车未找到');
}
$goodsId = $cart->goods_id;
$skuId = $cart->sku_id;
$count = $cart->goods_count;
}
/*检查库存*/
Helper::checkStock($goodsId, $count, $skuId);
$tra = Yii::$app->db->beginTransaction();
try {
$order = new Order();
$order->type = Order::TYPE_SHOPPING;
if ($order->save()) {
throw new ServerErrorHttpException('服务器创建订单失败');
}
$this->createOrderGoods($order->id, $goodsId, $skuId, $count);/*创建订单商品*/
$this->saveGoodsInfo($order);/*保存订单商品信息*/
$tra->commit();
return true;
} catch (\Exception $e) {
$tra->rollBack();
return $e;
}
}
/**
* @param Order $order
* @throws ServerErrorHttpException
*/
private function saveGoodsInfo($order)
{
$orderGoods = $this->findOrderGoods($order->id);
foreach ($orderGoods as $goods) {
$order->goods_amount += $goods->price;
$order->goods_count += $goods->goods_count;
}
if (!$order->save()) {
throw new ServerErrorHttpException('服务器创建订单失败');
}
}
/**
* @param int $id
* @param int $goodsId
* @param int $skuId
* @param int $count
* @throws NotFoundHttpException
* @throws ServerErrorHttpException
* 创建订单商品
*/
private function createOrderGoods($id, $goodsId, $skuId, $count)
{
$goods = Goods::findOne($goodsId);
if (!$goods) {
throw new NotFoundHttpException('商品未找到');
}
$orderGoods = new OrderGoods();
$orderGoods->order_id = $id;
$orderGoods->goods_id = $skuId;
$orderGoods->sku_value = Helper::skuValue($skuId);
$orderGoods->goods_count = $count;
$orderGoods->goods_img = $goods->image;
$orderGoods->goods_name = $goods->name;
$orderGoods->price = Helper::countPrice($goodsId, $skuId);
if (!$orderGoods->save()) {
throw new ServerErrorHttpException('服务器创建订单商品失败');
}
}
/**
* @return array|Order|null
* 获取订单
*/
private function findOrder()
{
$id = Yii::$app->request->getQueryParam('id');
return Order::find()
->where(['id' => $id])
->andWhere(['user_id' => Yii::$app->user->getId()])
->one();
}
/**
* @param $id
* @return array|ActiveRecord[]|OrderGoods[]
*/
private function findOrderGoods($id)
{
return OrderGoods::find()
->where(['order_id' => $id])
->all();
}
}

6
backend/config/main.php

@ -58,8 +58,8 @@ return [
'file' => ['class' => 'backend\logic\file\FileManager'], 'file' => ['class' => 'backend\logic\file\FileManager'],
'goods' => ['class' => 'antgoods\goods\logic\goods\GoodsManager'], 'goods' => ['class' => 'antgoods\goods\logic\goods\GoodsManager'],
], ],
'as access' => [
'class' => 'iron\components\AccessControl',
],
// 'as access' => [
// 'class' => 'iron\components\AccessControl',
// ],
'params' => $params, 'params' => $params,
]; ];

17
backend/controllers/OrderController.php

@ -2,9 +2,11 @@
namespace backend\controllers; namespace backend\controllers;
use antgoods\goods\models\ars\Goods;
use Yii; use Yii;
use common\models\ars\Order; use common\models\ars\Order;
use common\models\searchs\OrderSearch; use common\models\searchs\OrderSearch;
use yii\debug\components\search\matchers\GreaterThanOrEqual;
use yii\web\Controller; use yii\web\Controller;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter; use yii\filters\VerbFilter;
@ -42,7 +44,7 @@ class OrderController extends Controller
'searchModel' => $searchModel, 'searchModel' => $searchModel,
'dataProvider' => $dataProvider, 'dataProvider' => $dataProvider,
'columns' => $searchModel->columns() 'columns' => $searchModel->columns()
]);
]);
} }
/** /**
@ -125,24 +127,25 @@ class OrderController extends Controller
throw new NotFoundHttpException('The requested page does not exist.'); throw new NotFoundHttpException('The requested page does not exist.');
} }
/** /**
* @author iron
* 文件导出
*/
* @author iron
* 文件导出
*/
public function actionExport() public function actionExport()
{ {
$searchModel = new OrderSearch(); $searchModel = new OrderSearch();
$params = Yii::$app->request->queryParams; $params = Yii::$app->request->queryParams;
if ($params['page-type'] == 'all') { if ($params['page-type'] == 'all') {
$dataProvider = $searchModel->allData($params);
$dataProvider = $searchModel->allData($params);
} else { } else {
$dataProvider = $searchModel->search($params); $dataProvider = $searchModel->search($params);
} }
\iron\widget\Excel::export([
\iron\widget\Excel::export([
'models' => $dataProvider->getModels(), 'models' => $dataProvider->getModels(),
'format' => 'Xlsx', 'format' => 'Xlsx',
'asAttachment' => true, 'asAttachment' => true,
'fileName' =>'Orders'. "-" .date('Y-m-d H/i/s', time()),
'fileName' => 'Orders' . "-" . date('Y-m-d H/i/s', time()),
'columns' => $searchModel->columns() 'columns' => $searchModel->columns()
]); ]);
} }

1
backend/controllers/SiteController.php

@ -2,6 +2,7 @@
namespace backend\controllers; namespace backend\controllers;
use antgoods\goods\models\ars\Goods;
use Yii; use Yii;
use yii\base\NotSupportedException; use yii\base\NotSupportedException;
use yii\web\Controller; use yii\web\Controller;

3
backend/web/css/site.css

@ -53,4 +53,7 @@
body::-webkit-scrollbar{ body::-webkit-scrollbar{
width: 1px; width: 1px;
height: 1px; height: 1px;
}
body{
margin:10px;
} }

59
common/models/ars/Order.php

@ -37,6 +37,23 @@ use yii\behaviors\TimestampBehavior;
*/ */
class Order extends \yii\db\ActiveRecord class Order extends \yii\db\ActiveRecord
{ {
const TYPE_SHOPPING = 1;//普通购物订单
const SHIPPING_TYPE_VIRTUAL_GOODS = 0;//虚拟货物
const SHIPPING_TYPE_PICKED_UP = 1;//自提
const SHIPPING_TYPE_EXPRESS = 2;//快递物流
const STATUS_UNCONFIRMED = 0;
const STATUS_NONPAYMENT = 1;
const STATUS_CANCEL = 2;
const STATUS_PAYMENT_TO_BE_CONFIRMED = 3;
const STATUS_TO_BE_SHIPPING = 6;
const STATUS_APPLY_REFUND = 4;
const STATUS_REFUND = 5;
const STATUS_SHIPMENT_ALL = 7;
const STATUS_SHIPMENT_PORTION = 8;
const STATUS_FINISH = 9;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
@ -45,6 +62,14 @@ class Order extends \yii\db\ActiveRecord
return 'ats_order'; return 'ats_order';
} }
public function fields()
{
$fields = parent::fields();
unset($fields['user_id']);
unset($fields['payment_sn']);
return $fields;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
@ -96,15 +121,33 @@ class Order extends \yii\db\ActiveRecord
'created_at' => '创建时间', 'created_at' => '创建时间',
]; ];
} }
public function beforeSave($insert)
{
if ($this->status === self::STATUS_UNCONFIRMED && $this->type == self::TYPE_SHOPPING) {
$this->shipping_amount = $this->countShippingAmount();
$this->receivables = $this->goods_amount + $this->shipping_amount;
$this->payment_amount = $this->receivables - $this->discount_amount;
}
return parent::beforeSave($insert);
}
private function countShippingAmount()
{
//TODO 根据运费模板计算运费
if ($this->shipping_type !== Order::SHIPPING_TYPE_EXPRESS) {
return 0;
}
return 0;
}
/** /**
* @author linyao
* @email 602604991@qq.com
* @created Nov 8, 2019
*
* 行为存储创建时间和更新时间
*/
* @author linyao
* @email 602604991@qq.com
* @created Nov 8, 2019
*
* 行为存储创建时间和更新时间
*/
public function behaviors() public function behaviors()
{ {
return [ return [
@ -112,7 +155,7 @@ class Order extends \yii\db\ActiveRecord
'class' => TimestampBehavior::className(), 'class' => TimestampBehavior::className(),
'createdAtAttribute' => 'created_at', 'createdAtAttribute' => 'created_at',
'updatedAtAttribute' => 'updated_at', 'updatedAtAttribute' => 'updated_at',
'value' => function() {
'value' => function () {
return time(); return time();
}, },
], ],

21
vendor/antgoods/goods/src/models/ars/Goods.php

@ -60,6 +60,8 @@ class Goods extends \yii\db\ActiveRecord
self::IS_SALE_NO => '否', self::IS_SALE_NO => '否',
self::IS_SALE_YES => '是' self::IS_SALE_YES => '是'
]; ];
//无限库存
const UNLIMITED_STOCK = -1;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
@ -68,13 +70,30 @@ class Goods extends \yii\db\ActiveRecord
return 'antgoods_goods'; return 'antgoods_goods';
} }
public function fields()
{
$fields = parent::fields();
unset($fields['is_sale']);
unset($fields['sort_order']);
unset($fields['pid']);
unset($fields['cat_id']);
unset($fields['brand_id']);
unset($fields['shop_cat_id']);
unset($fields['is_delete']);
unset($fields['express_template']);
unset($fields['model_id']);
return $fields;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function rules() public function rules()
{ {
return [ return [
[['pid', 'cat_id', 'brand_id', 'shop_cat_id', 'supplier_id', 'weight', 'length', 'width', 'height', 'diameter', 'sold_count', 'limit_count', 'stock', 'stock_warn', 'market_price', 'price', 'image', 'model_id', 'is_sale', 'sort_order', 'bouns_points', 'experience_points', 'is_delete', 'express_template'], 'integer'],
[['pid', 'cat_id', 'brand_id', 'shop_cat_id', 'supplier_id', 'weight', 'length', 'width', 'height',
'diameter', 'sold_count', 'limit_count', 'stock', 'stock_warn', 'market_price', 'price', 'image',
'model_id', 'is_sale', 'sort_order', 'bouns_points', 'experience_points', 'is_delete', 'express_template'], 'integer'],
[['cat_id', 'brand_id', 'shop_cat_id', 'name'], 'required'], [['cat_id', 'brand_id', 'shop_cat_id', 'name'], 'required'],
[['sn'], 'checkExist'], [['sn'], 'checkExist'],
[['description', 'coverImageId', 'detailImageId'], 'string'], [['description', 'coverImageId', 'detailImageId'], 'string'],

1
vendor/antgoods/goods/src/models/searchs/GoodsSearch.php

@ -180,7 +180,6 @@ class GoodsSearch extends Goods
'created_at' => $this->created_at, 'created_at' => $this->created_at,
'updated_at' => $this->updated_at, 'updated_at' => $this->updated_at,
]); ]);
$query->andFilterWhere(['like', 'name', $this->name]) $query->andFilterWhere(['like', 'name', $this->name])
->andFilterWhere(['like', 'sn', $this->sn]) ->andFilterWhere(['like', 'sn', $this->sn])
->andFilterWhere(['like', 'code', $this->code]) ->andFilterWhere(['like', 'code', $this->code])

8
vendor/iron/grid/GridView.php

@ -219,13 +219,13 @@ class GridView extends BaseListView
<div class="row"> <div class="row">
<div class="col-sm-12 col-md-6"> <div class="col-sm-12 col-md-6">
{batch} {batch}
<a href="{url}/create" class="btn btn-default"><i class="fas fa-plus-square mr-2"></i>添加</a>
<a href="{url}create" class="btn btn-default"><i class="fas fa-plus-square mr-2"></i>添加</a>
<!-- <a href="#" data-url='export' class="export btn btn-default"><i class="fa fa-file-excel-o"></i>导出</a>--> <!-- <a href="#" data-url='export' class="export btn btn-default"><i class="fa fa-file-excel-o"></i>导出</a>-->
<div class="btn-group"> <div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false"><i class="fas fa-file-upload mr-2"></i>导出</button> <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false"><i class="fas fa-file-upload mr-2"></i>导出</button>
<ul class="dropdown-menu" role="menu"> <ul class="dropdown-menu" role="menu">
<li> <a class="dropdown-item export-page" href="#" data-url="{url}/export">本页</a></li>
<li> <a class="dropdown-item export-all" href="#" data-url="{url}/export">全部</a></li>
<li> <a class="dropdown-item export-page" href="#" data-url="{url}export">本页</a></li>
<li> <a class="dropdown-item export-all" href="#" data-url="{url}export">全部</a></li>
</ul> </ul>
</div> </div>
<!-- <button type="button" id="export" class="btn btn-default"><i class="fa fa-file-excel-o"></i>导出</button>--> <!-- <button type="button" id="export" class="btn btn-default"><i class="fa fa-file-excel-o"></i>导出</button>-->
@ -446,7 +446,7 @@ SCRIPT;
case '{batch}': case '{batch}':
return $this->renderBatch(); return $this->renderBatch();
case '{url}': case '{url}':
return Yii::$app->request->url;
return strpos(Yii::$app->request->url,'index') ?'': Yii::$app->request->url.'/';
default: default:
return false; return false;
} }

Loading…
Cancel
Save