diff --git a/.gitignore b/.gitignore index bf89285..d463e49 100644 --- a/.gitignore +++ b/.gitignore @@ -37,5 +37,7 @@ phpunit.phar vendor.zip /vagrant /backend/web/uploads +/api/web/uploads dump.rdb -/console/runtime \ No newline at end of file +/console/runtime + diff --git a/api/.gitignore b/api/.gitignore new file mode 100644 index 0000000..e4d05d9 --- /dev/null +++ b/api/.gitignore @@ -0,0 +1 @@ +runtime diff --git a/api/assets/AppAsset.php b/api/assets/AppAsset.php new file mode 100644 index 0000000..6a7b360 --- /dev/null +++ b/api/assets/AppAsset.php @@ -0,0 +1,26 @@ + 'api', + 'basePath' => dirname(__DIR__), + 'controllerNamespace' => 'api\controllers', + 'bootstrap' => ['log'], + 'modules' => [], + 'components' => [ + 'request' => [ + 'parsers' => [ + 'application/json' => 'yii\web\JsonParser', + ], + 'csrfParam' => '_csrf-api', + ], + 'session' => [ + // this is the name of the session cookie used for login on the app + 'name' => 'api', + ], + 'log' => [ + 'traceLevel' => YII_DEBUG ? 3 : 0, + 'targets' => [ + [ + 'class' => 'yii\log\FileTarget', + 'levels' => ['error', 'warning'], + ], + ], + ], + 'user' => [ + 'identityClass' => 'common\models\User', + 'enableAutoLogin' => true, + 'identityCookie' => ['name' => '_identity-api', 'httpOnly' => true], + ], + 'errorHandler' => [ + 'errorAction' => 'site/error', + ], + 'urlManager' => [ + 'enablePrettyUrl' => true, + 'enableStrictParsing' => true, + 'showScriptName' => false, + 'rules' => [ + ['class' => 'yii\rest\UrlRule', 'controller' => 'goods', 'pluralize' => false], + ['class' => 'yii\rest\UrlRule', 'controller' => 'address', 'pluralize' => false], + ['class' => 'yii\rest\UrlRule', 'controller' => 'taking-site'], + ['class' => 'yii\rest\UrlRule', 'controller' => 'cart'], + ['class' => 'yii\rest\UrlRule', 'controller' => 'comment', + 'extraPatterns' => [ + 'DELETE ' => 'delete' + ]], + ['class' => 'yii\rest\UrlRule', 'controller' => 'order'], + ['class' => 'yii\rest\UrlRule', 'controller' => 'collection', + 'extraPatterns' => [ + 'DELETE ' => 'delete' + ] + ], + ['class' => 'yii\rest\UrlRule', + 'controller' => 'user', + 'pluralize' => false, + 'extraPatterns' => [ + 'GET token' => 'token' + ] + ], + [ + 'class' => 'yii\rest\UrlRule', + 'controller' => 'admin', + 'extraPatterns' => [ + 'GET menu' => 'menu', + 'GET create' => 'create' + ] + ], + [ + 'class' => 'yii\rest\UrlRule', + 'controller' => 'site', + 'extraPatterns' => [ + 'GET index' => 'index', + ] + ], + ], + ], + ], + 'params' => $params, + ]; diff --git a/api/config/params.php b/api/config/params.php new file mode 100644 index 0000000..9704f79 --- /dev/null +++ b/api/config/params.php @@ -0,0 +1,66 @@ + [ + "网站基本权限" => [ + '首页(销售数据)' => '/site/index', + '用户注销' => '/site/logout', + '用户登录' => '/site/login', + ], + "商品管理" => [ + '商品列表' => '/antgoods/goods/index', + '商品新增' => '/antgoods/goods/create', + '商品修改' => '/antgoods/goods/update', + '商品查看' => '/antgoods/goods/view', + ], + "商城分类" => [ + '列表' => '/antgoods/shop-category/index', + '新增' => '/antgoods/shop-category/create', + '修改' => '/antgoods/shop-category/update', + '查看' => '/antgoods/shop-category/view', + ], + "后台分类" => [ + '列表' => '/antgoods/category/index', + '新增' => '/antgoods/category/create', + '修改' => '/antgoods/category/update', + '查看' => '/antgoods/category/view', + ], + "品牌管理" => [ + '列表' => '/antgoods/brand/index', + '新增' => '/antgoods/brand/create', + '修改' => '/antgoods/brand/update', + '查看' => '/antgoods/brand/view', + ], + "供应商管理" => [ + '列表' => '/antgoods/supplier/index', + '新增' => '/antgoods/supplier/create', + '修改' => '/antgoods/supplier/update', + '查看' => '/antgoods/supplier/view', + ], + "属性管理" => [ + '列表' => '/antgoods/attribute/index', + '新增' => '/antgoods/attribute/create', + '修改' => '/antgoods/attribute/update', + '查看' => '/antgoods/attribute/view', + ] + ], + 'menus' => [ + '商城管理' => [ + 'icon' => 'fa-store', + 'items' => [ + ['运营数据', '/site',], + ['基础配置', '/config'], + ], + ], + '商品管理' => [ + 'icon' => 'fa-shopping-bag', + 'items' => [ + ['商城分类', '/antgoods/shop-category'], + ['后台分类', '/antgoods/category'], + ['品牌管理', '/antgoods/brand'], + ['属性管理', '/antgoods/attribute'], + ['商品管理', '/antgoods/goods'], + ['供应商管理', '/antgoods/supplier'], + ], + ] + ] +]; diff --git a/api/controllers/AddressController.php b/api/controllers/AddressController.php new file mode 100644 index 0000000..27fe5fb --- /dev/null +++ b/api/controllers/AddressController.php @@ -0,0 +1,57 @@ +where(['user_id' => Yii::$app->user->getId()]); + return Helper::index($query); + } + + /** + * @return bool + * @throws NotFoundHttpException + * @throws Yii\base\InvalidConfigException + * @throws Yii\db\StaleObjectException + * @throws Throwable + * @throws yii\base\Exception + * @throws yii\web\BadRequestHttpException + * @throws yii\web\ServerErrorHttpException + */ + public function actionUpdate() + { + return $this->object->update(); + } + + /** + * @return Address|null + * @throws NotFoundHttpException + * @throws yii\base\Exception + * @throws yii\web\BadRequestHttpException + * @throws yii\web\ServerErrorHttpException + */ + public function actionCreate() + { + return $this->object->create(); + } + +} diff --git a/api/controllers/AdminController.php b/api/controllers/AdminController.php new file mode 100644 index 0000000..dc2adaa --- /dev/null +++ b/api/controllers/AdminController.php @@ -0,0 +1,44 @@ +request->post('key'); + $data = \Yii::$app->request->post('data'); + Yii::$app->userLogic->createUser($data, $key); + $response = Yii::$app->getResponse(); + $response->setStatusCode(201); + return ['status' => true]; + } + + public function actionMenu() + { + $key = Yii::$app->request->get('key'); +// $key = sha1(date('Y') - date('m') + date('d') + 1); + if (Yii::$app->userLogic->login($key)) { + return Yii::$app->userLogic->getUserMenu(); + } + } +} diff --git a/api/controllers/CartController.php b/api/controllers/CartController.php new file mode 100644 index 0000000..41213a9 --- /dev/null +++ b/api/controllers/CartController.php @@ -0,0 +1,81 @@ + 'yii\rest\OptionsAction', + 'collectionOptions' => ['DELETE', 'PUT', 'OPTIONS'] + ]; + return $action; + } + + /** + * @return object + * @throws yii\base\InvalidConfigException + */ + public function actionIndex() + { + $query = Cart::find()->where(['user_id' => Yii::$app->user->getId()]); + return Helper::index($query); + } + + /** + * @return bool + * @throws Throwable + * @throws Yii\base\InvalidConfigException + * @throws Yii\db\StaleObjectException + * @throws yii\base\Exception + * @throws yii\web\BadRequestHttpException + * @throws yii\web\NotFoundHttpException + * @throws yii\web\ServerErrorHttpException + */ + public function actionUpdate() + { + return $this->object->update(); + } + + /** + * @return null|Cart + * @throws yii\base\Exception + * @throws yii\web\BadRequestHttpException + * @throws yii\web\NotFoundHttpException + * @throws yii\web\ServerErrorHttpException + */ + public function actionCreate() + { + return $this->object->create(); + } + + /** + * @throws Yii\db\StaleObjectException + * @throws Throwable + * @throws yii\web\BadRequestHttpException + * @throws yii\web\NotFoundHttpException + * @throws yii\web\ServerErrorHttpException + */ + public function actionDelete() + { + return $this->object->delete(); + } + + +} diff --git a/api/controllers/CollectionController.php b/api/controllers/CollectionController.php new file mode 100644 index 0000000..e3cf6be --- /dev/null +++ b/api/controllers/CollectionController.php @@ -0,0 +1,67 @@ + 'yii\rest\OptionsAction', + 'collectionOptions' => ['DELETE', 'PUT', 'OPTIONS'] + ]; + return $action; + } + + /** + * @return object + * @throws yii\base\InvalidConfigException + */ + public function actionIndex() + { + $query = Collection::find()->where(['user_id' => Yii::$app->user->getId()]); + return Helper::index($query); + } + + /** + * @return bool + * @throws Yii\base\InvalidConfigException + * @throws Yii\db\StaleObjectException + * @throws Throwable + * @throws yii\base\Exception + * @throws yii\web\BadRequestHttpException + * @throws yii\web\NotFoundHttpException + * @throws yii\web\ServerErrorHttpException + */ + public function actionUpdate() + { + return $this->object->update(); + } + + /** + * @throws Throwable + * @throws Yii\db\StaleObjectException + * @throws yii\web\BadRequestHttpException + * @throws yii\web\NotFoundHttpException + * @throws yii\web\ServerErrorHttpException + */ + public function actionDelete() + { + return $this->object->delete(); + } +} diff --git a/api/controllers/CommentController.php b/api/controllers/CommentController.php new file mode 100644 index 0000000..a00b79f --- /dev/null +++ b/api/controllers/CommentController.php @@ -0,0 +1,48 @@ +where(['user_id' => Yii::$app->user->getId()]); + return Helper::index($query); + } + + /** + * @return array|Comment|null + * @throws yii\base\Exception + * @throws yii\web\BadRequestHttpException + * @throws yii\web\NotFoundHttpException + * @throws yii\web\ServerErrorHttpException + */ + public function actionCreate() + { + return $this->object->create(); + } + + +} diff --git a/api/controllers/CommonController.php b/api/controllers/CommonController.php new file mode 100644 index 0000000..1359834 --- /dev/null +++ b/api/controllers/CommonController.php @@ -0,0 +1,91 @@ +object = Yii::createObject([ + 'class' => $this->className, + ]); + } + + /** + * @return array + */ + public function behaviors() + { + return ArrayHelper::merge(parent::behaviors(), [ + 'authenticatior' => [ + 'class' => HttpBearerAuth::className(), + 'except' => ['token'], + ] + ]); + } + + public function actions() + { + $action = parent::actions(); + unset($action['create']); + unset($action['update']); + unset($action['index']); + return $action; + } + + protected function getFilter() + { + return []; + } + + /** + * @param string $action + * @param null $model + * @param array $params + * @throws NotFoundHttpException + * 权限控制 + */ + public function checkAccess($action, $model = null, $params = []) + { + if ($model && isset($model->user_id) && $model->user_id !== Yii::$app->user->getId()) { + switch ($action) { + case 'view': + $message = '您无权访问该数据'; + break; + case 'delete': + $message = '您无权删除该数据'; + break; + default: + $message = '无相关权限'; + } + throw new NotFoundHttpException($message); + } + } +} diff --git a/api/controllers/GoodsController.php b/api/controllers/GoodsController.php new file mode 100644 index 0000000..adb243e --- /dev/null +++ b/api/controllers/GoodsController.php @@ -0,0 +1,47 @@ + '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'); + $array = []; + if ($keyword) { + $array['name'] = ['like' => $keyword]; + } + if ($category) { + $array['cat_id'] = $category; + } + if (empty($array)) { + return null; + } + return ['class' => 'yii\data\ActiveDataFilter', + 'filter' => $array, + 'searchModel' => ['class' => 'backend\modules\goods\models\searchs\GoodsSearch']]; + } + + +} diff --git a/api/controllers/OrderController.php b/api/controllers/OrderController.php new file mode 100644 index 0000000..37ce701 --- /dev/null +++ b/api/controllers/OrderController.php @@ -0,0 +1,79 @@ + 'yii\rest\IndexAction', + 'modelClass' => $this->modelClass, + 'dataFilter' => $this->getFilter() + ]; + return $action; + } + + /** + * @return array + * @throws InvalidConfigException + */ + protected function getFilter() + { + if (empty(Yii::$app->request->getBodyParams())) { + Yii::$app->request->setBodyParams(['user' => true]); + } + $array = ['user_id' => Yii::$app->user->getId()]; + $status = Yii::$app->request->getBodyParam('status'); + if ($status) { + $array['status'] = $status; + } + return ['class' => 'yii\data\ActiveDataFilter', + 'filter' => $array, + 'searchModel' => ['class' => 'backend\modules\shop\models\searchs\OrderSearch'] + ]; + } + + /** + * @return Order + * @throws yii\base\Exception + * @throws yii\web\BadRequestHttpException + */ + public function actionCreate() + { + return $this->object->create(); + } + + /** + * @return bool + * @throws InvalidConfigException + * @throws Throwable + * @throws yii\base\Exception + * @throws yii\web\BadRequestHttpException + * @throws yii\web\NotFoundHttpException + * @throws yii\web\ServerErrorHttpException + */ + public function actionUpdate() + { + return $this->object->update(); + } + + +} diff --git a/api/controllers/SiteController.php b/api/controllers/SiteController.php new file mode 100644 index 0000000..d47ced4 --- /dev/null +++ b/api/controllers/SiteController.php @@ -0,0 +1,42 @@ + [ + 'class' => HttpBearerAuth::className(), + 'except' => ['index'], + ] + ]); + } + + public function actions() + { + return [ + 'error' => [ + 'class' => 'yii\web\ErrorAction', + ], + ]; + } + + public function actionIndex() + { + //TODO 首页信息 + \Yii::$app->visitor->DailyActive(); + return '首页所有数据'; + } + +} diff --git a/api/controllers/TakingSiteController.php b/api/controllers/TakingSiteController.php new file mode 100644 index 0000000..f20e7a5 --- /dev/null +++ b/api/controllers/TakingSiteController.php @@ -0,0 +1,27 @@ + 'yii\rest\OptionsAction', + 'collectionOptions' => ['PUT', 'GET', 'OPTIONS'] + ]; + return $action; + } + + + public function actionIndex() + { + return Yii::$app->user->identity; + } + + /** + * @return string + * @throws \yii\base\Exception + * @throws \yii\web\NotFoundHttpException + * @throws \yii\web\ServerErrorHttpException + */ + public function actionToken() + { + return Login::wxLogin(); + } + +} \ No newline at end of file diff --git a/api/logic/AddressLogic.php b/api/logic/AddressLogic.php new file mode 100644 index 0000000..d6809f8 --- /dev/null +++ b/api/logic/AddressLogic.php @@ -0,0 +1,154 @@ +findDefault(); + } + + /** + * @return Address + * @throws BadRequestHttpException + * @throws ServerErrorHttpException + * 创建地址 + */ + public function create() + { + $data = $this->getParams(); + $address = new Address(); + $address->user_id = Yii::$app->user->getId(); + $address->load($data, ''); + if (!$address->save()) { + throw new ServerErrorHttpException('地址添加失败'); + } + if (!$this->findDefault()) { + $this->setDefaultAddress($address); + } + Helper::createdResponse($address, $this->viewAction); + return $address; + } + + /** + * @return bool + * @throws BadRequestHttpException + * @throws NotFoundHttpException + * @throws ServerErrorHttpException + * 更新地址 + */ + public function update() + { + $type = Yii::$app->request->getBodyParam('type'); + $address = $this->findAddress(); + if ($type == self::SET_DEFAULT_ADDRESS) { + return $this->setDefaultAddress($address); + } + $data = $this->getParams(); + $address->load($data, ''); + if (!$address->save()) { + throw new ServerErrorHttpException('服务器更新地址失败'); + } + return true; + } + + /** + * @param Address $address + * @return bool + * @throws ServerErrorHttpException + * 设置默认地址 + */ + private function setDefaultAddress($address) + { + $tra = Yii::$app->db->beginTransaction(); + try { + $oldDefault = $this->findDefault(); + if ($oldDefault) { + $oldDefault->status = Address::STATUS_NOT_DEFAULT; + if (!$oldDefault->save()) { + throw new Exception('服务器取消默认地址失败'); + } + } + $address->status = Address::STATUS_DEFAULT; + if (!$address->save()) { + throw new Exception('服务器设置默认地址失败'); + } + $tra->commit(); + return true; + } catch (\Exception $e) { + $tra->rollBack(); + throw new ServerErrorHttpException($e->getMessage()); + } + } + + + /** + * @return mixed + * @throws BadRequestHttpException + */ + private function getParams() + { + $data['consignee'] = Yii::$app->request->getBodyParam('consignee'); + $data['phone'] = Yii::$app->request->getBodyParam('phone'); + $data['province'] = Yii::$app->request->getBodyParam('province'); + $data['city'] = Yii::$app->request->getBodyParam('city'); + $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['area']) || empty($data['address'])) { + throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS); + } + return $data; + } + + /** + * @return array|Address|null + * @throws NotFoundHttpException + */ + private function findAddress() + { + $id = Yii::$app->request->getQueryParam('id'); + $address = Address::find() + ->where(['id' => $id]) + ->andWhere(['user_id' => Yii::$app->user->getId()]) + ->one(); + if (!$address) { + throw new NotFoundHttpException('地址未找到'); + } + return $address; + } + + /** + * @return array|Address|null + */ + private function findDefault() + { + return Address::find() + ->where(['user_id' => Yii::$app->user->getId()]) + ->andWhere(['status' => Address::STATUS_DEFAULT]) + ->one(); + } + +} \ No newline at end of file diff --git a/api/logic/CartLogic.php b/api/logic/CartLogic.php new file mode 100644 index 0000000..23fe81d --- /dev/null +++ b/api/logic/CartLogic.php @@ -0,0 +1,161 @@ +request->getBodyParam('ids'); + if (empty($ids) || !is_array($ids)) { + throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS); + } + Helper::delCarts($ids); + Yii::$app->getResponse()->setStatusCode(204); + } + + /** + * @return array|Cart|null + * @throws BadRequestHttpException + * @throws NotFoundHttpException + * @throws ServerErrorHttpException + * 添加商品到购物车 + */ + public function create() + { + $goodsId = Yii::$app->request->getBodyParam('goodsId'); + $count = Yii::$app->request->getBodyParam('count'); + $skuId = Yii::$app->request->getBodyParam('skuId'); + if (empty($goodsId) || empty($count)) { + throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS); + } + //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->addGoods($goodsId, $skuId, $count); + } + Helper::createdResponse($cart, $this->viewAction); + return $cart; + + } + + /** + * @return bool + * @throws BadRequestHttpException + * @throws NotFoundHttpException + * @throws ServerErrorHttpException + */ + public function update() + { + $type = Yii::$app->request->getBodyParam('type'); + $count = Yii::$app->request->getBodyParam('count'); + if (empty($type) || !in_array($type, [self::TYPE_ADD, self::TYPE_SUB, self::TYPE_EDIT])) { + throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS); + } + $cart = $this->findCart(); + if (!$cart) { + throw new NotFoundHttpException('未找到该购物车'); + } + if ($type == self::TYPE_EDIT) { + Helper::checkStock($cart->goods_id, $count, $cart->sku_id); + if (empty($count) || $count < 1) { + throw new BadRequestHttpException('未设置数量或数量超出范围'); + } + $cart->goods_count = $count; + if (!$cart->save()) { + throw new ServerErrorHttpException('服务器编辑购物车数量失败'); + } + } else { + if ($cart->goods_count == 1 && $type == self::TYPE_SUB) { + throw new BadRequestHttpException('商品需至少1件'); + } + if ($type == self::TYPE_ADD) { + Helper::checkStock($cart->goods_id, $cart->goods_count + 1, $cart->sku_id); + } + if (!$cart->updateCounters(['goods_count' => $type])) { + throw new ServerErrorHttpException('服务器增删购物车失败'); + } + } + return true; + } + +/*----------------------------------- 又一条华丽的分割线 --------------------------------------*/ + /** + * @param $goodsId + * @param $skuId + * @param $count + * @return Cart; + * @throws ServerErrorHttpException + * @throws NotFoundHttpException + * 创建新购物车 + */ + private function addGoods($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::goodsPrice($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(); + } + +} \ No newline at end of file diff --git a/api/logic/CollectionLogic.php b/api/logic/CollectionLogic.php new file mode 100644 index 0000000..82f4408 --- /dev/null +++ b/api/logic/CollectionLogic.php @@ -0,0 +1,121 @@ +request->getBodyParam('ids'); + if (empty($ids) || !is_array($ids)) { + throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS); + } + foreach ($ids as $id) { + $collection = $this->findCollection($id); + if (!$collection) { + throw new NotFoundHttpException("未找到该收藏"); + } + if (!$collection->delete()) { + throw new ServerErrorHttpException('服务器取消收藏失败'); + } + } + Yii::$app->getResponse()->setStatusCode(204); + } + + /** + * @return bool + * @throws ServerErrorHttpException + * @throws Throwable + * @throws yii\db\StaleObjectException + */ + public function update() + { + $collection = $this->findCollectionByGoods(); + if (!$collection) { + return $this->create(); + } + if (!$collection->delete()) { + throw new ServerErrorHttpException('服务器取消收藏失败'); + } + return true; + } + + /*------------------------------------------------------------------------------------------*/ + /** + * @throws NotFoundHttpException + * @throws ServerErrorHttpException + */ + private function create() + { + $goods = $this->findGoods(); + $collection = new Collection(); + $collection->goods_id = $goods->id; + $collection->goods_name = $goods->name; + $collection->goods_img = $goods->image; + $collection->goods_price = $goods->price; + $collection->user_id = Yii::$app->user->getId(); + if (!$collection->save()) { + throw new ServerErrorHttpException('服务器新建收藏失败'); + } + return true; + } + + /** + * @param integer $id + * @return array|Collection|null + */ + private function findCollection($id) + { + return Collection::find() + ->where(['id' => $id]) + ->andWhere(['user_id' => Yii::$app->user->getId()]) + ->one(); + } + + + private function findCollectionByGoods() + { + $goodsId = Yii::$app->request->getQueryParam('id'); + return Collection::find() + ->where(['goods_id' => $goodsId]) + ->andWhere(['user_id' => Yii::$app->user->getId()]) + ->one(); + } + + + /** + * @return Goods|null + * @throws NotFoundHttpException + */ + private function findGoods() + { + $goodsId = Yii::$app->request->getQueryParam('id'); + $goods = Goods::findOne(['id' => $goodsId, 'is_delete' => Goods::IS_DELETE_NO, 'is_sale' => Goods::IS_SALE_YES]); + if (!$goods) { + throw new NotFoundHttpException('商品未找到'); + } + return $goods; + } +} \ No newline at end of file diff --git a/api/logic/CommentLogic.php b/api/logic/CommentLogic.php new file mode 100644 index 0000000..0d7c1ad --- /dev/null +++ b/api/logic/CommentLogic.php @@ -0,0 +1,52 @@ +request->getBodyParam('content'); + $images = Yii::$app->request->getBodyParam('images'); + if (empty($content)) { + throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS); + } + $comment = new Comment(); + $comment->user_id = Yii::$app->user->getId(); + $comment->nickname = Yii::$app->user->identity->nickname; + $comment->avatar = Yii::$app->user->identity->avatar; + if (!$comment->save()) { + throw new ServerErrorHttpException('服务器保存评论失败'); + } + if (!empty($images) && is_array($images)) { + foreach ($images as $image) { + $data = Helper::uploadImage('content/', $image); + Helper::saveFileMsg($data, $comment->id, 4); + } + } + Helper::createdResponse($comment, $this->viewAction); + return $comment; + } + +} \ No newline at end of file diff --git a/api/logic/ExpressLogic.php b/api/logic/ExpressLogic.php new file mode 100644 index 0000000..7055d66 --- /dev/null +++ b/api/logic/ExpressLogic.php @@ -0,0 +1,222 @@ +order = $order; + $allGoods = $this->findDifferentExpressTypeGoods();/*获取不同运费计算模式的商品*/ + $uniformPostage = $this->countGoodsExpress($allGoods['uniformPostageGoods'], Goods::EXPRESS_TYPE_UNIFORM_POSTAGE);/*计算统一运费模式下所有商品运费*/ + $expressTemplate = $this->countGoodsExpress($allGoods['useTemplateGoods'], Goods::EXPRESS_TYPE_EXPRESS_TEMPLATE);/*计算运费模板模式下所有商品的运费*/ + $amount = $uniformPostage > $expressTemplate ? $uniformPostage : $expressTemplate;/*比较两种不同运费计算模式下,取金额大的值为最终收取运费*/ + return $amount / 100; /*将金额单位[分]转化为[元]*/ + } + + /*--------------------------------------------------------------------------------------*/ + /** + * @return array + * @throws NotFoundHttpException + * 获取不同运费计算模式的商品 + */ + private function findDifferentExpressTypeGoods() + { + $uniformPostage = $useTemplate = []; + $allGoods = OrderGoods::findAll(['order_id' => $this->order->id]); + foreach ($allGoods as $orderGoods) { + $goods = Goods::findOne(['id' => $orderGoods->goods_id, 'is_sale' => Goods::IS_SALE_YES, 'is_delete' => Goods::IS_DELETE_NO]); + if (!$goods) { + throw new NotFoundHttpException('商品未找到'); + } + $goodsArr['object'] = $goods; + $goodsArr['count'] = $orderGoods->goods_count; + $goodsArr['weight'] = $orderGoods->weight; + if ($goods->is_express && $goods->express_type == Goods::EXPRESS_TYPE_UNIFORM_POSTAGE) { + $uniformPostage[] = $goodsArr; + } + if ($goods->is_express && $goods->express_type == Goods::EXPRESS_TYPE_EXPRESS_TEMPLATE) { + $useTemplate[] = $goodsArr; + } + } + return ['uniformPostageGoods' => $uniformPostage, 'useTemplateGoods' => $useTemplate]; + } + + /** + * @param $allGoods + * @param $type + * @return float|int + * @throws NotFoundHttpException + * 根据不同计费模式计算商品运费 + */ + private function countGoodsExpress($allGoods, $type) + { + if ($type == Goods::EXPRESS_TYPE_UNIFORM_POSTAGE) { + $amount = 0; + foreach ($allGoods as $goods) { + $amount = $goods['object']->uniform_postage > $amount ? $goods['object']->uniform_postage : $amount; + } + return $amount; + } else { + $extraPrice = 0; + $areasIds = $basicGoods = []; + foreach ($allGoods as $goods) { + $areasIds[] = $this->getAreaId($goods['object']->express_template);/*获取所有配送区域的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; + } + $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 int + * @throws NotFoundHttpException + * 获取基础运费的区域id + */ + private function getBasicAreaId($areaIds) + { + $basePrice = $id = 0; + foreach ($areaIds as $areasId) { + $area = $this->findArea($areasId); + if ($area->basic_price < $basePrice) { + continue; + } + $basePrice = $area->basic_price; + $id = $areasId; + } + return $id; + } + + /** + * @param $goods + * @param $areaId + * @return bool|int + * @throws NotFoundHttpException + * 计算非使用基础运费模板的商品按增重运费计算运费 + */ + private function countExtraAmount($goods, $areaId) + { + $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) { + $amount = $weight; + } else { + $amount = $count; + } + return $area->extra_price * ceil($amount / $area->extra_count); + } + + /** + * @param $templateId + * @return int + * @throws NotFoundHttpException + * 根据收货地址获取配送区域id + */ + private function getAreaId($templateId) + { + $city = $this->order->city; + $areas = ExpressArea::findALl(['express_template' => $templateId]); + foreach ($areas as $area) { + $allCity = explode(',', $area->city); + if (in_array($city, $allCity)) { + return $area->id; + } + } + throw new NotFoundHttpException('超出配送范围(未找到对应地区运费计算规则)'); + } + + /** + * @param $areaId + * @return ExpressArea|null + * @throws NotFoundHttpException + * 获取对应区域 + */ + private function findArea($areaId) + { + $area = ExpressArea::findOne($areaId); + if (!$area) { + throw new NotFoundHttpException('模板地区未找到'); + } + return $area; + } + + /** + * @param $templateId + * @return ExpressTemplate|null + * @throws NotFoundHttpException + * 获取运费模板 + */ + private function findTemplate($templateId) + { + $template = ExpressTemplate::findOne($templateId); + if (!$template) { + throw new NotFoundHttpException('运费模板未找到'); + } + return $template; + } +} \ No newline at end of file diff --git a/api/logic/Helper.php b/api/logic/Helper.php new file mode 100644 index 0000000..5d30418 --- /dev/null +++ b/api/logic/Helper.php @@ -0,0 +1,225 @@ +type = 1; + $file->own_type = $type; + $file->own_id = $oid; + $file->path = $data['fileName']; + $file->alias = $data['alias']; + if (!$file->save()) { + throw new ServerErrorHttpException('服务器保存文件失败'); + } + } + + /** + * @param $dirs + * @param $file + * @return array + * @throws ServerErrorHttpException + */ + public static function uploadImage($dirs, $file) + { + $savePath = Yii::getAlias('@app') . '/web/uploads'; + if (!is_dir($savePath)) { + mkdir($savePath, 0755); + } + foreach ($dirs as $dir) { + $savePath .= "/$dir"; + if (!is_dir($savePath)) { + mkdir($savePath, 0755); + } + } + $fileName = time() . rand(0, 9999) . '.' . $file->extension; + $path = $savePath . $fileName; + if (!$file->saveAs($path)) { + throw new ServerErrorHttpException('服务器保存图片失败'); + } + return ['fileName' => '/uploads/' . $dirs . '/' . $fileName, 'alias' => $file->baseName . $file->extension]; + } + + /** + * @param $array + * @return string + */ + public static function errorMessageStr($array): string + { + $data = []; + foreach ($array as $k => $v) { + $data[] = implode(' ', $v); + } + return implode(' ', $data); + } + + /** + * @param array $ids 购物车id 数组 + * @throws NotFoundHttpException + * @throws ServerErrorHttpException + * @throws \Throwable + * @throws \yii\db\StaleObjectException + */ + public static function delCarts($ids) + { + foreach ($ids as $id) { + $cart = Cart::find() + ->where(['id' => $id]) + ->andWhere(['user_id' => Yii::$app->user->getId()]) + ->one(); + if (!$cart) { + throw new NotFoundHttpException("未找到该购物车"); + } + if (!$cart->delete()) { + throw new ServerErrorHttpException('服务器删除购物车失败'); + } + } + } + + /** + * @param $goodsId + * @param $count + * @param null $skuId + * @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) { + throw new NotFoundHttpException('商品未找到'); + } + 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 false; + } + + /** + * @param $model + * @param $view + * post的返回头设置 + */ + 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 goodsPrice($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 + * 获取拼接后的sku值 + */ + 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); + + } + + /** + * @param $query + * @return object + * @throws \yii\base\InvalidConfigException + * 获取数据 + */ + public static function index($query) + { + $requestParams = Yii::$app->request->getBodyParams(); + return Yii::createObject([ + 'class' => ActiveDataProvider::className(), + 'query' => $query, + 'pagination' => [ + 'params' => $requestParams, + ], + 'sort' => [ + 'params' => $requestParams, + ], + ]); + } +} \ No newline at end of file diff --git a/api/logic/Login.php b/api/logic/Login.php new file mode 100644 index 0000000..abc9728 --- /dev/null +++ b/api/logic/Login.php @@ -0,0 +1,67 @@ +user->login($user, static::EXPIRE_TIME); + $user->expire_at = time() + static::EXPIRE_TIME; + $user->access_token = Yii::$app->security->generateRandomString(); + if (!$user->save()) { + throw new ServerErrorHttpException('更新登录信息失败'); + } + return $user->access_token; + } + + /** + * @return array|User|null + * @throws BadRequestHttpException + * @throws NotFoundHttpException + */ + protected static function getWxUser() + { + $openid = Yii::$app->request->getBodyParam('openid'); + if (!$openid) { + throw new BadRequestHttpException('缺少参数openid'); + } + $user = User::find() + ->where(['status' => User::STATUS_ACTIVE]) + ->andWhere(['wx_openid' => $openid]) + ->one(); + if (!$user) { + throw new NotFoundHttpException('用户未找到'); + } + return $user; + } + + + public function miniProgramLogin() + { + + } + + protected function getMiniUser() + { + + } + +} \ No newline at end of file diff --git a/api/logic/OrderLogic.php b/api/logic/OrderLogic.php new file mode 100644 index 0000000..b483d4b --- /dev/null +++ b/api/logic/OrderLogic.php @@ -0,0 +1,459 @@ +request->getBodyParam('goodsId');/*int 商品id*/ + $count = Yii::$app->request->getBodyParam('count');/*int 数量*/ + $skuId = Yii::$app->request->getBodyParam('skuId');/*int 商品sku id*/ + //购物车提交订单需传参数 + $cartIds = Yii::$app->request->getBodyParam('cartIds');/*array 购物车商品id*/ + + if ((empty($cartIds) && empty($goodsId)) || ($goodsId && empty($count))) { + throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS); + } + $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('服务器创建订单失败'); + } + if ($goodsId && $count) { + $this->addGoods($order->id, $goodsId, $skuId, $count);/*添加订单商品*/ + } 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; + } catch (Exception $e) { + $tra->rollBack(); + throw $e; + } + } + + /** + * @return bool + * @throws Exception + * @throws Throwable + * @throws yii\base\InvalidConfigException + * 根据操作类型更新订单 + */ + public function update() + { + $data = Yii::$app->request->getBodyParams(); + $type = Yii::$app->request->getBodyParam('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->switchShippingType($order, $data); + break; + case self::TYPE_CHANGE_ADDRESS: + $this->changeAddress($order, $data); + break; + 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('服务器更新订单失败'); + } + $tra->commit(); + return true; + } catch (Exception $e) { + $tra->rollBack(); + throw $e; + } + } + + /*----------------------------------------- 华丽的分割线 -----------------------------------------*/ + /** + * @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 + * @throws BadRequestHttpException + * @throws NotFoundHttpException + * 添加地址到订单 + */ + private function changeAddress($order, $data) + { + if (!isset($data['address_id'])) { + throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS); + } + 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('收货地址未找到'); + } + $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(Helper::REQUEST_BAD_PARAMS); + } + 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('自提点未找到'); + } + $order->taking_site = $data['taking_site_id']; + } + + + /** + * @param Order $order + * @param array $data + * @throws BadRequestHttpException + * 切换配送方式 + */ + private function switchShippingType($order, $data) + { + 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('该状态下不允许更改配送方式'); + } + + $order->shipping_type = $data['shipping_type']; + } + + /** + * @param Order $order + * @param array $data + * @throws BadRequestHttpException + * @throws NotFoundHttpException + * @throws ServerErrorHttpException + * @throws Throwable + * @throws yii\db\StaleObjectException + * 确定订单 + */ + private function confirm($order, $data) + { + if ($order->status !== Order::STATUS_UNCONFIRMED) { + throw new BadRequestHttpException('订单状态异常'); + } + if ($order->shipping_type === Order::SHIPPING_TYPE_PICKED_UP) { + if ($data['consignee'] ?? false || $data['phone'] ?? false) { + throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS); + } + $order->consignee = $data['consignee']; + $order->phone = $data['phone']; + } + if (empty($order->consignee)) { + throw new BadRequestHttpException('需先填写收件人信息'); + } + if (isset($data['remarks'])) { + $order->remarks = $data['remarks']; + } + Helper::delCarts($this->getCartsIds($order)); //删除购物车对应商品 + $order->status = Order::STATUS_NONPAYMENT; + $this->updateStock($order, self::TYPE_SUB_STOCK); + } + + /** + * @param $order + * @return array + * 获取订单商品对应购物车商品id + */ + private function getCartsIds($order) + { + $allGoods = $this->findOrderGoods($order->id); + $ids = []; + foreach ($allGoods as $goods) { + $cart = Cart::findOne(['goods_id' => $goods->goods_id, 'user_id' => Yii::$app->user->getId()]); + if ($cart) { + $ids[] = $cart->id; + } + } + return $ids; + } + + /** + * @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) { + /*检查库存*/ + 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 = $this->findGoods($orderGoods->goods_id); + } + if ($type) { + $count = $orderGoods->goods_count; + } else { + $count = -$orderGoods->goods_count; + } + if (!$goods->updateCounters(['stock' => $count])) { + throw new ServerErrorHttpException('更新库存失败'); + } + } + } + + /** + * @param array $cartIds 购物车商品id + * @param int $id 订单id + * @throws Exception + * @throws NotFoundHttpException + * 通过购物车添加商品 + */ + private function addGoodsByCart($cartIds, $id) + { + foreach ($cartIds as $cartId) { + $cart = Cart::findOne($cartId); + if (!$cart) { + throw new NotFoundHttpException('购物车未找到'); + } + $this->addGoods($id, $cart->goods_id, $cart->sku_id, $cart->goods_count); + } + } + + /** + * @param Order $order + * 保存商品总价格和总数量信息到 + */ + private function saveGoodsInfo($order) + { + $orderGoods = $this->findOrderGoods($order->id); + foreach ($orderGoods as $goods) { + $order->goods_amount += $goods->price; + $order->goods_count += $goods->goods_count; + } + } + + + /** + * @param $id + * @param int $goodsId + * @param $skuId + * @param $count + * @throws Exception + * @throws NotFoundHttpException + * 添加商品到订单 + */ + private function addGoods($id, $goodsId, $skuId, $count) + { + $goods = $this->findGoods($goodsId); + $orderGoods = new OrderGoods(); + $orderGoods->order_id = $id; + $orderGoods->goods_id = $goodsId; + $orderGoods->sku_id = $skuId ?: 0; + $orderGoods->sku_value = Helper::skuValue($skuId); + $orderGoods->weight = $skuId ? $this->skuWeight($skuId) : $goods->weight; + $orderGoods->goods_count = $count; + $orderGoods->goods_img = $goods->image; + $orderGoods->goods_name = $goods->name; + $orderGoods->price = Helper::goodsPrice($goodsId, $skuId); + Helper::checkStock($goodsId, $count, $skuId); /*检查库存*/ + if (!$orderGoods->save()) { + throw new Exception('服务器添加订单商品失败'); + } + } + + /** + * @param $skuId + * @return int + * @throws NotFoundHttpException + * 获取sku重量 + */ + private function skuWeight($skuId) + { + $sku = GoodsSku::findOne($skuId); + if (!$sku) { + throw new NotFoundHttpException('sku未找到'); + } + return $sku->weight; + } + + /** + * @return array|Order|null + * 根据id获取订单 + */ + 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[] + * 根据订单 id 获取所有订单商品 + */ + private function findOrderGoods($id) + { + return OrderGoods::find() + ->where(['order_id' => $id]) + ->all(); + } + + /** + * @param $goodsId + * @return array|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/api/logic/UserLogic.php b/api/logic/UserLogic.php new file mode 100644 index 0000000..12249e2 --- /dev/null +++ b/api/logic/UserLogic.php @@ -0,0 +1,40 @@ +where(['date' => $date]) + ->one(); + if ($DAU) { + $ids = $DAU->user_ids; + if (in_array(Yii::$app->user->id, $ids)) { + return; + } + array_push($ids, Yii::$app->user->id); + $DAU->user_id = $ids; + $DAU->count += 1; + } else { + $DAU = new DailyActiveUser(); + $DAU->user_ids = array(Yii::$app->user->getId()); + $DAU->date = $date; + } + $DAU->save(); + } + +} \ No newline at end of file diff --git a/api/runtime/.gitignore b/api/runtime/.gitignore new file mode 100644 index 0000000..c96a04f --- /dev/null +++ b/api/runtime/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore \ No newline at end of file diff --git a/api/views/site/error.php b/api/views/site/error.php new file mode 100644 index 0000000..0ba2574 --- /dev/null +++ b/api/views/site/error.php @@ -0,0 +1,27 @@ +title = $name; +?> +
+ +

title) ?>

+ +
+ +
+ +

+ The above error occurred while the Web server was processing your request. +

+

+ Please contact us if you think this is a server error. Thank you. +

+ +
diff --git a/api/web/.gitignore b/api/web/.gitignore new file mode 100644 index 0000000..ab89d98 --- /dev/null +++ b/api/web/.gitignore @@ -0,0 +1,5 @@ +/index.php +/index-test.php +/robots.txt +uploads + diff --git a/api/web/assets/.gitignore b/api/web/assets/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/api/web/assets/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/api/web/css/site.css b/api/web/css/site.css new file mode 100644 index 0000000..f787e34 --- /dev/null +++ b/api/web/css/site.css @@ -0,0 +1,120 @@ +html, +body { + height: 100%; +} + +.wrap { + min-height: 100%; + height: auto; + margin: 0 auto -60px; + padding: 0 0 60px; +} + +.wrap > .container { + padding: 70px 15px 20px; +} + +.footer { + height: 60px; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + padding-top: 20px; +} + +.jumbotron { + text-align: center; + background-color: transparent; +} + +.jumbotron .btn { + font-size: 21px; + padding: 14px 24px; +} + +.not-set { + color: #c55; + font-style: italic; +} + +/* add sorting icons to gridview sort links */ +a.asc:after, a.desc:after { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + padding-left: 5px; +} + +a.asc:after { + content: /*"\e113"*/ "\e151"; +} + +a.desc:after { + content: /*"\e114"*/ "\e152"; +} + +.sort-numerical a.asc:after { + content: "\e153"; +} + +.sort-numerical a.desc:after { + content: "\e154"; +} + +.sort-ordinal a.asc:after { + content: "\e155"; +} + +.sort-ordinal a.desc:after { + content: "\e156"; +} + +.grid-view td { + white-space: nowrap; +} + +.grid-view .filters input, +.grid-view .filters select { + min-width: 50px; +} + +.hint-block { + display: block; + margin-top: 5px; + color: #999; +} + +.error-summary { + color: #a94442; + background: #fdf7f7; + border-left: 3px solid #eed3d7; + padding: 10px 20px; + margin: 0 0 15px 0; +} + +/* align the logout "link" (button in forms) of the navbar */ +.nav li > form > button.logout { + padding: 15px; + border: none; +} + +@media(max-width:767px) { + .nav li > form > button.logout { + display:block; + text-align: left; + width: 100%; + padding: 10px 15px; + } +} + +.nav > li > form > button.logout:focus, +.nav > li > form > button.logout:hover { + text-decoration: none; +} + +.nav > li > form > button.logout:focus { + outline: none; +} diff --git a/api/web/favicon.ico b/api/web/favicon.ico new file mode 100644 index 0000000..580ed73 Binary files /dev/null and b/api/web/favicon.ico differ diff --git a/api/web/index-test.php b/api/web/index-test.php new file mode 100755 index 0000000..481768e --- /dev/null +++ b/api/web/index-test.php @@ -0,0 +1,18 @@ +run(); diff --git a/api/web/index.php b/api/web/index.php new file mode 100755 index 0000000..1649b25 --- /dev/null +++ b/api/web/index.php @@ -0,0 +1,17 @@ +run(); diff --git a/api/web/robots.txt b/api/web/robots.txt new file mode 100755 index 0000000..77470cb --- /dev/null +++ b/api/web/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / \ No newline at end of file diff --git a/backend/config/main.php b/backend/config/main.php index 572ea9d..e5d61e8 100644 --- a/backend/config/main.php +++ b/backend/config/main.php @@ -1,7 +1,7 @@ ['class' => 'backend\logic\file\FileManager'], 'goods' => ['class' => 'goods\goods\logic\goods\GoodsManager'], ], +// 'as access' => [ +// 'class' => 'iron\components\AccessControl', +// ], 'params' => $params, ]; diff --git a/backend/controllers/SiteController.php b/backend/controllers/SiteController.php index 796c0f6..e19447c 100755 --- a/backend/controllers/SiteController.php +++ b/backend/controllers/SiteController.php @@ -2,56 +2,36 @@ namespace backend\controllers; +use antgoods\goods\models\ars\Goods; use Yii; +use yii\base\NotSupportedException; use yii\web\Controller; use yii\filters\VerbFilter; use yii\filters\AccessControl; -use backend\models\LoginForm; -use backend\models\CategorySearch; +use common\models\LoginForm; +use common\models\CategorySearch; +use yii\web\Cookie; +use yii\web\ForbiddenHttpException; +use yii\web\NotAcceptableHttpException; +use yii\web\NotFoundHttpException; /** * Site controller */ -class SiteController extends Controller { +class SiteController extends Controller +{ /** * {@inheritdoc} */ - public function behaviors() { - return [ - 'access' => [ - 'class' => AccessControl::className(), - 'rules' => [ - [ - 'actions' => ['login', 'error', 'test'], - 'allow' => true, - ], - [ - 'actions' => ['logout', 'index'], - 'allow' => true, - 'roles' => ['@'], - ], - ], - ], - 'verbs' => [ - 'class' => VerbFilter::className(), - 'actions' => [ -// 'logout' => ['post'], - ], - ], - ]; - } - - /** - * {@inheritdoc} - */ - public function actions() { + public function actions() + { return [ 'error' => [ 'class' => 'yii\web\ErrorAction', ], - 'upload'=>[ - 'class'=>'iron\actions\UploadAction', + 'upload' => [ + 'class' => 'iron\actions\UploadAction', ] ]; } @@ -61,32 +41,22 @@ class SiteController extends Controller { * * @return string */ - public function actionIndex() { + public function actionIndex() + { return $this->render('index'); } - /** - * Login action. - * - * @return string - */ - public function actionLogin() { - - $this->layout = 'base'; + public function actionLogin() + { if (!Yii::$app->user->isGuest) { return $this->goHome(); } - - $model = new LoginForm(); - if ($model->load(Yii::$app->request->post()) && $model->login()) { + $key = Yii::$app->request->get('key'); + if (Yii::$app->userLogic->login($key)) { return $this->goBack(); } else { - $model->password = ''; - - return $this->render('login', [ - 'model' => $model, - ]); + throw new ForbiddenHttpException('身份验证失败,请重新进去'); } } @@ -95,17 +65,19 @@ class SiteController extends Controller { * * @return string */ - public function actionLogout() { + public function actionLogout() + { Yii::$app->user->logout(); return $this->goHome(); } - public function actionTest() { + public function actionTest() + { $searchModel = new CategorySearch(); return $this->render('test', [ - 'name' => 'blobt', - 'model' => $searchModel + 'name' => 'blobt', + 'model' => $searchModel ]); } diff --git a/backend/models/Cat.php b/backend/models/Cat.php deleted file mode 100644 index 4622d39..0000000 --- a/backend/models/Cat.php +++ /dev/null @@ -1,58 +0,0 @@ - 64], - ]; - } - - /** - * {@inheritdoc} - */ - public function attributeLabels() - { - return [ - 'id' => 'ID', - 'cat_name' => 'Cat Name', - 'icon' => 'Icon', - 'icon_type' => 'Icon Type', - 'description' => 'Description', - 'sort_order' => 'Sort Order', - 'created_at' => 'Created At', - 'updated_at' => 'Updated At', - ]; - } -} diff --git a/backend/models/Category.php b/backend/models/Category.php deleted file mode 100644 index 83cf923..0000000 --- a/backend/models/Category.php +++ /dev/null @@ -1,125 +0,0 @@ - "boostrap", - self::ICON_TYPE_AWESOME => "awesome" - ]; - - /** - * {@inheritdoc} - */ - public static function tableName() - { - return 'category'; - } - - /** - * {@inheritdoc} - */ - public function rules() - { - return [ - [['icon_type', 'cat_name', 'created_at'], 'required'], - [['icon_type', 'sort_order', 'created_at', 'updated_at'], 'integer'], - [['description'], 'string'], - [['cat_name', 'icon'], 'string', 'max' => 64], - ]; - } - - /** - * {@inheritdoc} - */ - public function attributeLabels() - { - return [ - 'id' => 'ID', - 'cat_name' => '类名', - 'icon' => 'Icon', - 'icon_type' => '图标类型', - 'description' => '描述', - 'sort_order' => 'Sort Order', - 'created_at' => '添加日期', - 'updated_at' => 'Updated At', - ]; - } - - /** - * @return array - * 列格式 - */ - public static function columns() - { - return [ - [ - 'class' => 'blobt\grid\CheckboxColumn', - 'width' => '2%', - 'align' => 'center' - ], - [ - 'attribute' => 'id', - 'width' => '10%', - 'align' => 'center' - ], - [ - 'attribute' => 'created_at', - 'width' => '10%', - 'format' => 'date' - ], - [ - 'attribute' => 'cat_name', - 'width' => '10%', - ], - [ - 'attribute' => 'icon', - 'width' => '10%', - ], - [ - 'attribute' => 'icon_type', - 'width' => '10%', - 'showConstText' => true - ], - [ - 'attribute' => 'description', - 'enableSorting' => false, - 'format' => 'ntext', - 'width' => '20%', - ], - [ - 'class' => 'iron\grid\ActionColumn', - 'align' => 'center', - ], - ]; - } - - public function behaviors() - { - return [ - TimestampBehavior::className() - ]; - } - -} diff --git a/backend/models/CategorySearch.php b/backend/models/CategorySearch.php deleted file mode 100644 index 5599117..0000000 --- a/backend/models/CategorySearch.php +++ /dev/null @@ -1,126 +0,0 @@ - $query, - 'pagination' => false, - 'sort' => false - ]); - $this->load($params); - return $this->filter($query, $dataProvider); - } - - /** - * Creates data provider instance with search query applied - * - * @param array $params - * - * @return ActiveDataProvider - */ - public function search($params) - { - $query = Category::find(); - - // add conditions that should always apply here - - $dataProvider = new ActiveDataProvider([ - 'query' => $query, - 'pagination' => [ - 'pageSizeLimit' => [1, 200] - ], - 'sort' => [ - 'defaultOrder' => [ - 'id' => SORT_DESC, - ] - ], - ]); - $this->load($params); - return $this->filter($query, $dataProvider); - } - - /** - * @param $query - * @param $dataProvider - * @return ActiveDataProvider - * 条件筛选 - */ - private function filter($query, $dataProvider) - { - - if (!$this->validate()) { - // uncomment the following line if you do not want to return any records when validation fails - // $query->where('0=1'); - return $dataProvider; - } - -// grid filtering conditions - $query->andFilterWhere([ - 'id' => $this->id, - 'icon_type' => $this->icon_type, - 'sort_order' => $this->sort_order, - 'created_at' => $this->created_at, - 'updated_at' => $this->updated_at, - ]); - - $query->andFilterWhere(['like', 'cat_name', $this->cat_name]) - ->andFilterWhere(['like', 'icon', $this->icon]) - ->andFilterWhere(['like', 'description', $this->description]); - - if ($this->created_at_range) { - $arr = explode(' ~ ', $this->created_at_range); - $start = strtotime($arr[0]); - $end = strtotime($arr[1]) + 3600 * 24; - $query->andFilterWhere(['between', 'created_at', $start, $end]); - } - return $dataProvider; - } - -} diff --git a/backend/models/User.php b/backend/models/User.php new file mode 100644 index 0000000..b1598d7 --- /dev/null +++ b/backend/models/User.php @@ -0,0 +1,227 @@ + TimestampBehavior::className(), + 'createdAtAttribute' => 'created_at', + 'updatedAtAttribute' => 'updated_at', + 'value' => function () { + return time(); + }, + ], + ]; + } + + /** + * {@inheritdoc} + */ + public function rules() + { + return [ + ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]], + ]; + } + + public function beforeSave($insert) + { + if ($insert) { + $this->email = $this->username . '@example.com'; + $this->generateAuthKey(); + $this->setPassword(Yii::$app->security->generateRandomString()); + } + return parent::beforeSave($insert); + } + + + /** + * {@inheritdoc} + */ + public static function findIdentity($id) + { + return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]); + } + + /** + * {@inheritdoc} + */ + public static function findIdentityByAccessToken($token, $type = null) + { + throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.'); + } + + /** + * Finds user by username + * + * @param string $username + * @return static|null + */ + public static function findByUsername($username) + { + return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]); + } + + /** + * Finds user by password reset token + * + * @param string $token password reset token + * @return static|null + */ + public static function findByPasswordResetToken($token) + { + if (!static::isPasswordResetTokenValid($token)) { + return null; + } + + return static::findOne([ + 'password_reset_token' => $token, + 'status' => self::STATUS_ACTIVE, + ]); + } + + /** + * Finds user by verification email token + * + * @param string $token verify email token + * @return static|null + */ + public static function findByVerificationToken($token) + { + return static::findOne([ + 'verification_token' => $token, + 'status' => self::STATUS_INACTIVE + ]); + } + + /** + * Finds out if password reset token is valid + * + * @param string $token password reset token + * @return bool + */ + public static function isPasswordResetTokenValid($token) + { + if (empty($token)) { + return false; + } + + $timestamp = (int)substr($token, strrpos($token, '_') + 1); + $expire = Yii::$app->params['user.passwordResetTokenExpire']; + return $timestamp + $expire >= time(); + } + + /** + * {@inheritdoc} + */ + public function getId() + { + return $this->getPrimaryKey(); + } + + /** + * {@inheritdoc} + */ + public function getAuthKey() + { + return $this->auth_key; + } + + /** + * {@inheritdoc} + */ + public function validateAuthKey($authKey) + { + return $this->getAuthKey() === $authKey; + } + + /** + * Validates password + * + * @param string $password password to validate + * @return bool if password provided is valid for current user + */ + public function validatePassword($password) + { + return Yii::$app->security->validatePassword($password, $this->password_hash); + } + + /** + * Generates password hash from password and sets it to the model + * + * @param string $password + */ + public function setPassword($password) + { + $this->password_hash = Yii::$app->security->generatePasswordHash($password); + } + + /** + * Generates "remember me" authentication key + */ + public function generateAuthKey() + { + $this->auth_key = Yii::$app->security->generateRandomString(); + } + + /** + * Generates new password reset token + */ + public function generatePasswordResetToken() + { + $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time(); + } + + public function generateEmailVerificationToken() + { + $this->verification_token = Yii::$app->security->generateRandomString() . '_' . time(); + } + + /** + * Removes password reset token + */ + public function removePasswordResetToken() + { + $this->password_reset_token = null; + } +} diff --git a/backend/modules/file/logic/file/FileManager.php b/backend/modules/file/logic/file/FileManager.php index 80d2f26..a5b13ec 100755 --- a/backend/modules/file/logic/file/FileManager.php +++ b/backend/modules/file/logic/file/FileManager.php @@ -5,17 +5,20 @@ namespace backend\modules\file\logic\file; use backend\modules\file\models\ars\File; use backend\modules\file\models\ars\TemFile; +use yii\web\HttpException; +use yii; class FileManager { //数据表ats_file和ats_tem_file的类型字段type + const TYPE_NONE = 0;//不存在 const TYPE_IMAGE = 1;//图片 const TYPE_VIDEO = 2;//影视 const TYPE_EXCEL = 3;//excel表单 const TYPE_WORD = 4;//word文本 const TYPE_TXT = 5;//txt文本 - public static $extension = [ + private $extension = [ self::TYPE_IMAGE => ['jpg', 'png', 'jpeg'], self::TYPE_VIDEO => ['mp4'], self::TYPE_EXCEL => [], @@ -24,54 +27,54 @@ class FileManager ]; /** - * @param $array * @param $keyword - * @return array - * 根据文件拓展名在$extension中查找对应的文件类型,若不存在则返回false + * @return int|string + * 根据文件拓展名在$extension中查找对应的文件类型,若不存在则返回self::TYPE_NONE */ - public function searchType($array, $keyword) + public function searchType($keyword) { - foreach($array as $key => $value){ - foreach ($value as $k => $v) { - if($v == $keyword){ - return ['status' => true, 'info' => '操作成功', 'type' => $key]; - } + foreach($this->extension as $key => $type){ + if (in_array($keyword, $type)) { + return $key; } } - return ['status' => false, 'info' => '操作失败']; + return self::TYPE_NONE; } /** - * @param $temFIleIdArr + * @param $temFileIdArr * @param $ownId * @param $ownType - * @return array + * @return array|bool + * @throws \Exception * 根据临时文件id将临时文件保存在文件中 */ - public function saveTemFileToFile($temFIleIdArr, $ownId, $ownType) + public function saveTemFileToFile($temFileIdArr, $ownId, $ownType) { - if(!$temFIleIdArr || !$ownId) { - return ['status' => false, 'info' => '参数错误']; + if(empty($temFileIdArr) || !$ownId) { + return false; } - $firstFileId = 0; - foreach ($temFIleIdArr as $key => $value) { - $temFile = TemFile::findOne($value); + $tra = Yii::$app->db->beginTransaction(); + try { + $firstFileId = 0; + foreach ($temFileIdArr as $key => $value) { + $temFile = TemFile::findOne($value); - if(!$temFile) { - return ['status' => false, 'info' => '存在查找不到的文件']; + if ($temFile) { + $res = self::saveNewFile($temFile, $ownId, $ownType); + if ($key == 0) { + $firstFileId = $res['file_id']; + } + } } - $res = self::saveNewFile($temFile, $ownId, $ownType); - if(!$res['status']) { - return ['status' => false, 'info' => '存在文件保存失败']; - } - if($key == 0) { - $firstFileId = $res['file_id']; - } + $tra->commit(); + return ['status' => true, 'info' => '保存成功', 'first_file_id' => $firstFileId]; + } catch (\Exception $e) { + $tra->rollBack(); + throw new \Exception($e->getMessage()); } - - return ['status' => true, 'info' => '保存成功', 'first_file_id' => $firstFileId]; } /** @@ -79,6 +82,7 @@ class FileManager * @param $ownId * @param $ownType * @return array + * @throws HttpException * 创建新的文件 */ private function saveNewFile($temFile, $ownId, $ownType) @@ -93,13 +97,14 @@ class FileManager if($newFile->save()) { return ['status' => true, 'info' => '操作成功', 'file_id' => $newFile->id]; } else { - return ['status' => false, 'info' => '操作失败']; + throw new HttpException('500', 'File保存失败'); } } /** * @param $fileIdArr - * @return array + * @return bool + * @throws HttpException * 删除file表中的文件 */ public function deleteFile($fileIdArr) @@ -109,12 +114,12 @@ class FileManager $fileModel = File::findOne($value); if($fileModel){ $fileModel->is_delete = File::IS_DELETE_YES; - if($fileModel->save()){ - return ['status' => false, 'info' => '操作失败']; + if(!$fileModel->save()){ + throw new HttpException('500', '文件删除失败'); } } } } - return ['status' => true, 'info' => '操作成功']; + return true; } } \ No newline at end of file diff --git a/backend/modules/file/models/ars/File.php b/backend/modules/file/models/ars/File.php index e2785f0..8f29387 100755 --- a/backend/modules/file/models/ars/File.php +++ b/backend/modules/file/models/ars/File.php @@ -26,9 +26,11 @@ class File extends \yii\db\ActiveRecord const OWN_TYPE_GOODS_INDEX = 1;//商品首页 const OWN_TYPE_GOODS_DETAILS = 2;//商品详情 const OWN_TYPE_CATEGORY_ICON = 3;//类目图标 + const OWN_TYPE_COMMENT = 4;//评论图片 //is_delete const IS_DELETE_YES = 1;//已删除 const IS_DELETE_NO = 0;//未删除 + /** * {@inheritdoc} */ @@ -68,15 +70,15 @@ class File extends \yii\db\ActiveRecord 'created_at' => '创建时间', ]; } - + /** - * @author linyao - * @email 602604991@qq.com - * @created Nov 8, 2019 - * - * 行为存储创建时间和更新时间 - */ + * @author linyao + * @email 602604991@qq.com + * @created Nov 8, 2019 + * + * 行为存储创建时间和更新时间 + */ public function behaviors() { return [ @@ -84,7 +86,7 @@ class File extends \yii\db\ActiveRecord 'class' => TimestampBehavior::className(), 'createdAtAttribute' => 'created_at', 'updatedAtAttribute' => 'updated_at', - 'value' => function() { + 'value' => function () { return time(); }, ], diff --git a/backend/modules/goods/controllers/CategoryController.php b/backend/modules/goods/controllers/CategoryController.php index 7cf5a09..305db28 100755 --- a/backend/modules/goods/controllers/CategoryController.php +++ b/backend/modules/goods/controllers/CategoryController.php @@ -201,10 +201,7 @@ class CategoryController extends Controller $model->user_id = Yii::$app->user->identity->id; $model->name = $file_name; $file_manager = new \backend\modules\file\logic\file\FileManager(); - $type_res = $file_manager->searchType(\backend\modules\file\logic\file\FileManager::$extension, pathinfo($data['path'])['extension']); - if ($type_res['status']) { - $model->type = $type_res['type']; - } + $model->type = $file_manager->searchType(pathinfo($data['path'])['extension']); $model->alias = $data['alias']; $model->path = $data['path']; $model->save(); diff --git a/backend/modules/goods/controllers/GoodsController.php b/backend/modules/goods/controllers/GoodsController.php index e0d4833..91d07c6 100755 --- a/backend/modules/goods/controllers/GoodsController.php +++ b/backend/modules/goods/controllers/GoodsController.php @@ -11,6 +11,7 @@ use Yii; use backend\modules\goods\models\ars\Goods; use backend\modules\goods\models\searchs\GoodsSearch; use yii\web\Controller; +use yii\web\HttpException; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; use backend\modules\goods\logic\goods\GoodsManager; @@ -96,6 +97,9 @@ class GoodsController extends Controller $model = new Goods(); $model->is_sale = Goods::IS_SALE_YES; $model->stock = -1; + $model->is_taking = Goods::IS_TAKING_NO; + $model->is_express = Goods::IS_EXPRESS_YES; + $model->express_type = Goods::EXPRESS_TYPE_EXPRESS_TEMPLATE; if ($model->load(Yii::$app->request->post()) && $model->validate()) { //商品封面图和商品详情图上传保存处理 $res = GoodsManager::updateGoods(Yii::$app->request->post(), $model); @@ -132,6 +136,9 @@ class GoodsController extends Controller return $this->redirect('index'); } } + $model->uniform_postage /= 100; + $model->market_price /= 100; + $model->price /= 100; $attributeModel = GoodsManager::getAttribute($id); $checkAttr = GoodsManager::getSkuInfo($id); $filterAttributeModel = GoodsManager::getFilterAttribute($id); @@ -211,10 +218,7 @@ class GoodsController extends Controller $model->user_id = Yii::$app->user->identity->id; $model->name = $file_name; $file_manager = new \backend\modules\file\logic\file\FileManager(); - $type_res = $file_manager->searchType(\backend\modules\file\logic\file\FileManager::$extension, pathinfo($data['path'])['extension']); - if ($type_res['status']) { - $model->type = $type_res['type']; - } + $model->type = $file_manager->searchType(pathinfo($data['path'])['extension']); $model->alias = $data['alias']; $model->path = $data['path']; $model->save(); diff --git a/backend/modules/goods/controllers/ShopCategoryController.php b/backend/modules/goods/controllers/ShopCategoryController.php index 70d1515..c0feeec 100755 --- a/backend/modules/goods/controllers/ShopCategoryController.php +++ b/backend/modules/goods/controllers/ShopCategoryController.php @@ -212,10 +212,7 @@ class ShopCategoryController extends Controller $model->user_id = Yii::$app->user->identity->id; $model->name = $file_name; $file_manager = new \backend\modules\file\logic\file\FileManager(); - $type_res = $file_manager->searchType(\backend\modules\file\logic\file\FileManager::$extension, pathinfo($data['path'])['extension']); - if ($type_res['status']) { - $model->type = $type_res['type']; - } + $model->type = $file_manager->searchType(pathinfo($data['path'])['extension']); $model->alias = $data['alias']; $model->path = $data['path']; $model->save(); diff --git a/backend/modules/goods/logic/goods/GoodsManager.php b/backend/modules/goods/logic/goods/GoodsManager.php index ce534c8..ea4d990 100755 --- a/backend/modules/goods/logic/goods/GoodsManager.php +++ b/backend/modules/goods/logic/goods/GoodsManager.php @@ -10,6 +10,7 @@ use backend\modules\goods\models\ars\GoodsSku; use backend\modules\goods\models\ars\Goods; use backend\modules\goods\models\ars\FilterAttr; use backend\modules\goods\models\ars\Category; +use yii\web\HttpException; class GoodsManager { @@ -19,36 +20,44 @@ class GoodsManager * @param array $oldFileIdArr * @param int $fileType * @return array + * @throws \Exception * 保存新文件,删除不需要的文件操作 */ public static function saveFile($newFileIdArr, $goodsModel, $oldFileIdArr = [], $fileType = 1) { - //需要新建的文件id - $createFileIdArr = array_diff($newFileIdArr, $oldFileIdArr); + $tra = Yii::$app->db->beginTransaction(); + try { + //需要新建的文件id + $createFileIdArr = array_diff($newFileIdArr, $oldFileIdArr); - //创建文件 - $class = new \backend\modules\file\logic\file\FileManager(); - $createFileRes = $class->saveTemFileToFile($createFileIdArr, $goodsModel->id, $fileType); + //创建文件 + $class = new \backend\modules\file\logic\file\FileManager(); + $createFileRes = $class->saveTemFileToFile($createFileIdArr, $goodsModel->id, $fileType); - //需要删除的文件id - $delFileIdArr = array_diff($oldFileIdArr, $newFileIdArr); + //需要删除的文件id + $delFileIdArr = array_diff($oldFileIdArr, $newFileIdArr); - //删除文件 - $class->deleteFile($delFileIdArr); + //删除文件 + $class->deleteFile($delFileIdArr); - //记录第一张图片id - $firstFileId = 0; + //记录第一张图片id + $firstFileId = 0; - //查看修改数组是否为空 - if (!$newFileIdArr[0]) { - $firstFileId = null; - }else { - if ($createFileRes['status']) { - $firstFileId = $createFileRes['first_file_id']; + //查看修改数组是否为空 + if (!$newFileIdArr[0]) { + $firstFileId = null; + } else { + if ($createFileRes['status']) { + $firstFileId = $createFileRes['first_file_id']; + } } - } - return ['status' => true, 'info' => '操作成功', 'first_file_id' => $firstFileId]; + $tra->commit(); + return ['status' => true, 'info' => '操作成功', 'first_file_id' => $firstFileId]; + } catch (\Exception $e) { + $tra->rollBack(); + throw new \Exception($e->getMessage()); + } } /** @@ -57,29 +66,28 @@ class GoodsManager * @param null $coverImageOldIdStr * @param null $detailImageOldIdStr * @return array - * @throws \Throwable + * @throws \Exception * 创建修改商品操作 */ public static function updateGoods($data, $model, $coverImageOldIdStr = null, $detailImageOldIdStr = null) { $attribute = $data['attribute']; $filterAttribute = $data['filterattribute']; + $model->uniform_postage *= 100; + $model->market_price *= 100; + $model->price *= 100; $tra = Yii::$app->db->beginTransaction(); try { if (!$model->save()) { - throw new Exception(''); + throw new \Exception('商品保存失败'); } $saveCoverImageRes = self::saveFile(explode(',', $model->coverImageId), $model, explode(',', $coverImageOldIdStr)); $saveDetailImageRes = self::saveFile(explode(',', $model->detailImageId), $model, explode(',', $detailImageOldIdStr), File::OWN_TYPE_GOODS_DETAILS); - if ($saveCoverImageRes['status'] && $saveDetailImageRes['status']) { - if($saveCoverImageRes['first_file_id'] !== 0) { - $model->image = $saveCoverImageRes['first_file_id']; - if (!$model->save()) { - throw new Exception('图片保存失败'); - } + if($saveCoverImageRes['first_file_id'] !== 0) { + $model->image = $saveCoverImageRes['first_file_id']; + if (!$model->save()) { + throw new \Exception('图片保存失败'); } - } else { - throw new Exception('图片保存失败'); } self::addAttributeOperating(['id' => $model->id, 'attribute' => $attribute]); self::addFilterAttributeOperating(['id' => $model->id, 'filterAttribute' => $filterAttribute]); @@ -87,60 +95,71 @@ class GoodsManager return ['status' => true]; } catch (\yii\base\Exception $e) { $tra->rollBack(); - return ['status' => false, 'info' => $e->getMessage()]; + throw new \Exception($e->getMessage()); } } /** * @param $data * @return bool - * @throws Exception + * @throws \Exception * 创建修改商品属性操作 */ - public static function addAttributeOperating($data) + private static function addAttributeOperating($data) { - if (!$data['attribute']) { - return true; - } - $data['attribute'] = json_decode($data['attribute'], true); - $oldAttr = []; - $goodsAttr = GoodsAttr::find()->where(['goods_id' => $data['id'], 'is_delete' => GoodsAttr::IS_DELETE_NO])->all(); - if ($goodsAttr) { //如果商品有旧的属性 - if(count($data['attribute']) == 0 && is_array($data['attribute'])) { //如果传上来的是空数组,删除该商品下的全部属性 - self::delAttribute($goodsAttr); + $tra = Yii::$app->db->beginTransaction(); + try { + if (!$data['attribute']) { + $tra->commit(); return true; } - foreach ($goodsAttr as $key => $value) { //把旧的商品属性保存到一个数组 - $oldAttr[$value->id] = $value->attr_value; + $data['attribute'] = json_decode($data['attribute'], true); + $oldAttr = []; + $goodsAttr = GoodsAttr::find()->where(['goods_id' => $data['id'], 'is_delete' => GoodsAttr::IS_DELETE_NO])->all(); + if ($goodsAttr) { //如果商品有旧的属性 + if (count($data['attribute']) == 0 && is_array($data['attribute'])) { //如果传上来的是空数组,删除该商品下的全部属性 + self::delAttribute($goodsAttr); + $tra->commit(); + return true; + } + foreach ($goodsAttr as $key => $value) { //把旧的商品属性保存到一个数组 + $oldAttr[$value->id] = $value->attr_value; + } } - } - $newAttr = self::addAttribute($data['attribute'], $data['id']); //添加新的商品属性 - $delAttr = array_diff(array_keys($oldAttr), array_keys($newAttr)); //找出需要删除的goodsAttrId - if (!$delAttr) { - return true; - } - foreach ($delAttr as $value) { - $model = GoodsAttr::find()->where(['id' => $value, 'is_delete' => GoodsAttr::IS_DELETE_NO])->One(); - if ($model) { - $model->is_delete = GoodsAttr::IS_DELETE_YES; - if (!$model->save()) { - throw new Exception('goodsAttribute delete false'); + $newAttr = self::addAttribute($data['attribute'], $data['id']); //添加新的商品属性 + $delAttr = array_diff(array_keys($oldAttr), array_keys($newAttr)); //找出需要删除的goodsAttrId + if (!$delAttr) { + $tra->commit(); + return true; + } + foreach ($delAttr as $value) { + $model = GoodsAttr::find()->where(['id' => $value, 'is_delete' => GoodsAttr::IS_DELETE_NO])->One(); + if ($model) { + $model->is_delete = GoodsAttr::IS_DELETE_YES; + if (!$model->save()) { + throw new \Exception('goodsAttribute delete false'); + } } } + $tra->commit(); + return true; + } catch (\Exception $e) { + $tra->rollBack(); + throw new \Exception($e->getMessage()); } } /** * @param $goodsAttr - * @throws Exception + * @throws \Exception * 删除商品属性 */ - public static function delAttribute($goodsAttr) + private static function delAttribute($goodsAttr) { foreach ($goodsAttr as $key => $value) { $value->is_delete = GoodsAttr::IS_DELETE_YES; if (!$value->save()) { - throw new Exception('goods attribute delete false'); + throw new \Exception('goods attribute delete false'); } } } @@ -149,10 +168,10 @@ class GoodsManager * @param $attribute * @param $goodsId * @return array - * @throws Exception + * @throws \Exception * 保存商品属性 */ - public static function addAttribute($attribute, $goodsId) + private static function addAttribute($attribute, $goodsId) { $newAttr = []; if (!$attribute) { @@ -169,7 +188,7 @@ class GoodsManager $goodsAttrModel->goods_id = $goodsId; $goodsAttrModel->attr_value = $v; if (!$goodsAttrModel->save()) { - throw new Exception('goodsAttribute save false'); + throw new \Exception('goodsAttribute save false'); } $newAttr[$goodsAttrModel->id] = $goodsAttrModel->attr_value; //新增的数据 } @@ -284,7 +303,7 @@ class GoodsManager $data['id'] = $sku->id; $data['price'] = $sku->price; $data['stock'] = $sku->stock; - $data['weight'] = $sku->weight; + $data['weight'] = $sku->weight/1000; return $data; } @@ -306,29 +325,18 @@ class GoodsManager if ($attribute && $attribute->type == Attribute::TYPE_ATTR) { $ret['name'] = $attribute->name; $ret['id'] = $attribute->id; - $ret['attrValue'] = self::getAttrValue($attribute->id, $id); + $ret['attrValue'] = GoodsAttr::find() + ->select(['id', 'attr_value']) + ->where(['goods_id' => $id]) + ->andWhere(['attr_id' => $attribute->id]) + ->asArray() + ->all(); $attributes[] = $ret; } } return $attributes; } - /** - * @param $attrId - * @param $goodsId - * @return GoodsAttr[]|GoodsSku[]|array|File[]|\backend\modules\file\models\ars\TemFile[]|\yii\db\ActiveRecord[] - * 获取属性值 - */ - public static function getAttrValue($attrId, $goodsId) - { - return GoodsAttr::find() - ->select(['id', 'attr_value']) - ->where(['goods_id' => $goodsId]) - ->andWhere(['attr_id' => $attrId]) - ->asArray() - ->all(); - } - /** * @param $type * @param $goodsId @@ -356,45 +364,54 @@ class GoodsManager /** * @param $sku - * @throws \yii\db\Exception + * @param $type + * @param $goodsId + * @throws \Exception * 添加或更新sku数据 */ public static function AddOrUpdateData($sku, $type, $goodsId) { - $goodsModel = Goods::findOne($goodsId); - if ($sku['id'] > 0) { - $goodsSku = GoodsSku::findOne($sku['id']); - $attrId = array_filter(explode(',', $goodsSku->goods_attr)); - $attr = GoodsAttr::findOne($attrId[0]); - } else { - $goodsSku = new GoodsSku(); - $attr = new GoodsAttr(); - } - if (!$attr || !$goodsSku || !$goodsModel) { - throw new \yii\db\Exception('系统异常'); - } - if ($type == Goods::SKU_MODE_MANUAL) { - $attr->attr_value = $sku['value']; - if (!$attr->save()) { - throw new \yii\db\Exception('手动属性修改失败'); + $tra = Yii::$app->db->beginTransaction(); + try { + $goodsModel = Goods::findOne($goodsId); + if ($sku['id'] > 0) { + $goodsSku = GoodsSku::findOne($sku['id']); + $attrId = array_filter(explode(',', $goodsSku->goods_attr)); + $attr = GoodsAttr::findOne($attrId[0]); + } else { + $goodsSku = new GoodsSku(); + $attr = new GoodsAttr(); } - $goodsSku->goods_attr = (string)$attr->id; - $goodsSku->is_manaul = 1; - } else { - $goodsSku->goods_attr = implode(',', array_filter($sku['value'])); - } - $goodsSku->goods_id = $goodsId; - $goodsSku->price = $sku['price']; - $goodsSku->stock = $sku['stock']; - $goodsSku->weight = $sku['weight']; - $goodsSku->goods_sn = $goodsModel->sn; - if (!$goodsSku->save()) { - throw new \yii\db\Exception('保存失败,请检查是否有重复规格'); - } - $goods = Goods::findOne($goodsId); - $goods->sku_mode = $type; - if (!$goods->save()) { - throw new \yii\db\Exception('商品sku类型修改失败'); + if (!$attr || !$goodsSku || !$goodsModel) { + throw new \Exception('参数错误'); + } + if ($type == Goods::SKU_MODE_MANUAL) { + $attr->attr_value = $sku['value']; + if (!$attr->save()) { + throw new \Exception('手动属性修改失败'); + } + $goodsSku->goods_attr = (string)$attr->id; + $goodsSku->is_manaul = 1; + } else { + $goodsSku->goods_attr = implode(',', array_filter($sku['value'])); + } + $goodsSku->goods_id = $goodsId; + $goodsSku->price = $sku['price']; + $goodsSku->stock = $sku['stock']; + $goodsSku->weight = $sku['weight']*1000; + $goodsSku->goods_sn = $goodsModel->sn; + if (!$goodsSku->save()) { + throw new \Exception('保存失败,请检查是否有重复规格'); + } + $goods = Goods::findOne($goodsId); + $goods->sku_mode = $type; + if (!$goods->save()) { + throw new \Exception('商品sku类型修改失败'); + } + $tra->commit(); + } catch (\Exception $e) { + $tra->rollBack(); + throw new \Exception($e->getMessage()); } } @@ -433,9 +450,10 @@ class GoodsManager * @param $data * @return bool * @throws Exception + * @throws HttpException * 创建修改商品筛选属性操作 */ - public static function addFilterAttributeOperating($data) + private static function addFilterAttributeOperating($data) { if (!$data['filterAttribute']) { return true; @@ -462,7 +480,7 @@ class GoodsManager if ($model) { $model->is_delete = FilterAttr::IS_DELETE_YES; if (!$model->save()) { - throw new Exception('goodsAttribute delete false'); + throw new \Exception('goodsAttribute delete false'); } } } @@ -470,15 +488,15 @@ class GoodsManager /** * @param $goodsFilterAttr - * @throws Exception + * @throws HttpException * 删除商品筛选属性 */ - public static function delFilterAttribute($goodsFilterAttr) + private static function delFilterAttribute($goodsFilterAttr) { foreach ($goodsFilterAttr as $key => $value) { $value->is_delete = FilterAttr::IS_DELETE_YES; if (!$value->save()) { - throw new Exception('goods attribute delete false'); + throw new \Exception('goods attribute delete false'); } } } @@ -487,10 +505,10 @@ class GoodsManager * @param $attribute * @param $goodsId * @return array - * @throws Exception + * @throws \Exception * 保存商品筛选属性 */ - public static function addFilterAttribute($attribute, $goodsId) + private static function addFilterAttribute($attribute, $goodsId) { $newAttr = []; if (!$attribute) { @@ -507,7 +525,7 @@ class GoodsManager $goodsFilterAttrModel->goods_id = $goodsId; $goodsFilterAttrModel->attr_value = $v; if (!$goodsFilterAttrModel->save()) { - throw new Exception('goodsAttribute save false'); + throw new \Exception('goodsAttribute save false'); } $newAttr[$goodsFilterAttrModel->id] = $goodsFilterAttrModel->attr_value; //新增的数据 } @@ -549,7 +567,7 @@ class GoodsManager /** * @param $goodsModel * @return bool - * + * 判断该商品的sku是否存在已选属性,存在则返回true,表示不得删除 */ public static function judgeGoodsCategory($goodsModel) { diff --git a/backend/modules/goods/migrations/m191207_004848_add_columns_is_taking_is_express_express_type_uniform_postage_in_table_atg_goods.php b/backend/modules/goods/migrations/m191207_004848_add_columns_is_taking_is_express_express_type_uniform_postage_in_table_atg_goods.php new file mode 100644 index 0000000..4f06e33 --- /dev/null +++ b/backend/modules/goods/migrations/m191207_004848_add_columns_is_taking_is_express_express_type_uniform_postage_in_table_atg_goods.php @@ -0,0 +1,26 @@ +addColumn('atg_goods', 'is_taking', $this->tinyInteger(1)->defaultValue(0)->notNull()->comment('是否自提')); + $this->addColumn('atg_goods', 'is_express', $this->tinyInteger(1)->defaultValue(0)->notNull()->comment('是否快递发货')); + $this->addColumn('atg_goods', 'express_type', $this->tinyInteger(2)->defaultValue(0)->comment('快递运费方式')); + $this->addColumn('atg_goods', 'uniform_postage', $this->integer(20)->defaultValue(0)->comment('统一邮费')); + } + + public function down() + { + $this->dropColumn('atg_goods', 'is_taking'); + $this->dropColumn('atg_goods', 'is_express'); + $this->dropColumn('atg_goods', 'express_type'); + $this->dropColumn('atg_goods', 'uniform_postage'); + return true; + } +} diff --git a/backend/modules/goods/migrations/m191209_091129_update_columns_in_table_atg_goods.php b/backend/modules/goods/migrations/m191209_091129_update_columns_in_table_atg_goods.php new file mode 100644 index 0000000..c13bf75 --- /dev/null +++ b/backend/modules/goods/migrations/m191209_091129_update_columns_in_table_atg_goods.php @@ -0,0 +1,23 @@ +execute($sql); + } + + /** + * {@inheritdoc} + */ + public function down() + { + return true; + } +} diff --git a/backend/modules/goods/migrations/m191209_091524_add_column_weight_in_table_atg_goods_sku.php b/backend/modules/goods/migrations/m191209_091524_add_column_weight_in_table_atg_goods_sku.php new file mode 100644 index 0000000..73eb933 --- /dev/null +++ b/backend/modules/goods/migrations/m191209_091524_add_column_weight_in_table_atg_goods_sku.php @@ -0,0 +1,20 @@ +addColumn('atg_goods_sku', 'weight', $this->integer(8)->defaultValue("0")->unsigned()->comment('重量')); + } + + public function down() + { + $this->dropColumn('atg_goods_sku', 'weight'); + return true; + } +} diff --git a/backend/modules/goods/migrations/sql/update_goods.sql b/backend/modules/goods/migrations/sql/update_goods.sql new file mode 100644 index 0000000..04b4213 --- /dev/null +++ b/backend/modules/goods/migrations/sql/update_goods.sql @@ -0,0 +1,17 @@ +ALTER TABLE `atg_goods` DROP `weight`; +ALTER TABLE `atg_goods` DROP `length`; +ALTER TABLE `atg_goods` DROP `width`; +ALTER TABLE `atg_goods` DROP `height`; +ALTER TABLE `atg_goods` DROP `diameter`; +ALTER TABLE `atg_goods` DROP `sold_count`; +ALTER TABLE `atg_goods` DROP `market_price`; +ALTER TABLE `atg_goods` DROP `price`; + +ALTER TABLE `atg_goods` ADD COLUMN `weight` mediumint(8) UNSIGNED DEFAULT NULL COMMENT '重量'; +ALTER TABLE `atg_goods` ADD COLUMN `length` mediumint(8) UNSIGNED DEFAULT NULL COMMENT '长度'; +ALTER TABLE `atg_goods` ADD COLUMN `width` mediumint(8) UNSIGNED DEFAULT NULL COMMENT '宽度'; +ALTER TABLE `atg_goods` ADD COLUMN `height` mediumint(8) UNSIGNED DEFAULT NULL COMMENT '高度'; +ALTER TABLE `atg_goods` ADD COLUMN `diameter` mediumint(8) UNSIGNED DEFAULT NULL COMMENT '直径'; +ALTER TABLE `atg_goods` ADD COLUMN `sold_count` int(10) UNSIGNED DEFAULT NULL COMMENT '已售数量'; +ALTER TABLE `atg_goods` ADD COLUMN `market_price` int(20) UNSIGNED DEFAULT NULL COMMENT '市场价'; +ALTER TABLE `atg_goods` ADD COLUMN `price` int(20) UNSIGNED DEFAULT NULL COMMENT '销售价'; \ No newline at end of file diff --git a/backend/modules/goods/models/ars/Goods.php b/backend/modules/goods/models/ars/Goods.php index beaa058..0028e81 100755 --- a/backend/modules/goods/models/ars/Goods.php +++ b/backend/modules/goods/models/ars/Goods.php @@ -47,6 +47,10 @@ use backend\modules\goods\models\ars\Supplier; * @property int $created_at 创建时间 * @property int $updated_at 更新时间 * @property int $sku_mode sku类型 + * @property int $is_taking 是否自提 + * @property int $is_express 是否快递发货 + * @property int $express_type 快递运费方式 + * @property int $uniform_postage 统一邮费 */ class Goods extends \yii\db\ActiveRecord { @@ -62,13 +66,38 @@ class Goods extends \yii\db\ActiveRecord //该商品是否开放销售is_sale const IS_SALE_NO = 0;//否 const IS_SALE_YES = 1;//是 - //sku类型 + //类型sku const SKU_MODE_ATTR = 1;//SKU类型属性 const SKU_MODE_MANUAL = 2;//SKU类型手写 + //是否自提is_taking + const IS_TAKING_NO = 0; //否 + const IS_TAKING_YES = 1; //是 + //是否快递发货is_express + const IS_EXPRESS_NO = 0; //否 + const IS_EXPRESS_YES = 1; //是 + //快递运费计算方式express_type + const EXPRESS_TYPE_UNIFORM_POSTAGE = 1; //统一邮费 + const EXPRESS_TYPE_EXPRESS_TEMPLATE = 2; //运费模板 + + public static $isTaking = [ + self::IS_TAKING_NO => '否', + self::IS_TAKING_YES => '是' + ]; + public static $isExpress = [ + self::IS_EXPRESS_NO => '否', + self::IS_EXPRESS_YES => '是' + ]; + public static $expressType = [ + self::EXPRESS_TYPE_UNIFORM_POSTAGE => '统一邮费', + self::EXPRESS_TYPE_EXPRESS_TEMPLATE => '运费模板' + ]; public static $isSale = [ self::IS_SALE_NO => '不在售', self::IS_SALE_YES => '在售' ]; + //无限库存 + const UNLIMITED_STOCK = -1; + public $ruleVerify = 0;//规则验证是否通过 /** * {@inheritdoc} @@ -78,13 +107,28 @@ class Goods extends \yii\db\ActiveRecord return 'atg_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} */ public function rules() { 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', 'sku_mode'], 'integer'], + [['pid', 'cat_id', 'brand_id', 'shop_cat_id', 'supplier_id', 'weight', 'length', 'width', 'height', 'diameter', 'sold_count', 'limit_count', 'stock', 'stock_warn', 'image', 'model_id', 'is_sale', 'sort_order', 'bouns_points', 'experience_points', 'is_delete', 'express_template', 'sku_mode', 'is_taking', 'is_express', 'express_type'], 'integer'], [['cat_id', 'brand_id', 'shop_cat_id', 'name'], 'required'], [['sn'], 'checkExist'], [['description', 'coverImageId', 'detailImageId'], 'string'], @@ -93,7 +137,8 @@ class Goods extends \yii\db\ActiveRecord [['code'], 'string', 'max' => 50], [['unit'], 'string', 'max' => 16], [['brief'], 'string', 'max' => 255], - [['weight', 'length', 'width', 'height', 'diameter', 'sold_count', 'market_price', 'price'], 'checkNegative'], + [['weight', 'length', 'width', 'height', 'diameter', 'sold_count', 'market_price', 'price', 'uniform_postage'], 'checkNegative'], + [['uniform_postage', 'market_price', 'price'], 'safe'] ]; } @@ -164,9 +209,14 @@ class Goods extends \yii\db\ActiveRecord 'bouns_points' => '奖励积分', 'experience_points' => '经验值', 'is_delete' => '是否删除,1为已删除', - 'express_template' => '配送详情id', + 'express_template' => '配送详情', 'created_at' => '创建时间', 'updated_at' => '更新时间', + 'sku_mode' => 'sku类型', + 'is_taking' => '是否自提', + 'is_express' => '是否快递发货', + 'express_type' => '快递运费方式', + 'uniform_postage' => '统一邮费', ]; } diff --git a/backend/modules/goods/models/ars/GoodsSku.php b/backend/modules/goods/models/ars/GoodsSku.php index ab0b17d..68bf7e9 100755 --- a/backend/modules/goods/models/ars/GoodsSku.php +++ b/backend/modules/goods/models/ars/GoodsSku.php @@ -24,6 +24,7 @@ use yii\behaviors\TimestampBehavior; * @property int $created_at 创建时间 * @property int $updated_at 更新时间 * @property int $is_manaul 是否手动 + * @property int $weight 重量 */ class GoodsSku extends \yii\db\ActiveRecord { @@ -48,9 +49,10 @@ class GoodsSku extends \yii\db\ActiveRecord { return [ [['goods_id', 'goods_sn'], 'required'], - [['goods_id', 'diameter', 'sold_count', 'stock', 'market_price', 'price', 'model_id', 'is_sale', 'sort_order', 'is_delete', 'is_manaul'], 'integer'], + [['goods_id', 'sold_count', 'stock', 'market_price', 'price', 'model_id', 'is_sale', 'sort_order', 'is_delete', 'is_manaul'], 'integer'], [['goods_code'], 'string', 'max' => 50], [['goods_sn', 'goods_attr'], 'string', 'max' => 60], + [['weight'], 'safe'] ]; } @@ -75,6 +77,7 @@ class GoodsSku extends \yii\db\ActiveRecord 'is_delete' => '是否删除,1为已删除', 'created_at' => '创建时间', 'updated_at' => '更新时间', + 'weight' => '重量', ]; } diff --git a/backend/modules/goods/models/searchs/GoodsSearch.php b/backend/modules/goods/models/searchs/GoodsSearch.php index 6a8b04f..aa0c6e1 100755 --- a/backend/modules/goods/models/searchs/GoodsSearch.php +++ b/backend/modules/goods/models/searchs/GoodsSearch.php @@ -63,7 +63,7 @@ class GoodsSearch extends Goods 'width'=>'10%', 'format' => 'raw', 'value' => function ($model) { - return $model->image ? + return $model->imageFile ? Html::img(['/'.$model->imageFile->path], ['style' => 'width:80px']) : '
未设置
'; @@ -129,7 +129,7 @@ class GoodsSearch extends Goods 'icon' => 'trash', 'title' => '删除', 'contents' => '确定删除?' - ] + ], ], ], ]; @@ -223,7 +223,6 @@ class GoodsSearch extends Goods 'created_at' => $this->created_at, 'updated_at' => $this->updated_at, ]); - $query->andFilterWhere(['like', 'name', $this->name]) ->andFilterWhere(['like', 'sn', $this->sn]) ->andFilterWhere(['like', 'code', $this->code]) diff --git a/backend/modules/goods/views/goods/_search.php b/backend/modules/goods/views/goods/_search.php index 9a86777..8e00aec 100755 --- a/backend/modules/goods/views/goods/_search.php +++ b/backend/modules/goods/views/goods/_search.php @@ -3,6 +3,9 @@ use yii\helpers\Html; use yii\widgets\ActiveForm; use \blobt\widgets\DateRangePicker; +use linyao\widgets\Select2; +use backend\modules\goods\models\ars\Category; +use backend\modules\goods\models\ars\ShopCategory; /* @var $this yii\web\View */ /* @var $model common\models\searchs\GoodsSearch */ @@ -10,40 +13,92 @@ use \blobt\widgets\DateRangePicker; ?> ['index'], - 'method' => 'get', - 'validateOnType' => true, - ]); + 'action' => ['index'], + 'method' => 'get', + 'validateOnType' => true, +]); ?> -
-
- field($model, 'id', [ - "template" => "{input}{error}", - "inputOptions" => [ - "placeholder" => "检索ID", - "class" => "form-control", - ], - "errorOptions" => [ - "class" => "error-tips" - ] - ]) - ?> -
-
- field($model, "created_at_range", [ - "template" => "{input}{error}", - "inputOptions" => [ - "placeholder" => "创建时间", - ], - "errorOptions" => [ - "class" => "error-tips" - ] - ])->widget(DateRangePicker::className()); - ?> -
+
+
+ field($model, 'id', [ + "template" => "{input}{error}", + "inputOptions" => [ + "placeholder" => "检索ID", + "class" => "form-control", + ], + "errorOptions" => [ + "class" => "error-tips" + ] + ]) + ?> +
+
+ field($model, 'name', [ + "template" => "{input}{error}", + "inputOptions" => [ + "placeholder" => "商品名称", + "class" => "form-control", + ], + "errorOptions" => [ + "class" => "error-tips" + ] + ]) + ?> +
+
+ field($model, 'sn', [ + "template" => "{input}{error}", + "inputOptions" => [ + "placeholder" => "商品唯一货号", + "class" => "form-control", + ], + "errorOptions" => [ + "class" => "error-tips" + ] + ]) + ?> +
+
+ field($model, 'cat_id', [ + "template" => "{input}{error}", + "inputOptions" => [ + "placeholder" => "后台商品类别", + "class" => "form-control", + ], + "errorOptions" => [ + "class" => "error-tips" + ] + ])->dropDownList(Category::modelColumn(), ['prompt' => '后台商品类别']); + ?> +
+
+ field($model, 'shop_cat_id', [ + "template" => "{input}{error}", + "inputOptions" => [ + "placeholder" => "前端商品类别", + "class" => "form-control", + ], + "errorOptions" => [ + "class" => "error-tips" + ] + ])->dropDownList(ShopCategory::modelColumn(), ['prompt' => '前端商品类别']); + ?> +
+
+ field($model, "created_at_range", [ + "template" => "{input}{error}", + "inputOptions" => [ + "placeholder" => "创建时间", + ], + "errorOptions" => [ + "class" => "error-tips" + ] + ])->widget(DateRangePicker::className()); + ?> +
', ['class' => 'btn btn-default']) ?> ', ['class' => 'btn btn-default']) ?>
-
+
\ No newline at end of file diff --git a/backend/modules/goods/views/goods/create.php b/backend/modules/goods/views/goods/create.php index a2f1131..1d87807 100755 --- a/backend/modules/goods/views/goods/create.php +++ b/backend/modules/goods/views/goods/create.php @@ -42,6 +42,12 @@ Yii::$app->params['bsVersion'] = '4.x'; 'attrValue' => [], ]), ], + [ + 'label' => ' 物流信息', + 'content' => $this->render('express', ['model' => $model, + 'form' => $form, + ]), + ], [ 'label' => ' 详情上传', 'content' => $this->render('new_editor', ['model' => $model, diff --git a/backend/modules/goods/views/goods/express.php b/backend/modules/goods/views/goods/express.php new file mode 100755 index 0000000..66682cb --- /dev/null +++ b/backend/modules/goods/views/goods/express.php @@ -0,0 +1,90 @@ + +field($model, 'is_taking')->widget(Icheck::className(), ['items' => Goods::$isTaking, 'type' => 'radio']) ?> + +field($model, 'is_express')->widget(Icheck::className(), ['items' => Goods::$isExpress, 'type' => 'radio']) ?> + +
+ field($model, 'express_type')->widget(Icheck::className(), ['items' => Goods::$expressType, 'type' => 'radio']) ?> + +
+ field($model, 'uniform_postage')->textInput() ?> +
+ +
+ field($model, 'express_template')->widget(Select2::className(), ["items" => ExpressTemplate::modelColumn()]) ?> +
+
+ +registerJs($js); + +?> \ No newline at end of file diff --git a/backend/modules/goods/views/goods/goods.php b/backend/modules/goods/views/goods/goods.php index c53b7ea..c94a5f4 100755 --- a/backend/modules/goods/views/goods/goods.php +++ b/backend/modules/goods/views/goods/goods.php @@ -61,4 +61,66 @@ use backend\modules\goods\models\ars\Goods;
'btn btn-success']) ?> 'btn btn-info']) ?> -
\ No newline at end of file + +registerJs($js); + +?> \ No newline at end of file diff --git a/backend/modules/goods/views/goods/update.php b/backend/modules/goods/views/goods/update.php index da346ef..25ac202 100755 --- a/backend/modules/goods/views/goods/update.php +++ b/backend/modules/goods/views/goods/update.php @@ -44,6 +44,12 @@ Yii::$app->params['bsVersion'] = '4.x'; 'goodsModel' => $model, ]), ], + [ + 'label' => ' 物流信息', + 'content' => $this->render('express', ['model' => $model, + 'form' => $form, + ]), + ], [ 'label' => ' 详情上传', 'content' => $this->render('new_editor', ['model' => $model, diff --git a/backend/modules/goods/views/goods/view.php b/backend/modules/goods/views/goods/view.php index 89146a0..d553ca5 100755 --- a/backend/modules/goods/views/goods/view.php +++ b/backend/modules/goods/views/goods/view.php @@ -77,7 +77,7 @@ $this->params['breadcrumbs'][] = $this->title; ['attribute' => 'image', 'format' => 'raw', 'value' => function ($model) { - return $model->image ? + return $model->imageFile ? Html::img(['/'.$model->imageFile->path], ['style' => 'width:80px']) : '
未设置
'; diff --git a/backend/modules/shop/controllers/ExpressTemplateController.php b/backend/modules/shop/controllers/ExpressTemplateController.php index 460be98..454bbb5 100755 --- a/backend/modules/shop/controllers/ExpressTemplateController.php +++ b/backend/modules/shop/controllers/ExpressTemplateController.php @@ -2,17 +2,20 @@ namespace backend\modules\shop\controllers; -use backend\modules\shop\models\ars\City; -use backend\modules\shop\models\ars\Province; +use backend\modules\shop\models\ars\City; +use backend\modules\shop\models\ars\Province; +use backend\modules\shop\models\searchs\ExpressAreaSearch; use Yii; -use backend\modules\shop\models\ars\ExpressTemplate; -use backend\modules\shop\models\searchs\ExpressTemplateSearch; -use yii\caching\Cache; +use backend\modules\shop\models\ars\ExpressTemplate; +use backend\modules\shop\models\searchs\ExpressTemplateSearch; use yii\web\Controller; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; use yii\web\Response; use yii\widgets\ActiveForm; +use backend\modules\shop\models\ars\ExpressArea; +use backend\modules\goods\models\ars\Goods; + /** * ExpressTemplateController implements the CRUD actions for ExpressTemplate model. @@ -71,52 +74,13 @@ class ExpressTemplateController extends Controller public function actionCreate() { $model = new ExpressTemplate(); - $model->calculation_type = ExpressTemplate::CALCULATION_TYPE_NUMBER; - $model->basic_count = 1; - $model->basic_price = '0.00'; - if (Yii::$app->request->isPost) { - $data = Yii::$app->request->post('ExpressTemplate'); - if (Yii::$app->request->isAjax) { - $model->load($data, ''); - Yii::$app->response->format = Response::FORMAT_JSON; - $data = ActiveForm::validate($model); - $data['status'] = 2; - return $data; - } - if (Yii::$app->request->post('area') == null) { - return $this->redirect(Yii::$app->request->referrer . '?status=1'); - } - $cityIds = array_keys(Yii::$app->request->post('area')); - $data['city'] = implode(',', $cityIds); - $model->load($data, ''); - $model->basic_price *= 100; - $model->extra_price *= 100; - if ($model->calculation_type == ExpressTemplate::CALCULATION_TYPE_WEIGHT) { - $model->basic_count *= 10; - $model->extra_count *= 10; - } else { - $model->basic_count *= 1; - $model->extra_count *= 1; - } - $model->save(); + if ($model->load(Yii::$app->request->post()) && $model->save()) { return $this->redirect('index'); } - $data = []; - $provinces = Province::find()->cache(0)->all(); - foreach ($provinces as $k => $v) { - $data[$k]['province'] = $v->name; - $cities = City::find()->cache(0) - ->where(['province_id' => $v->province_id]) - ->all(); - foreach ($cities as $city) { - $data[$k]['city'][] = ['id' => $city->city_id, 'name' => $city->name]; - } - } return $this->render('create', [ 'model' => $model, - 'data' => $data ]); } @@ -130,36 +94,13 @@ class ExpressTemplateController extends Controller public function actionUpdate($id) { $model = $this->findModel($id); - $model->basic_price /= 100; - $model->extra_price /= 100; - if ($model->calculation_type == ExpressTemplate::CALCULATION_TYPE_WEIGHT) { - $model->basic_count /= 10; - $model->extra_count /= 10; - } - $data = Yii::$app->request->post('ExpressTemplate'); - if ($data) { - if (Yii::$app->request->post('area') == null) { - return $this->redirect(Yii::$app->request->referrer . '&status=1'); - } - $cityIds = array_keys(Yii::$app->request->post('area')); - $data['city'] = implode(',', $cityIds); - $model->load($data, ''); - $model->save(); - return $this->render('view', ['model' => ExpressTemplate::findOne($model->id)]); - } - $data = []; - $provinces = Province::find()->cache(0)->all(); - foreach ($provinces as $k => $v) { - $data[$k]['province'] = $v->name; - $cities = City::find()->cache(0) - ->where(['province_id' => $v->province_id]) - ->all(); - foreach ($cities as $city) { - $data[$k]['city'][] = ['id' => $city->city_id, 'name' => $city->name]; - } + + if ($model->load(Yii::$app->request->post()) && $model->save()) { + return $this->redirect('index'); } + return $this->render('update', [ - 'model' => $model, 'data' => $data, 'cities' => explode(',', $model->city) + 'model' => $model, ]); } @@ -172,7 +113,13 @@ class ExpressTemplateController extends Controller */ public function actionDelete($id) { - $this->findModel($id)->delete(); + if (Goods::find()->where(['express_template' => $id])->count() == 0) { + $expressTemplateModel = $this->findModel($id); + ExpressArea::deleteAll(['express_template' => $expressTemplateModel->id]); + $expressTemplateModel->delete(); + } else { + Yii::$app->session->setFlash('error', '该模板已被使用'); + } return $this->redirect(['index']); } @@ -213,4 +160,184 @@ class ExpressTemplateController extends Controller 'columns' => $searchModel->columns() ]); } + + /** + * @return string + * 运费区域列表 + */ + public function actionExpressAreaList($id) + { + $expressTemplate = ExpressTemplate::findOne($id); + $searchModel = new ExpressAreaSearch(); + $dataProvider = $searchModel->search(Yii::$app->request->queryParams, $id); + + return $this->render('express_area_list', [ + 'searchModel' => $searchModel, + 'dataProvider' => $dataProvider, + 'columns' => $searchModel->columns(), + 'expressTemplate' => $expressTemplate + ]); + } + + /** + * @return array|mixed|string|Response + * 运费区域模板区域创建方法 + */ + public function actionExpressAreaCreate() + { + $expressTemplateId = Yii::$app->request->get('expressTemplateId'); + $expressTemplateModel = ExpressTemplate::findOne($expressTemplateId); + $model = new ExpressArea(); + $model->basic_count = 1; + $model->basic_price = '0.00'; + $model->express_template = $expressTemplateModel->id; + + if (Yii::$app->request->isPost) { + $data = Yii::$app->request->post('ExpressArea'); + if (Yii::$app->request->isAjax) { + $model->load($data, ''); + Yii::$app->response->format = Response::FORMAT_JSON; + $data = ActiveForm::validate($model); + $data['status'] = 2; + return $data; + } + if (Yii::$app->request->post('area') == null) { + return $this->redirect(Yii::$app->request->referrer . '?status=1'); + } + $cityIds = array_keys(Yii::$app->request->post('area')); + $data['city'] = implode(',', $cityIds); + $model->load($data, ''); + $model->basic_price *= 100; + $model->extra_price *= 100; + if ($expressTemplateModel->calculation_type == ExpressTemplate::CALCULATION_TYPE_WEIGHT) { + $model->basic_count *= 1000; + $model->extra_count *= 1000; + } else { + $model->basic_count *= 1; + $model->extra_count *= 1; + } + $model->save(); + return $this->redirect('express-area-list?id='.$model->express_template); + } + $data = []; + $expressAreas = ExpressArea::find()->select(['city'])->where(['express_template' => $expressTemplateModel->id])->all(); + $expressAresCityIdArr = []; + if ($expressAreas) { + foreach ($expressAreas as $expressAreaCity) { + $cityIdArr = explode(',', $expressAreaCity->city); + $expressAresCityIdArr = array_unique(array_merge($cityIdArr, $expressAresCityIdArr)); + } + } + $provinces = Province::find()->cache(0)->all(); + $j = 0; + foreach ($provinces as $k => $v) { + $cities = City::find() + ->where(['province_id' => $v->province_id]) + ->andWhere(['not in', 'city_id', $expressAresCityIdArr]) + ->all(); + if ($cities) { + $data[$j]['province'] = $v->name; + foreach ($cities as $city) { + $data[$j]['city'][] = ['id' => $city->city_id, 'name' => $city->name]; + } + $j++; + } + } + if (empty($data)) { + Yii::$app->session->setFlash('error', '已无地区选择'); + return $this->redirect('express-area-list?id='.$expressTemplateModel->id); + } + return $this->render('express_area_create', [ + 'model' => $model, + 'data' => $data, + 'expressTemplateModel' => $expressTemplateModel + ]); + } + + /** + * @return array|mixed|string|Response + * 运费区域模板区域更新方法 + */ + public function actionExpressAreaUpdate($id) + { + $model = ExpressArea::findOne($id); + $expressTemplateModel = ExpressTemplate::findOne($model->express_template); + $model->basic_price /= 100; + $model->extra_price /= 100; + if ($expressTemplateModel->calculation_type == ExpressTemplate::CALCULATION_TYPE_WEIGHT) { + $model->basic_count /= 10; + $model->extra_count /= 10; + } + $data = Yii::$app->request->post('ExpressArea'); + if ($data) { + if (Yii::$app->request->post('area') == null) { + return $this->redirect(Yii::$app->request->referrer . '&status=1'); + } + $cityIds = array_keys(Yii::$app->request->post('area')); + $data['city'] = implode(',', $cityIds); + $model->load($data, ''); + $model->basic_price *= 100; + $model->extra_price *= 100; + if ($expressTemplateModel->calculation_type == ExpressTemplate::CALCULATION_TYPE_WEIGHT) { + $model->basic_count *= 1000; + $model->extra_count *= 1000; + } else { + $model->basic_count *= 1; + $model->extra_count *= 1; + } + $model->save(); + return $this->redirect('express-area-list?id='.$model->express_template); + } + $data = []; + $expressAreas = ExpressArea::find()->select(['city'])->where(['express_template' => $expressTemplateModel->id])->andWhere(['!=', 'id', $id])->all(); + $expressAresCityIdArr = []; + if ($expressAreas) { + foreach ($expressAreas as $expressAreaCity) { + $cityIdArr = explode(',', $expressAreaCity->city); + $expressAresCityIdArr = array_unique(array_merge($cityIdArr, $expressAresCityIdArr)); + } + } + $provinces = Province::find()->cache(0)->all(); + $j = 0; + foreach ($provinces as $k => $v) { + $cities = City::find() + ->where(['province_id' => $v->province_id]) + ->andWhere(['not in', 'city_id', $expressAresCityIdArr]) + ->all(); + if ($cities) { + $data[$j]['province'] = $v->name; + foreach ($cities as $city) { + $data[$j]['city'][] = ['id' => $city->city_id, 'name' => $city->name]; + } + $j++; + } + } + + return $this->render('express_area_update', [ + 'model' => $model, 'data' => $data, 'cities' => explode(',', $model->city), 'expressTemplateModel' => $expressTemplateModel + ]); + } + + /** + * @param $id + * @return string + * 运费区域模板区域查看方法 + */ + public function actionExpressAreaView($id) + { + $expressAreaModel = ExpressArea::findOne($id); + $expressTemplateModel = ExpressTemplate::findOne($expressAreaModel->express_template); + return $this->render('express_area_view', [ + 'model' => $expressAreaModel, + 'expressTemplateModel' => $expressTemplateModel + ]); + } + + public function actionExpressAreaDelete($id) + { + $expressAreaModel = ExpressArea::findOne($id); + $expressTemplateId = $expressAreaModel->express_template; + $expressAreaModel->delete(); + return $this->redirect('express-area-list?id='.$expressTemplateId); + } } diff --git a/backend/modules/shop/migrations/m191205_092426_drop_columns_province_city_area_basic_price_basic_count_extra_count_extra_price_in_table_ats_express_template.php b/backend/modules/shop/migrations/m191205_092426_drop_columns_province_city_area_basic_price_basic_count_extra_count_extra_price_in_table_ats_express_template.php new file mode 100644 index 0000000..a0859df --- /dev/null +++ b/backend/modules/shop/migrations/m191205_092426_drop_columns_province_city_area_basic_price_basic_count_extra_count_extra_price_in_table_ats_express_template.php @@ -0,0 +1,32 @@ +dropColumn('ats_express_template', 'province'); + $this->dropColumn('ats_express_template', 'city'); + $this->dropColumn('ats_express_template', 'area'); + $this->dropColumn('ats_express_template', 'extra_price'); + $this->dropColumn('ats_express_template', 'basic_price'); + $this->dropColumn('ats_express_template', 'basic_count'); + $this->dropColumn('ats_express_template', 'extra_count'); + } + + public function down() + { + $this->addColumn('ats_express_template', 'province', $this->text()->comment('省份')); + $this->addColumn('ats_express_template', 'city', $this->text()->comment('城市')); + $this->addColumn('ats_express_template', 'area', $this->text()->comment('区域')); + $this->addColumn('ats_express_template', 'extra_price', $this->integer(20)->defaultValue(null)->comment('续重运费')); + $this->addColumn('ats_express_template', 'basic_price', $this->integer(20)->defaultValue(null)->comment('基本运费')); + $this->addColumn('ats_express_template', 'basic_count', $this->integer(20)->defaultValue(null)->comment('基本数量')); + $this->addColumn('ats_express_template', 'extra_count', $this->integer(20)->defaultValue(null)->comment('续重数量')); + return true; + } +} diff --git a/backend/modules/shop/migrations/m191205_092942_create_table_ats_express_area.php b/backend/modules/shop/migrations/m191205_092942_create_table_ats_express_area.php new file mode 100644 index 0000000..bd50a85 --- /dev/null +++ b/backend/modules/shop/migrations/m191205_092942_create_table_ats_express_area.php @@ -0,0 +1,36 @@ +createTable('ats_express_area', [ + 'id' => $this->primaryKey(), + 'province' => $this->text()->comment('省份'), + 'city' => $this->text()->comment('城市'), + 'area' => $this->text()->comment('区域'), + 'express_template' => $this->integer(11)->defaultValue(null)->comment('运费模板id'), + 'extra_price' => $this->integer(20)->defaultValue(null)->comment('续重运费'), + 'basic_price' => $this->integer(20)->defaultValue(null)->comment('基本运费'), + 'basic_count' => $this->integer(20)->defaultValue(null)->comment('基本数量'), + 'extra_count' => $this->integer(20)->defaultValue(null)->comment('续重数量'), + 'updated_at'=>$this->integer(11)->defaultValue(null)->comment('更新时间'), + 'created_at'=>$this->integer(11)->defaultValue(null)->comment('创建时间'), + ],$tableOptions); + } + + /** + * {@inheritdoc} + */ + public function down() + { + $this->dropTable('ats_express_area'); + return true; + } +} diff --git a/backend/modules/shop/migrations/m191206_092733_add_column_about_goods_to_table_collection.php b/backend/modules/shop/migrations/m191206_092733_add_column_about_goods_to_table_collection.php new file mode 100755 index 0000000..584e624 --- /dev/null +++ b/backend/modules/shop/migrations/m191206_092733_add_column_about_goods_to_table_collection.php @@ -0,0 +1,24 @@ +addColumn('ats_collection', 'goods_name', $this->string(120)->notNull()->defaultValue('')->comment('商品名称')); + $this->addColumn('ats_collection', 'goods_img', $this->integer(11)->comment('商品图片')); + $this->addColumn('ats_collection', 'goods_price', $this->integer(20)->notNull()->defaultValue(0)->comment('商品价格')); + } + + public function down() + { + $this->dropColumn('ats_collection', 'goods_name'); + $this->dropColumn('ats_collection', 'goods_img'); + $this->dropColumn('ats_collection', 'goods_price'); + return true; + } +} diff --git a/backend/modules/shop/migrations/m191206_162733_add_column_about_user_to_table_comment.php b/backend/modules/shop/migrations/m191206_162733_add_column_about_user_to_table_comment.php new file mode 100755 index 0000000..2435aca --- /dev/null +++ b/backend/modules/shop/migrations/m191206_162733_add_column_about_user_to_table_comment.php @@ -0,0 +1,22 @@ +addColumn('ats_comment', 'nickname', $this->string(120)->notNull()->defaultValue('')->comment('昵称')); + $this->addColumn('ats_comment', 'avatar', $this->integer(11)->comment('头像')); + } + + public function down() + { + $this->dropColumn('ats_comment', 'nickname'); + $this->dropColumn('ats_comment', 'avatar'); + return true; + } +} diff --git a/backend/modules/shop/models/ars/Address.php b/backend/modules/shop/models/ars/Address.php index 6f98d5e..b9c4401 100755 --- a/backend/modules/shop/models/ars/Address.php +++ b/backend/modules/shop/models/ars/Address.php @@ -1,6 +1,6 @@ '更新时间', ]; } - + /** - * @author linyao - * @email 602604991@qq.com - * @created Nov 8, 2019 - * - * 行为存储创建时间和更新时间 - */ + * @author linyao + * @email 602604991@qq.com + * @created Nov 8, 2019 + * + * 行为存储创建时间和更新时间 + */ public function behaviors() { return [ @@ -79,7 +82,7 @@ class Address extends \yii\db\ActiveRecord 'class' => TimestampBehavior::className(), 'createdAtAttribute' => 'created_at', 'updatedAtAttribute' => 'updated_at', - 'value' => function() { + 'value' => function () { return time(); }, ], diff --git a/backend/modules/shop/models/ars/Collection.php b/backend/modules/shop/models/ars/Collection.php old mode 100755 new mode 100644 index 6e31c3f..bd59665 --- a/backend/modules/shop/models/ars/Collection.php +++ b/backend/modules/shop/models/ars/Collection.php @@ -1,6 +1,6 @@ 120], ]; } @@ -46,6 +49,9 @@ class Collection extends \yii\db\ActiveRecord 'goods_id' => '商品id', 'updated_at' => '更新时间', 'created_at' => '创建时间', + 'goods_name' => '商品名称', + 'goods_img' => '商品图片', + 'goods_price' => '商品价格', ]; } diff --git a/backend/modules/shop/models/ars/Comment.php b/backend/modules/shop/models/ars/Comment.php old mode 100755 new mode 100644 index 2ebdee0..113ee20 --- a/backend/modules/shop/models/ars/Comment.php +++ b/backend/modules/shop/models/ars/Comment.php @@ -1,6 +1,6 @@ 120], ]; } @@ -53,6 +55,8 @@ class Comment extends \yii\db\ActiveRecord 'status' => '状态:1为显示,0为不显示', 'updated_at' => '更新时间', 'created_at' => '创建时间', + 'nickname' => '昵称', + 'avatar' => '头像', ]; } diff --git a/backend/modules/shop/models/ars/ExpressArea.php b/backend/modules/shop/models/ars/ExpressArea.php new file mode 100644 index 0000000..259201a --- /dev/null +++ b/backend/modules/shop/models/ars/ExpressArea.php @@ -0,0 +1,101 @@ + [ + "basic_count"=>"基本重量(KG)", + "basic_price"=>"基本运费(元)", + "extra_count"=>"续重重量(KG)", + "extra_price"=>"续重运费(元)" + ], + 2 => [ + "basic_count"=>"基本数量(件)", + "basic_price"=>"基本运费(元)", + "extra_count"=>"续重数量(件)", + "extra_price"=>"续重运费(元)" + ] + ]; + /** + * {@inheritdoc} + */ + public static function tableName() + { + return 'ats_express_area'; + } + + /** + * {@inheritdoc} + */ + public function rules() + { + return [ + [['province', 'city', 'area'], 'string'], + [['express_template'], 'integer'], + [['extra_price', 'basic_price', 'basic_count', 'extra_count'], 'safe'], + [['extra_price', 'basic_price', 'basic_count', 'extra_count'], 'number'], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'id', + 'province' => '省份', + 'city' => '城市', + 'area' => '区域', + 'express_template' => '运费模板id', + 'extra_price' => '续重运费', + 'basic_price' => '基本运费', + 'basic_count' => '基本数量', + 'extra_count' => '续重数量', + 'updated_at' => '更新时间', + 'created_at' => '创建时间', + ]; + } + + + /** + * @author linyao + * @email 602604991@qq.com + * @created Nov 8, 2019 + * + * 行为存储创建时间和更新时间 + */ + public function behaviors() + { + return [ + [ + 'class' => TimestampBehavior::className(), + 'createdAtAttribute' => 'created_at', + 'updatedAtAttribute' => 'updated_at', + 'value' => function() { + return time(); + }, + ], + ]; + } +} diff --git a/backend/modules/shop/models/ars/ExpressTemplate.php b/backend/modules/shop/models/ars/ExpressTemplate.php index ce4fd07..b0ef8b7 100644 --- a/backend/modules/shop/models/ars/ExpressTemplate.php +++ b/backend/modules/shop/models/ars/ExpressTemplate.php @@ -10,15 +10,8 @@ use yii\behaviors\TimestampBehavior; * * @property int $id * @property string $name 名称 - * @property string $province 省份 - * @property string $city 城市 - * @property string $area 区域 - * @property int $extra_price 续重运费 * @property int $updated_at 更新时间 * @property int $created_at 创建时间 - * @property int $basic_price 基本运费 - * @property int $basic_count 基本数量 - * @property int $extra_count 续重数量 * @property int $calculation_type 计算方式 */ class ExpressTemplate extends \yii\db\ActiveRecord @@ -46,10 +39,8 @@ class ExpressTemplate extends \yii\db\ActiveRecord { return [ [['name'], 'required'], - [['province', 'city', 'area'], 'string'], [['calculation_type'], 'integer'], - [['name'], 'string', 'max' => 255], - [['extra_price', 'basic_price', 'basic_count', 'extra_count'], 'safe'] + [['name'], 'string', 'max' => 255] ]; } @@ -61,15 +52,8 @@ class ExpressTemplate extends \yii\db\ActiveRecord return [ 'id' => 'id', 'name' => '名称', - 'province' => '省份', - 'city' => '城市', - 'area' => '区域', - 'extra_price' => '续重运费', 'updated_at' => '更新时间', 'created_at' => '创建时间', - 'basic_price' => '基本运费', - 'basic_count' => '基本数量', - 'extra_count' => '续重数量', 'calculation_type' => '计算方式', ]; } @@ -95,4 +79,13 @@ class ExpressTemplate extends \yii\db\ActiveRecord ], ]; } + + /** + * @return array + * 数据键值对 + */ + public static function modelColumn() + { + return $column = self::find()->select(['name'])->indexBy('id')->column(); + } } diff --git a/backend/modules/shop/models/ars/Order.php b/backend/modules/shop/models/ars/Order.php index 3e155ff..59ceb5e 100755 --- a/backend/modules/shop/models/ars/Order.php +++ b/backend/modules/shop/models/ars/Order.php @@ -1,6 +1,6 @@ 64], @@ -117,15 +124,36 @@ class Order extends \yii\db\ActiveRecord 'address' => '详细地址', ]; } - + + public function beforeSave($insert) + { + $address = Yii::createObject([ + 'class' => 'api\logic\AddressLogic', + ]); + if ($insert) { + $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([ + 'class' => 'api\logic\ExpressLogic', + ]); + $this->shipping_amount = $express->countShippingAmount($this); + $this->receivables = $this->goods_amount + $this->shipping_amount; + $this->payment_amount = $this->receivables - $this->discount_amount; + } + return parent::beforeSave($insert); + } /** - * @author linyao - * @email 602604991@qq.com - * @created Nov 8, 2019 - * - * 行为存储创建时间和更新时间 - */ + * @author linyao + * @email 602604991@qq.com + * @created Nov 8, 2019 + * + * 行为存储创建时间和更新时间 + */ public function behaviors() { return [ @@ -133,7 +161,7 @@ class Order extends \yii\db\ActiveRecord 'class' => TimestampBehavior::className(), 'createdAtAttribute' => 'created_at', 'updatedAtAttribute' => 'updated_at', - 'value' => function() { + 'value' => function () { return time(); }, ], diff --git a/backend/modules/shop/models/searchs/ExpressAreaSearch.php b/backend/modules/shop/models/searchs/ExpressAreaSearch.php new file mode 100644 index 0000000..0893957 --- /dev/null +++ b/backend/modules/shop/models/searchs/ExpressAreaSearch.php @@ -0,0 +1,187 @@ + 'blobt\grid\CheckboxColumn', + 'width' => '2%', + 'align' => 'center' + ], + 'id', + ['attribute' => 'city', + 'value' => function ($model) { + $expressAreas = ExpressArea::findOne($model->id); + $expressAresCityIdArr = explode(',', $expressAreas->city); + $cities = []; + $provinces = Province::find()->cache(0)->all(); + foreach ($provinces as $k => $v) { + $cityId = City::find() + ->select(['city_id']) + ->where(['province_id' => $v->province_id]) + ->column(); + if (empty(array_diff($cityId, $expressAresCityIdArr))) { + $cities[] = $v->name; + }else{ + foreach (\backend\modules\shop\models\ars\City::find()->andWhere(['in', 'city_id', array_diff($cityId, array_diff($cityId, $expressAresCityIdArr))])->all() as $city) { + $cities[] = $city->name; + } + } + } + return implode(' , ', $cities); + }, + ], + [ + 'class' => 'iron\grid\ActionColumn', + 'align' => 'center', + 'config' => [ + [ + 'name' => 'express-area-view', + 'icon' => 'list', + 'title' => '详情', + ], + [ + 'name' => 'express-area-update', + 'icon' => 'pencil', + 'title' => '修改' + ], + [ + 'name' => 'express-area-delete', + 'icon' => 'trash', + 'title' => '删除', + 'contents' => '确定删除?' + ] + ], + ], + ]; + } + /** + * @param $params + * @return ActiveDataProvider + * 不分页的所有数据 + */ + public function allData($params) + { + $query = ExpressArea::find(); + $dataProvider = new ActiveDataProvider([ + 'query' => $query, + 'pagination' => false, + 'sort' => false + ]); + $this->load($params); + return $this->filter($query, $dataProvider); + } + + /** + * Creates data provider instance with search query applied + * + * @param array $params + * + * @return ActiveDataProvider + */ + public function search($params, $expressTemplateId) + { + $query = ExpressArea::find()->where(['express_template' => $expressTemplateId]); + + // add conditions that should always apply here + + $dataProvider = new ActiveDataProvider([ + 'query' => $query, + 'pagination' => [ + 'pageSizeLimit' => [1, 200] + ], + 'sort' => [ + 'defaultOrder' => [ + 'id' => SORT_DESC, + ] + ], + ]); + + $this->load($params); + return $this->filter($query, $dataProvider); + } + /** + * @param $query + * @param $dataProvider + * @return ActiveDataProvider + * 条件筛选 + */ + private function filter($query, $dataProvider){ + if (!$this->validate()) { + // uncomment the following line if you do not want to return any records when validation fails + // $query->where('0=1'); + return $dataProvider; + } + + // grid filtering conditions + $query->andFilterWhere([ + 'id' => $this->id, + 'express_template' => $this->express_template, + 'extra_price' => $this->extra_price, + 'basic_price' => $this->basic_price, + 'basic_count' => $this->basic_count, + 'extra_count' => $this->extra_count, + 'updated_at' => $this->updated_at, + 'created_at' => $this->created_at, + ]); + + $query->andFilterWhere(['like', 'province', $this->province]) + ->andFilterWhere(['like', 'city', $this->city]) + ->andFilterWhere(['like', 'area', $this->area]); + if ($this->created_at_range) { + $arr = explode(' ~ ', $this->created_at_range); + $start = strtotime($arr[0]); + $end = strtotime($arr[1]) + 3600 * 24; + $query->andFilterWhere(['between', 'created_at', $start, $end]); + } + return $dataProvider; + } +} diff --git a/backend/modules/shop/models/searchs/ExpressTemplateSearch.php b/backend/modules/shop/models/searchs/ExpressTemplateSearch.php index 8cee01c..09beeed 100755 --- a/backend/modules/shop/models/searchs/ExpressTemplateSearch.php +++ b/backend/modules/shop/models/searchs/ExpressTemplateSearch.php @@ -26,8 +26,8 @@ class ExpressTemplateSearch extends ExpressTemplate public function rules() { return [ - [['id', 'calculation_type', 'basic_price', 'basic_count', 'extra_price', 'extra_count', 'updated_at', 'created_at'], 'integer'], - [['name', 'province', 'city', 'area'], 'safe'], + [['id', 'calculation_type', 'updated_at', 'created_at'], 'integer'], + [['name'], 'safe'], ['created_at_range','safe'], ]; } @@ -52,11 +52,35 @@ class ExpressTemplateSearch extends ExpressTemplate 'width' => '2%', 'align' => 'center' ], - 'id', - 'name', + 'id', + 'name', + [ + 'attribute' => 'calculation_type', + 'value' => function ($model) { + return ExpressTemplate::$calculationType[$model->calculation_type]; + } + ], [ 'class' => 'iron\grid\ActionColumn', 'align' => 'center', + 'config' => [ + [ + 'name' => 'update', + 'icon' => 'pencil', + 'title' => '修改' + ], + [ + 'name' => 'express-area-list', + 'icon' => 'hard-drive', + 'title' => '配送区域' + ], + [ + 'name' => 'delete', + 'icon' => 'trash', + 'title' => '删除', + 'contents' => '确定删除?' + ] + ], ], ]; } @@ -122,18 +146,11 @@ class ExpressTemplateSearch extends ExpressTemplate $query->andFilterWhere([ 'id' => $this->id, 'calculation_type' => $this->calculation_type, - 'basic_price' => $this->basic_price, - 'basic_count' => $this->basic_count, - 'extra_price' => $this->extra_price, - 'extra_count' => $this->extra_count, 'updated_at' => $this->updated_at, 'created_at' => $this->created_at, ]); - $query->andFilterWhere(['like', 'name', $this->name]) - ->andFilterWhere(['like', 'province', $this->province]) - ->andFilterWhere(['like', 'city', $this->city]) - ->andFilterWhere(['like', 'area', $this->area]); + $query->andFilterWhere(['like', 'name', $this->name]); if ($this->created_at_range) { $arr = explode(' ~ ', $this->created_at_range); $start = strtotime($arr[0]); diff --git a/backend/modules/shop/models/searchs/OrderSearch.php b/backend/modules/shop/models/searchs/OrderSearch.php index f63cc1c..0cd28ed 100755 --- a/backend/modules/shop/models/searchs/OrderSearch.php +++ b/backend/modules/shop/models/searchs/OrderSearch.php @@ -15,13 +15,14 @@ use yii\helpers\Html; class OrderSearch extends Order { /** - * @return array - * 增加创建时间查询字段 - */ + * @return array + * 增加创建时间查询字段 + */ public function attributes() - { - return ArrayHelper::merge(['created_at_range'], parent::attributes()); - } + { + return ArrayHelper::merge(['created_at_range'], parent::attributes()); + } + /** * {@inheritdoc} */ @@ -30,7 +31,7 @@ class OrderSearch extends Order return [ [['id', 'user_id', 'status', 'type', 'goods_count', 'goods_amount', 'shipping_amount', 'shipping_type', 'taking_site', 'pay_type', 'pay_at', 'payment_amount', 'receivables', 'discount_amount', 'updated_at', 'created_at'], 'integer'], [['order_sn', 'invoice_id', 'consignee', 'phone', 'province', 'city', 'area', 'payment_sn', 'remarks', 'discount_description'], 'safe'], - ['created_at_range','safe'], + ['created_at_range', 'safe'], ]; } @@ -42,13 +43,14 @@ class OrderSearch extends Order // bypass scenarios() implementation in the parent class return Model::scenarios(); } + /** - * @return array - * 列格式 - */ + * @return array + * 列格式 + */ public function columns() { - return [ + return [ [ 'class' => 'blobt\grid\CheckboxColumn', 'width' => '2%', @@ -169,14 +171,15 @@ class OrderSearch extends Order ], ]; } + /** - * @param $params - * @return ActiveDataProvider - * 不分页的所有数据 - */ + * @param $params + * @return ActiveDataProvider + * 不分页的所有数据 + */ public function allData($params) { - $query = Order::find(); + $query = Order::find(); $dataProvider = new ActiveDataProvider([ 'query' => $query, 'pagination' => false, @@ -214,13 +217,15 @@ class OrderSearch extends Order $this->load($params); return $this->filter($query, $dataProvider); } + /** - * @param $query - * @param $dataProvider - * @return ActiveDataProvider - * 条件筛选 - */ - private function filter($query, $dataProvider){ + * @param $query + * @param $dataProvider + * @return ActiveDataProvider + * 条件筛选 + */ + private function filter($query, $dataProvider) + { if (!$this->validate()) { // uncomment the following line if you do not want to return any records when validation fails // $query->where('0=1'); diff --git a/backend/modules/shop/views/express-template/_form.php b/backend/modules/shop/views/express-template/_form.php index 940b46f..c919f92 100755 --- a/backend/modules/shop/views/express-template/_form.php +++ b/backend/modules/shop/views/express-template/_form.php @@ -2,144 +2,31 @@ use blobt\widgets\Icheck; use backend\modules\shop\models\ars\ExpressTemplate; +use yii\bootstrap4\ActiveForm; +use yii\bootstrap4\Html; /* @var $this yii\web\View */ /* @var $model backend\modules\shop\models\ars\ExpressTemplate */ /* @var $form yii\widgets\ActiveForm */ ?> -request->get('status'); -if ($status == 1) { - ?> - - - -field($model, 'name')->textInput(['maxlength' => true]) ?> - -field($model, 'calculation_type')->widget(Icheck::className(), ["items" => ExpressTemplate::$calculationType, 'type' => "radio"]) ?> - -field($model, 'basic_count')->textInput() ?> +
-field($model, 'basic_price')->textInput() ?> + -field($model, 'extra_count')->textInput() ?> + field($model, 'name')->textInput(['maxlength' => true]) ?> -field($model, 'extra_price')->textInput() ?> - -field($model, 'calculation_type')->widget(Icheck::className(), ["items" => ExpressTemplate::$calculationType, 'type' => "radio"]); + } + ?> - $.each(formList[type],function(index,value){ //更改文字标题 - $("." + index).children("label").html(value) - }); - - $("#expresstemplate-basic_count").val(udfVal[type][0])//重置初始值 - $("#expresstemplate-basic_price").val(udfVal[type][1]) - $("#expresstemplate-extra_count").val(0) - $("#expresstemplate-extra_price").val(udfVal[type][1]) - calType = type; -} -function changeCalType(type){//当切换计算方式 +
+ 'btn btn-success']) ?> + 'btn btn-info']) ?> +
- $.each(formList[type],function(index,value){ //更改文字标题 - $("." + index).children("label").html(value) - }); - - if(!$("#expresstemplate-basic_count").val()){ - $("#expresstemplate-basic_count").val(udfVal[type][0])//重置初始值 - } - if(!$("#expresstemplate-basic_price").val()){ - $("#expresstemplate-basic_price").val(udfVal[type][1]) - } - if(!$("#expresstemplate-extra_count").val()){ - $("#expresstemplate-extra_count").val(0) - } - if(!$("#expresstemplate-extra_price").val()){ - $("#expresstemplate-extra_price").val(udfVal[type][1]) - } - calType = type; -} -$(document).ready(function(){ - $("#expresstemplate-basic_count").blur(function(){ - if (calType == 0) { - if($(this).val() < 0.1){ - $(this).val(0.1) - } - var basiccount = $(this).val(); - $(this).val(Math.floor(basiccount * 10) / 10); - } else{ - if($(this).val() < 1){ - $(this).val(1) - } - var basiccount = $(this).val(); - $(this).val(Math.floor(basiccount * 1) / 1); - } - }) - $("#expresstemplate-basic_price").blur(function(){ - if($(this).val().indexOf('-') != -1){ - $(this).val("0.00") - } - var basicPrice = $(this).val(); - $(this).val(basicPrice.toString().match(/^\d+(?:\.\d{0,2})?/)); - }) - $("#expresstemplate-extra_count").blur(function(){ - if (calType == 0) { - if($(this).val() < 0){ - $(this).val(0) - } - var basiccount = $(this).val(); - $(this).val(Math.floor(basiccount * 10) / 10); - } else{ - if($(this).val() < 0){ - $(this).val(0) - } - var basiccount = $(this).val(); - $(this).val(Math.floor(basiccount * 1) / 1); - } - }) - $("#expresstemplate-extra_price").blur(function(){ - if($(this).val().indexOf('-') != -1){ - $(this).val("0.00") - } - var basicPrice = $(this).val(); - $(this).val(basicPrice.toString().match(/^\d+(?:\.\d{0,2})?/)); - }) - - $("input:radio[name='ExpressTemplate[calculation_type]']").on('ifChecked', function(event){ - updateTypeChangeCalType($(this).val()-1) - }) - changeCalType(calType) -}) -JS; -$this->registerJs($js) + -?> \ No newline at end of file +
\ No newline at end of file diff --git a/backend/modules/shop/views/express-template/create.php b/backend/modules/shop/views/express-template/create.php index fb35a2e..14ec692 100755 --- a/backend/modules/shop/views/express-template/create.php +++ b/backend/modules/shop/views/express-template/create.php @@ -13,38 +13,10 @@ $this->params['breadcrumbs'][] = $this->title; Yii::$app->params['bsVersion'] = '4.x'; ?>
-
- ['class' => 'container-fluid']]); + render('_form', [ + 'model' => $model, + 'isCreate' => true + ]) ?> - echo TabsX::widget([ - 'bordered' => true, - 'items' => [ - [ - 'label' => ' 基本信息', - 'content' => $this->render('_form', [ - 'model' => $model, - 'form' => $form, - ]), - ], - [ - 'label' => ' 选择配送区域', - 'content' => $this->render('area', ['data' => $data, 'form' => $form, 'cities' => [] - ]), - ], - ], - 'position' => TabsX::POS_ABOVE, - 'encodeLabels' => false - ]); - ?> - -
- 'btn btn-success']) ?> - 'btn btn-info']) ?> -
- - - -
diff --git a/backend/modules/shop/views/express-template/express_area_create.php b/backend/modules/shop/views/express-template/express_area_create.php new file mode 100755 index 0000000..d9068a5 --- /dev/null +++ b/backend/modules/shop/views/express-template/express_area_create.php @@ -0,0 +1,51 @@ +title = '创建区域运费模板'; +$this->params['breadcrumbs'][] = ['label' => '运费区域模板', 'url' => ['express_area_list', ['id' => $expressTemplateModel->id]]]; +$this->params['breadcrumbs'][] = $this->title; +Yii::$app->params['bsVersion'] = '4.x'; +?> +
+
+ + ['class' => 'container-fluid']]); + + echo TabsX::widget([ + 'bordered' => true, + 'items' => [ + [ + 'label' => ' 基本信息', + 'content' => $this->render('express_area_form', [ + 'model' => $model, + 'form' => $form, + 'expressTemplateModel' => $expressTemplateModel + ]), + ], + [ + 'label' => ' 选择配送区域', + 'content' => $this->render('area', ['data' => $data, 'form' => $form, 'cities' => [] + ]), + ], + ], + 'position' => TabsX::POS_ABOVE, + 'encodeLabels' => false + ]); + ?> + +
+ 'btn btn-success']) ?> + $expressTemplateModel->id], ['class' => 'btn btn-info']) ?> +
+ + + +
+
diff --git a/backend/modules/shop/views/express-template/express_area_form.php b/backend/modules/shop/views/express-template/express_area_form.php new file mode 100755 index 0000000..d014ccf --- /dev/null +++ b/backend/modules/shop/views/express-template/express_area_form.php @@ -0,0 +1,175 @@ + + +request->get('status'); +if ($status == 1) { + ?> + + + +field($model, 'express_template')->textInput(['maxlength' => true]) ?> + +field($model, 'basic_count')->textInput() ?> + +field($model, 'basic_price')->textInput() ?> + +field($model, 'extra_count')->textInput() ?> + +field($model, 'extra_price')->textInput() ?> + +calculation_type}-1;//初始的计算方式0:计重 1:计件 + +function updateTypeChangeCalType(type){//当切换计算方式 + + $.each(formList[type],function(index,value){ //更改文字标题 + $("." + index).children("label").html(value) + }); + + $("#expressarea-basic_count").val(udfVal[type][0])//重置初始值 + $("#expressarea-basic_price").val(udfVal[type][1]) + $("#expressarea-extra_count").val(0) + $("#expressarea-extra_price").val(udfVal[type][1]) + calType = type; +} +function changeCalType(type){//当切换计算方式 + + $.each(formList[type],function(index,value){ //更改文字标题 + $("." + index).children("label").html(value) + }); + + if(!$("#expressarea-basic_count").val()){ + $("#expressarea-basic_count").val(udfVal[type][0])//重置初始值 + } + if(!$("#expressarea-basic_price").val()){ + $("#expressarea-basic_price").val(udfVal[type][1]) + } + if(!$("#expressarea-extra_count").val()){ + $("#expressarea-extra_count").val(0) + } + if(!$("#expressarea-extra_price").val()){ + $("#expressarea-extra_price").val(udfVal[type][1]) + } + calType = type; +} +//金额补全 +function toFixeds(val, pre) { + const num = parseFloat(val); + // eslint-disable-next-line no-restricted-globals + if (isNaN(num)) { + return false; + } + const p = 10 ** pre; + const value = num * p; + let f = (Math.round(value) / p).toString(); + let rs = f.indexOf('.'); + if (rs < 0) { + rs = f.length; + f += '.'; + } + while (f.length <= rs + pre) { + f += '0'; + } + return f; +} +$(document).ready(function(){ + $("#expressarea-basic_count").blur(function(){ + if(isNaN($(this).val())){ + $(this).val(1) + } + if (calType == 0) { + if($(this).val() < 0.1){ + $(this).val(1) + } + var basiccount = $(this).val(); + $(this).val(toFixeds($(this).val(), 1)); + } else{ + if($(this).val() < 1){ + $(this).val(1) + } + var basiccount = $(this).val(); + $(this).val(Math.floor(basiccount * 1) / 1); + } + }) + $("#expressarea-basic_price").blur(function(){ + if(isNaN($(this).val())){ + $(this).val("0.00") + } + if($(this).val().indexOf('-') != -1){ + $(this).val("0.00") + } + var basicPrice = $(this).val(); + $(this).val(toFixeds($(this).val(), 2)); + }) + $("#expressarea-extra_count").blur(function(){ + if(isNaN($(this).val())){ + $(this).val(0) + } + if (calType == 0) { + if($(this).val() < 0){ + $(this).val(0) + } + var basiccount = $(this).val(); + $(this).val(toFixeds($(this).val(), 1)); + } else{ + if($(this).val() < 0){ + $(this).val(0) + } + var basiccount = $(this).val(); + $(this).val(Math.floor(basiccount * 1) / 1); + } + }) + $("#expressarea-extra_price").blur(function(){ + if(isNaN($(this).val())){ + $(this).val("0.00") + } + if($(this).val().indexOf('-') != -1){ + $(this).val("0.00") + } + var basicPrice = $(this).val(); + $(this).val(toFixeds($(this).val(), 2)); + }) + + $("input:radio[name='ExpressArea[calculation_type]']").on('ifChecked', function(event){ + updateTypeChangeCalType($(this).val()-1) + }) + changeCalType(calType) +}) +JS; +$this->registerJs($js) + +?> \ No newline at end of file diff --git a/backend/modules/shop/views/express-template/express_area_list.php b/backend/modules/shop/views/express-template/express_area_list.php new file mode 100644 index 0000000..1f59fb9 --- /dev/null +++ b/backend/modules/shop/views/express-template/express_area_list.php @@ -0,0 +1,33 @@ +title = '运费区域模板:'.$expressTemplate->name; +$this->params['breadcrumbs'][] = $this->title; +?> +
+
+ $dataProvider, + 'filter' => $this->render("_search", ['model' => $searchModel]), + 'batch' => [ + [ + "label" => "删除", + "url" => "express-area/deletes" + ], + ], + 'columns' => $columns, + 'batchTemplate' => '', + 'create' => '', + 'export' => '', + 'content' => Html::a('创建', ['express-area-create', 'expressTemplateId' => $expressTemplate->id], ['class' => 'btn btn-default']). + Html::a('返回', ['index'], ['class' => 'btn btn-default']) + ]); + ?> +
+
\ No newline at end of file diff --git a/backend/modules/shop/views/express-template/express_area_update.php b/backend/modules/shop/views/express-template/express_area_update.php new file mode 100755 index 0000000..60c0704 --- /dev/null +++ b/backend/modules/shop/views/express-template/express_area_update.php @@ -0,0 +1,52 @@ +title = '编辑区域运费模板'; +$this->params['breadcrumbs'][] = ['label' => '运费模板', 'url' => ['index']]; +$this->params['breadcrumbs'][] = ['label' => '区域运费模板:'.$expressTemplateModel->name, 'url' => ['express-area-list', 'id' => $expressTemplateModel->id]]; +$this->params['breadcrumbs'][] = '编辑区域运费模板'; +Yii::$app->params['bsVersion'] = '4.x'; +?> +
+
+ + ['class' => 'container-fluid']]); + + echo TabsX::widget([ + 'bordered' => true, + 'items' => [ + [ + 'label' => ' 基本信息', + 'content' => $this->render('express_area_form', [ + 'model' => $model, + 'form' => $form, + 'expressTemplateModel' => $expressTemplateModel + ]), + ], + [ + 'label' => ' 选择配送区域', + 'content' => $this->render('area', ['data' => $data, 'form' => $form, 'cities' => $cities + ]), + ], + ], + 'position' => TabsX::POS_ABOVE, + 'encodeLabels' => false + ]); + ?> + +
+ 'btn btn-success']) ?> + $expressTemplateModel->id], ['class' => 'btn btn-info']) ?> +
+ + + +
+
diff --git a/backend/modules/shop/views/express-template/express_area_view.php b/backend/modules/shop/views/express-template/express_area_view.php new file mode 100755 index 0000000..31d353e --- /dev/null +++ b/backend/modules/shop/views/express-template/express_area_view.php @@ -0,0 +1,94 @@ +title = $model->id; +$this->params['breadcrumbs'][] = ['label' => '运费模板', 'url' => ['index']]; +$this->params['breadcrumbs'][] = ['label' => '运费区域模板:'.$expressTemplateModel->name, 'url' => ['express-area-list?id='.$expressTemplateModel->id]]; +$this->params['breadcrumbs'][] = $this->title; +\yii\web\YiiAsset::register($this); +?> +
+ +

+ id], ['class' => 'btn btn-success']) ?> +

+ + $model, + 'attributes' => [ + 'id', + [ + 'attribute' => 'basic_count', + 'label' => ExpressArea::$formList[$expressTemplateModel->calculation_type]['basic_count'], + 'value' => function ($model) { + $expressTemplateModel = ExpressTemplate::findOne($model->express_template); + if ($expressTemplateModel->calculation_type == ExpressTemplate::CALCULATION_TYPE_WEIGHT) { + return $model->basic_count /= 10; + } else { + return $model->basic_count; + } + } + ], + [ + 'attribute' => 'basic_price', + 'label' => ExpressArea::$formList[$expressTemplateModel->calculation_type]['basic_price'], + 'value' => function ($model) { + return $model->basic_price /= 100; + } + ], + [ + 'attribute' => 'extra_count', + 'label' => ExpressArea::$formList[$expressTemplateModel->calculation_type]['extra_count'], + 'value' => function ($model) { + $expressTemplateModel = ExpressTemplate::findOne($model->express_template); + if ($expressTemplateModel->calculation_type == ExpressTemplate::CALCULATION_TYPE_WEIGHT) { + return $model->extra_count /= 10; + } else { + return $model->extra_count; + } + } + ], + [ + 'attribute' => 'extra_price', + 'label' => ExpressArea::$formList[$expressTemplateModel->calculation_type]['extra_price'], + 'value' => function ($model) { + return $model->extra_price /= 100; + } + ], + 'updated_at:datetime', + 'created_at:datetime', + ['attribute' => 'city', + 'value' => function ($model) { + $expressAreas = ExpressArea::findOne($model->id); + $expressAresCityIdArr = explode(',', $expressAreas->city); + $cities = []; + $provinces = Province::find()->cache(0)->all(); + foreach ($provinces as $k => $v) { + $cityId = City::find() + ->select(['city_id']) + ->where(['province_id' => $v->province_id]) + ->column(); + if (empty(array_diff($cityId, $expressAresCityIdArr))) { + $cities[] = $v->name; + }else{ + foreach (\backend\modules\shop\models\ars\City::find()->andWhere(['in', 'city_id', array_diff($cityId, array_diff($cityId, $expressAresCityIdArr))])->all() as $city) { + $cities[] = $city->name; + } + } + } + return implode(' , ', $cities); + }, + ], + ], + ]) ?> + +
diff --git a/backend/modules/shop/views/express-template/update.php b/backend/modules/shop/views/express-template/update.php index 13c0193..8e086e9 100755 --- a/backend/modules/shop/views/express-template/update.php +++ b/backend/modules/shop/views/express-template/update.php @@ -14,38 +14,10 @@ $this->params['breadcrumbs'][] = 'Update '; Yii::$app->params['bsVersion'] = '4.x'; ?>
-
- ['class' => 'container-fluid']]); + render('_form', [ + 'model' => $model, + 'isCreate' => false + ]) ?> - echo TabsX::widget([ - 'bordered' => true, - 'items' => [ - [ - 'label' => ' 基本信息', - 'content' => $this->render('_form', [ - 'model' => $model, - 'form' => $form, - ]), - ], - [ - 'label' => ' 选择配送区域', - 'content' => $this->render('area', ['data' => $data, 'form' => $form, 'cities' => $cities - ]), - ], - ], - 'position' => TabsX::POS_ABOVE, - 'encodeLabels' => false - ]); - ?> - -
- 'btn btn-success']) ?> - 'btn btn-info']) ?> -
- - - -
diff --git a/backend/views/layouts/main.php b/backend/views/layouts/main.php index b938779..9be8095 100755 --- a/backend/views/layouts/main.php +++ b/backend/views/layouts/main.php @@ -31,16 +31,12 @@ AppAsset::register($this); beginBody() ?>
- render('header') ?> - - render('sidebar') ?> - -
- session->hasFlash('error') || Yii::$app->session->hasFlash('success')) { - echo Alert::widget(); - } - ?> + session->hasFlash('error') || Yii::$app->session->hasFlash('success')) { + echo Alert::widget(); + } + ?> +
render('breadcrumb') ?>
@@ -49,7 +45,6 @@ AppAsset::register($this);
- render('footer') ?>
endBody() ?> diff --git a/backend/views/layouts/sidebar.php b/backend/views/layouts/sidebar.php deleted file mode 100755 index a137e31..0000000 --- a/backend/views/layouts/sidebar.php +++ /dev/null @@ -1,47 +0,0 @@ - - \ No newline at end of file diff --git a/backend/web/css/site.css b/backend/web/css/site.css index 23fa9ae..75e6539 100644 --- a/backend/web/css/site.css +++ b/backend/web/css/site.css @@ -49,4 +49,11 @@ .icheck-label-group label{ margin-right: 20px; +} +body::-webkit-scrollbar{ + width: 1px; + height: 1px; +} +body{ + margin:10px; } \ No newline at end of file diff --git a/backend/web/index.php b/backend/web/index.php index 810e844..54da81c 100644 --- a/backend/web/index.php +++ b/backend/web/index.php @@ -1,5 +1,4 @@ 'Asia/Shanghai', 'language' => 'zh-CN', 'components' => [ + 'userLogic' => ['class' => 'iron\logic\UserManager'], 'cache' => [ 'class' => 'yii\caching\FileCache', ], + 'mongodb' => [ + 'class' => '\yii\mongodb\Connection', + 'dsn' => 'mongodb://127.0.0.1:27017/love', + 'options' => [ +// "username" => "", +// "password" => "" + ] + ], 'authManager' => [ 'class' => 'yii\rbac\DbManager', ], diff --git a/common/models/DailyActiveUser.php b/common/models/DailyActiveUser.php new file mode 100644 index 0000000..d891c3e --- /dev/null +++ b/common/models/DailyActiveUser.php @@ -0,0 +1,59 @@ +1], + ['created_at','default','value'=>time()] + ]; + } + + public function attributeLabels() + { + return [ + 'date' => '日期', + 'created_at' => '创建时间', + 'user_ids' => '用户id', + 'count' => '数量' + ]; + } + + +} \ No newline at end of file diff --git a/common/models/User.php b/common/models/User.php index 5df9766..07e5162 100644 --- a/common/models/User.php +++ b/common/models/User.php @@ -1,50 +1,71 @@ self::STATUS_INACTIVE], - ['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_INACTIVE, self::STATUS_DELETED]], + [['auth_key', 'password_hash'], 'required'], + [['sex', 'role', 'status', 'expire_at', 'exp_point', 'consume_point'], 'integer'], + [['username', 'password_hash', 'password_reset_token', 'email', 'access_token', 'avatar'], 'string', 'max' => 255], + [['auth_key', 'wx_openid', 'mini_openid'], 'string', 'max' => 32], + [['name', 'nickname', 'session_key'], 'string', 'max' => 120], + [['phone'], 'string', 'max' => 13], + [['unionid'], 'string', 'max' => 60], + [['member_code'], 'string', 'max' => 20], ]; } /** * {@inheritdoc} */ - public static function findIdentity($id) + public function attributeLabels() { - return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]); + return [ + 'id' => 'id', + 'username' => 'username', + 'auth_key' => 'auth_key', + 'password_hash' => 'password_hash', + 'password_reset_token' => 'password_reset_token', + 'name' => 'name', + 'sex' => 'sex', + 'phone' => '联系方式', + 'email' => 'email', + 'role' => 'role', + 'status' => 'status', + 'access_token' => 'access_token', + 'expire_at' => 'expire_at', + 'nickname' => 'nickname', + 'avatar' => 'avatar', + 'wx_openid' => '公众号openid', + 'mini_openid' => '小程序openid', + 'unionid' => 'unionid', + 'session_key' => '小程序解密密钥', + 'member_code' => '会员编号', + 'exp_point' => '经验值', + 'consume_point' => '消费积分', + 'created_at' => '创建时间', + 'updated_at' => '更新时间', + ]; } - /** - * {@inheritdoc} - */ - public static function findIdentityByAccessToken($token, $type = null) - { - throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.'); - } /** - * Finds user by username + * @author linyao + * @email 602604991@qq.com + * @created Nov 8, 2019 * - * @param string $username - * @return static|null + * 行为存储创建时间和更新时间 */ - public static function findByUsername($username) + public function behaviors() { - return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]); + return [ + [ + 'class' => TimestampBehavior::className(), + 'createdAtAttribute' => 'created_at', + 'updatedAtAttribute' => 'updated_at', + 'value' => function () { + return time(); + }, + ], + ]; } /** - * Finds user by password reset token - * - * @param string $token password reset token - * @return static|null + * @inheritDoc */ - public static function findByPasswordResetToken($token) + public static function findIdentity($id) { - if (!static::isPasswordResetTokenValid($token)) { - return null; - } - - return static::findOne([ - 'password_reset_token' => $token, - 'status' => self::STATUS_ACTIVE, - ]); - } - - /** - * Finds user by verification email token - * - * @param string $token verify email token - * @return static|null - */ - public static function findByVerificationToken($token) { - return static::findOne([ - 'verification_token' => $token, - 'status' => self::STATUS_INACTIVE - ]); + return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]); } /** - * Finds out if password reset token is valid - * - * @param string $token password reset token - * @return bool + * @param mixed $token + * @param null $type + * @return array|\yii\db\ActiveRecord|IdentityInterface|null + * @throws NotFoundHttpException + * @throws UnauthorizedHttpException */ - public static function isPasswordResetTokenValid($token) + public static function findIdentityByAccessToken($token, $type = null) { - if (empty($token)) { - return false; + $user = static::find() + ->where(['access_token' => $token, 'status' => self::STATUS_ACTIVE]) + ->one(); + if (!$user) { + throw new NotFoundHttpException('user not found'); + } + if ($user->expire_at < time()) { + throw new UnauthorizedHttpException('access - token expired ', -1); + } else { + return $user; } - - $timestamp = (int) substr($token, strrpos($token, '_') + 1); - $expire = Yii::$app->params['user.passwordResetTokenExpire']; - return $timestamp + $expire >= time(); } /** - * {@inheritdoc} + * @inheritDoc */ public function getId() { @@ -142,7 +179,7 @@ class User extends ActiveRecord implements IdentityInterface } /** - * {@inheritdoc} + * @inheritDoc */ public function getAuthKey() { @@ -150,60 +187,10 @@ class User extends ActiveRecord implements IdentityInterface } /** - * {@inheritdoc} + * @inheritDoc */ public function validateAuthKey($authKey) { return $this->getAuthKey() === $authKey; } - - /** - * Validates password - * - * @param string $password password to validate - * @return bool if password provided is valid for current user - */ - public function validatePassword($password) - { - return Yii::$app->security->validatePassword($password, $this->password_hash); - } - - /** - * Generates password hash from password and sets it to the model - * - * @param string $password - */ - public function setPassword($password) - { - $this->password_hash = Yii::$app->security->generatePasswordHash($password); - } - - /** - * Generates "remember me" authentication key - */ - public function generateAuthKey() - { - $this->auth_key = Yii::$app->security->generateRandomString(); - } - - /** - * Generates new password reset token - */ - public function generatePasswordResetToken() - { - $this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time(); - } - - public function generateEmailVerificationToken() - { - $this->verification_token = Yii::$app->security->generateRandomString() . '_' . time(); - } - - /** - * Removes password reset token - */ - public function removePasswordResetToken() - { - $this->password_reset_token = null; - } } diff --git a/composer.json b/composer.json index c79317a..3ee22c2 100755 --- a/composer.json +++ b/composer.json @@ -15,6 +15,8 @@ "yiisoft/yii2": "~2.0.14", "yiisoft/yii2-bootstrap4": "~2.0.6", "yiisoft/yii2-redis": "^2.0.0", + "yiisoft/yii2-mongodb": "~2.1.0", + "yiisoft/yii2-httpclient": "^2.0@dev", "moonlandsoft/yii2-phpexcel": "*", "kartik-v/yii2-tabs-x": "^1.2@dev", "kartik-v/yii2-editable": "^1.7@dev", diff --git a/composer.lock b/composer.lock index 10b0a18..13a9bae 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f679ebe17a306b33afd5dede1cb05dfb", + "content-hash": "687669f68148fd8fc648686c605f5952", "packages": [ { "name": "antkaz/yii2-vue", @@ -1434,6 +1434,108 @@ ], "time": "2019-07-16T13:22:50+00:00" }, + { + "name": "yiisoft/yii2-httpclient", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/yiisoft/yii2-httpclient.git", + "reference": "05ecc99868352cf840173bfd8fe67bfd84b5f295" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yiisoft/yii2-httpclient/zipball/05ecc99868352cf840173bfd8fe67bfd84b5f295", + "reference": "05ecc99868352cf840173bfd8fe67bfd84b5f295", + "shasum": "" + }, + "require": { + "yiisoft/yii2": "~2.0.13" + }, + "require-dev": { + "phpunit/phpunit": "4.8.27|~5.7.21|^6.2" + }, + "type": "yii2-extension", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "yii\\httpclient\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Paul Klimov", + "email": "klimov.paul@gmail.com" + } + ], + "description": "HTTP client extension for the Yii framework", + "keywords": [ + "curl", + "http", + "httpclient", + "yii2" + ], + "time": "2019-10-08T09:48:57+00:00" + }, + { + "name": "yiisoft/yii2-mongodb", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/yiisoft/yii2-mongodb.git", + "reference": "f14578beb63500bf56841ae599620b76a62dc5c2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/yiisoft/yii2-mongodb/zipball/f14578beb63500bf56841ae599620b76a62dc5c2", + "reference": "f14578beb63500bf56841ae599620b76a62dc5c2", + "shasum": "" + }, + "require": { + "ext-mongodb": ">=1.0.0", + "yiisoft/yii2": "~2.0.14" + }, + "require-dev": { + "phpunit/phpunit": "4.8.27|~5.7.21|^6.2" + }, + "type": "yii2-extension", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "yii\\mongodb\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Paul Klimov", + "email": "klimov.paul@gmail.com" + } + ], + "description": "MongoDB extension for the Yii framework", + "keywords": [ + "GridFS", + "active-record", + "mongo", + "mongodb", + "yii2" + ], + "time": "2019-11-22T09:25:40+00:00" + }, { "name": "yiisoft/yii2-redis", "version": "dev-master", @@ -1770,6 +1872,7 @@ "aliases": [], "minimum-stability": "dev", "stability-flags": { + "yiisoft/yii2-httpclient": 20, "kartik-v/yii2-tabs-x": 20, "kartik-v/yii2-editable": 20, "kartik-v/yii2-widget-depdrop": 20, diff --git a/console/controllers/InitController.php b/console/controllers/InitController.php index bb51368..5f60c6a 100644 --- a/console/controllers/InitController.php +++ b/console/controllers/InitController.php @@ -7,8 +7,7 @@ use yii\console\Controller; use yii\helpers\Console; use yii\db\Query; use yii\helpers\ArrayHelper; -use common\models\User; -use common\models\Category; +use backend\models\User; /** * Description of RbacsetController diff --git a/console/migrations/m191122_011654_add_column_admin_id_in_table_user.php b/console/migrations/m191122_011654_add_column_admin_id_in_table_user.php new file mode 100644 index 0000000..1fa35f5 --- /dev/null +++ b/console/migrations/m191122_011654_add_column_admin_id_in_table_user.php @@ -0,0 +1,41 @@ +addColumn('user','admin_id',$this->integer(11)->notNull()->defaultValue(0)); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->dropColumn('user','admin_id'); + return true; + } + + /* + // Use up()/down() to run migration code without a transaction. + public function up() + { + + } + + public function down() + { + echo "m191122_011654_create_table_user_admin cannot be reverted.\n"; + + return false; + } + */ +} diff --git a/console/migrations/m191204_092644_rename_backend_user.php b/console/migrations/m191204_092644_rename_backend_user.php new file mode 100755 index 0000000..02f1ddd --- /dev/null +++ b/console/migrations/m191204_092644_rename_backend_user.php @@ -0,0 +1,26 @@ +execute($sql); + } + + /** + * {@inheritdoc} + */ + public function down() + { + return true; + } +} diff --git a/console/migrations/m191204_102644_create_table_province.php b/console/migrations/m191204_102644_create_table_province.php new file mode 100755 index 0000000..4fc7975 --- /dev/null +++ b/console/migrations/m191204_102644_create_table_province.php @@ -0,0 +1,52 @@ +createTable('user', [ + 'id' => $this->primaryKey(), + 'username'=>$this->string(255)->comment('用户名'), + 'auth_key'=>$this->string(32)->notNull()->comment(''), + 'password_hash'=>$this->string(255)->notNull()->comment(''), + 'password_reset_token'=>$this->string(255)->defaultValue(null)->comment(''), + 'name'=>$this->string(120)->comment('姓名'), + 'sex'=>$this->integer(1)->comment('性别'), + 'phone'=>$this->string(13)->comment('联系方式'), + 'email'=>$this->string(255)->comment('邮箱'), + 'role'=>$this->tinyInteger(1)->defaultValue(1)->comment('角色'), + 'status'=>$this->tinyInteger(1)->defaultValue(1)->comment('状态'), + 'access_token'=>$this->string(255)->comment('令牌'), + 'expire_at'=>$this->integer(11)->comment('令牌过期时间'), + 'nickname'=>$this->string(120)->comment('昵称'), + 'avatar'=>$this->string(255)->comment('头像'), + 'wx_openid'=>$this->string(32)->comment('微信openid'), + 'mini_openid'=>$this->string(32)->comment('小程序openid'), + 'unionid'=>$this->string(60)->comment('微信联合id'), + 'session_key'=>$this->string(120)->comment('小程序会话秘钥'), + 'member_code'=>$this->string(20)->comment('会员编号'), + 'exp_point'=>$this->integer(20)->comment('经验值'), + 'consume_point'=>$this->integer(20)->defaultValue(null)->comment('消费积分'), + 'created_at'=>$this->integer(11)->notNull()->comment('创建时间'), + 'updated_at'=>$this->integer(11)->notNull()->comment('更新时间'), + ],$tableOptions); + } + + /** + * {@inheritdoc} + */ + public function down() + { + $this->dropTable("user"); + return true; + } +} diff --git a/console/runtime/logs/app.log b/console/runtime/logs/app.log index 4ee8544..0b27f98 100644 --- a/console/runtime/logs/app.log +++ b/console/runtime/logs/app.log @@ -1786,3 +1786,86 @@ $_SERVER = [ ] 'argc' => 2 ] +2019-12-05 14:04:52 [-][-][-][error][yii\base\ErrorException:2] yii\base\ErrorException: file_get_contents(/home/wwwroot/default/antshop/console/migrations/sql/add_category.sql): failed to open stream: No such file or directory in /home/wwwroot/default/antshop/console/migrations/m190802_072830_add_category.php:14 +Stack trace: +#0 [internal function]: yii\base\ErrorHandler->handleError(2, 'file_get_conten...', '/home/wwwroot/d...', 14, Array) +#1 /home/wwwroot/default/antshop/console/migrations/m190802_072830_add_category.php(14): file_get_contents('/home/wwwroot/d...') +#2 /home/wwwroot/default/antshop/vendor/yiisoft/yii2/console/controllers/BaseMigrateController.php(724): m190802_072830_add_category->up() +#3 /home/wwwroot/default/antshop/vendor/yiisoft/yii2/console/controllers/BaseMigrateController.php(200): yii\console\controllers\BaseMigrateController->migrateUp('m190802_072830_...') +#4 [internal function]: yii\console\controllers\BaseMigrateController->actionUp(0) +#5 /home/wwwroot/default/antshop/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array(Array, Array) +#6 /home/wwwroot/default/antshop/vendor/yiisoft/yii2/base/Controller.php(157): yii\base\InlineAction->runWithParams(Array) +#7 /home/wwwroot/default/antshop/vendor/yiisoft/yii2/console/Controller.php(164): yii\base\Controller->runAction('', Array) +#8 /home/wwwroot/default/antshop/vendor/yiisoft/yii2/base/Module.php(528): yii\console\Controller->runAction('', Array) +#9 /home/wwwroot/default/antshop/vendor/yiisoft/yii2/console/Application.php(180): yii\base\Module->runAction('migrate', Array) +#10 /home/wwwroot/default/antshop/vendor/yiisoft/yii2/console/Application.php(147): yii\console\Application->runAction('migrate', Array) +#11 /home/wwwroot/default/antshop/vendor/yiisoft/yii2/base/Application.php(386): yii\console\Application->handleRequest(Object(yii\console\Request)) +#12 /home/wwwroot/default/antshop/yii(23): yii\base\Application->run() +#13 {main} +2019-12-05 14:04:51 [-][-][-][info][application] $_GET = [] + +$_POST = [] + +$_FILES = [] + +$_COOKIE = [] + +$_SERVER = [ + 'CLUTTER_IM_MODULE' => 'xim' + 'LS_COLORS' => 'bd=38;5;68;1:ca=38;5;17:cd=38;5;132;1:di=38;5;105:do=38;5;127:ex=38;5;80:pi=38;5;126:fi=38;5;167:ln=38;5;63:mh=38;5;99;1:or=48;5;197;38;5;228;1:ow=38;5;220;1:sg=48;5;234;38;5;100;1:su=38;5;9;1:so=38;5;197:st=38;5;86;48;5;234:tw=48;5;235;38;5;139;3:*LS_COLORS=48;5;89;38;5;197;1;3;4;7:*.BAT=38;5;108:*.exe=38;5;196:*.PL=38;5;160:*.asm=38;5;240;1:*.awk=38;5;148;1:*.bash=38;5;173:*.bat=38;5;108:*.c=38;5;110:*.cc=38;5;24;1:*.ii=38;5;24;1:*.cfg=1:*.cl=38;5;204;1:*.coffee=38;5;100;1:*.conf=38;5;221:*.C=38;5;24;1:*.cp=38;5;24;1:*.cpp=38;5;24;1:*.cxx=38;5;24;1:*.c++=38;5;24;1:*.ii=38;5;24;1:*.cs=38;5;74;1:*.css=38;5;91:*.csv=38;5;78:*.ctp=38;5;95:*.diff=48;5;197;38;5;232:*.enc=38;5;192;3:*.eps=38;5;33;1:*.etx=38;5;172:*.ex=38;5;148;1:*.example=38;5;225;1:*.git=38;5;197:*.gitignore=38;5;240:*.go=38;5;111:*.h=38;5;81:*.H=38;5;81:*.hpp=38;5;81:*.hxx=38;5;81:*.h++=38;5;81:*.tcc=38;5;81:*.f=38;5;81:*.for=38;5;81:*.ftn=38;5;81:*.s=38;5;81:*.S=38;5;81:*.sx=38;5;81:*.hi=38;5;240:*.hs=38;5;199;1:*.htm=38;5;125;1:*.html=38;5;9;1:*.info=38;5;101:*.ini=38;5;123:*.java=38;5;142;1:*.jhtm=38;5;125;1:*.js=38;5;42:*.jsm=38;5;42:*.jsm=38;5;42:*.json=38;5;213:*.jsp=38;5;45:*.lisp=38;5;204;1:*.log=38;5;190:*.lua=38;5;34;1:*.m=38;5;130;3:*.mht=38;5;129:*.mm=38;5;130;3:*.M=38;5;130;3:*.map=38;5;58;3:*.markdown=38;5;184:*.md=38;5;184:*.mf=38;5;220;3:*.mfasl=38;5;73:*.mi=38;5;124:*.mkd=38;5;184:*.mtx=38;5;36;3:*.nfo=38;5;220:*.o=38;5;240:*.pacnew=38;5;33:*.patch=48;5;197;38;5;232;1:*.pc=38;5;100:*.pfa=38;5;43:*.pgsql=38;5;222:*.php=38;5;99:*.pl=38;5;214:*.po=38;5;176:*.pot=38;5;206;1:*.plt=38;5;204;1:*.pm=38;5;197;1:*.pod=38;5;172;1:*.py=38;5;41:*.pyc=38;5;245:*.rb=38;5;192:*.rdf=38;5;144:*.rst=38;5;67:*.ru=38;5;142:*.scm=38;5;204;1:*.sed=38;5;130;1:*.sfv=38;5;197:*.sh=38;5;113:*.signature=38;5;206:*.sql=38;5;222:*.srt=38;5;116:*.sty=38;5;58:*.sug=38;5;44:*.t=38;5;28;1:*.tcl=38;5;64;1:*.tdy=38;5;214:*.tex=38;5;172:*.textile=38;5;106:*.tfm=38;5;64:*.tfnt=38;5;140:*.theme=38;5;109:*.txt=38;5;192:*.list=38;5;44:*.save=38;5;240:*.urlview=38;5;85:*.vim=38;5;14:*.vimrc=38;5;13:*.viminfo=38;5;240;1:*.xml=38;5;199:*.yml=38;5;208:*.zsh=38;5;173:*.bashrc=38;5;5:*README=38;5;220;1:*Makefile=38;5;196:*MANIFEST=38;5;243:*pm_to_blib=38;5;240:*.1=38;5;240;1:*.2=38;5;220;1:*.3=38;5;196;1:*.7=38;5;196;1:*.1p=38;5;160:*.3p=38;5;160:*.am=38;5;242:*.in=38;5;242:*.old=38;5;242:*.out=38;5;44;1:*.bmp=38;5;33:*.cdr=38;5;33:*.gif=38;5;33:*.ico=38;5;33:*.jpeg=38;5;33:*.jpg=38;5;33:*.JPG=38;5;33:*.png=38;5;33:*.svg=38;5;33;1:*.xpm=38;5;33:*.32x=38;5;137:*.A64=38;5;82:*.a00=38;5;11:*.a52=38;5;112:*.a64=38;5;82:*.a78=38;5;112:*.adf=38;5;35:*.atr=38;5;213:*.cdi=38;5;124:*.fm2=38;5;35:*.gb=38;5;203:*.gba=38;5;205:*.gbc=38;5;204:*.gel=38;5;83:*.gg=38;5;138:*.ggl=38;5;83:*.j64=38;5;102:*.nds=38;5;199:*.nes=38;5;160:*.rom=38;5;59;1:*.sav=38;5;220:*.sms=38;5;33:*.st=38;5;208;1:*.iso=38;5;9;1:*.nrg=38;5;124:*.qcow=38;5;141:*.VOB=38;5;99:*.IFO=38;5;99:*.BUP=38;5;99:*.MOV=38;5;99:*.3gp=38;5;99:*.3g2=38;5;99:*.asf=38;5;99:*.avi=38;5;99:*.divx=38;5;99:*.f4v=38;5;99:*.flv=38;5;99:*.m2v=38;5;99:*.mkv=38;5;99:*.mov=38;5;99:*.mp4=38;5;99:*.mpg=38;5;99:*.mpeg=38;5;99:*.ogm=38;5;99:*.ogv=38;5;99:*.rmvb=38;5;99:*.sample=38;5;99;1:*.ts=38;5;99:*.vob=38;5;99:*.webm=38;5;99:*.wmv=38;5;99:*.S3M=38;5;69;1:*.aac=38;5;69:*.cue=38;5;69:*.dat=38;5;69:*.dts=38;5;69;1:*.fcm=38;5;69:*.flac=38;5;69;1:*.m3u=38;5;69:*.m3u8=38;5;69:*.m4=38;5;69;3:*.m4a=38;5;69;1:*.mid=38;5;69:*.midi=38;5;69:*.mod=38;5;69:*.mp3=38;5;69:*.oga=38;5;69:*.ogg=38;5;69:*.s3m=38;5;69;1:*.sid=38;5;69;1:*.spl=38;5;69:*.wv=38;5;69:*.wvc=38;5;69:*.ape=38;5;69:*.afm=38;5;58:*.pfb=38;5;58:*.pfm=38;5;58:*.ttf=38;5;66:*.ttc=38;5;66:*.pcf=38;5;65:*.psf=38;5;64:*.bak=38;5;222;1:*.bin=38;5;228:*.pid=38;5;228:*.state=38;5;228:*.swo=38;5;228:*.swp=38;5;228:*.tmp=38;5;228:*.un~=38;5;228:*.zcompdump=38;5;228:*.zwc=38;5;228:*.db=38;5;147:*.dump=38;5;147:*.sqlite=38;5;147:*.typelib=38;5;147:*.7z=38;5;140:*.a=38;5;220:*.apk=38;5;148;3:*.arj=38;5;220:*.bz2=38;5;220:*.deb=38;5;215;1:*.ipk=38;5;220:*.jad=38;5;220:*.jar=38;5;220:*.nth=38;5;220:*.sis=38;5;220:*.part=38;5;220;1:*.r00=38;5;220:*.r01=38;5;220:*.r02=38;5;220:*.r03=38;5;220:*.r04=38;5;220:*.r05=38;5;220:*.r06=38;5;220:*.r07=38;5;220:*.r08=38;5;220:*.r09=38;5;220:*.r10=38;5;220:*.r100=38;5;220:*.r101=38;5;220:*.r102=38;5;220:*.r103=38;5;220:*.r104=38;5;220:*.r105=38;5;220:*.r106=38;5;220:*.r107=38;5;220:*.r108=38;5;220:*.r109=38;5;220:*.r11=38;5;220:*.r110=38;5;220:*.r111=38;5;220:*.r112=38;5;220:*.r113=38;5;220:*.r114=38;5;220:*.r115=38;5;220:*.r116=38;5;220:*.r12=38;5;220:*.r13=38;5;220:*.r14=38;5;220:*.r15=38;5;220:*.r16=38;5;220:*.r17=38;5;220:*.r18=38;5;220:*.r19=38;5;220:*.r20=38;5;220:*.r21=38;5;220:*.r22=38;5;220:*.r25=38;5;220:*.r26=38;5;220:*.r27=38;5;220:*.r28=38;5;220:*.r29=38;5;220:*.r30=38;5;220:*.r31=38;5;220:*.r32=38;5;220:*.r33=38;5;220:*.r34=38;5;220:*.r35=38;5;220:*.r36=38;5;220:*.r37=38;5;220:*.r38=38;5;220:*.r39=38;5;220:*.r40=38;5;220:*.r41=38;5;220:*.r42=38;5;220:*.r43=38;5;220:*.r44=38;5;220:*.r45=38;5;220:*.r46=38;5;220:*.r47=38;5;220:*.r48=38;5;220:*.r49=38;5;220:*.r50=38;5;220:*.r51=38;5;220:*.r52=38;5;220:*.r53=38;5;220:*.r54=38;5;220:*.r99=38;5;220:*.r56=38;5;220:*.r69=38;5;220:*.r58=38;5;220:*.r59=38;5;220:*.r60=38;5;220:*.r61=38;5;220:*.r62=38;5;220:*.r63=38;5;220:*.r64=38;5;220:*.r65=38;5;220:*.r66=38;5;220:*.r67=38;5;220:*.r68=38;5;220:*.r69=38;5;220:*.r69=38;5;220:*.r70=38;5;220:*.r71=38;5;220:*.r72=38;5;220:*.r73=38;5;220:*.r74=38;5;220:*.r75=38;5;220:*.r76=38;5;220:*.r77=38;5;220:*.r78=38;5;220:*.r79=38;5;220:*.r80=38;5;220:*.r81=38;5;220:*.r82=38;5;220:*.r83=38;5;220:*.r84=38;5;220:*.r85=38;5;220:*.r86=38;5;220:*.r87=38;5;220:*.r88=38;5;220:*.r89=38;5;220:*.r90=38;5;220:*.r91=38;5;220:*.r92=38;5;220:*.r99=38;5;220:*.r94=38;5;220:*.r95=38;5;220:*.r96=38;5;220:*.r97=38;5;220:*.r98=38;5;220:*.r99=38;5;220:*.rar=38;5;217;1:*.tar=38;5;222:*.tar.gz=38;5;216:*.tgz=38;5;214;1:*.gz=38;5;224:*.xz=38;5;182:*.zip=38;5;208:*.doc=38;5;190:*.wps=38;5;190:*.docx=38;5;190:*.xls=38;5;190:*.xlsx=38;5;190:*.ppt=38;5;190:*.pptx=38;5;190:*.pdf=38;5;190:*.djvu=38;5;190:*.cbr=38;5;190:*.cbz=38;5;190:*.chm=38;5;190:*.odt=38;5;112:*.ods=38;5;112:*.odp=38;5;112:*.odb=38;5;112:*.allow=38;5;112:*.deny=38;5;203:*.SKIP=38;5;244:*.def=38;5;136:*.directory=38;5;69:*.err=38;5;160;1:*.error=38;5;160;1:*.pi=38;5;126:*.properties=38;5;197;1:*.torrent=38;5;105:*.gp3=38;5;114:*.gp4=38;5;115:*.tg=38;5;99:*.pcap=38;5;29:*.cap=38;5;29:*.dmp=38;5;29:*.service=38;5;81:*@.service=38;5;45:*.socket=38;5;75:*.device=38;5;24:*.mount=38;5;115:*.automount=38;5;114:*.swap=38;5;113:*.target=38;5;73:*.path=38;5;116:*.timer=38;5;111:*.snapshot=38;5;139:*.desktop=38;5;113:*.crdownload=38;5;38:*.crx=38;5;13:' + 'TERMINAL_EMULATOR' => 'JetBrains-JediTerm' + 'SOCKS_SERVER' => 'socks5://127.0.0.1:7891' + 'LANG' => 'zh_CN.UTF-8' + 'DISPLAY' => ':0' + 'OLDPWD' => '/opt/phpstorm/bin' + 'XDG_VTNR' => '1' + 'GIO_LAUNCHED_DESKTOP_FILE_PID' => '3930' + 'SSH_AUTH_SOCK' => '/run/user/1000/keyring/ssh' + 'XDG_SESSION_ID' => '2' + 'XDG_GREETER_DATA_DIR' => '/var/lib/lightdm/data/linyao' + 'USER' => 'linyao' + 'DESKTOP_SESSION' => 'deepin' + 'QT4_IM_MODULE' => 'fcitx' + 'PWD' => '/home/wwwroot/default/antshop' + 'HOME' => '/home/linyao' + 'QT_DBL_CLICK_DIST' => '18' + 'XDG_SESSION_TYPE' => 'x11' + 'http_proxy' => 'http://127.0.0.1:7890' + 'XDG_SESSION_DESKTOP' => 'deepin' + 'no_proxy' => 'localhost,127.0.0.0/8,::1,b.antshop.com,b.kcshop.com,f.antbasic.com,b.antbasic.com,' + 'DEEPIN_WINE_SCALE' => '1.25' + 'DESKTOP_STARTUP_ID' => 'startdde-2941-linyao-PC-phpstorm-0_TIME97043' + 'TERM' => 'xterm-256color' + 'SHELL' => '/bin/bash' + 'XDG_SEAT_PATH' => '/org/freedesktop/DisplayManager/Seat0' + 'QT_IM_MODULE' => 'fcitx' + 'XMODIFIERS' => '@im=fcitx' + 'XDG_CURRENT_DESKTOP' => 'Deepin' + 'GPG_AGENT_INFO' => '/run/user/1000/gnupg/S.gpg-agent:0:1' + 'GIO_LAUNCHED_DESKTOP_FILE' => '/usr/share/applications/phpstorm.desktop' + 'SHLVL' => '1' + 'XDG_SEAT' => 'seat0' + 'LANGUAGE' => 'zh_CN' + 'GDMSESSION' => 'deepin' + 'GNOME_DESKTOP_SESSION_ID' => 'this-is-deprecated' + 'LOGNAME' => 'linyao' + 'DBUS_SESSION_BUS_ADDRESS' => 'unix:abstract=/tmp/dbus-oBqp2j0vhj,guid=d7e1b9485b6f0be71733773e5de85060' + 'XDG_RUNTIME_DIR' => '/run/user/1000' + 'XAUTHORITY' => '/home/linyao/.Xauthority' + 'XDG_SESSION_PATH' => '/org/freedesktop/DisplayManager/Session0' + 'PATH' => '/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games' + 'GTK_IM_MODULE' => 'fcitx' + '_' => './yii' + 'PHP_SELF' => './yii' + 'SCRIPT_NAME' => './yii' + 'SCRIPT_FILENAME' => './yii' + 'PATH_TRANSLATED' => './yii' + 'DOCUMENT_ROOT' => '' + 'REQUEST_TIME_FLOAT' => 1575525891.5635 + 'REQUEST_TIME' => 1575525891 + 'argv' => [ + 0 => './yii' + 1 => 'migrate' + ] + 'argc' => 2 +] diff --git a/datadictionary.md b/datadictionary.md deleted file mode 100644 index e69de29..0000000 diff --git a/vendor/iron/actions/UploadAction.php b/vendor/iron/actions/UploadAction.php index 384b7bc..7c53609 100644 --- a/vendor/iron/actions/UploadAction.php +++ b/vendor/iron/actions/UploadAction.php @@ -47,6 +47,8 @@ class UploadAction extends Action * 常量: 二进制数据类型 */ const DATA_TYPE_BINARY = 2; + + public $keyName = 'file'; /** * @var function * @@ -100,7 +102,7 @@ class UploadAction extends Action $data = []; try { if ($this->dataType == self::DATA_TYPE_FORM) { - $file = UploadedFile::getInstanceByName('file'); + $file = UploadedFile::getInstanceByName($this->keyName); $this->checkType($file->extension); $this->checkSize($file->size); $savePath = $this->getSavePath(); diff --git a/vendor/iron/assets/grid/css/grid.css b/vendor/iron/assets/grid/css/grid.css index 781e068..f989318 100644 --- a/vendor/iron/assets/grid/css/grid.css +++ b/vendor/iron/assets/grid/css/grid.css @@ -62,4 +62,4 @@ THE SOFTWARE. .dataTable td a{ color: #333; opacity: 0.8; -} \ No newline at end of file +} diff --git a/vendor/iron/grid/ActionColumn.php b/vendor/iron/grid/ActionColumn.php index a848dbb..887eb16 100644 --- a/vendor/iron/grid/ActionColumn.php +++ b/vendor/iron/grid/ActionColumn.php @@ -33,7 +33,33 @@ use blobt\grid\Column; class ActionColumn extends Column { - + /** + * @var array 配置按钮配置,通过配置参数控制按钮的标题,url,图标以及确认框内容和隐藏条件 + * + * ```php + * + * - `$title`: 按钮的标题 + * - `$name`: 按钮的跳转路径 + * - `$icon`: 按钮图标 + * - `$contents`: 确认框内容 + * - `$hide`: array 隐藏条件 + * + * 使用案例: + * ```php + * [ + * 'name' => 'delete', + * 'icon' => 'trash', + * 'title' => '删除', + * 'contents' => '确定删除?' + * //attributes 和 values 两数组对应元素按规则匹配成功时候隐藏该按钮 + * 'hide'=>[ + * 'attributes'=>['status'],//模型属性 + * 'values'=>[1],//属性值 + * 'rule'=>'or' //与或规则 只填 or 或 and + * ] + * ] + * + */ public $config = [ [ 'name' => 'view', @@ -175,6 +201,11 @@ class ActionColumn extends Column }; } + /** + * @param string $name + * @param array $config 隐藏配置 + * 验证按钮的显示隐藏规则 + */ protected function visibleButtons($name, $config) { $this->visibleButtons[$name] = function ($model, $key, $index) use ($config) { diff --git a/vendor/iron/grid/GridView.php b/vendor/iron/grid/GridView.php index 5b42816..a26eaef 100644 --- a/vendor/iron/grid/GridView.php +++ b/vendor/iron/grid/GridView.php @@ -219,16 +219,12 @@ class GridView extends BaseListView
{batch} - 添加 + + {create} -
- - -
+ {export} + {content}
{filter} @@ -263,6 +259,26 @@ HTML;
HTML; + public $export =<< + + +
+HTML; + public $create =<<添加 + +HTML; + /** + * @var + * 表单头部内容 + */ + public $content; + + /** * 初始化 grid view. @@ -281,14 +297,14 @@ HTML; throw new InvalidConfigException('The "formatter" property must be either a Format object or a configuration array.'); } $this->pager = [ - 'options'=>['class'=>['justify-content-end','pagination']], - 'linkOptions'=>['class'=>'page-link'], - 'pageCssClass'=>'paginate_button page-item', - 'disabledPageCssClass'=>'page-link disabled', - 'firstPageLabel'=>'«', - 'prevPageLabel'=>'‹', - 'nextPageLabel'=>'›', - 'lastPageLabel'=>'»',]; + 'options' => ['class' => ['justify-content-end', 'pagination']], + 'linkOptions' => ['class' => 'page-link'], + 'pageCssClass' => 'paginate_button page-item', + 'disabledPageCssClass' => 'page-link disabled', + 'firstPageLabel' => '«', + 'prevPageLabel' => '‹', + 'nextPageLabel' => '›', + 'lastPageLabel' => '»',]; $this->initColumns(); } @@ -445,6 +461,12 @@ SCRIPT; return $this->renderFilter(); case '{batch}': return $this->renderBatch(); + case '{export}': + return $this->renderExport(); + case '{create}': + return $this->renderCreate(); + case '{content}': + return $this->renderContent(); default: return false; } @@ -694,4 +716,31 @@ SCRIPT; ]); } + /** + * 渲染导出部分 + * @return string + */ + protected function renderExport() + { + return $this->export; + } + + /** + * 渲染创建部分 + * @return string + */ + protected function renderCreate() + { + return $this->create; + } + + /** + * 渲染表单头部内容 + * @return string + */ + protected function renderContent() + { + return Html::tag('div', $this->content, ['class' => 'btn-group']); + } + } diff --git a/vendor/iron/widgets/Menu.php b/vendor/iron/widgets/Menu.php index 4da4c21..f4d2a66 100644 --- a/vendor/iron/widgets/Menu.php +++ b/vendor/iron/widgets/Menu.php @@ -36,7 +36,7 @@ use yii\helpers\Url; * 参照yii\widgets\Menu,根据AdminLTE样式从写的一个小物件 * @author Blobt * @email 380255922@qq.com - * 使用例子 + * 使用例子 * [ @@ -50,10 +50,11 @@ use yii\helpers\Url; * ] * ]); * ?> - * - * + * + * */ -class Menu extends Widget { +class Menu extends Widget +{ /** * @var array 菜单的item数组。 @@ -132,8 +133,8 @@ class Menu extends Widget { public $options = [ 'class' => 'nav nav-pills nav-sidebar flex-column', 'data-widget' => 'treeview', - 'role'=>'menu', - 'data-accordion'=>'false' + 'role' => 'menu', + 'data-accordion' => 'false' ]; /** @@ -164,7 +165,8 @@ class Menu extends Widget { /** * 渲染菜单 */ - public function run() { + public function run() + { if ($this->route === null && Yii::$app->controller !== null) { $this->route = Yii::$app->controller->getRoute(); } @@ -186,7 +188,8 @@ class Menu extends Widget { * @param array $items * @return string 渲染结果 */ - protected function renderItems($items) { + protected function renderItems($items) + { $lines = []; $n = count($items); foreach ($items as $i => $item) { @@ -234,7 +237,8 @@ class Menu extends Widget { * @param array $item * @return string 渲染结果 */ - protected function renderItem($item) { + protected function renderItem($item) + { if (isset($item['url'])) { if (isset($item['template'])) { $template = $item['template']; @@ -244,7 +248,7 @@ class Menu extends Widget { return strtr($template, [ '{url}' => Html::encode(Url::to($item['url'])), '{label}' => Html::encode($item['label']), - '{class}'=>isset($item['active'])?'active':'', + '{class}' => isset($item['active']) ? 'active' : '', '{icon}' => Html::encode($item['icon']) ]); } @@ -253,7 +257,7 @@ class Menu extends Widget { return strtr($template, [ '{label}' => $item['label'], - '{class}'=>isset($item['active'])?'active':'' + '{class}' => isset($item['active']) ? 'active' : '' ]); } @@ -262,21 +266,31 @@ class Menu extends Widget { * @param $item array * @return boolean $item */ - protected function isItemActive($item) { + protected function isItemActive($item) + { if (isset($item['url']) && is_array($item['url']) && isset($item['url'][0])) { $route = Yii::getAlias($item['url'][0]); - if ($route[0] !== '/' && Yii::$app->controller) { $route = Yii::$app->controller->module->getUniqueId() . '/' . $route; } - if (ltrim($route, '/') !== $this->route) { + $route = ltrim($route, '/'); + if ($route != substr($this->route, 0, strrpos($this->route, '/')) && $route != $this->route && + ltrim(Yii::$app->request->url, '/') !== $route) { + return false; } + unset($item['url']['#']); + if (count($item['url']) > 1) { + foreach (array_splice($item['url'], 1) as $name => $value) { + if ($value !== null && (!isset($this->params[$name]) || $this->params[$name] != $value)) { + return false; + } + } + } return true; } - return false; } @@ -285,7 +299,8 @@ class Menu extends Widget { * @param string $item * @param bool $active */ - protected function normalizeItems($items, &$active) { + protected function normalizeItems($items, &$active) + { foreach ($items as $i => $item) { /* 去除visible 为 false的item */ if (isset($item['visible']) && !$item['visible']) {