diff --git a/antgoods/.gitignore b/antgoods/.gitignore new file mode 100755 index 0000000..4b9a47c --- /dev/null +++ b/antgoods/.gitignore @@ -0,0 +1,2 @@ +cert +runtime diff --git a/antgoods/assets/AppAsset.php b/antgoods/assets/AppAsset.php new file mode 100755 index 0000000..6a7b360 --- /dev/null +++ b/antgoods/assets/AppAsset.php @@ -0,0 +1,26 @@ + 'antgoods', + 'basePath' => dirname(__DIR__), + 'controllerNamespace' => 'antgoods\controllers', + 'bootstrap' => ['log'], + 'defaultRoute' => '/category', + 'modules' => [ + ], + 'components' => [ + 'request' => [ + 'parsers' => [ + 'application/json' => 'yii\web\JsonParser', + ], + 'csrfParam' => '_csrf-api', + ], + 'user' => [ + 'identityClass' => 'common\models\User', + 'enableAutoLogin' => true, + 'identityCookie' => ['name' => '_identity-antgoods', 'httpOnly' => true], + ], + 'session' => [ + // this is the name of the session cookie used for login on the app + 'name' => 'antgoods', + ], + 'log' => [ + 'traceLevel' => YII_DEBUG ? 3 : 0, + 'targets' => [ + [ + 'class' => 'yii\log\FileTarget', + 'levels' => ['error', 'warning'], + ], + [ + 'class' => 'yii\log\FileTarget', + 'levels' => ['info', 'error'], + 'categories' => ['imagetest'], + 'logFile' => '@app/runtime/logs/imagetest.log', + 'logVars' => [], + 'exportInterval' => 1, + 'prefix' => function ($message) { + } + ], + ], + ], + 'errorHandler' => [ + 'errorAction' => 'site/error', + ], + 'urlManager' => [ + 'enablePrettyUrl' => true, + 'showScriptName' => false, + 'rules' => [ + ], + ], + 'file' => ['class' => 'backend\logic\file\FileManager'], + ], + 'params' => $params, +]; diff --git a/antgoods/config/params.php b/antgoods/config/params.php new file mode 100755 index 0000000..7f754b9 --- /dev/null +++ b/antgoods/config/params.php @@ -0,0 +1,4 @@ + 'admin@example.com', +]; diff --git a/antgoods/controllers/AttributeController.php b/antgoods/controllers/AttributeController.php new file mode 100644 index 0000000..18061b6 --- /dev/null +++ b/antgoods/controllers/AttributeController.php @@ -0,0 +1,170 @@ + [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => ['POST'], + ], + ], + ]; + } + + /** + * Lists all Attribute models. + * @return mixed + */ + public function actionIndex() + { + $searchModel = new AttributeSearch(); + $dataProvider = $searchModel->search(Yii::$app->request->queryParams); + + return $this->render('index', [ + 'searchModel' => $searchModel, + 'dataProvider' => $dataProvider, + 'columns' => $searchModel->columns() + ]); + } + + /** + * Displays a single Attribute model. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionView($id) + { + return $this->render('view', [ + 'model' => $this->findModel($id), + ]); + } + + /** + * Creates a new Attribute model. + * If creation is successful, the browser will be redirected to the 'view' page. + * @return mixed + */ + public function actionCreate() + { + $model = new Attribute(); + $model->sort_order = 0; + $model->cat_id = 0; + + if ($model->load(Yii::$app->request->post()) && $model->validate()) { + $model->value = str_replace(',', ',', $model->value); + $array = explode(',', $model->value); + if (count($array) != count(array_unique($array))) { + \Yii::$app->getSession()->setFlash('error', '不能有相同的属性值'); + return $this->render('create', ['model' => $model]); + } + if ($model->save()) { + return $this->redirect(['index']); + } + } + + return $this->render('create', [ + 'model' => $model, + ]); + } + + /** + * Updates an existing Attribute model. + * If update is successful, the browser will be redirected to the 'view' page. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionUpdate($id) + { + $model = $this->findModel($id); + + if ($model->load(Yii::$app->request->post()) && $model->validate()) { + $model->value = str_replace(',', ',', $model->value); + $array = explode(',', $model->value); + if (count($array) != count(array_unique($array))) { + \Yii::$app->getSession()->setFlash('error', '不能有相同的属性值'); + return $this->render('create', ['model' => $model]); + } + if ($model->save()) { + return $this->redirect(['index']); + } + return $this->redirect('index'); + } + + return $this->render('update', [ + 'model' => $model, + ]); + } + + /** + * Deletes an existing Attribute model. + * If deletion is successful, the browser will be redirected to the 'index' page. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionDelete($id) + { + $model = $this->findModel($id); + $model->is_delete = Attribute::IS_DELETE_YES; + $model->save(); + + return $this->redirect(['index']); + } + + /** + * Finds the Attribute model based on its primary key value. + * If the model is not found, a 404 HTTP exception will be thrown. + * @param integer $id + * @return Attribute the loaded model + * @throws NotFoundHttpException if the model cannot be found + */ + protected function findModel($id) + { + if (($model = Attribute::findOne($id)) !== null) { + return $model; + } + + throw new NotFoundHttpException('The requested page does not exist.'); + } + /** + * @author iron + * 文件导出 + */ + public function actionExport() + { + $searchModel = new AttributeSearch(); + $params = Yii::$app->request->queryParams; + if ($params['page-type'] == 'all') { + $dataProvider = $searchModel->allData($params); + } else { + $dataProvider = $searchModel->search($params); + } + \iron\widget\Excel::export([ + 'models' => $dataProvider->getModels(), + 'format' => 'Xlsx', + 'asAttachment' => true, + 'fileName' =>'Attributes'. "-" .date('Y-m-d H/i/s', time()), + 'columns' => $searchModel->columns() + ]); + } +} diff --git a/antgoods/controllers/BrandController.php b/antgoods/controllers/BrandController.php new file mode 100644 index 0000000..af957b2 --- /dev/null +++ b/antgoods/controllers/BrandController.php @@ -0,0 +1,151 @@ + [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => ['POST'], + ], + ], + ]; + } + + /** + * Lists all Brand models. + * @return mixed + */ + public function actionIndex() + { + $searchModel = new BrandSearch(); + $dataProvider = $searchModel->search(Yii::$app->request->queryParams); + + return $this->render('index', [ + 'searchModel' => $searchModel, + 'dataProvider' => $dataProvider, + 'columns' => $searchModel->columns() + ]); + } + + /** + * Displays a single Brand model. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionView($id) + { + return $this->render('view', [ + 'model' => $this->findModel($id), + ]); + } + + /** + * Creates a new Brand model. + * If creation is successful, the browser will be redirected to the 'view' page. + * @return mixed + */ + public function actionCreate() + { + $model = new Brand(); + + if ($model->load(Yii::$app->request->post()) && $model->save()) { + return $this->redirect('index'); + } + + return $this->render('create', [ + 'model' => $model, + ]); + } + + /** + * Updates an existing Brand model. + * If update is successful, the browser will be redirected to the 'view' page. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionUpdate($id) + { + $model = $this->findModel($id); + + if ($model->load(Yii::$app->request->post()) && $model->save()) { + return $this->redirect('index'); + } + + return $this->render('update', [ + 'model' => $model, + ]); + } + + /** + * Deletes an existing Brand model. + * If deletion is successful, the browser will be redirected to the 'index' page. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionDelete($id) + { + $model = $this->findModel($id); + $model->is_delete = Brand::IS_DELETE_YES; + $model->save(); + + return $this->redirect(['index']); + } + + /** + * Finds the Brand model based on its primary key value. + * If the model is not found, a 404 HTTP exception will be thrown. + * @param integer $id + * @return Brand the loaded model + * @throws NotFoundHttpException if the model cannot be found + */ + protected function findModel($id) + { + if (($model = Brand::findOne($id)) !== null) { + return $model; + } + + throw new NotFoundHttpException('The requested page does not exist.'); + } + /** + * @author iron + * 文件导出 + */ + public function actionExport() + { + $searchModel = new BrandSearch(); + $params = Yii::$app->request->queryParams; + if ($params['page-type'] == 'all') { + $dataProvider = $searchModel->allData($params); + } else { + $dataProvider = $searchModel->search($params); + } + \iron\widget\Excel::export([ + 'models' => $dataProvider->getModels(), + 'format' => 'Xlsx', + 'asAttachment' => true, + 'fileName' =>'Brands'. "-" .date('Y-m-d H/i/s', time()), + 'columns' => $searchModel->columns() + ]); + } +} diff --git a/antgoods/controllers/CategoryController.php b/antgoods/controllers/CategoryController.php new file mode 100644 index 0000000..fcc2366 --- /dev/null +++ b/antgoods/controllers/CategoryController.php @@ -0,0 +1,276 @@ + [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => ['POST'], + ], + ], + ]; + } + + public function actions() + { + return [ + 'upload' => [ + 'class' => 'iron\actions\UploadAction', + 'path' => 'xls/', + 'maxSize' => 20480, + ] + ]; + } + + /** + * Lists all Category models. + * @return mixed + */ + public function actionIndex() + { + $searchModel = new CategorySearch(); + $dataProvider = $searchModel->search(Yii::$app->request->queryParams); + + return $this->render('index', [ + 'searchModel' => $searchModel, + 'dataProvider' => $dataProvider, + 'columns' => $searchModel->columns() + ]); + } + + /** + * Displays a single Category model. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionView($id) + { + return $this->render('view', [ + 'model' => $this->findModel($id), + ]); + } + + /** + * Creates a new Category model. + * If creation is successful, the browser will be redirected to the 'view' page. + * @return mixed + */ + public function actionCreate() + { + $model = new Category(); + $model->is_show = Category::IS_SHOW_DISPLAY; + $model->sort_order = 0; + + if ($model->load(Yii::$app->request->post()) && $model->validate()) { + + //类目图片上传保存处理 + $icon_image_id_str = $model->iconImageId; + $model->save(); + $save_icon_image_res = GoodsManager::saveFile(explode(',', $icon_image_id_str), $model, [], File::OWN_TYPE_CATEGORY_ICON); + if($save_icon_image_res['status']){ + $model->icon = $save_icon_image_res['first_file_id']; + $model->save(); + } + + return $this->redirect('index'); + } + + return $this->render('create', [ + 'model' => $model, + ]); + } + + /** + * Updates an existing Category model. + * If update is successful, the browser will be redirected to the 'view' page. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionUpdate($id) + { + $model = $this->findModel($id); + $model->iconImageId = $model->icon; + //记录已保存的类目图片id,用于修改 + $icon_image_old_id_arr = $model->icon; + + if ($model->load(Yii::$app->request->post()) && $model->validate()) { + + //类目图片上传保存处理 + $icon_image_id_str = $model->iconImageId; + $model->save(); + $save_icon_image_res = GoodsManager::saveFile(explode(',', $icon_image_id_str), $model, explode(',', $icon_image_old_id_arr), File::OWN_TYPE_CATEGORY_ICON); + if($save_icon_image_res['status'] && $save_icon_image_res['first_file_id'] !== 0){ + $model->icon = $save_icon_image_res['first_file_id']; + $model->save(); + } + + return $this->redirect('index'); + } + + return $this->render('update', [ + 'model' => $model, + ]); + } + + /** + * Deletes an existing Category model. + * If deletion is successful, the browser will be redirected to the 'index' page. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionDelete($id) + { + $model = $this->findModel($id); + + $model->is_delete = Category::IS_DELETE_YES; + $model->save(); + + return $this->redirect(['index']); + } + + /** + * Finds the Category model based on its primary key value. + * If the model is not found, a 404 HTTP exception will be thrown. + * @param integer $id + * @return Category the loaded model + * @throws NotFoundHttpException if the model cannot be found + */ + protected function findModel($id) + { + if (($model = Category::findOne($id)) !== null) { + return $model; + } + + throw new NotFoundHttpException('The requested page does not exist.'); + } + /** + * @author iron + * 文件导出 + */ + public function actionExport() + { + $searchModel = new CategorySearch(); + $params = Yii::$app->request->queryParams; + if ($params['page-type'] == 'all') { + $dataProvider = $searchModel->allData($params); + } else { + $dataProvider = $searchModel->search($params); + } + \iron\widget\Excel::export([ + 'models' => $dataProvider->getModels(), + 'format' => 'Xlsx', + 'asAttachment' => true, + 'fileName' =>'Categories'. "-" .date('Y-m-d H/i/s', time()), + 'columns' => $searchModel->columns() + ]); + } + + /** + * 处理文件上传成功后回调保存到临时文件表中,并返回临时文件id + */ + public function actionSaveFile() + { + if(!class_exists('\common\models\ars\TemFile') || !class_exists('\backend\logic\file\FileManager')){ + return ''; + } + + $data = Yii::$app->request->get('data'); + $file_name = Yii::$app->request->get('fileName')[0]; + + if ($data['status'] == true) { + $model = new \common\models\ars\TemFile(); + $model->user_id = Yii::$app->user->identity->id; + $model->name = $file_name; + $file_manager = new \backend\logic\file\FileManager(); + $type_res = $file_manager->searchType(\backend\logic\file\FileManager::$extension, pathinfo($data['path'])['extension']); + if ($type_res['status']) { + $model->type = $type_res['type']; + } + $model->alias = $data['alias']; + $model->path = $data['path']; + $model->save(); + return $model->id; + } + } + + /** + * @return string + * 点击删除按钮时同时删除字符串中的id + */ + public function actionImgIdDel() + { + //判断该类是否存在 + if(!class_exists('\common\models\ars\TemFile') || !class_exists('\common\models\ars\File')){ + return ''; + } + + $img_id = Yii::$app->request->get('imgid'); + $img_id_arr = explode(',', $img_id); + if(isset(Yii::$app->request->get('data')['alias'])) { + $alias = Yii::$app->request->get('data')['alias']; + $tem_file = \common\models\ars\TemFile::findOne(['alias' => $alias]); + if ($tem_file) { + $img_id_arr = array_diff($img_id_arr, [$tem_file->id]); + } + }else{ + foreach (Yii::$app->request->get() as $key => $value) { + $tem_file = \common\models\ars\File::findOne(['alias' => $value]); + if ($tem_file) { + $img_id_arr = array_diff($img_id_arr, [$tem_file->id]); + } + } + } + $img_id_str = implode(',', $img_id_arr); + return $img_id_str; + } + + /** + * @return bool|false|string + * 加载已有的文件 + */ + public function actionImageFile() + { + //判断该类是否存在 + if(!class_exists('\common\models\ars\File')){ + return false; + } + + $file_id_str = Yii::$app->request->get('fileidstr'); + $file_id_arr = explode(',', $file_id_str); + $data = \common\models\ars\File::find()->where(['id' => $file_id_arr])->all(); + $res = array(); + if($data) { + $i = 0; + foreach ($data as $key => $value) { + $res[$i]['name'] = $value->alias; + $res[$i]['path'] = Yii::$app->request->hostInfo . '/' . $value->path; + $res[$i]['size'] = filesize($value->path); + $i++; + } + } + return json_encode($res); + } +} diff --git a/antgoods/controllers/ConfigController.php b/antgoods/controllers/ConfigController.php new file mode 100755 index 0000000..4ae8433 --- /dev/null +++ b/antgoods/controllers/ConfigController.php @@ -0,0 +1,76 @@ + [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => ['POST'], + ], + ], + ]; + } + + /** + * Lists all Category models. + * @return mixed + */ + public function actionIndex() + { + return $this->render('index'); + } + + + /** + * Updates an existing Category model. + * If update is successful, the browser will be redirected to the 'view' page. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionUpdate($id) + { + $model = $this->findModel($id); + + if ($model->load(Yii::$app->request->post()) && $model->save()) { + return $this->redirect('index'); + } + + return $this->render('update', [ + 'model' => $model, + ]); + } + + /** + * Finds the Category model based on its primary key value. + * If the model is not found, a 404 HTTP exception will be thrown. + * @param integer $id + * @return Category the loaded model + * @throws NotFoundHttpException if the model cannot be found + */ + protected function findModel($id) + { + if (($model = Category::findOne($id)) !== null) { + return $model; + } + + throw new NotFoundHttpException('The requested page does not exist.'); + } +} diff --git a/antgoods/controllers/GoodsController.php b/antgoods/controllers/GoodsController.php new file mode 100644 index 0000000..c2891cc --- /dev/null +++ b/antgoods/controllers/GoodsController.php @@ -0,0 +1,359 @@ + [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => ['POST'], + ], + ], + ]; + } + + public function actions() + { + return [ + 'upload' => [ + 'class' => 'iron\actions\UploadAction', + 'path' => 'xls/', + 'maxSize' => 20480, + ], + 'ueditor' => [ + 'class' => 'common\widgets\ueditor\UeditorAction', + 'config' => [ + //上传图片配置 + 'imageUrlPrefix' => "", /* 图片访问路径前缀 */ + 'imagePathFormat' => "/uploads/origin/introduce/" . md5(time() . rand(000, 999)), /* 上传保存路径,可以自定义保存路径和文件名格式 */ + ] + ], + ]; + } + + /** + * Lists all Goods models. + * @return mixed + */ + public function actionIndex() + { + $searchModel = new GoodsSearch(); + $dataProvider = $searchModel->search(Yii::$app->request->queryParams); + + return $this->render('index', [ + 'searchModel' => $searchModel, + 'dataProvider' => $dataProvider, + 'columns' => $searchModel->columns() + ]); + } + + /** + * Displays a single Goods model. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionView($id) + { + return $this->render('view', [ + 'model' => $this->findModel($id), + ]); + } + + /** + * Creates a new Goods model. + * If creation is successful, the browser will be redirected to the 'view' page. + * @return mixed + */ + public function actionCreate() + { + $model = new Goods(); + $model->is_sale = Goods::IS_SALE_YES; + $model->stock = -1; + if ($model->load(Yii::$app->request->post()) && $model->validate()) { + //商品封面图和商品详情图上传保存处理 + $res = GoodsManager::updateGoods(Yii::$app->request->post(), $model); + if ($res['status']) { + return $this->redirect('index'); + } + } else { + $model->ruleVerify = 1; + } + return $this->render('create', [ + 'model' => $model, + ]); + } + + /** + * Updates an existing Goods model. + * If update is successful, the browser will be redirected to the 'view' page. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionUpdate($id) + { + $model = $this->findModel($id); + $model->coverImageId = $model->image; + $model->detailImageId = implode(',', File::find()->select('id')->where(['is_delete' => File::IS_DELETE_NO, 'own_id' => $model->id, 'own_type' => File::OWN_TYPE_GOODS_DETAILS])->column()); + //记录已保存的商品图片id,用于修改 + $cover_image_old_id_str = $model->image; + $detail_image_old_id_str = $model->detailImageId; + if ($model->load(Yii::$app->request->post()) && $model->validate()) { + //商品封面图和商品详情图上传保存处理 + $res = GoodsManager::updateGoods(Yii::$app->request->post(), $model, $cover_image_old_id_str, $detail_image_old_id_str); + if ($res['status']) { + return $this->redirect('index'); + } + } + $attributeModel = GoodsManager::getAttribute($id); + $checkAttr = GoodsManager::getSkuInfo($id); + $filterAttributeModel = GoodsManager::getFilterAttribute($id); + $judgeGoodsCategory = GoodsManager::judgeGoodsCategory($model); + return $this->render('update', [ + 'model' => $model, + 'attributeModel' => $attributeModel, + 'attrValue' => $checkAttr, + 'filterAttributeModel' => $filterAttributeModel, + 'judgeGoodsCategory' => $judgeGoodsCategory, + ]); + } + + /** + * Deletes an existing Goods model. + * If deletion is successful, the browser will be redirected to the 'index' page. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionDelete($id) + { + $model = $this->findModel($id); + $model->is_delete = Goods::IS_DELETE_YES; + $model->save(); + + return $this->redirect(['index']); + } + + /** + * Finds the Goods model based on its primary key value. + * If the model is not found, a 404 HTTP exception will be thrown. + * @param integer $id + * @return Goods the loaded model + * @throws NotFoundHttpException if the model cannot be found + */ + protected function findModel($id) + { + if (($model = Goods::findOne($id)) !== null) { + return $model; + } + + throw new NotFoundHttpException('The requested page does not exist.'); + } + /** + * @author iron + * 文件导出 + */ + public function actionExport() + { + $searchModel = new GoodsSearch(); + $params = Yii::$app->request->queryParams; + if ($params['page-type'] == 'all') { + $dataProvider = $searchModel->allData($params); + } else { + $dataProvider = $searchModel->search($params); + } + \iron\widget\Excel::export([ + 'models' => $dataProvider->getModels(), + 'format' => 'Xlsx', + 'asAttachment' => true, + 'fileName' =>'Goods'. "-" .date('Y-m-d H/i/s', time()), + 'columns' => $searchModel->columns() + ]); + } + + /** + * 处理文件上传成功后回调保存到临时文件表中,并返回临时文件id + */ + public function actionSaveFile() + { + if(!class_exists('\common\models\ars\TemFile') || !class_exists('\backend\logic\file\FileManager')){ + return ''; + } + + $data = Yii::$app->request->get('data'); + $file_name = Yii::$app->request->get('fileName')[0]; + + if ($data['status'] == true) { + $model = new \common\models\ars\TemFile(); + $model->user_id = Yii::$app->user->identity->id; + $model->name = $file_name; + $file_manager = new \backend\logic\file\FileManager(); + $type_res = $file_manager->searchType(\backend\logic\file\FileManager::$extension, pathinfo($data['path'])['extension']); + if ($type_res['status']) { + $model->type = $type_res['type']; + } + $model->alias = $data['alias']; + $model->path = $data['path']; + $model->save(); + return $model->id; + } + } + + /** + * @return string + * 点击删除按钮时同时删除字符串中的id + */ + public function actionImgIdDel() + { + //判断该类是否存在 + if(!class_exists('\common\models\ars\TemFile') || !class_exists('\common\models\ars\File')){ + return ''; + } + + $img_id = Yii::$app->request->get('imgid'); + $img_id_arr = explode(',', $img_id); + if(isset(Yii::$app->request->get('data')['alias'])) { + $alias = Yii::$app->request->get('data')['alias']; + $tem_file = \common\models\ars\TemFile::findOne(['alias' => $alias]); + if ($tem_file) { + $img_id_arr = array_diff($img_id_arr, [$tem_file->id]); + } + }else{ + foreach (Yii::$app->request->get() as $key => $value) { + $tem_file = \common\models\ars\File::findOne(['alias' => $value]); + if ($tem_file) { + $img_id_arr = array_diff($img_id_arr, [$tem_file->id]); + } + } + } + $img_id_str = implode(',', $img_id_arr); + return $img_id_str; + } + + /** + * @return bool|false|string + * 加载已有的文件 + */ + public function actionImageFile() + { + //判断该类是否存在 + if(!class_exists('\common\models\ars\File')){ + return false; + } + + $rule_verify = Yii::$app->request->get('ruleverify'); + $file_id_str = Yii::$app->request->get('fileidstr'); + $file_id_arr = explode(',', $file_id_str); + if ($rule_verify == 1) { + $data = \common\models\ars\TemFile::find()->where(['id' => $file_id_arr])->all(); + } else { + $data = \common\models\ars\File::find()->where(['id' => $file_id_arr])->all(); + } + $res = array(); + if($data) { + $i = 0; + foreach ($data as $key => $value) { + $res[$i]['name'] = $value->alias; + $res[$i]['path'] = Yii::$app->request->hostInfo . '/' . $value->path; + $res[$i]['size'] = filesize($value->path); + $i++; + } + } + return json_encode($res); + } + + /** + * @param $id + * @return string + * 商品编辑sku + */ + + public function actionEditSku($id) + { + $sku = GoodsManager::getCreatedSku($id); + $attributes = GoodsManager::getAttrs($id); + return $this->render('sku_edit', [ + 'attributes' => $attributes, + 'sku' => $sku,]); + } + + /** + * @return array + * @throws \Throwable + * 添加sku + */ + public function actionAddSku() + { + $data = []; + Yii::$app->response->format = 'json'; + $res = Yii::$app->request->post('sku'); + $goodsId = Yii::$app->request->post('goodsId'); + $tra = Yii::$app->db->beginTransaction(); + try { + $data['originalIds'] = GoodsManager::getOriginalIds($res['type'], $goodsId); + $data['acceptIds'] = []; + foreach ($res['data'] as $sku) { + GoodsManager::AddOrUpdateData($sku, $res['type'], $goodsId); + if ($sku['id'] > 0) { + $data['acceptIds'][] = $sku['id']; + } + } + GoodsManager::deleteSku($res['type'], $data, $goodsId); + $tra->commit(); + return ['status' => true]; + } catch (\Exception $e) { + $tra->rollBack(); + return ['status' => false, 'info' => $e->getMessage()]; + } + } + + public function actionSwitch() + { + Yii::$app->response->format = 'json'; + $data = []; + $type = Yii::$app->request->get('type'); + $id = Yii::$app->request->get('goodsId'); + $data['sku'] = GoodsManager::getCreatedSku($id, $type); + $data['attributes'] = GoodsManager::getAttrs($id, $type); + return $data; + } + + /** + * @return false|string + * 根据商品分类获取商品属性 + */ + public function actionFilterAttribute() + { + $catId = Yii::$app->request->get('catId')??0; + $goodsId = Yii::$app->request->get('goodsId')??0; + $allAttr = Attribute::find()->where(['type' => Attribute::TYPE_ATTR])->andWhere(['cat_id' => [0,$catId]])->asArray()->all(); + return json_encode($allAttr); + } +} diff --git a/antgoods/controllers/ShopCategoryController.php b/antgoods/controllers/ShopCategoryController.php new file mode 100644 index 0000000..3a32b55 --- /dev/null +++ b/antgoods/controllers/ShopCategoryController.php @@ -0,0 +1,287 @@ + [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => ['POST'], + ], + ], + ]; + } + + public function actions() + { + return [ + 'upload' => [ + 'class' => 'iron\actions\UploadAction', + 'path' => 'xls/', + 'maxSize' => 20480, + ] + ]; + } + + /** + * Lists all ShopCategory models. + * @return mixed + */ + public function actionIndex() + { + $searchModel = new ShopCategorySearch(); + $dataProvider = $searchModel->search(Yii::$app->request->queryParams); + + return $this->render('index', [ + 'searchModel' => $searchModel, + 'dataProvider' => $dataProvider, + 'columns' => $searchModel->columns() + ]); + } + + /** + * Displays a single ShopCategory model. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionView($id) + { + return $this->render('view', [ + 'model' => $this->findModel($id), + ]); + } + + /** + * Creates a new ShopCategory model. + * If creation is successful, the browser will be redirected to the 'view' page. + * @return mixed + */ + public function actionCreate() + { + $model = new ShopCategory(); + $model->is_show = ShopCategory::IS_SHOW_HIDE; + $model->sort_order = 0; + + if ($model->load(Yii::$app->request->post())) { + if ($model->filter_attr != null && is_array($model->filter_attr)) { + $model->filter_attr = implode(',', $model->filter_attr); + } else { + $model->filter_attr = ''; + } + + //类目图片上传保存处理 + $icon_image_id_str = $model->iconImageId; + $model->save(); + $save_icon_image_res = GoodsManager::saveFile(explode(',', $icon_image_id_str), $model, [], File::OWN_TYPE_CATEGORY_ICON); + if($save_icon_image_res['status']){ + $model->icon = $save_icon_image_res['first_file_id']; + $model->save(); + } + + return $this->redirect('index'); + } + + return $this->render('create', [ + 'model' => $model, + ]); + } + + /** + * Updates an existing ShopCategory model. + * If update is successful, the browser will be redirected to the 'view' page. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionUpdate($id) + { + $model = $this->findModel($id); + if ($model->filter_attr != null) { + $model->filter_attr = explode(',', $model->filter_attr); + } + $model->iconImageId = $model->icon; + $icon_image_old_id_arr = $model->icon;//记录已保存的类目图片id,用于修改 + + if ($model->load(Yii::$app->request->post())) { + if ($model->filter_attr != null && is_array($model->filter_attr)) { + $model->filter_attr = implode(',', $model->filter_attr); + } else { + $model->filter_attr = ''; + } + + //类目图片上传保存处理 + $icon_image_id_str = $model->iconImageId; + $model->save(); + $save_icon_image_res = GoodsManager::saveFile(explode(',', $icon_image_id_str), $model, explode(',', $icon_image_old_id_arr), File::OWN_TYPE_CATEGORY_ICON); + if($save_icon_image_res['status'] && $save_icon_image_res['first_file_id'] !== 0){ + $model->icon = $save_icon_image_res['first_file_id']; + $model->save(); + } + + return $this->redirect('index'); + } + + return $this->render('update', [ + 'model' => $model, + ]); + } + + /** + * Deletes an existing ShopCategory model. + * If deletion is successful, the browser will be redirected to the 'index' page. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionDelete($id) + { + $model = $this->findModel($id); + $model->is_delete = ShopCategory::IS_DELETE_YES; + $model->save(); + + return $this->redirect(['index']); + } + + /** + * Finds the ShopCategory model based on its primary key value. + * If the model is not found, a 404 HTTP exception will be thrown. + * @param integer $id + * @return ShopCategory the loaded model + * @throws NotFoundHttpException if the model cannot be found + */ + protected function findModel($id) + { + if (($model = ShopCategory::findOne($id)) !== null) { + return $model; + } + + throw new NotFoundHttpException('The requested page does not exist.'); + } + /** + * @author iron + * 文件导出 + */ + public function actionExport() + { + $searchModel = new ShopCategorySearch(); + $params = Yii::$app->request->queryParams; + if ($params['page-type'] == 'all') { + $dataProvider = $searchModel->allData($params); + } else { + $dataProvider = $searchModel->search($params); + } + \iron\widget\Excel::export([ + 'models' => $dataProvider->getModels(), + 'format' => 'Xlsx', + 'asAttachment' => true, + 'fileName' =>'Shop Categories'. "-" .date('Y-m-d H/i/s', time()), + 'columns' => $searchModel->columns() + ]); + } + + /** + * 处理文件上传成功后回调保存到临时文件表中,并返回临时文件id + */ + public function actionSaveFile() + { + if(!class_exists('\common\models\ars\TemFile') || !class_exists('\backend\logic\file\FileManager')){ + return ''; + } + + $data = Yii::$app->request->get('data'); + $file_name = Yii::$app->request->get('fileName')[0]; + + if ($data['status'] == true) { + $model = new \common\models\ars\TemFile(); + $model->user_id = Yii::$app->user->identity->id; + $model->name = $file_name; + $file_manager = new \backend\logic\file\FileManager(); + $type_res = $file_manager->searchType(\backend\logic\file\FileManager::$extension, pathinfo($data['path'])['extension']); + if ($type_res['status']) { + $model->type = $type_res['type']; + } + $model->alias = $data['alias']; + $model->path = $data['path']; + $model->save(); + return $model->id; + } + } + + /** + * @return string + * 点击删除按钮时同时删除字符串中的id + */ + public function actionImgIdDel() + { + //判断该类是否存在 + if(!class_exists('\common\models\ars\TemFile') || !class_exists('\common\models\ars\File')){ + return ''; + } + + $img_id = Yii::$app->request->get('imgid'); + $img_id_arr = explode(',', $img_id); + if(isset(Yii::$app->request->get('data')['alias'])) { + $alias = Yii::$app->request->get('data')['alias']; + $tem_file = \common\models\ars\TemFile::findOne(['alias' => $alias]); + if ($tem_file) { + $img_id_arr = array_diff($img_id_arr, [$tem_file->id]); + } + }else{ + foreach (Yii::$app->request->get() as $key => $value) { + $tem_file = \common\models\ars\File::findOne(['alias' => $value]); + if ($tem_file) { + $img_id_arr = array_diff($img_id_arr, [$tem_file->id]); + } + } + } + $img_id_str = implode(',', $img_id_arr); + return $img_id_str; + } + + /** + * @return bool|false|string + * 加载已有的文件 + */ + public function actionImageFile() + { + //判断该类是否存在 + if(!class_exists('\common\models\ars\File')){ + return false; + } + + $file_id_str = Yii::$app->request->get('fileidstr'); + $file_id_arr = explode(',', $file_id_str); + $data = \common\models\ars\File::find()->where(['id' => $file_id_arr])->all(); + $res = array(); + if($data) { + $i = 0; + foreach ($data as $key => $value) { + $res[$i]['name'] = $value->alias; + $res[$i]['path'] = Yii::$app->request->hostInfo . '/' . $value->path; + $res[$i]['size'] = filesize($value->path); + $i++; + } + } + return json_encode($res); + } +} diff --git a/antgoods/controllers/SiteController.php b/antgoods/controllers/SiteController.php new file mode 100755 index 0000000..155c9f8 --- /dev/null +++ b/antgoods/controllers/SiteController.php @@ -0,0 +1,112 @@ + [ + '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() { + return [ + 'error' => [ + 'class' => 'yii\web\ErrorAction', + ], + 'upload'=>[ + 'class'=>'iron\actions\UploadAction', + ] + ]; + } + + /** + * Displays homepage. + * + * @return string + */ + public function actionIndex() { + return $this->render('index'); + } + + /** + * Login action. + * + * @return string + */ + public function actionLogin() { + + $this->layout = 'base'; + + if (!Yii::$app->user->isGuest) { + return $this->goHome(); + } + + $model = new LoginForm(); + if ($model->load(Yii::$app->request->post()) && $model->login()) { + return $this->goBack(); + } else { + $model->password = ''; + + return $this->render('login', [ + 'model' => $model, + ]); + } + } + + /** + * Logout action. + * + * @return string + */ + public function actionLogout() { + Yii::$app->user->logout(); + + return $this->goHome(); + } + + public function actionTest() { + $searchModel = new CategorySearch(); + return $this->render('test', [ + 'name' => 'blobt', + 'model' => $searchModel + ]); + } + +} diff --git a/antgoods/controllers/SupplierController.php b/antgoods/controllers/SupplierController.php new file mode 100644 index 0000000..67c067b --- /dev/null +++ b/antgoods/controllers/SupplierController.php @@ -0,0 +1,151 @@ + [ + 'class' => VerbFilter::className(), + 'actions' => [ + 'delete' => ['POST'], + ], + ], + ]; + } + + /** + * Lists all Supplier models. + * @return mixed + */ + public function actionIndex() + { + $searchModel = new SupplierSearch(); + $dataProvider = $searchModel->search(Yii::$app->request->queryParams); + + return $this->render('index', [ + 'searchModel' => $searchModel, + 'dataProvider' => $dataProvider, + 'columns' => $searchModel->columns() + ]); + } + + /** + * Displays a single Supplier model. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionView($id) + { + return $this->render('view', [ + 'model' => $this->findModel($id), + ]); + } + + /** + * Creates a new Supplier model. + * If creation is successful, the browser will be redirected to the 'view' page. + * @return mixed + */ + public function actionCreate() + { + $model = new Supplier(); + + if ($model->load(Yii::$app->request->post()) && $model->save()) { + return $this->redirect('index'); + } + + return $this->render('create', [ + 'model' => $model, + ]); + } + + /** + * Updates an existing Supplier model. + * If update is successful, the browser will be redirected to the 'view' page. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionUpdate($id) + { + $model = $this->findModel($id); + + if ($model->load(Yii::$app->request->post()) && $model->save()) { + return $this->redirect('index'); + } + + return $this->render('update', [ + 'model' => $model, + ]); + } + + /** + * Deletes an existing Supplier model. + * If deletion is successful, the browser will be redirected to the 'index' page. + * @param integer $id + * @return mixed + * @throws NotFoundHttpException if the model cannot be found + */ + public function actionDelete($id) + { + $model = $this->findModel($id); + $model->is_delete = Supplier::IS_DELETE_YES; + $model->save(); + + return $this->redirect(['index']); + } + + /** + * Finds the Supplier model based on its primary key value. + * If the model is not found, a 404 HTTP exception will be thrown. + * @param integer $id + * @return Supplier the loaded model + * @throws NotFoundHttpException if the model cannot be found + */ + protected function findModel($id) + { + if (($model = Supplier::findOne($id)) !== null) { + return $model; + } + + throw new NotFoundHttpException('The requested page does not exist.'); + } + /** + * @author iron + * 文件导出 + */ + public function actionExport() + { + $searchModel = new SupplierSearch(); + $params = Yii::$app->request->queryParams; + if ($params['page-type'] == 'all') { + $dataProvider = $searchModel->allData($params); + } else { + $dataProvider = $searchModel->search($params); + } + \iron\widget\Excel::export([ + 'models' => $dataProvider->getModels(), + 'format' => 'Xlsx', + 'asAttachment' => true, + 'fileName' =>'Suppliers'. "-" .date('Y-m-d H/i/s', time()), + 'columns' => $searchModel->columns() + ]); + } +} diff --git a/antgoods/logic/goods/GoodsManager.php b/antgoods/logic/goods/GoodsManager.php new file mode 100644 index 0000000..c9d134d --- /dev/null +++ b/antgoods/logic/goods/GoodsManager.php @@ -0,0 +1,578 @@ + false, 'info' => '操作失败']; + } + + //需要新建的文件id + $createFileIdArr = array_diff($newFileIdArr, $oldFileIdArr); + + //创建文件 + $class = new \backend\logic\file\FileManager(); + $createFileRes = $class->saveTemFileToFile($createFileIdArr, $goodsModel->id, $fileType); + + //需要删除的文件id + $delFileIdArr = array_diff($oldFileIdArr, $newFileIdArr); + + //删除文件 + $class->deleteFile($delFileIdArr); + + //记录第一张图片id + $firstFileId = 0; + + //查看修改数组是否为空 + if (!$newFileIdArr[0]) { + $firstFileId = null; + }else { + if ($createFileRes['status']) { + $firstFileId = $createFileRes['first_file_id']; + } + } + + return ['status' => true, 'info' => '操作成功', 'first_file_id' => $firstFileId]; + } + + /** + * @param $data + * @param $model + * @param null $coverImageOldIdStr + * @param null $detailImageOldIdStr + * @return array + * @throws \Throwable + * 创建修改商品操作 + */ + public static function updateGoods($data, $model, $coverImageOldIdStr = null, $detailImageOldIdStr = null) + { + $attribute = $data['attribute']; + $filterAttribute = $data['filterattribute']; + $tra = Yii::$app->db->beginTransaction(); + try { + if (!$model->save()) { + 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('图片保存失败'); + } + } + } else { + throw new Exception('图片保存失败'); + } + self::addAttributeOperating(['id' => $model->id, 'attribute' => $attribute]); + self::addFilterAttributeOperating(['id' => $model->id, 'filterAttribute' => $filterAttribute]); + $tra->commit(); + return ['status' => true]; + } catch (\yii\base\Exception $e) { + $tra->rollBack(); + return ['status' => false, 'info' => $e->getMessage()]; + } + } + + /** + * @param $data + * @return bool + * @throws Exception + * 创建修改商品属性操作 + */ + public 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); + 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'); + } + } + } + } + + /** + * @param $goodsAttr + * @throws Exception + * 删除商品属性 + */ + public 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'); + } + } + } + + /** + * @param $attribute + * @param $goodsId + * @return array + * @throws Exception + * 保存商品属性 + */ + public static function addAttribute($attribute, $goodsId) + { + $newAttr = []; + if (!$attribute) { + return []; + } + foreach ($attribute as $value) { + foreach ($value['value'] as $k => $v) { + $goodsAttrModel = new GoodsAttr(); + $goodsAttrModel->attr_id = $value['id']; + $attr = GoodsAttr::find()->where(['goods_id' => $goodsId, 'attr_id' => $value['id'], 'attr_value' => $v, 'is_delete' => GoodsAttr::IS_DELETE_NO])->one(); + if ($attr) { + $newAttr[$attr->id] = $attr->attr_value; //原有的数据 + } else { + $goodsAttrModel->goods_id = $goodsId; + $goodsAttrModel->attr_value = $v; + if (!$goodsAttrModel->save()) { + throw new Exception('goodsAttribute save false'); + } + $newAttr[$goodsAttrModel->id] = $goodsAttrModel->attr_value; //新增的数据 + } + } + } + return $newAttr; + } + + /** + * @param $id + * @return Attribute|array|null + * 获取属性信息 + */ + public static function getAttribute($id) + { + $goodsAttributes = GoodsAttr::find()->where(['goods_id' => $id, 'is_delete' => GoodsAttr::IS_DELETE_NO])->andWhere(['!=', 'attr_id', 0])->all(); + $filter = []; + $goodsAttributeModel = []; + if (!$goodsAttributes) { + return $goodsAttributeModel; + } + foreach ($goodsAttributes as $key => $value) { + $attribute = Attribute::findOne($value->attr_id); + if (!in_array($attribute->name, $filter)) { + $filter[] = $attribute->name; + $attribute = ['name' => $attribute->name, 'id' => $attribute->id, 'value' => [$value->attr_value]]; + $goodsAttributeModel[] = $attribute; + } else { + foreach ($goodsAttributeModel as $k => $v) { + if ($v['name'] == $attribute->name) { + $goodsAttributeModel[$k]['value'][] = $value->attr_value; + } + } + } + } + return $goodsAttributeModel; + } + + /** + * @param $id + * @return array + * 获取sku信息 + */ + public static function getSkuInfo($id) + { + $skus = GoodsSku::find()->where(['goods_id' => $id, 'is_delete' => GoodsSku::IS_DELETE_NO])->all(); + $attrId = []; + foreach ($skus as $sku) { + $attrId = array_merge(explode(',', $sku->goods_attr), $attrId); + } + $attrs = GoodsAttr::find()->where(['id' => $attrId, 'is_delete' => GoodsAttr::IS_DELETE_NO])->andWhere(['!=', 'attr_id', 0])->all(); + $checkAttr = []; + $filterAttr = []; + foreach ($attrs as $value) { + $attr = Attribute::findOne(['id' => $value->attr_id, 'is_delete' => Attribute::IS_DELETE_NO]); + if (!in_array($attr->name, $filterAttr)) { + $filterAttr[] = $attr->name; + $newAttr = ['id' => $attr->id, 'name' => $attr->name, 'value' => [$value->attr_value]]; + $checkAttr[] = $newAttr; + } else { + foreach ($checkAttr as $key => $item) { + if ($item['name'] == $attr->name) { //如果attr_id与$filter的attr_id相符,入栈 + $checkAttr[$key]['value'][] = $value->attr_value; + } + } + } + } + return $checkAttr; + } + + /** + * @param $id + * @return mixed + * 已创建sku信息 + */ + public static function getCreatedSku($id, $type = 0) + { + $goods = Goods::findOne($id); + $data['type'] = $type ?: $goods->sku_mode; + $data['data'] = []; + if ($data['type'] == Goods::SKU_MODE_ATTR) { + $sku = GoodsSku::find() + ->where(['goods_id' => $id, 'is_manaul' => 0]) + ->all(); + } else { + $sku = GoodsSku::find() + ->where(['goods_id' => $id, 'is_manaul' => 1]) + ->all(); + } + foreach ($sku as $value) { + $data['data'][] = self::getAttrInfo($data['type'], $value); + } + return $data; + } + + /** + * @param $type + * @param $sku + * @return array + * 获取商品详情 + */ + public static function getAttrInfo($type, $sku) + { + $data = []; + if ($type == Goods::SKU_MODE_ATTR) { + $data['value'] = array_filter(explode(',', $sku->goods_attr)); + } else { + $attr = explode(',', $sku->goods_attr); + $goodsAttr = GoodsAttr::findOne($attr[0]); + $data['value'] = $goodsAttr->attr_value; + } + $data['id'] = $sku->id; + $data['price'] = $sku->price; + $data['stock'] = $sku->stock; + $data['weight'] = $sku->weight; + return $data; + } + + /** + * @param $id + * @return array + * 获取商品属性 + */ + public static function getAttrs($id) + { + $attrId = GoodsAttr::find()->where(['goods_id' => $id, 'is_delete' => GoodsAttr::IS_DELETE_NO]) + ->andWhere(['>', 'attr_id', 0]) + ->select('attr_id') + ->distinct() + ->all(); + $attributes = []; + foreach ($attrId as $v) { + $attribute = Attribute::findOne($v); + if ($attribute && $attribute->type == Attribute::TYPE_ATTR) { + $ret['name'] = $attribute->name; + $ret['id'] = $attribute->id; + $ret['attrValue'] = self::getAttrValue($attribute->id, $id); + $attributes[] = $ret; + } + } + return $attributes; + } + + /** + * @param $attrId + * @param $goodsId + * @return GoodsAttr[]|GoodsSku[]|array|File[]|\common\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 + * @return array + * 获取已存储的商品sku的id + */ + public static function getOriginalIds($type, $goodsId) + { + $ids = []; + if ($type == Goods::SKU_MODE_MANUAL) { + $query = GoodsSku::find() + ->where(['is_manaul' => 1]); + } else { + $query = GoodsSku::find() + ->where(['is_manaul' => 0]); + } + $sku = $query + ->andWhere(['goods_id' => $goodsId]) + ->all(); + foreach ($sku as $value) { + $ids[] = $value->id; + } + return $ids; + } + + /** + * @param $sku + * @throws \yii\db\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('手动属性修改失败'); + } + $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类型修改失败'); + } + } + + /** + * @param $type + * @param $data + * @param $goodsId + * @return bool + * @throws \Throwable + * @throws \yii\db\StaleObjectException + * 删除sku + */ + public static function deleteSku($type, $data, $goodsId) + { + if (!$data['originalIds']) { + return true; + } + if ($type == Goods::SKU_MODE_MANUAL) { + $query = GoodsSku::find() + ->where(['is_manaul' => 1]); + } else { + $query = GoodsSku::find() + ->where(['is_manaul' => 0]); + } + $sku = $query + ->andWhere(['goods_id' => $goodsId]) + ->andWhere(['in', 'id', $data['originalIds']]) + ->andWhere(['not in', 'id', $data['acceptIds']]) + ->all(); + foreach ($sku as $value) { + $value->delete(); + } + } + + /** + * @param $data + * @return bool + * @throws Exception + * 创建修改商品筛选属性操作 + */ + public static function addFilterAttributeOperating($data) + { + if (!$data['filterAttribute']) { + return true; + } + $data['filterAttribute'] = json_decode($data['filterAttribute'], true); + $oldFilterAttr = []; + $goodsFilterAttr = FilterAttr::find()->where(['goods_id' => $data['id'], 'is_delete' => FilterAttr::IS_DELETE_NO])->all(); + if ($goodsFilterAttr) { //如果商品有旧的属性 + if(count($data['filterAttribute']) == 0 && is_array($data['filterAttribute'])) { //如果传上来的是空数组,删除该商品下的全部属性 + self::delFilterAttribute($goodsFilterAttr); + return true; + } + foreach ($goodsFilterAttr as $key => $value) { //把旧的商品属性保存到一个数组 + $oldFilterAttr[$value->id] = $value->attr_value; + } + } + $newAttr = self::addFilterAttribute($data['filterAttribute'], $data['id']); //添加新的商品属性 + $delAttr = array_diff(array_keys($oldFilterAttr), array_keys($newAttr)); //找出需要删除的goodsAttrId + if (!$delAttr) { + return true; + } + foreach ($delAttr as $value) { + $model = FilterAttr::find()->where(['id' => $value, 'is_delete' => FilterAttr::IS_DELETE_NO])->One(); + if ($model) { + $model->is_delete = FilterAttr::IS_DELETE_YES; + if (!$model->save()) { + throw new Exception('goodsAttribute delete false'); + } + } + } + } + + /** + * @param $goodsFilterAttr + * @throws Exception + * 删除商品筛选属性 + */ + public 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'); + } + } + } + + /** + * @param $attribute + * @param $goodsId + * @return array + * @throws Exception + * 保存商品筛选属性 + */ + public static function addFilterAttribute($attribute, $goodsId) + { + $newAttr = []; + if (!$attribute) { + return []; + } + foreach ($attribute as $value) { + foreach ($value['value'] as $k => $v) { + $goodsFilterAttrModel = new FilterAttr(); + $goodsFilterAttrModel->attr_id = $value['id']; + $attr = FilterAttr::find()->where(['goods_id' => $goodsId, 'attr_id' => $value['id'], 'attr_value' => $v, 'is_delete' => FilterAttr::IS_DELETE_NO])->one(); + if ($attr) { + $newAttr[$attr->id] = $attr->attr_value; //原有的数据 + } else { + $goodsFilterAttrModel->goods_id = $goodsId; + $goodsFilterAttrModel->attr_value = $v; + if (!$goodsFilterAttrModel->save()) { + throw new Exception('goodsAttribute save false'); + } + $newAttr[$goodsFilterAttrModel->id] = $goodsFilterAttrModel->attr_value; //新增的数据 + } + } + } + return $newAttr; + } + + /** + * @param $id + * @return Attribute|array|null + * 获取筛选属性信息 + */ + public static function getFilterAttribute($id) + { + $goodsFilterAttributes = FilterAttr::find()->where(['goods_id' => $id, 'is_delete' => FilterAttr::IS_DELETE_NO])->andWhere(['!=', 'attr_id', 0])->all(); + $filter = []; + $goodsFilterAttributeModel = []; + if (!$goodsFilterAttributes) { + return $goodsFilterAttributeModel; + } + foreach ($goodsFilterAttributes as $key => $value) { + $attribute = Attribute::findOne($value->attr_id); + if (!in_array($attribute->name, $filter)) { + $filter[] = $attribute->name; + $attribute = ['name' => $attribute->name, 'id' => $attribute->id, 'value' => [$value->attr_value]]; + $goodsFilterAttributeModel[] = $attribute; + } else { + foreach ($goodsFilterAttributeModel as $k => $v) { + if ($v['name'] == $attribute->name) { + $goodsFilterAttributeModel[$k]['value'][] = $value->attr_value; + } + } + } + } + return $goodsFilterAttributeModel; + } + + /** + * @param $goodsModel + * @return bool + * + */ + public static function judgeGoodsCategory($goodsModel) + { + $skus = GoodsSku::find()->where(['goods_id' => $goodsModel->id, 'is_delete' => GoodsSku::IS_DELETE_NO])->all(); + $attrId = []; + foreach ($skus as $sku) { + $attrId = array_merge(explode(',', $sku->goods_attr), $attrId); + } + $goodsAttr = array_unique(GoodsAttr::find()->select(['attr_id'])->where(['id' => $attrId, 'is_delete' => GoodsAttr::IS_DELETE_NO])->andWhere(['!=', 'attr_id', 0])->column()); + $attrArr = array_unique(Attribute::find()->select(['cat_id'])->where(['is_delete' => Attribute::IS_DELETE_NO, 'id' => $goodsAttr])->column()); + if (in_array($goodsModel->cat_id, $attrArr)) { + return true; //存在,则返回true,表示后台分类不得修改 + } + return false; //否则返回false,表示后台分类可以修改 + } + + public static function categoryBtreeList() + { + + } +} \ No newline at end of file diff --git a/antgoods/models/.gitkeep b/antgoods/models/.gitkeep new file mode 100755 index 0000000..72e8ffc --- /dev/null +++ b/antgoods/models/.gitkeep @@ -0,0 +1 @@ +* diff --git a/antgoods/models/ars/Attribute.php b/antgoods/models/ars/Attribute.php new file mode 100644 index 0000000..0b077d7 --- /dev/null +++ b/antgoods/models/ars/Attribute.php @@ -0,0 +1,111 @@ + 50], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'id', + 'name' => '规格名称', + 'value' => '规格内容(每项以逗号隔开)', + 'type' => '类型', + 'sort_order' => '排序', + 'is_delete' => '是否删除,1为已删除', + 'created_at' => '创建时间', + 'updated_at' => '更新时间', + 'cat_id' => '后台商品分类', + ]; + } + + + /** + * @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(); + }, + ], + ]; + } + + /** + * @return array + * 数据键值对 + */ + public static function modelColumn() + { + return $column = self::find()->select(['name'])->where(['is_delete' => self::IS_DELETE_NO])->indexBy('id')->column(); + } + + public function beforeSave($insert) + { + if(!$this->type){ + $this->type = self::TYPE_ATTR; + } + return parent::beforeSave($insert); // TODO: Change the autogenerated stub + } + + public function getCategory() + { + return $this->hasOne(Category::className(), ['id' => 'cat_id']); + } +} diff --git a/antgoods/models/ars/Brand.php b/antgoods/models/ars/Brand.php new file mode 100644 index 0000000..09ef7c3 --- /dev/null +++ b/antgoods/models/ars/Brand.php @@ -0,0 +1,82 @@ + 50], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'id', + 'name' => '品牌名', + 'is_delete' => '是否删除,1为已删除', + 'created_at' => '创建时间', + 'updated_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(); + }, + ], + ]; + } + + public static function modelColumn() + { + return $column = self::find()->select(['name'])->where(['is_delete' => self::IS_DELETE_NO])->indexBy('id')->column(); + } +} diff --git a/antgoods/models/ars/Category.php b/antgoods/models/ars/Category.php new file mode 100644 index 0000000..181da3e --- /dev/null +++ b/antgoods/models/ars/Category.php @@ -0,0 +1,114 @@ + '显示', + self::IS_SHOW_HIDE => '隐藏' + ]; + + /** + * {@inheritdoc} + */ + public static function tableName() + { + return 'antgoods_category'; + } + + /** + * {@inheritdoc} + */ + public function rules() + { + return [ + [['name'], 'required'], + [['pid', 'goods_count', 'sort_order', 'is_show', 'is_delete', 'icon'], 'integer'], + [['name'], 'string', 'max' => 60], + [['iconImageId'], 'string'], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'id', + 'name' => '类别名称', + 'pid' => '父级', + 'goods_count' => '商品数量', + 'sort_order' => '排序', + 'icon' => '图标', + 'is_show' => '是否显示', + 'is_delete' => '是否删除,1为已删除', + 'created_at' => '创建时间', + 'updated_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(); + }, + ], + ]; + } + + /** + * @return array + * 数据键值对 + */ + public static function modelColumn() + { + return $column = self::find()->select(['name'])->where(['is_delete' => self::IS_DELETE_NO])->indexBy('id')->column(); + } + + public function getIconFile() + { + return $this->hasOne(File::className(), ['id' => 'icon']); + } +} diff --git a/antgoods/models/ars/FilterAttr.php b/antgoods/models/ars/FilterAttr.php new file mode 100644 index 0000000..c6b8aa2 --- /dev/null +++ b/antgoods/models/ars/FilterAttr.php @@ -0,0 +1,81 @@ + 50], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'id', + 'goods_id' => '商品id', + 'attr_id' => '属性id', + 'attr_value' => '属性值', + 'is_delete' => '是否删除,1为已删除', + 'created_at' => '创建时间', + 'updated_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/antgoods/models/ars/Goods.php b/antgoods/models/ars/Goods.php new file mode 100644 index 0000000..ebc748e --- /dev/null +++ b/antgoods/models/ars/Goods.php @@ -0,0 +1,232 @@ + '不在售', + self::IS_SALE_YES => '在售' + ]; + public $ruleVerify = 0;//规则验证是否通过 + /** + * {@inheritdoc} + */ + public static function tableName() + { + return 'antgoods_goods'; + } + + /** + * {@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'], + [['cat_id', 'brand_id', 'shop_cat_id', 'name'], 'required'], + [['sn'], 'checkExist'], + [['description', 'coverImageId', 'detailImageId'], 'string'], + [['name'], 'string', 'max' => 120], + [['sn'], 'string', 'max' => 60], + [['code'], 'string', 'max' => 50], + [['unit'], 'string', 'max' => 16], + [['brief'], 'string', 'max' => 255], + [['weight', 'length', 'width', 'height', 'diameter', 'sold_count', 'market_price', 'price'], 'checkNegative'], + ]; + } + + /** + * @param $attribute + * @param $params + * 验证是否为负数 + */ + public function checkNegative($attribute, $params) + { + if ($this->$attribute < 0) { + $this->addError($attribute, "不得为负数"); + } + } + + /** + * @param $attribute + * @param $params + * 验证商品编号唯一 + */ + public function checkExist($attribute, $params) + { + $goods = self::find()->where([$attribute => $this->$attribute, 'is_delete' => 0])->one(); + if ($this->isNewRecord) { + if ($goods) { + $this->addError($attribute, "该商品编号已经存在"); + } + } else { + if ($goods && $goods->id != $this->id) { + $this->addError($attribute, "该商品编号已经存在"); + } + } + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'id', + 'pid' => '父级id', + 'cat_id' => '后台商品类别', + 'brand_id' => '品牌', + 'shop_cat_id' => '前端商品类别', + 'name' => '商品名称', + 'sn' => '商品唯一货号', + 'code' => '商品货码', + 'supplier_id' => '供应商', + 'weight' => '重量', + 'length' => '长度', + 'width' => '宽度', + 'height' => '高度', + 'diameter' => '直径', + 'unit' => '单位', + 'sold_count' => '已售数量', + 'limit_count' => '限购数量', + 'stock' => '库存', + 'stock_warn' => '库存警告', + 'market_price' => '市场价', + 'price' => '销售价', + 'brief' => '简介', + 'description' => '详细介绍', + 'image' => '首页图片', + 'model_id' => '模型id', + 'is_sale' => '销售状态', + 'sort_order' => '排序', + 'bouns_points' => '奖励积分', + 'experience_points' => '经验值', + 'is_delete' => '是否删除,1为已删除', + 'express_template' => '配送详情id', + 'created_at' => '创建时间', + 'updated_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(); + }, + ], + ]; + } + + /** + * @param bool $insert + * @return bool + * 自动填入参数 + */ + public function beforeSave($insert) + { + if (!$this->sn) { + $this->sn = time() . rand(1111, 9999); + } + return parent::beforeSave($insert); // TODO: Change the autogenerated stub + } + + public function getCategory() + { + return $this->hasOne(Category::className(), ['id' => 'cat_id']); + } + + public function getShopCategory() + { + return $this->hasOne(ShopCategory::className(), ['id' => 'shop_cat_id']); + } + + public function getImageFile() + { + return $this->hasOne(File::className(), ['id' => 'image']); + } + + public function getBrand() + { + return $this->hasOne(Brand::className(), ['id' => 'brand_id']); + } + + public function getSupplier() + { + return $this->hasOne(Supplier::className(), ['id' => 'supplier_id']); + } +} diff --git a/antgoods/models/ars/GoodsAttr.php b/antgoods/models/ars/GoodsAttr.php new file mode 100644 index 0000000..4cb2495 --- /dev/null +++ b/antgoods/models/ars/GoodsAttr.php @@ -0,0 +1,81 @@ + 50], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'id', + 'goods_id' => '商品id', + 'attr_id' => '属性id', + 'attr_value' => '属性名', + 'is_delete' => '是否删除,1为已删除', + 'created_at' => '创建时间', + 'updated_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/antgoods/models/ars/GoodsSku.php b/antgoods/models/ars/GoodsSku.php new file mode 100644 index 0000000..45e729a --- /dev/null +++ b/antgoods/models/ars/GoodsSku.php @@ -0,0 +1,102 @@ + 50], + [['goods_sn', 'goods_attr'], 'string', 'max' => 60], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'id', + 'goods_id' => '商品id', + 'goods_code' => '商品条码', + 'goods_sn' => '商品唯一货号', + 'goods_attr' => '属性匹配', + 'sold_count' => '已售数量', + 'stock' => '库存', + 'market_price' => '市场价', + 'price' => '销售价', + 'model_id' => '模型id', + 'is_sale' => '该商品是否开放销售,1为是,0为否', + 'sort_order' => '排序', + 'is_delete' => '是否删除,1为已删除', + 'created_at' => '创建时间', + 'updated_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/antgoods/models/ars/ShopCategory.php b/antgoods/models/ars/ShopCategory.php new file mode 100644 index 0000000..1212ec2 --- /dev/null +++ b/antgoods/models/ars/ShopCategory.php @@ -0,0 +1,122 @@ + '显示', + self::IS_SHOW_HIDE => '隐藏' + ]; + + /** + * {@inheritdoc} + */ + public static function tableName() + { + return 'antgoods_shop_category'; + } + + /** + * {@inheritdoc} + */ + public function rules() + { + return [ + [['name'], 'required'], + [['pid', 'goods_count', 'sort_order', 'icon', 'is_show', 'is_delete', 'iconImageId'], 'integer'], + [['filter_attr'], 'safe'], + [['name'], 'string', 'max' => 60], + [['keywords'], 'string', 'max' => 100], + [['desc'], 'string', 'max' => 255], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'id', + 'name' => '类别名称', + 'pid' => '父级', + 'goods_count' => '商品数量', + 'keywords' => '关键字', + 'desc' => '描述', + 'sort_order' => '排序', + 'icon' => '图标', + 'filter_attr' => '筛选属性', + 'is_show' => '是否显示', + 'is_delete' => '是否删除', + 'created_at' => '创建时间', + 'updated_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(); + }, + ], + ]; + } + + /** + * @return array + * 数据键值对 + */ + public static function modelColumn() + { + return $column = self::find()->select(['name'])->where(['is_delete' => self::IS_DELETE_NO])->indexBy('id')->column(); + } + + public function getIconFile() + { + return $this->hasOne(File::className(), ['id' => 'icon']); + } +} diff --git a/antgoods/models/ars/Supplier.php b/antgoods/models/ars/Supplier.php new file mode 100644 index 0000000..31bc64d --- /dev/null +++ b/antgoods/models/ars/Supplier.php @@ -0,0 +1,96 @@ + 50], + [['phone'], 'string', 'max' => 20], + ['phone', 'filter', 'filter' => 'trim'], + ['phone','match','pattern'=>'/^[1][34578][0-9]{9}$/'], + ['phone', 'unique', 'targetClass' => '\antgoods\models\ars\Supplier', 'message' => '手机号已被使用'], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'id', + 'name' => '供应商名称', + 'full_name' => '供应商全称', + 'phone' => '手机号码', + 'address' => '地址', + 'is_delete' => '是否删除,1为已删除', + 'created_at' => '创建时间', + 'updated_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(); + }, + ], + ]; + } + + /** + * @return array + * 数据键值对 + */ + public static function modelColumn() + { + return $column = self::find()->select(['name'])->where(['is_delete' => self::IS_DELETE_NO])->indexBy('id')->column(); + } +} diff --git a/antgoods/models/searchs/AttributeSearch.php b/antgoods/models/searchs/AttributeSearch.php new file mode 100644 index 0000000..dc97a43 --- /dev/null +++ b/antgoods/models/searchs/AttributeSearch.php @@ -0,0 +1,162 @@ + 'blobt\grid\CheckboxColumn', + 'width' => '2%', + 'align' => 'center' + ], + 'id', + 'name', + 'value', + 'sort_order', + ['attribute' => 'cat_id', + 'value' => function ($model){ + return $model->cat_id ? $model->category->name : '无限制'; + }, + ], + [ + 'class' => 'iron\grid\ActionColumn', + 'align' => 'center', + 'config' => [ + [ + 'name' => 'update', + 'icon' => 'pencil', + 'title' => '修改' + ], + [ + 'name' => 'delete', + 'icon' => 'trash', + 'title' => '删除', + 'contents' => '确定删除?' + ] + ], + ], + ]; + } + /** + * @param $params + * @return ActiveDataProvider + * 不分页的所有数据 + */ + public function allData($params) + { + $query = Attribute::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) + { + $query = Attribute::find()->where(['is_delete' => Attribute::IS_DELETE_NO]); + + // 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){ + $query->andFilterWhere(['is_delete' => Attribute::IS_DELETE_NO]); + 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, + 'type' => $this->type, + 'sort_order' => $this->sort_order, + 'is_delete' => $this->is_delete, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]); + + $query->andFilterWhere(['like', 'name', $this->name]) + ->andFilterWhere(['like', 'value', $this->value]); + 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/antgoods/models/searchs/BrandSearch.php b/antgoods/models/searchs/BrandSearch.php new file mode 100644 index 0000000..a91ad40 --- /dev/null +++ b/antgoods/models/searchs/BrandSearch.php @@ -0,0 +1,152 @@ + 'blobt\grid\CheckboxColumn', + 'width' => '2%', + 'align' => 'center' + ], + 'id', + 'name', + [ + 'class' => 'iron\grid\ActionColumn', + 'align' => 'center', + 'config' => [ + [ + 'name' => 'update', + 'icon' => 'pencil', + 'title' => '修改' + ], + [ + 'name' => 'delete', + 'icon' => 'trash', + 'title' => '删除', + 'contents' => '确定删除?' + ] + ], + ], + ]; + } + /** + * @param $params + * @return ActiveDataProvider + * 不分页的所有数据 + */ + public function allData($params) + { + $query = Brand::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) + { + $query = Brand::find()->where(['is_delete' => Brand::IS_DELETE_NO]); + + // 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){ + $query->andFilterWhere(['is_delete' => Brand::IS_DELETE_NO]); + 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, + 'is_delete' => $this->is_delete, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]); + + $query->andFilterWhere(['like', 'name', $this->name]); + 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/antgoods/models/searchs/CategorySearch.php b/antgoods/models/searchs/CategorySearch.php new file mode 100644 index 0000000..1a0f1a1 --- /dev/null +++ b/antgoods/models/searchs/CategorySearch.php @@ -0,0 +1,172 @@ + 'blobt\grid\CheckboxColumn', + 'width' => '2%', + 'align' => 'center' + ], + 'id', + 'name', + ['attribute' => 'icon', + 'contentOptions' => [ + 'align' => 'center', + ], + 'width'=>'10%', + 'format' => 'raw', + 'value' => function ($model) { + return $model->iconFile ? + Html::img(['/'.$model->iconFile->path], ['style' => 'width:80px']) + : '
未设置
'; + + } + ], + 'sort_order', + [ + 'class' => 'iron\grid\ActionColumn', + 'align' => 'center', + 'config' => [ + [ + 'name' => 'update', + 'icon' => 'pencil', + 'title' => '修改' + ], + [ + 'name' => 'delete', + 'icon' => 'trash', + 'title' => '删除', + 'contents' => '确定删除?' + ] + ], + ], + ]; + } + /** + * @param $params + * @return ActiveDataProvider + * 不分页的所有数据 + */ + public function allData($params) + { + $query = Category::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) + { + $query = Category::find()->where(['is_delete' => Category::IS_DELETE_NO]); + + // 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){ + $query->andFilterWhere(['is_delete' => Category::IS_DELETE_NO]); + 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, + 'pid' => $this->pid, + 'goods_count' => $this->goods_count, + 'sort_order' => $this->sort_order, + 'is_show' => $this->is_show, + 'is_delete' => $this->is_delete, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + 'icon' => $this->icon, + ]); + + $query->andFilterWhere(['like', 'name', $this->name]); + 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/antgoods/models/searchs/GoodsSearch.php b/antgoods/models/searchs/GoodsSearch.php new file mode 100644 index 0000000..4e9797a --- /dev/null +++ b/antgoods/models/searchs/GoodsSearch.php @@ -0,0 +1,241 @@ + 'blobt\grid\CheckboxColumn', + 'width' => '2%', + 'align' => 'center' + ], + 'id', + ['attribute' => 'image', + 'contentOptions' => [ + 'align' => 'center', + ], + 'width'=>'10%', + 'format' => 'raw', + 'value' => function ($model) { + return $model->image ? + Html::img(['/'.$model->imageFile->path], ['style' => 'width:80px']) + : '
未设置
'; + + } + ], + 'name', + [ + 'attribute' => 'cat_id', + 'width' => '10%', + 'value' => function ($model) { + return $model->category ? $model->category->name : ''; + }, + ], + [ + 'attribute' => 'shop_cat_id', + 'width' => '10%', + 'value' => function ($model) { + return $model->shopCategory ? $model->shopCategory->name : ''; + }, + ], + [ + 'attribute' => 'stock', + 'width' => '5%', + 'value' => function ($model) { + if ($model->stock == -1) { + return '未开启'; + } else { + return $model->stock; + } + }, + ], + 'price', + ['attribute' => 'is_sale', + 'width' => '5%', + 'value' => + function ($model) { + return $model->is_sale==Goods::IS_SALE_YES ? '在售' : '不在售'; + + }, + ], + 'updated_at:datetime', + [ + 'class' => 'iron\grid\ActionColumn', + 'align' => 'center', + 'config' => [ + [ + 'name' => 'view', + 'icon' => 'list', + 'title' => '详情', + ], + [ + 'name' => 'update', + 'icon' => 'pencil', + 'title' => '修改' + ], + [ + 'name' => 'edit-sku', + 'icon' => 'hard-drive', + 'title' => '商品sku' + ], + [ + 'name' => 'delete', + 'icon' => 'trash', + 'title' => '删除', + 'contents' => '确定删除?' + ] + ], + ], + ]; + } + /** + * @param $params + * @return ActiveDataProvider + * 不分页的所有数据 + */ + public function allData($params) + { + $query = Goods::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) + { + $query = Goods::find()->where(['is_delete' => Goods::IS_DELETE_NO]); + + // 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){ + $query->andFilterWhere(['is_delete' => Goods::IS_DELETE_NO]); + 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, + 'pid' => $this->pid, + 'cat_id' => $this->cat_id, + 'brand_id' => $this->brand_id, + 'shop_cat_id' => $this->shop_cat_id, + 'supplier_id' => $this->supplier_id, + 'weight' => $this->weight, + 'length' => $this->length, + 'width' => $this->width, + 'height' => $this->height, + 'diameter' => $this->diameter, + 'sold_count' => $this->sold_count, + 'limit_count' => $this->limit_count, + 'stock' => $this->stock, + 'stock_warn' => $this->stock_warn, + 'market_price' => $this->market_price, + 'price' => $this->price, + 'image' => $this->image, + 'model_id' => $this->model_id, + 'is_sale' => $this->is_sale, + 'sort_order' => $this->sort_order, + 'bouns_points' => $this->bouns_points, + 'experience_points' => $this->experience_points, + 'is_delete' => $this->is_delete, + 'express_template' => $this->express_template, + '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]) + ->andFilterWhere(['like', 'unit', $this->unit]) + ->andFilterWhere(['like', 'brief', $this->brief]) + ->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/antgoods/models/searchs/ShopCategorySearch.php b/antgoods/models/searchs/ShopCategorySearch.php new file mode 100644 index 0000000..6cbd842 --- /dev/null +++ b/antgoods/models/searchs/ShopCategorySearch.php @@ -0,0 +1,162 @@ + 'blobt\grid\CheckboxColumn', + 'width' => '2%', + 'align' => 'center' + ], + 'id', + 'name', + ['attribute' => 'icon', + 'contentOptions' => [ + 'align' => 'center', + ], + 'width'=>'10%', + 'format' => 'raw', + 'value' => function ($model) { + return $model->iconFile ? + Html::img(['/'.$model->iconFile->path], ['style' => 'width:80px']) + : '
未设置
'; + + } + ], + 'sort_order', + [ + 'class' => 'iron\grid\ActionColumn', + 'align' => 'center', + ], + ]; + } + /** + * @param $params + * @return ActiveDataProvider + * 不分页的所有数据 + */ + public function allData($params) + { + $query = ShopCategory::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) + { + $query = ShopCategory::find() + ->where(['is_delete' => ShopCategory::IS_DELETE_NO]); + + // 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, + 'pid' => $this->pid, + 'goods_count' => $this->goods_count, + 'sort_order' => $this->sort_order, + 'icon' => $this->icon, + 'is_show' => $this->is_show, + 'is_delete' => $this->is_delete, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]); + + $query->andFilterWhere(['like', 'name', $this->name]) + ->andFilterWhere(['like', 'keywords', $this->keywords]) + ->andFilterWhere(['like', 'desc', $this->desc]) + ->andFilterWhere(['like', 'filter_attr', $this->filter_attr]); + 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/antgoods/models/searchs/SupplierSearch.php b/antgoods/models/searchs/SupplierSearch.php new file mode 100644 index 0000000..1d70164 --- /dev/null +++ b/antgoods/models/searchs/SupplierSearch.php @@ -0,0 +1,161 @@ + 'blobt\grid\CheckboxColumn', + 'width' => '2%', + 'align' => 'center' + ], + 'id', + 'name', + 'full_name', + 'phone', + 'address', + //'is_delete', + //'created_at', + //'updated_at', + [ + 'class' => 'iron\grid\ActionColumn', + 'align' => 'center', + 'config' => [ + [ + 'name' => 'update', + 'icon' => 'pencil', + 'title' => '修改' + ], + [ + 'name' => 'delete', + 'icon' => 'trash', + 'title' => '删除', + 'contents' => '确定删除?' + ] + ], + ], + ]; + } + /** + * @param $params + * @return ActiveDataProvider + * 不分页的所有数据 + */ + public function allData($params) + { + $query = Supplier::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) + { + $query = Supplier::find()->where(['is_delete' => Supplier::IS_DELETE_NO]); + + // 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){ + $query->andFilterWhere(['is_delete' => Supplier::IS_DELETE_NO]); + 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, + 'is_delete' => $this->is_delete, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, + ]); + + $query->andFilterWhere(['like', 'name', $this->name]) + ->andFilterWhere(['like', 'full_name', $this->full_name]) + ->andFilterWhere(['like', 'phone', $this->phone]) + ->andFilterWhere(['like', 'address', $this->address]); + 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/antgoods/views/attribute/_form.php b/antgoods/views/attribute/_form.php new file mode 100644 index 0000000..da40e0e --- /dev/null +++ b/antgoods/views/attribute/_form.php @@ -0,0 +1,32 @@ + + +
+ + + + field($model, 'name')->textInput(['maxlength' => true]) ?> + + field($model, 'value')->textarea(['rows' => 6]) ?> + + field($model, 'sort_order')->textInput() ?> + + field($model, 'cat_id')->widget(Select2::className(), ["items" => array_merge([0 => '请选择'], Category::modelColumn()), "promptText" => false]) ?> + +
+ 'btn btn-success']) ?> + 'btn btn-info']) ?> +
+ + + +
diff --git a/antgoods/views/attribute/_search.php b/antgoods/views/attribute/_search.php new file mode 100644 index 0000000..0a9d3be --- /dev/null +++ b/antgoods/views/attribute/_search.php @@ -0,0 +1,49 @@ + + + ['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()); + ?> +
+
+ ', ['class' => 'btn btn-default']) ?> + ', ['class' => 'btn btn-default']) ?> +
+
+ \ No newline at end of file diff --git a/antgoods/views/attribute/create.php b/antgoods/views/attribute/create.php new file mode 100644 index 0000000..2192559 --- /dev/null +++ b/antgoods/views/attribute/create.php @@ -0,0 +1,18 @@ +title = '创建规格'; +$this->params['breadcrumbs'][] = ['label' => '规格管理', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ + render('_form', [ + 'model' => $model, + ]) ?> + +
diff --git a/antgoods/views/attribute/index.php b/antgoods/views/attribute/index.php new file mode 100644 index 0000000..b147a9f --- /dev/null +++ b/antgoods/views/attribute/index.php @@ -0,0 +1,28 @@ +title = '规格管理'; +$this->params['breadcrumbs'][] = $this->title; +?> +
+
+ $dataProvider, + 'filter' => $this->render("_search", ['model' => $searchModel]), + 'batch' => [ + [ + "label" => "删除", + "url" => "attribute/deletes" + ], + ], + 'columns' => $columns + ]); + ?> +
+
\ No newline at end of file diff --git a/antgoods/views/attribute/update.php b/antgoods/views/attribute/update.php new file mode 100644 index 0000000..d21423f --- /dev/null +++ b/antgoods/views/attribute/update.php @@ -0,0 +1,19 @@ +title = '编辑规格: ' . $model->name; +$this->params['breadcrumbs'][] = ['label' => '规格管理', 'url' => ['index']]; +$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->id]]; +$this->params['breadcrumbs'][] = 'Update '; +?> +
+ + render('_form', [ + 'model' => $model, + ]) ?> + +
diff --git a/antgoods/views/attribute/view.php b/antgoods/views/attribute/view.php new file mode 100644 index 0000000..9475eb3 --- /dev/null +++ b/antgoods/views/attribute/view.php @@ -0,0 +1,33 @@ +title = $model->name; +$this->params['breadcrumbs'][] = ['label' => '规格管理', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +\yii\web\YiiAsset::register($this); +?> +
+ +

+ 'btn btn-success']) ?> +

+ + $model, + 'attributes' => [ + 'id', + 'name', + 'value:ntext', + 'type', + 'sort_order', + 'created_at:datetime', + 'updated_at:datetime', + ], + ]) ?> + +
diff --git a/antgoods/views/brand/_form.php b/antgoods/views/brand/_form.php new file mode 100644 index 0000000..fe87664 --- /dev/null +++ b/antgoods/views/brand/_form.php @@ -0,0 +1,24 @@ + + +
+ + + + field($model, 'name')->textInput(['maxlength' => true]) ?> + +
+ 'btn btn-success']) ?> + 'btn btn-info']) ?> +
+ + + +
diff --git a/antgoods/views/brand/_search.php b/antgoods/views/brand/_search.php new file mode 100644 index 0000000..ed21354 --- /dev/null +++ b/antgoods/views/brand/_search.php @@ -0,0 +1,49 @@ + + + ['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()); + ?> +
+
+ ', ['class' => 'btn btn-default']) ?> + ', ['class' => 'btn btn-default']) ?> +
+
+ \ No newline at end of file diff --git a/antgoods/views/brand/create.php b/antgoods/views/brand/create.php new file mode 100644 index 0000000..ab0e683 --- /dev/null +++ b/antgoods/views/brand/create.php @@ -0,0 +1,18 @@ +title = '创建品牌'; +$this->params['breadcrumbs'][] = ['label' => '品牌管理', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ + render('_form', [ + 'model' => $model, + ]) ?> + +
diff --git a/antgoods/views/brand/index.php b/antgoods/views/brand/index.php new file mode 100644 index 0000000..7f2b6ba --- /dev/null +++ b/antgoods/views/brand/index.php @@ -0,0 +1,28 @@ +title = '品牌管理'; +$this->params['breadcrumbs'][] = $this->title; +?> +
+
+ $dataProvider, + 'filter' => $this->render("_search", ['model' => $searchModel]), + 'batch' => [ + [ + "label" => "删除", + "url" => "brand/deletes" + ], + ], + 'columns' => $columns + ]); + ?> +
+
\ No newline at end of file diff --git a/antgoods/views/brand/update.php b/antgoods/views/brand/update.php new file mode 100644 index 0000000..c8453dc --- /dev/null +++ b/antgoods/views/brand/update.php @@ -0,0 +1,19 @@ +title = '编辑品牌: ' . $model->name; +$this->params['breadcrumbs'][] = ['label' => '品牌管理', 'url' => ['index']]; +$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->id]]; +$this->params['breadcrumbs'][] = '编辑 '; +?> +
+ + render('_form', [ + 'model' => $model, + ]) ?> + +
diff --git a/antgoods/views/brand/view.php b/antgoods/views/brand/view.php new file mode 100644 index 0000000..f5cb312 --- /dev/null +++ b/antgoods/views/brand/view.php @@ -0,0 +1,30 @@ +title = $model->name; +$this->params['breadcrumbs'][] = ['label' => '品牌管理', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +\yii\web\YiiAsset::register($this); +?> +
+ +

+ 'btn btn-success']) ?> +

+ + $model, + 'attributes' => [ + 'id', + 'name', + 'created_at:datetime', + 'updated_at:datetime', + ], + ]) ?> + +
diff --git a/antgoods/views/category/_form.php b/antgoods/views/category/_form.php new file mode 100644 index 0000000..482e25b --- /dev/null +++ b/antgoods/views/category/_form.php @@ -0,0 +1,47 @@ + + +
+ + + + field($model, 'name')->textInput(['maxlength' => true]) ?> + + field($model, 'pid')->dropDownList(array_merge([0 => '一级分类'], Category::modelColumn())) ?> + + field($model, 'sort_order')->textInput() ?> + + field($model, 'iconImageId')->hiddenInput()->label('') ?> + field($model, 'iconImagePath')->widget(\iron\widgets\Upload::className(), [ + 'url' => 'upload', + 'deleteUrl' => 'img-id-del', + 'dragdropWidth'=> 800, + 'afterSave' => 'save-file', + 'maxCount' => 1, + 'fillInAttribute' => 'iconImageId', + 'model' => $model, + 'previewConfig' => [ + 'url' => Url::to(['image-file', 'fileidstr' => $model->iconImageId]), + ], + ])->label('类目图片') ?> + + field($model, 'is_show')->widget(Icheck::className(), ["items" => $model::$isShow, 'type' => "radio"]) ?> + +
+ 'btn btn-success']) ?> + 'btn btn-info']) ?> +
+ + + +
diff --git a/antgoods/views/category/_search.php b/antgoods/views/category/_search.php new file mode 100644 index 0000000..d43cb1d --- /dev/null +++ b/antgoods/views/category/_search.php @@ -0,0 +1,49 @@ + + + ['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()); + ?> +
+
+ ', ['class' => 'btn btn-default']) ?> + ', ['class' => 'btn btn-default']) ?> +
+
+ \ No newline at end of file diff --git a/antgoods/views/category/create.php b/antgoods/views/category/create.php new file mode 100644 index 0000000..a88ba47 --- /dev/null +++ b/antgoods/views/category/create.php @@ -0,0 +1,18 @@ +title = '创建后台商品分类'; +$this->params['breadcrumbs'][] = ['label' => '后台商品分类', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
+ + render('_form', [ + 'model' => $model, + ]) ?> + +
diff --git a/antgoods/views/category/index.php b/antgoods/views/category/index.php new file mode 100644 index 0000000..0f5127f --- /dev/null +++ b/antgoods/views/category/index.php @@ -0,0 +1,28 @@ +title = '后台商品分类'; +$this->params['breadcrumbs'][] = $this->title; +?> +
+
+ $dataProvider, + 'filter' => $this->render("_search", ['model' => $searchModel]), + 'batch' => [ + [ + "label" => "删除", + "url" => "category/deletes" + ], + ], + 'columns' => $columns + ]); + ?> +
+
\ No newline at end of file diff --git a/antgoods/views/category/update.php b/antgoods/views/category/update.php new file mode 100644 index 0000000..cb213ab --- /dev/null +++ b/antgoods/views/category/update.php @@ -0,0 +1,19 @@ +title = '编辑后台商品分类: ' . $model->name; +$this->params['breadcrumbs'][] = ['label' => '后台商品分类', 'url' => ['index']]; +$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->id]]; +$this->params['breadcrumbs'][] = '编辑 '; +?> +
+ + render('_form', [ + 'model' => $model, + ]) ?> + +
diff --git a/antgoods/views/category/view.php b/antgoods/views/category/view.php new file mode 100644 index 0000000..37a7243 --- /dev/null +++ b/antgoods/views/category/view.php @@ -0,0 +1,41 @@ +title = $model->name; +$this->params['breadcrumbs'][] = ['label' => '后台商品分类', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +\yii\web\YiiAsset::register($this); +?> +
+ +

+ 'btn btn-success']) ?> +

+ + $model, + 'attributes' => [ + 'id', + 'name', + 'pid', + 'goods_count', + 'sort_order', + 'icon_type', + 'icon', + [ + 'attribute' => 'is_show', + 'value' => function ($model) { + return $model->is_show == \antgoods\models\ars\Category::IS_SHOW_DISPLAY ? '显示':'隐藏'; + } + ], + 'created_at:datetime', + 'updated_at:datetime', + ], + ]) ?> + +
diff --git a/antgoods/views/config/index.php b/antgoods/views/config/index.php new file mode 100755 index 0000000..3bbeb28 --- /dev/null +++ b/antgoods/views/config/index.php @@ -0,0 +1,27 @@ + + +配置页 diff --git a/antgoods/views/goods/_form.php b/antgoods/views/goods/_form.php new file mode 100644 index 0000000..6ee45ba --- /dev/null +++ b/antgoods/views/goods/_form.php @@ -0,0 +1,107 @@ + + +
+ + + + field($model, 'cat_id')->dropDownList(Category::modelColumn(), ['prompt' => '请选择']) ?> + + field($model, 'brand_id')->dropDownList(Brand::modelColumn(), ['prompt' => '请选择']) ?> + + field($model, 'shop_cat_id')->dropDownList(ShopCategory::modelColumn(), ['prompt' => '请选择']) ?> + + field($model, 'name')->textInput(['maxlength' => true]) ?> + + field($model, 'sn')->textInput(['maxlength' => true]) ?> + + field($model, 'code')->textInput(['maxlength' => true]) ?> + + field($model, 'supplier_id')->dropDownList(Supplier::modelColumn(), ['prompt' => '请选择']) ?> + + field($model, 'weight')->textInput() ?> + + field($model, 'length')->textInput() ?> + + field($model, 'width')->textInput() ?> + + field($model, 'height')->textInput() ?> + + field($model, 'diameter')->textInput() ?> + + field($model, 'unit')->textInput(['maxlength' => true]) ?> + + field($model, 'limit_count')->textInput() ?> + + field($model, 'stock')->textInput() ?> + + field($model, 'stock_warn')->textInput() ?> + + field($model, 'market_price')->textInput() ?> + + field($model, 'price')->textInput() ?> + + field($model, 'brief')->textInput(['maxlength' => true]) ?> + + field($model, 'description')->textarea(['rows' => 6]) ?> + + field($model, 'model_id')->textInput() ?> + + field($model, 'is_sale')->radioList($model::$isSale) ?> + + field($model, 'sort_order')->textInput() ?> + + field($model, 'bouns_points')->textInput() ?> + + field($model, 'experience_points')->textInput() ?> + + field($model, 'express_template')->textInput() ?> + + field($model, 'coverImageId')->hiddenInput()->label('') ?> + field($model, 'coverImagePath')->widget(\iron\widgets\Upload::className(), [ + 'url' => 'upload', + 'deleteUrl' => 'img-id-del', + 'dragdropWidth'=> 800, + 'afterSave' => 'save-file', + 'maxCount' => 1, + 'fillInAttribute' => 'coverImageId', + 'model' => $model, + 'previewConfig' => [ + 'url' => Url::to(['image-file', 'fileidstr' => $model->coverImageId]), + ], + ])->label('商品封面图') ?> + + field($model, 'detailImageId')->hiddenInput()->label('') ?> + field($model, 'detailImagePath')->widget(\iron\widgets\Upload::className(), [ + 'url' => 'upload', + 'deleteUrl' => 'img-id-del', + 'dragdropWidth'=> 800, + 'afterSave' => 'save-file', + 'maxCount' => 5, + 'fillInAttribute' => 'detailImageId', + 'model' => $model, + 'previewConfig' => [ + 'url' => Url::to(['image-file', 'fileidstr' => $model->detailImageId]), + ], + ])->label('商品详情图') ?> + +
+ 'btn btn-success']) ?> + 'btn btn-info']) ?> +
+ + + +
diff --git a/antgoods/views/goods/_search.php b/antgoods/views/goods/_search.php new file mode 100644 index 0000000..9a86777 --- /dev/null +++ b/antgoods/views/goods/_search.php @@ -0,0 +1,49 @@ + + + ['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()); + ?> +
+
+ ', ['class' => 'btn btn-default']) ?> + ', ['class' => 'btn btn-default']) ?> +
+
+ \ No newline at end of file diff --git a/antgoods/views/goods/attribute.php b/antgoods/views/goods/attribute.php new file mode 100755 index 0000000..cf3b70c --- /dev/null +++ b/antgoods/views/goods/attribute.php @@ -0,0 +1,22 @@ +where(['type' => Attribute::TYPE_ATTR])->asArray()->all(); +GoodsAttributeAsset::register($this); +?> + +
+ +
+
+ diff --git a/antgoods/views/goods/create.php b/antgoods/views/goods/create.php new file mode 100644 index 0000000..5003ce5 --- /dev/null +++ b/antgoods/views/goods/create.php @@ -0,0 +1,72 @@ +title = '创建商品'; +$this->params['breadcrumbs'][] = ['label' => '商品列表', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +Yii::$app->params['bsVersion'] = '4.x'; +?> +
+
+ + ['class' => 'container-fluid']]); + + echo TabsX::widget([ + 'bordered' => true, + 'items' => [ + [ + 'label' => ' 基本信息', + 'content' => $this->render('goods', ['model' => $model, + 'form' => $form, + 'judgeGoodsCategory' => false, //表示后台分类可以修改 + ]), + ], + [ + 'label' => ' 筛选规格', + 'content' => $this->render('filter_attribute', [ + 'filterModel' => [], + 'filterAttrValue' => [], + ]), + ], + [ + 'label' => ' 商品规格', + 'content' => $this->render('attribute', [ + 'model' => [], + 'attrValue' => [], + ]), + ], + [ + 'label' => ' 详情上传', + 'content' => $this->render('new_editor', ['model' => $model, + 'form' => $form, + ]), + ], + [ + 'label' => ' 图片上传', + 'content' => $this->render('picture', [ + 'model' => $model, + 'form' => $form + ]), + ], + ], + 'position' => TabsX::POS_ABOVE, + 'encodeLabels' => false + ]); + ?> + +
+ 'btn btn-success']) ?> + 'btn btn-info']) ?> +
+ + + +
+
diff --git a/antgoods/views/goods/filter_attribute.php b/antgoods/views/goods/filter_attribute.php new file mode 100755 index 0000000..9980068 --- /dev/null +++ b/antgoods/views/goods/filter_attribute.php @@ -0,0 +1,22 @@ +where(['type' => Attribute::TYPE_ATTR])->asArray()->all(); +GoodsFilterAttributeAsset::register($this); +?> + +
+ +
+
+ diff --git a/antgoods/views/goods/goods.php b/antgoods/views/goods/goods.php new file mode 100644 index 0000000..0d2e11d --- /dev/null +++ b/antgoods/views/goods/goods.php @@ -0,0 +1,63 @@ + +field($model, 'cat_id')->dropDownList(Category::modelColumn(), ['prompt' => '请选择', 'disabled' => $judgeGoodsCategory]) ?> + +field($model, 'brand_id')->dropDownList(Brand::modelColumn(), ['prompt' => '请选择']) ?> + +field($model, 'shop_cat_id')->dropDownList(ShopCategory::modelColumn(), ['prompt' => '请选择']) ?> + +field($model, 'name')->textInput(['maxlength' => true]) ?> + +field($model, 'sn')->textInput(['maxlength' => true]) ?> + +field($model, 'code')->textInput(['maxlength' => true]) ?> + +field($model, 'supplier_id')->dropDownList(Supplier::modelColumn(), ['prompt' => '请选择']) ?> + +field($model, 'weight')->textInput() ?> + +field($model, 'length')->textInput() ?> + +field($model, 'width')->textInput() ?> + +field($model, 'height')->textInput() ?> + +field($model, 'diameter')->textInput() ?> + +field($model, 'unit')->textInput(['maxlength' => true]) ?> + +field($model, 'limit_count')->textInput() ?> + +field($model, 'stock')->textInput() ?> + +field($model, 'stock_warn')->textInput() ?> + +field($model, 'market_price')->textInput() ?> + +field($model, 'price')->textInput() ?> + +field($model, 'brief')->textInput(['maxlength' => true]) ?> + +field($model, 'is_sale')->radioList($model::$isSale) ?> + +field($model, 'sort_order')->textInput() ?> + +field($model, 'bouns_points')->textInput() ?> + +field($model, 'experience_points')->textInput() ?> + +
+ 'btn btn-success']) ?> + 'btn btn-info']) ?> +
\ No newline at end of file diff --git a/antgoods/views/goods/index.php b/antgoods/views/goods/index.php new file mode 100644 index 0000000..40421e3 --- /dev/null +++ b/antgoods/views/goods/index.php @@ -0,0 +1,28 @@ +title = '商品列表'; +$this->params['breadcrumbs'][] = $this->title; +?> +
+
+ $dataProvider, + 'filter' => $this->render("_search", ['model' => $searchModel]), + 'batch' => [ + [ + "label" => "删除", + "url" => "goods/deletes" + ], + ], + 'columns' => $columns + ]); + ?> +
+
\ No newline at end of file diff --git a/antgoods/views/goods/new_editor.php b/antgoods/views/goods/new_editor.php new file mode 100644 index 0000000..a35c049 --- /dev/null +++ b/antgoods/views/goods/new_editor.php @@ -0,0 +1,31 @@ + +
+
+
+ field($model, 'description')->widget('common\widgets\ueditor\Ueditor',[ + 'options'=>[ + 'initialFrameWidth' => 760,//宽度 + 'initialFrameHeight' => 500,//高度 + + ] + + ]) ?> +
+
+ + + +
+ 'btn btn-success']) ?> +
+
+ diff --git a/antgoods/views/goods/picture.php b/antgoods/views/goods/picture.php new file mode 100644 index 0000000..0b77d7c --- /dev/null +++ b/antgoods/views/goods/picture.php @@ -0,0 +1,37 @@ + +field($model, 'coverImageId')->hiddenInput()->label('') ?> +field($model, 'coverImagePath')->widget(\iron\widgets\Upload::className(), [ + 'url' => 'upload', + 'deleteUrl' => 'img-id-del', + 'dragdropWidth'=> 800, + 'afterSave' => 'save-file', + 'maxCount' => 1, + 'fillInAttribute' => 'coverImageId', + 'model' => $model, + 'ruleVerify' => $model->ruleVerify, + 'previewConfig' => [ + 'url' => Url::to(['image-file', 'fileidstr' => $model->coverImageId]), + ], +])->label('商品封面图') ?> + +field($model, 'detailImageId')->hiddenInput()->label('') ?> +field($model, 'detailImagePath')->widget(\iron\widgets\Upload::className(), [ + 'url' => 'upload', + 'deleteUrl' => 'img-id-del', + 'dragdropWidth'=> 800, + 'afterSave' => 'save-file', + 'maxCount' => 5, + 'fillInAttribute' => 'detailImageId', + 'model' => $model, + 'ruleVerify' => $model->ruleVerify, + 'previewConfig' => [ + 'url' => Url::to(['image-file', 'fileidstr' => $model->detailImageId]), + ], +])->label('商品详情图') ?> diff --git a/antgoods/views/goods/sku_edit.php b/antgoods/views/goods/sku_edit.php new file mode 100644 index 0000000..af194a9 --- /dev/null +++ b/antgoods/views/goods/sku_edit.php @@ -0,0 +1,15 @@ +title = '添加SKU'; +$this->params['breadcrumbs'][] = ['label' => '商品列表', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +GoodsSkuEditAsset::register($this); +?> +
+ \ No newline at end of file diff --git a/antgoods/views/goods/update.php b/antgoods/views/goods/update.php new file mode 100644 index 0000000..221e40a --- /dev/null +++ b/antgoods/views/goods/update.php @@ -0,0 +1,74 @@ +title = '编辑商品: ' . $model->name; +$this->params['breadcrumbs'][] = ['label' => '商品管理', 'url' => ['index']]; +$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->id]]; +$this->params['breadcrumbs'][] = '编辑 '; +Yii::$app->params['bsVersion'] = '4.x'; +?> +
+
+ ['class' => 'container-fluid']]); + + echo TabsX::widget([ + 'bordered' => true, + 'items' => [ + [ + 'label' => ' 基本信息', + 'content' => $this->render('goods', [ + 'model' => $model, + 'form' => $form, + 'judgeGoodsCategory' => $judgeGoodsCategory + ]), + ], + [ + 'label' => ' 筛选规格', + 'content' => $this->render('filter_attribute', [ + 'filterModel' => $filterAttributeModel, + 'filterAttrValue' => [], + ]), + ], + [ + 'label' => ' 商品规格', + 'content' => $this->render('attribute', [ + 'model' => $attributeModel, + 'attrValue' => $attrValue, + 'goodsModel' => $model, + ]), + ], + [ + 'label' => ' 图片上传', + 'content' => $this->render('picture', [ + 'model' => $model, + 'form' => $form, + ]), + ], + ], + 'position' => TabsX::POS_ABOVE, + 'encodeLabels' => false + ]); + ?> + +
+ 'btn btn-success']) ?> + 'btn btn-info']) ?> +
+ + +
+ + render('_form', [ +// 'model' => $model, +// ]) + ?> + +
diff --git a/antgoods/views/goods/view.php b/antgoods/views/goods/view.php new file mode 100644 index 0000000..8c61b50 --- /dev/null +++ b/antgoods/views/goods/view.php @@ -0,0 +1,113 @@ +title = $model->name; +$this->params['breadcrumbs'][] = ['label' => '商品管理', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +\yii\web\YiiAsset::register($this); +?> +
+ +

+ 'btn btn-success']) ?> +

+ + $model, + 'attributes' => [ + 'id', + 'name', + 'sn', + [ + 'attribute' => 'cat_id', + 'width' => '10%', + 'value' => function ($model) { + return $model->category ? $model->category->name : ''; + }, + ], + [ + 'attribute' => 'shop_cat_id', + 'width' => '10%', + 'value' => function ($model) { + return $model->shopCategory ? $model->shopCategory->name : ''; + }, + ], + [ + 'attribute' => 'brand_id', + 'width' => '10%', + 'value' => function ($model) { + return $model->brand ? $model->brand->name : ''; + }, + ], + 'code', + [ + 'attribute' => 'supplier_id', + 'width' => '10%', + 'value' => function ($model) { + return $model->supplier ? $model->supplier->name : ''; + }, + ], + 'weight', + 'length', + 'width', + 'height', + 'diameter', + 'unit', + [ + 'attribute' => 'stock', + 'width' => '5%', + 'value' => function ($model) { + if ($model->stock == -1) { + return '未开启'; + } else { + return $model->stock; + } + }, + ], + 'market_price', + 'price', + 'brief', + ['attribute' => 'image', + 'format' => 'raw', + 'value' => function ($model) { + return $model->image ? + Html::img(['/'.$model->imageFile->path], ['style' => 'width:80px']) + : '
未设置
'; + + } + ], + [ + 'label' => '详情图', + 'format' => 'raw', + 'value' => function ($model) { + $image = ''; + $imgs = File::findAll(['own_id' => $model->id, 'own_type' => File::OWN_TYPE_GOODS_DETAILS, 'is_delete' => File::IS_DELETE_NO]); + foreach ($imgs as $img) { + $image .= Html::img(['/'.$img->path], ['style' => 'width:150px']); + } + return $image; + + } + ], + ['attribute' => 'is_sale', + 'width' => '5%', + 'value' => + function ($model) { + return $model->is_sale ? Goods::$isSale[$model->is_sale] : '未设置'; + + }, + ], + 'sort_order', + 'created_at:datetime', + 'updated_at:datetime', + ], + ]) ?> + +
diff --git a/antgoods/views/layouts/base.php b/antgoods/views/layouts/base.php new file mode 100755 index 0000000..987f0b3 --- /dev/null +++ b/antgoods/views/layouts/base.php @@ -0,0 +1,33 @@ + +beginPage() ?> + + + + + + + registerCsrfMetaTags() ?> + <?= Html::encode($this->title) ?> + head() ?> + + + beginBody() ?> + + + + endBody() ?> + + +endPage() ?> diff --git a/antgoods/views/layouts/breadcrumb.php b/antgoods/views/layouts/breadcrumb.php new file mode 100755 index 0000000..57806ab --- /dev/null +++ b/antgoods/views/layouts/breadcrumb.php @@ -0,0 +1,25 @@ + +
+
+
+ title)): ?> +

title ?>params['subtitle'])): ?> + params['subtitle'] ?>

+ +
+
+ 'ol', + 'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [], + 'itemTemplate' => "\n", + 'activeItemTemplate' => "
  • {link}
  • \n", + 'options' => ['class' => 'breadcrumb float-sm-right'] + ]); + ?> +
    +
    \ No newline at end of file diff --git a/antgoods/views/layouts/footer.php b/antgoods/views/layouts/footer.php new file mode 100755 index 0000000..a0a801d --- /dev/null +++ b/antgoods/views/layouts/footer.php @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/antgoods/views/layouts/header.php b/antgoods/views/layouts/header.php new file mode 100755 index 0000000..0fd795d --- /dev/null +++ b/antgoods/views/layouts/header.php @@ -0,0 +1,67 @@ + +
    +
    + + +
    \ No newline at end of file diff --git a/antgoods/views/layouts/main.php b/antgoods/views/layouts/main.php new file mode 100755 index 0000000..b938779 --- /dev/null +++ b/antgoods/views/layouts/main.php @@ -0,0 +1,57 @@ + + +beginPage() ?> + + + + + + + registerCsrfMetaTags() ?> + <?= Html::encode($this->title) ?> + + + + + + + + head() ?> + + + beginBody() ?> +
    + render('header') ?> + + render('sidebar') ?> + +
    + session->hasFlash('error') || Yii::$app->session->hasFlash('success')) { + echo Alert::widget(); + } + ?> +
    + render('breadcrumb') ?> +
    +
    + +
    +
    + + render('footer') ?> +
    + endBody() ?> + + +endPage() ?> diff --git a/antgoods/views/layouts/sidebar.php b/antgoods/views/layouts/sidebar.php new file mode 100755 index 0000000..f296711 --- /dev/null +++ b/antgoods/views/layouts/sidebar.php @@ -0,0 +1,33 @@ + + \ No newline at end of file diff --git a/antgoods/views/shop-category/_form.php b/antgoods/views/shop-category/_form.php new file mode 100644 index 0000000..ecc4a20 --- /dev/null +++ b/antgoods/views/shop-category/_form.php @@ -0,0 +1,55 @@ + + +
    + + + + field($model, 'name')->textInput(['maxlength' => true]) ?> + + field($model, 'keywords')->textInput(['maxlength' => true]) ?> + + field($model, 'pid')->dropDownList(array_merge([0 => '一级分类'], ShopCategory::modelColumn())) ?> + + field($model, 'desc')->textInput(['maxlength' => true]) ?> + + field($model, 'sort_order')->textInput() ?> + + field($model, 'iconImageId')->hiddenInput()->label('') ?> + field($model, 'iconImagePath')->widget(\iron\widgets\Upload::className(), [ + 'url' => 'upload', + 'deleteUrl' => 'img-id-del', + 'dragdropWidth'=> 800, + 'afterSave' => 'save-file', + 'maxCount' => 1, + 'fillInAttribute' => 'iconImageId', + 'model' => $model, + 'previewConfig' => [ + 'url' => Url::to(['image-file', 'fileidstr' => $model->iconImageId]), + ], + ])->label('类目图片') ?> + + field($model, 'filter_attr')->widget(Select2::className(), ["items" => Attribute::modelColumn(), "promptText" => false, 'options' => ['multiple' => true, 'placeholder' => '请选择...'] ]) ?> + + field($model, 'is_show')->widget(Icheck::className(), ["items" => $model::$isShow, 'type' => "radio"]) ?> + +
    + 'btn btn-success']) ?> + 'btn btn-info']) ?> +
    + + + +
    diff --git a/antgoods/views/shop-category/_search.php b/antgoods/views/shop-category/_search.php new file mode 100644 index 0000000..1e839e6 --- /dev/null +++ b/antgoods/views/shop-category/_search.php @@ -0,0 +1,49 @@ + + + ['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()); + ?> +
    +
    + ', ['class' => 'btn btn-default']) ?> + ', ['class' => 'btn btn-default']) ?> +
    +
    + \ No newline at end of file diff --git a/antgoods/views/shop-category/create.php b/antgoods/views/shop-category/create.php new file mode 100644 index 0000000..73f3eae --- /dev/null +++ b/antgoods/views/shop-category/create.php @@ -0,0 +1,18 @@ +title = '创建前端商品分类'; +$this->params['breadcrumbs'][] = ['label' => '前端商品分类', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
    + + render('_form', [ + 'model' => $model, + ]) ?> + +
    diff --git a/antgoods/views/shop-category/index.php b/antgoods/views/shop-category/index.php new file mode 100644 index 0000000..af3692d --- /dev/null +++ b/antgoods/views/shop-category/index.php @@ -0,0 +1,28 @@ +title = '前端商品分类'; +$this->params['breadcrumbs'][] = $this->title; +?> +
    +
    + $dataProvider, + 'filter' => $this->render("_search", ['model' => $searchModel]), + 'batch' => [ + [ + "label" => "删除", + "url" => "shopcategory/deletes" + ], + ], + 'columns' => $columns + ]); + ?> +
    +
    \ No newline at end of file diff --git a/antgoods/views/shop-category/update.php b/antgoods/views/shop-category/update.php new file mode 100644 index 0000000..5c97d16 --- /dev/null +++ b/antgoods/views/shop-category/update.php @@ -0,0 +1,19 @@ +title = '编辑前端商品分类: ' . $model->name; +$this->params['breadcrumbs'][] = ['label' => '前端商品分类', 'url' => ['index']]; +$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->id]]; +$this->params['breadcrumbs'][] = '编辑 '; +?> +
    + + render('_form', [ + 'model' => $model, + ]) ?> + +
    diff --git a/antgoods/views/shop-category/view.php b/antgoods/views/shop-category/view.php new file mode 100644 index 0000000..c6ef07e --- /dev/null +++ b/antgoods/views/shop-category/view.php @@ -0,0 +1,64 @@ +title = $model->name; +$this->params['breadcrumbs'][] = ['label' => '前端商品分类', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +\yii\web\YiiAsset::register($this); +$filter_attr_arr = explode(',', $model->filter_attr); +$attr_str = ''; +foreach ($filter_attr_arr as $filter_attr_id) { + $attr = Attribute::findOne($filter_attr_id); + if ($attr) { + $attr_str = $attr_str . ',' . $attr->name; + } +} +$attr_str = substr($attr_str, 1); +?> +
    + +

    + 'btn btn-success']) ?> +

    + + $model, + 'attributes' => [ + 'id', + 'name', + 'keywords', + 'desc', + 'sort_order', + ['attribute' => 'icon', + 'width'=>'10%', + 'format' => 'raw', + 'value' => function ($model) { + return $model->iconFile ? + \yii\bootstrap4\Html::img(['/'.$model->iconFile->path], ['style' => 'width:80px']) + : '未设置'; + + } + ], + ['attribute' => 'filter_attr', + 'value' => $attr_str + ], + ['attribute' => 'is_show', + 'width' => '5%', + 'value' => + function ($model) { + return $model->is_show == ShopCategory::IS_SHOW_HIDE ? '隐藏' : '显示'; + }, + ], + 'created_at:datetime', + 'updated_at:datetime', + ], + ]) ?> + +
    diff --git a/antgoods/views/site/error.php b/antgoods/views/site/error.php new file mode 100755 index 0000000..0ba2574 --- /dev/null +++ b/antgoods/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/antgoods/views/site/index.php b/antgoods/views/site/index.php new file mode 100755 index 0000000..21cb7e4 --- /dev/null +++ b/antgoods/views/site/index.php @@ -0,0 +1,6 @@ +title = 'Dashboard'; +$this->params['subtitle'] = 'Control panel'; +$this->params['breadcrumbs'][] = $this->title; +?> \ No newline at end of file diff --git a/antgoods/views/site/login.php b/antgoods/views/site/login.php new file mode 100755 index 0000000..461327c --- /dev/null +++ b/antgoods/views/site/login.php @@ -0,0 +1,34 @@ +title = '系统登录'; +$this->params['breadcrumbs'][] = $this->title; +?> +
    + +
    \ No newline at end of file diff --git a/antgoods/views/site/test.php b/antgoods/views/site/test.php new file mode 100755 index 0000000..f9eebef --- /dev/null +++ b/antgoods/views/site/test.php @@ -0,0 +1,68 @@ +title = '测试'; +$this->params['subtitle'] = '这是一个小小的测试'; +$this->params['breadcrumbs'][] = $this->title; + +/* @var $this yii\web\View */ +/* @var $model common\models\CategorySearch */ +/* @var $form yii\widgets\ActiveForm */ +?> + + + ['index'], + 'method' => 'get', + 'validateOnType' => true, + ]); +?> + +
    +
    + field($model, 'id', [ + "template" => "{input}{error}", + "inputOptions" => [ + "placeholder" => "检索的id", + "class" => "form-control" + ], + "errorOptions" => [ + "class" => "error-tips" + ] + ]) + ?> + + field($model, 'cat_name', [ + "template" => "{input}{error}", + "inputOptions" => [ + "placeholder" => "检索类名", + "class" => "form-control", + ], + "errorOptions" => [ + "class" => "error-tips" + ] + ]) + ?> + + field($model, "created_at", [ + "template" => "{input}{error}", + "errorOptions" => [ + "class" => "error-tips" + ] + ])->widget(DateRangePicker::className()); + ?> +
    +
    +
    + ', ['class' => 'btn btn-default']) ?> + ', ['class' => 'btn btn-default']) ?> +
    + + diff --git a/antgoods/views/supplier/_form.php b/antgoods/views/supplier/_form.php new file mode 100644 index 0000000..93942e2 --- /dev/null +++ b/antgoods/views/supplier/_form.php @@ -0,0 +1,30 @@ + + +
    + + + + field($model, 'name')->textInput(['maxlength' => true]) ?> + + field($model, 'full_name')->textInput(['maxlength' => true]) ?> + + field($model, 'phone')->textInput(['maxlength' => true]) ?> + + field($model, 'address')->textInput(['maxlength' => true]) ?> + +
    + 'btn btn-success']) ?> + 'btn btn-info']) ?> +
    + + + +
    diff --git a/antgoods/views/supplier/_search.php b/antgoods/views/supplier/_search.php new file mode 100644 index 0000000..1f00e41 --- /dev/null +++ b/antgoods/views/supplier/_search.php @@ -0,0 +1,49 @@ + + + ['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()); + ?> +
    +
    + ', ['class' => 'btn btn-default']) ?> + ', ['class' => 'btn btn-default']) ?> +
    +
    + \ No newline at end of file diff --git a/antgoods/views/supplier/create.php b/antgoods/views/supplier/create.php new file mode 100644 index 0000000..57e0b0e --- /dev/null +++ b/antgoods/views/supplier/create.php @@ -0,0 +1,18 @@ +title = '创建供应商'; +$this->params['breadcrumbs'][] = ['label' => '供应商管理', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +?> +
    + + render('_form', [ + 'model' => $model, + ]) ?> + +
    diff --git a/antgoods/views/supplier/index.php b/antgoods/views/supplier/index.php new file mode 100644 index 0000000..bad1e50 --- /dev/null +++ b/antgoods/views/supplier/index.php @@ -0,0 +1,28 @@ +title = '供应商管理'; +$this->params['breadcrumbs'][] = $this->title; +?> +
    +
    + $dataProvider, + 'filter' => $this->render("_search", ['model' => $searchModel]), + 'batch' => [ + [ + "label" => "删除", + "url" => "supplier/deletes" + ], + ], + 'columns' => $columns + ]); + ?> +
    +
    \ No newline at end of file diff --git a/antgoods/views/supplier/update.php b/antgoods/views/supplier/update.php new file mode 100644 index 0000000..a6aca3d --- /dev/null +++ b/antgoods/views/supplier/update.php @@ -0,0 +1,19 @@ +title = '编辑供应商: ' . $model->name; +$this->params['breadcrumbs'][] = ['label' => '供应商管理', 'url' => ['index']]; +$this->params['breadcrumbs'][] = ['label' => $model->name, 'url' => ['view', 'id' => $model->id]]; +$this->params['breadcrumbs'][] = '编辑 '; +?> +
    + + render('_form', [ + 'model' => $model, + ]) ?> + +
    diff --git a/antgoods/views/supplier/view.php b/antgoods/views/supplier/view.php new file mode 100644 index 0000000..6619f91 --- /dev/null +++ b/antgoods/views/supplier/view.php @@ -0,0 +1,33 @@ +title = $model->name; +$this->params['breadcrumbs'][] = ['label' => '供应商管理', 'url' => ['index']]; +$this->params['breadcrumbs'][] = $this->title; +\yii\web\YiiAsset::register($this); +?> +
    + +

    + 'btn btn-success']) ?> +

    + + $model, + 'attributes' => [ + 'id', + 'name', + 'full_name', + 'phone', + 'address', + 'created_at:datetime', + 'updated_at:datetime', + ], + ]) ?> + +
    diff --git a/antgoods/web/.gitignore b/antgoods/web/.gitignore new file mode 100755 index 0000000..cb7f43e --- /dev/null +++ b/antgoods/web/.gitignore @@ -0,0 +1,11 @@ +/index.php +/index-test.php +/robots.txt +uploads +css/umeditor/php/upload/ + +node_modules/ +yarn-error.log +yarn.lock +package-lock.json +ueditor diff --git a/antgoods/web/assets/.gitignore b/antgoods/web/assets/.gitignore new file mode 100755 index 0000000..d6b7ef3 --- /dev/null +++ b/antgoods/web/assets/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/antgoods/web/css/reset.css b/antgoods/web/css/reset.css new file mode 100755 index 0000000..9ff51eb --- /dev/null +++ b/antgoods/web/css/reset.css @@ -0,0 +1,48 @@ +/* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) +*/ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} +body { + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} \ No newline at end of file diff --git a/antgoods/web/css/site.css b/antgoods/web/css/site.css new file mode 100755 index 0000000..23fa9ae --- /dev/null +++ b/antgoods/web/css/site.css @@ -0,0 +1,52 @@ +/*公共样式*/ + +/*登录页*/ +.login-body{ + display: flex; + align-items: center; + height: 100vh; +} + +.login-body .line { + border-bottom: 1px solid #dadada; + line-height: 0.1em; + margin: 10px 0 20px; +} + +.login-body .line span { + background: #fff; + padding: 0 10px; +} + +.login-form { + box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); + margin: 0 auto; +} + +.login-form h2{ + text-align: center; + margin-bottom: 20px; +} + +.login-form h6 { + text-align: center; +} + +/*修复select2插件 from表框颜色不生效*/ +.form-group.has-error .select2-selection, .form-group.has-error .select2-selection { + border-color: #dd4b39; + box-shadow: none; +} + +.form-group.has-success .select2-selection, .form-group.has-success .select2-selection { + border-color: #00a65a; + box-shadow: none; +} + +.icheck-label-group { + padding-top: 2px; +} + +.icheck-label-group label{ + margin-right: 20px; +} \ No newline at end of file diff --git a/antgoods/web/custom/sku.49a56a9198d9c3ec233c.js b/antgoods/web/custom/sku.49a56a9198d9c3ec233c.js new file mode 100644 index 0000000..efefa7e --- /dev/null +++ b/antgoods/web/custom/sku.49a56a9198d9c3ec233c.js @@ -0,0 +1,58 @@ +!function(e){var t={};function n(r){if(t[r])return t[r].exports;var a=t[r]={i:r,l:!1,exports:{}};return e[r].call(a.exports,a,a.exports,n),a.l=!0,a.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)n.d(r,a,function(t){return e[t]}.bind(null,a));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/custom/",n(n.s=315)}([function(e,t,n){"use strict";e.exports=n(233)},function(e,t,n){e.exports=n(245)()},function(e,t,n){(function(e){e.exports=function(){"use strict";var t,r;function a(){return t.apply(null,arguments)}function i(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function o(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function c(e){return void 0===e}function s(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function l(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function u(e,t){var n,r=[];for(n=0;n>>0,r=0;r0)for(n=0;n<_.length;n++)c(a=t[r=_[n]])||(e[r]=a);return e}var M=!1;function b(e){y(this,e),this._d=new Date(null!=e._d?e._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),!1===M&&(M=!0,a.updateOffset(this),M=!1)}function g(e){return e instanceof b||null!=e&&null!=e._isAMomentObject}function w(e){return e<0?Math.ceil(e)||0:Math.floor(e)}function L(e){var t=+e,n=0;return 0!==t&&isFinite(t)&&(n=w(t)),n}function z(e,t,n){var r,a=Math.min(e.length,t.length),i=Math.abs(e.length-t.length),o=0;for(r=0;r=0?n?"+":"":"-")+Math.pow(10,Math.max(0,a)).toString().substr(1)+r}var N=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,I=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,R={},W={};function U(e,t,n,r){var a=r;"string"==typeof r&&(a=function(){return this[r]()}),e&&(W[e]=a),t&&(W[t[0]]=function(){return F(a.apply(this,arguments),t[1],t[2])}),n&&(W[n]=function(){return this.localeData().ordinal(a.apply(this,arguments),e)})}function B(e,t){return e.isValid()?(t=K(t,e.localeData()),R[t]=R[t]||function(e){var t,n,r,a=e.match(N);for(t=0,n=a.length;t=0&&I.test(e);)e=e.replace(I,r),I.lastIndex=0,n-=1;return e}var q=/\d/,J=/\d\d/,G=/\d{3}/,$=/\d{4}/,X=/[+-]?\d{6}/,Z=/\d\d?/,Q=/\d\d\d\d?/,ee=/\d\d\d\d\d\d?/,te=/\d{1,3}/,ne=/\d{1,4}/,re=/[+-]?\d{1,6}/,ae=/\d+/,ie=/[+-]?\d+/,oe=/Z|[+-]\d\d:?\d\d/gi,ce=/Z|[+-]\d\d(?::?\d\d)?/gi,se=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,le={};function ue(e,t,n){le[e]=D(t)?t:function(e,r){return e&&n?n:t}}function de(e,t){return d(le,e)?le[e](t._strict,t._locale):new RegExp(me(e.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,(function(e,t,n,r,a){return t||n||r||a}))))}function me(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var he={};function fe(e,t){var n,r=t;for("string"==typeof e&&(e=[e]),s(t)&&(r=function(e,n){n[t]=L(e)}),n=0;n68?1900:2e3)};var Se,Ye=De("FullYear",!0);function De(e,t){return function(n){return null!=n?(xe(this,e,n),a.updateOffset(this,t),this):Oe(this,e)}}function Oe(e,t){return e.isValid()?e._d["get"+(e._isUTC?"UTC":"")+t]():NaN}function xe(e,t,n){e.isValid()&&!isNaN(n)&&("FullYear"===t&&Te(e.year())&&1===e.month()&&29===e.date()?e._d["set"+(e._isUTC?"UTC":"")+t](n,e.month(),Ce(n,e.month())):e._d["set"+(e._isUTC?"UTC":"")+t](n))}function Ce(e,t){if(isNaN(e)||isNaN(t))return NaN;var n,r=(t%(n=12)+n)%n;return e+=(t-r)/12,1===r?Te(e)?29:28:31-r%7%2}Se=Array.prototype.indexOf?Array.prototype.indexOf:function(e){var t;for(t=0;t=0?(c=new Date(e+400,t,n,r,a,i,o),isFinite(c.getFullYear())&&c.setFullYear(e)):c=new Date(e,t,n,r,a,i,o),c}function Ue(e){var t;if(e<100&&e>=0){var n=Array.prototype.slice.call(arguments);n[0]=e+400,t=new Date(Date.UTC.apply(null,n)),isFinite(t.getUTCFullYear())&&t.setUTCFullYear(e)}else t=new Date(Date.UTC.apply(null,arguments));return t}function Be(e,t,n){var r=7+t-n;return-(7+Ue(e,0,r).getUTCDay()-t)%7+r-1}function Ke(e,t,n,r,a){var i,o,c=1+7*(t-1)+(7+n-r)%7+Be(e,r,a);return c<=0?o=He(i=e-1)+c:c>He(e)?(i=e+1,o=c-He(e)):(i=e,o=c),{year:i,dayOfYear:o}}function qe(e,t,n){var r,a,i=Be(e.year(),t,n),o=Math.floor((e.dayOfYear()-i-1)/7)+1;return o<1?r=o+Je(a=e.year()-1,t,n):o>Je(e.year(),t,n)?(r=o-Je(e.year(),t,n),a=e.year()+1):(a=e.year(),r=o),{week:r,year:a}}function Je(e,t,n){var r=Be(e,t,n),a=Be(e+1,t,n);return(He(e)-r+a)/7}function Ge(e,t){return e.slice(t,7).concat(e.slice(0,t))}U("w",["ww",2],"wo","week"),U("W",["WW",2],"Wo","isoWeek"),V("week","w"),V("isoWeek","W"),A("week",5),A("isoWeek",5),ue("w",Z),ue("ww",Z,J),ue("W",Z),ue("WW",Z,J),pe(["w","ww","W","WW"],(function(e,t,n,r){t[r.substr(0,1)]=L(e)})),U("d",0,"do","day"),U("dd",0,0,(function(e){return this.localeData().weekdaysMin(this,e)})),U("ddd",0,0,(function(e){return this.localeData().weekdaysShort(this,e)})),U("dddd",0,0,(function(e){return this.localeData().weekdays(this,e)})),U("e",0,0,"weekday"),U("E",0,0,"isoWeekday"),V("day","d"),V("weekday","e"),V("isoWeekday","E"),A("day",11),A("weekday",11),A("isoWeekday",11),ue("d",Z),ue("e",Z),ue("E",Z),ue("dd",(function(e,t){return t.weekdaysMinRegex(e)})),ue("ddd",(function(e,t){return t.weekdaysShortRegex(e)})),ue("dddd",(function(e,t){return t.weekdaysRegex(e)})),pe(["dd","ddd","dddd"],(function(e,t,n,r){var a=n._locale.weekdaysParse(e,r,n._strict);null!=a?t.d=a:f(n).invalidWeekday=e})),pe(["d","e","E"],(function(e,t,n,r){t[r]=L(e)}));var $e="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Xe="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Ze="Su_Mo_Tu_We_Th_Fr_Sa".split("_");function Qe(e,t,n){var r,a,i,o=e.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],r=0;r<7;++r)i=h([2e3,1]).day(r),this._minWeekdaysParse[r]=this.weekdaysMin(i,"").toLocaleLowerCase(),this._shortWeekdaysParse[r]=this.weekdaysShort(i,"").toLocaleLowerCase(),this._weekdaysParse[r]=this.weekdays(i,"").toLocaleLowerCase();return n?"dddd"===t?-1!==(a=Se.call(this._weekdaysParse,o))?a:null:"ddd"===t?-1!==(a=Se.call(this._shortWeekdaysParse,o))?a:null:-1!==(a=Se.call(this._minWeekdaysParse,o))?a:null:"dddd"===t?-1!==(a=Se.call(this._weekdaysParse,o))?a:-1!==(a=Se.call(this._shortWeekdaysParse,o))?a:-1!==(a=Se.call(this._minWeekdaysParse,o))?a:null:"ddd"===t?-1!==(a=Se.call(this._shortWeekdaysParse,o))?a:-1!==(a=Se.call(this._weekdaysParse,o))?a:-1!==(a=Se.call(this._minWeekdaysParse,o))?a:null:-1!==(a=Se.call(this._minWeekdaysParse,o))?a:-1!==(a=Se.call(this._weekdaysParse,o))?a:-1!==(a=Se.call(this._shortWeekdaysParse,o))?a:null}var et=se,tt=se,nt=se;function rt(){function e(e,t){return t.length-e.length}var t,n,r,a,i,o=[],c=[],s=[],l=[];for(t=0;t<7;t++)n=h([2e3,1]).day(t),r=this.weekdaysMin(n,""),a=this.weekdaysShort(n,""),i=this.weekdays(n,""),o.push(r),c.push(a),s.push(i),l.push(r),l.push(a),l.push(i);for(o.sort(e),c.sort(e),s.sort(e),l.sort(e),t=0;t<7;t++)c[t]=me(c[t]),s[t]=me(s[t]),l[t]=me(l[t]);this._weekdaysRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+c.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function at(){return this.hours()%12||12}function it(e,t){U(e,0,0,(function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)}))}function ot(e,t){return t._meridiemParse}U("H",["HH",2],0,"hour"),U("h",["hh",2],0,at),U("k",["kk",2],0,(function(){return this.hours()||24})),U("hmm",0,0,(function(){return""+at.apply(this)+F(this.minutes(),2)})),U("hmmss",0,0,(function(){return""+at.apply(this)+F(this.minutes(),2)+F(this.seconds(),2)})),U("Hmm",0,0,(function(){return""+this.hours()+F(this.minutes(),2)})),U("Hmmss",0,0,(function(){return""+this.hours()+F(this.minutes(),2)+F(this.seconds(),2)})),it("a",!0),it("A",!1),V("hour","h"),A("hour",13),ue("a",ot),ue("A",ot),ue("H",Z),ue("h",Z),ue("k",Z),ue("HH",Z,J),ue("hh",Z,J),ue("kk",Z,J),ue("hmm",Q),ue("hmmss",ee),ue("Hmm",Q),ue("Hmmss",ee),fe(["H","HH"],be),fe(["k","kk"],(function(e,t,n){var r=L(e);t[be]=24===r?0:r})),fe(["a","A"],(function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e})),fe(["h","hh"],(function(e,t,n){t[be]=L(e),f(n).bigHour=!0})),fe("hmm",(function(e,t,n){var r=e.length-2;t[be]=L(e.substr(0,r)),t[ge]=L(e.substr(r)),f(n).bigHour=!0})),fe("hmmss",(function(e,t,n){var r=e.length-4,a=e.length-2;t[be]=L(e.substr(0,r)),t[ge]=L(e.substr(r,2)),t[we]=L(e.substr(a)),f(n).bigHour=!0})),fe("Hmm",(function(e,t,n){var r=e.length-2;t[be]=L(e.substr(0,r)),t[ge]=L(e.substr(r))})),fe("Hmmss",(function(e,t,n){var r=e.length-4,a=e.length-2;t[be]=L(e.substr(0,r)),t[ge]=L(e.substr(r,2)),t[we]=L(e.substr(a))}));var ct,st=De("Hours",!0),lt={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Ee,monthsShort:Pe,week:{dow:0,doy:6},weekdays:$e,weekdaysMin:Ze,weekdaysShort:Xe,meridiemParse:/[ap]\.?m?\.?/i},ut={},dt={};function mt(e){return e?e.toLowerCase().replace("_","-"):e}function ht(t){var r=null;if(!ut[t]&&void 0!==e&&e&&e.exports)try{r=ct._abbr,n(310)("./"+t),ft(r)}catch(e){}return ut[t]}function ft(e,t){var n;return e&&((n=c(t)?vt(e):pt(e,t))?ct=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),ct._abbr}function pt(e,t){if(null!==t){var n,r=lt;if(t.abbr=e,null!=ut[e])Y("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),r=ut[e]._config;else if(null!=t.parentLocale)if(null!=ut[t.parentLocale])r=ut[t.parentLocale]._config;else{if(null==(n=ht(t.parentLocale)))return dt[t.parentLocale]||(dt[t.parentLocale]=[]),dt[t.parentLocale].push({name:e,config:t}),null;r=n._config}return ut[e]=new x(O(r,t)),dt[e]&&dt[e].forEach((function(e){pt(e.name,e.config)})),ft(e),ut[e]}return delete ut[e],null}function vt(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return ct;if(!i(e)){if(t=ht(e))return t;e=[e]}return function(e){for(var t,n,r,a,i=0;i0;){if(r=ht(a.slice(0,t).join("-")))return r;if(n&&n.length>=t&&z(a,n,!0)>=t-1)break;t--}i++}return ct}(e)}function _t(e){var t,n=e._a;return n&&-2===f(e).overflow&&(t=n[ye]<0||n[ye]>11?ye:n[Me]<1||n[Me]>Ce(n[_e],n[ye])?Me:n[be]<0||n[be]>24||24===n[be]&&(0!==n[ge]||0!==n[we]||0!==n[Le])?be:n[ge]<0||n[ge]>59?ge:n[we]<0||n[we]>59?we:n[Le]<0||n[Le]>999?Le:-1,f(e)._overflowDayOfYear&&(t<_e||t>Me)&&(t=Me),f(e)._overflowWeeks&&-1===t&&(t=ze),f(e)._overflowWeekday&&-1===t&&(t=ke),f(e).overflow=t),e}function yt(e,t,n){return null!=e?e:null!=t?t:n}function Mt(e){var t,n,r,i,o,c=[];if(!e._d){for(r=function(e){var t=new Date(a.now());return e._useUTC?[t.getUTCFullYear(),t.getUTCMonth(),t.getUTCDate()]:[t.getFullYear(),t.getMonth(),t.getDate()]}(e),e._w&&null==e._a[Me]&&null==e._a[ye]&&function(e){var t,n,r,a,i,o,c,s;if(null!=(t=e._w).GG||null!=t.W||null!=t.E)i=1,o=4,n=yt(t.GG,e._a[_e],qe(Vt(),1,4).year),r=yt(t.W,1),((a=yt(t.E,1))<1||a>7)&&(s=!0);else{i=e._locale._week.dow,o=e._locale._week.doy;var l=qe(Vt(),i,o);n=yt(t.gg,e._a[_e],l.year),r=yt(t.w,l.week),null!=t.d?((a=t.d)<0||a>6)&&(s=!0):null!=t.e?(a=t.e+i,(t.e<0||t.e>6)&&(s=!0)):a=i}r<1||r>Je(n,i,o)?f(e)._overflowWeeks=!0:null!=s?f(e)._overflowWeekday=!0:(c=Ke(n,r,a,i,o),e._a[_e]=c.year,e._dayOfYear=c.dayOfYear)}(e),null!=e._dayOfYear&&(o=yt(e._a[_e],r[_e]),(e._dayOfYear>He(o)||0===e._dayOfYear)&&(f(e)._overflowDayOfYear=!0),n=Ue(o,0,e._dayOfYear),e._a[ye]=n.getUTCMonth(),e._a[Me]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=c[t]=r[t];for(;t<7;t++)e._a[t]=c[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[be]&&0===e._a[ge]&&0===e._a[we]&&0===e._a[Le]&&(e._nextDay=!0,e._a[be]=0),e._d=(e._useUTC?Ue:We).apply(null,c),i=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[be]=24),e._w&&void 0!==e._w.d&&e._w.d!==i&&(f(e).weekdayMismatch=!0)}}var bt=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,gt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,wt=/Z|[+-]\d\d(?::?\d\d)?/,Lt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],zt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],kt=/^\/?Date\((\-?\d+)/i;function Ht(e){var t,n,r,a,i,o,c=e._i,s=bt.exec(c)||gt.exec(c);if(s){for(f(e).iso=!0,t=0,n=Lt.length;t0&&f(e).unusedInput.push(o),c=c.slice(c.indexOf(n)+n.length),l+=n.length),W[i]?(n?f(e).empty=!1:f(e).unusedTokens.push(i),ve(i,n,e)):e._strict&&!n&&f(e).unusedTokens.push(i);f(e).charsLeftOver=s-l,c.length>0&&f(e).unusedInput.push(c),e._a[be]<=12&&!0===f(e).bigHour&&e._a[be]>0&&(f(e).bigHour=void 0),f(e).parsedDateParts=e._a.slice(0),f(e).meridiem=e._meridiem,e._a[be]=function(e,t,n){var r;return null==n?t:null!=e.meridiemHour?e.meridiemHour(t,n):null!=e.isPM?((r=e.isPM(n))&&t<12&&(t+=12),r||12!==t||(t=0),t):t}(e._locale,e._a[be],e._meridiem),Mt(e),_t(e)}else Dt(e);else Ht(e)}function xt(e){var t=e._i,n=e._f;return e._locale=e._locale||vt(e._l),null===t||void 0===n&&""===t?v({nullInput:!0}):("string"==typeof t&&(e._i=t=e._locale.preparse(t)),g(t)?new b(_t(t)):(l(t)?e._d=t:i(n)?function(e){var t,n,r,a,i;if(0===e._f.length)return f(e).invalidFormat=!0,void(e._d=new Date(NaN));for(a=0;athis?this:e:v()}));function jt(e,t){var n,r;if(1===t.length&&i(t[0])&&(t=t[0]),!t.length)return Vt();for(n=t[0],r=1;r=0?new Date(e+400,t,n)-dn:new Date(e,t,n).valueOf()}function fn(e,t,n){return e<100&&e>=0?Date.UTC(e+400,t,n)-dn:Date.UTC(e,t,n)}function pn(e,t){U(0,[e,e.length],0,t)}function vn(e,t,n,r,a){var i;return null==e?qe(this,r,a).year:(t>(i=Je(e,r,a))&&(t=i),_n.call(this,e,t,n,r,a))}function _n(e,t,n,r,a){var i=Ke(e,t,n,r,a),o=Ue(i.year,0,i.dayOfYear);return this.year(o.getUTCFullYear()),this.month(o.getUTCMonth()),this.date(o.getUTCDate()),this}U(0,["gg",2],0,(function(){return this.weekYear()%100})),U(0,["GG",2],0,(function(){return this.isoWeekYear()%100})),pn("gggg","weekYear"),pn("ggggg","weekYear"),pn("GGGG","isoWeekYear"),pn("GGGGG","isoWeekYear"),V("weekYear","gg"),V("isoWeekYear","GG"),A("weekYear",1),A("isoWeekYear",1),ue("G",ie),ue("g",ie),ue("GG",Z,J),ue("gg",Z,J),ue("GGGG",ne,$),ue("gggg",ne,$),ue("GGGGG",re,X),ue("ggggg",re,X),pe(["gggg","ggggg","GGGG","GGGGG"],(function(e,t,n,r){t[r.substr(0,2)]=L(e)})),pe(["gg","GG"],(function(e,t,n,r){t[r]=a.parseTwoDigitYear(e)})),U("Q",0,"Qo","quarter"),V("quarter","Q"),A("quarter",7),ue("Q",q),fe("Q",(function(e,t){t[ye]=3*(L(e)-1)})),U("D",["DD",2],"Do","date"),V("date","D"),A("date",9),ue("D",Z),ue("DD",Z,J),ue("Do",(function(e,t){return e?t._dayOfMonthOrdinalParse||t._ordinalParse:t._dayOfMonthOrdinalParseLenient})),fe(["D","DD"],Me),fe("Do",(function(e,t){t[Me]=L(e.match(Z)[0])}));var yn=De("Date",!0);U("DDD",["DDDD",3],"DDDo","dayOfYear"),V("dayOfYear","DDD"),A("dayOfYear",4),ue("DDD",te),ue("DDDD",G),fe(["DDD","DDDD"],(function(e,t,n){n._dayOfYear=L(e)})),U("m",["mm",2],0,"minute"),V("minute","m"),A("minute",14),ue("m",Z),ue("mm",Z,J),fe(["m","mm"],ge);var Mn=De("Minutes",!1);U("s",["ss",2],0,"second"),V("second","s"),A("second",15),ue("s",Z),ue("ss",Z,J),fe(["s","ss"],we);var bn,gn=De("Seconds",!1);for(U("S",0,0,(function(){return~~(this.millisecond()/100)})),U(0,["SS",2],0,(function(){return~~(this.millisecond()/10)})),U(0,["SSS",3],0,"millisecond"),U(0,["SSSS",4],0,(function(){return 10*this.millisecond()})),U(0,["SSSSS",5],0,(function(){return 100*this.millisecond()})),U(0,["SSSSSS",6],0,(function(){return 1e3*this.millisecond()})),U(0,["SSSSSSS",7],0,(function(){return 1e4*this.millisecond()})),U(0,["SSSSSSSS",8],0,(function(){return 1e5*this.millisecond()})),U(0,["SSSSSSSSS",9],0,(function(){return 1e6*this.millisecond()})),V("millisecond","ms"),A("millisecond",16),ue("S",te,q),ue("SS",te,J),ue("SSS",te,G),bn="SSSS";bn.length<=9;bn+="S")ue(bn,ae);function wn(e,t){t[Le]=L(1e3*("0."+e))}for(bn="S";bn.length<=9;bn+="S")fe(bn,wn);var Ln=De("Milliseconds",!1);U("z",0,0,"zoneAbbr"),U("zz",0,0,"zoneName");var zn=b.prototype;function kn(e){return e}zn.add=tn,zn.calendar=function(e,t){var n=e||Vt(),r=Bt(n,this).startOf("day"),i=a.calendarFormat(this,r)||"sameElse",o=t&&(D(t[i])?t[i].call(this,n):t[i]);return this.format(o||this.localeData().calendar(i,this,Vt(n)))},zn.clone=function(){return new b(this)},zn.diff=function(e,t,n){var r,a,i;if(!this.isValid())return NaN;if(!(r=Bt(e,this)).isValid())return NaN;switch(a=6e4*(r.utcOffset()-this.utcOffset()),t=E(t)){case"year":i=rn(this,r)/12;break;case"month":i=rn(this,r);break;case"quarter":i=rn(this,r)/3;break;case"second":i=(this-r)/1e3;break;case"minute":i=(this-r)/6e4;break;case"hour":i=(this-r)/36e5;break;case"day":i=(this-r-a)/864e5;break;case"week":i=(this-r-a)/6048e5;break;default:i=this-r}return n?i:w(i)},zn.endOf=function(e){var t;if(void 0===(e=E(e))||"millisecond"===e||!this.isValid())return this;var n=this._isUTC?fn:hn;switch(e){case"year":t=n(this.year()+1,0,1)-1;break;case"quarter":t=n(this.year(),this.month()-this.month()%3+3,1)-1;break;case"month":t=n(this.year(),this.month()+1,1)-1;break;case"week":t=n(this.year(),this.month(),this.date()-this.weekday()+7)-1;break;case"isoWeek":t=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1)+7)-1;break;case"day":case"date":t=n(this.year(),this.month(),this.date()+1)-1;break;case"hour":t=this._d.valueOf(),t+=un-mn(t+(this._isUTC?0:this.utcOffset()*ln),un)-1;break;case"minute":t=this._d.valueOf(),t+=ln-mn(t,ln)-1;break;case"second":t=this._d.valueOf(),t+=sn-mn(t,sn)-1}return this._d.setTime(t),a.updateOffset(this,!0),this},zn.format=function(e){e||(e=this.isUtc()?a.defaultFormatUtc:a.defaultFormat);var t=B(this,e);return this.localeData().postformat(t)},zn.from=function(e,t){return this.isValid()&&(g(e)&&e.isValid()||Vt(e).isValid())?$t({to:this,from:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},zn.fromNow=function(e){return this.from(Vt(),e)},zn.to=function(e,t){return this.isValid()&&(g(e)&&e.isValid()||Vt(e).isValid())?$t({from:this,to:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},zn.toNow=function(e){return this.to(Vt(),e)},zn.get=function(e){return D(this[e=E(e)])?this[e]():this},zn.invalidAt=function(){return f(this).overflow},zn.isAfter=function(e,t){var n=g(e)?e:Vt(e);return!(!this.isValid()||!n.isValid())&&("millisecond"===(t=E(t)||"millisecond")?this.valueOf()>n.valueOf():n.valueOf()9999?B(n,t?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):D(Date.prototype.toISOString)?t?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",B(n,"Z")):B(n,t?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},zn.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var e="moment",t="";this.isLocal()||(e=0===this.utcOffset()?"moment.utc":"moment.parseZone",t="Z");var n="["+e+'("]',r=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",a=t+'[")]';return this.format(n+r+"-MM-DD[T]HH:mm:ss.SSS"+a)},zn.toJSON=function(){return this.isValid()?this.toISOString():null},zn.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},zn.unix=function(){return Math.floor(this.valueOf()/1e3)},zn.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},zn.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},zn.year=Ye,zn.isLeapYear=function(){return Te(this.year())},zn.weekYear=function(e){return vn.call(this,e,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},zn.isoWeekYear=function(e){return vn.call(this,e,this.isoWeek(),this.isoWeekday(),1,4)},zn.quarter=zn.quarters=function(e){return null==e?Math.ceil((this.month()+1)/3):this.month(3*(e-1)+this.month()%3)},zn.month=Fe,zn.daysInMonth=function(){return Ce(this.year(),this.month())},zn.week=zn.weeks=function(e){var t=this.localeData().week(this);return null==e?t:this.add(7*(e-t),"d")},zn.isoWeek=zn.isoWeeks=function(e){var t=qe(this,1,4).week;return null==e?t:this.add(7*(e-t),"d")},zn.weeksInYear=function(){var e=this.localeData()._week;return Je(this.year(),e.dow,e.doy)},zn.isoWeeksInYear=function(){return Je(this.year(),1,4)},zn.date=yn,zn.day=zn.days=function(e){if(!this.isValid())return null!=e?this:NaN;var t=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=e?(e=function(e,t){return"string"!=typeof e?e:isNaN(e)?"number"==typeof(e=t.weekdaysParse(e))?e:null:parseInt(e,10)}(e,this.localeData()),this.add(e-t,"d")):t},zn.weekday=function(e){if(!this.isValid())return null!=e?this:NaN;var t=(this.day()+7-this.localeData()._week.dow)%7;return null==e?t:this.add(e-t,"d")},zn.isoWeekday=function(e){if(!this.isValid())return null!=e?this:NaN;if(null!=e){var t=function(e,t){return"string"==typeof e?t.weekdaysParse(e)%7||7:isNaN(e)?null:e}(e,this.localeData());return this.day(this.day()%7?t:t-7)}return this.day()||7},zn.dayOfYear=function(e){var t=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==e?t:this.add(e-t,"d")},zn.hour=zn.hours=st,zn.minute=zn.minutes=Mn,zn.second=zn.seconds=gn,zn.millisecond=zn.milliseconds=Ln,zn.utcOffset=function(e,t,n){var r,i=this._offset||0;if(!this.isValid())return null!=e?this:NaN;if(null!=e){if("string"==typeof e){if(null===(e=Ut(ce,e)))return this}else Math.abs(e)<16&&!n&&(e*=60);return!this._isUTC&&t&&(r=Kt(this)),this._offset=e,this._isUTC=!0,null!=r&&this.add(r,"m"),i!==e&&(!t||this._changeInProgress?en(this,$t(e-i,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,a.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?i:Kt(this)},zn.utc=function(e){return this.utcOffset(0,e)},zn.local=function(e){return this._isUTC&&(this.utcOffset(0,e),this._isUTC=!1,e&&this.subtract(Kt(this),"m")),this},zn.parseZone=function(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var e=Ut(oe,this._i);null!=e?this.utcOffset(e):this.utcOffset(0,!0)}return this},zn.hasAlignedHourOffset=function(e){return!!this.isValid()&&(e=e?Vt(e).utcOffset():0,(this.utcOffset()-e)%60==0)},zn.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},zn.isLocal=function(){return!!this.isValid()&&!this._isUTC},zn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},zn.isUtc=qt,zn.isUTC=qt,zn.zoneAbbr=function(){return this._isUTC?"UTC":""},zn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},zn.dates=H("dates accessor is deprecated. Use date instead.",yn),zn.months=H("months accessor is deprecated. Use month instead",Fe),zn.years=H("years accessor is deprecated. Use year instead",Ye),zn.zone=H("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",(function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()})),zn.isDSTShifted=H("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",(function(){if(!c(this._isDSTShifted))return this._isDSTShifted;var e={};if(y(e,this),(e=xt(e))._a){var t=e._isUTC?h(e._a):Vt(e._a);this._isDSTShifted=this.isValid()&&z(e._a,t.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}));var Hn=x.prototype;function Tn(e,t,n,r){var a=vt(),i=h().set(r,t);return a[n](i,e)}function Sn(e,t,n){if(s(e)&&(t=e,e=void 0),e=e||"",null!=t)return Tn(e,t,n,"month");var r,a=[];for(r=0;r<12;r++)a[r]=Tn(e,r,n,"month");return a}function Yn(e,t,n,r){"boolean"==typeof e?(s(t)&&(n=t,t=void 0),t=t||""):(n=t=e,e=!1,s(t)&&(n=t,t=void 0),t=t||"");var a,i=vt(),o=e?i._week.dow:0;if(null!=n)return Tn(t,(n+o)%7,r,"day");var c=[];for(a=0;a<7;a++)c[a]=Tn(t,(a+o)%7,r,"day");return c}Hn.calendar=function(e,t,n){var r=this._calendar[e]||this._calendar.sameElse;return D(r)?r.call(t,n):r},Hn.longDateFormat=function(e){var t=this._longDateFormat[e],n=this._longDateFormat[e.toUpperCase()];return t||!n?t:(this._longDateFormat[e]=n.replace(/MMMM|MM|DD|dddd/g,(function(e){return e.slice(1)})),this._longDateFormat[e])},Hn.invalidDate=function(){return this._invalidDate},Hn.ordinal=function(e){return this._ordinal.replace("%d",e)},Hn.preparse=kn,Hn.postformat=kn,Hn.relativeTime=function(e,t,n,r){var a=this._relativeTime[n];return D(a)?a(e,t,n,r):a.replace(/%d/i,e)},Hn.pastFuture=function(e,t){var n=this._relativeTime[e>0?"future":"past"];return D(n)?n(t):n.replace(/%s/i,t)},Hn.set=function(e){var t,n;for(n in e)D(t=e[n])?this[n]=t:this["_"+n]=t;this._config=e,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},Hn.months=function(e,t){return e?i(this._months)?this._months[e.month()]:this._months[(this._months.isFormat||Ve).test(t)?"format":"standalone"][e.month()]:i(this._months)?this._months:this._months.standalone},Hn.monthsShort=function(e,t){return e?i(this._monthsShort)?this._monthsShort[e.month()]:this._monthsShort[Ve.test(t)?"format":"standalone"][e.month()]:i(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},Hn.monthsParse=function(e,t,n){var r,a,i;if(this._monthsParseExact)return je.call(this,e,t,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),r=0;r<12;r++){if(a=h([2e3,r]),n&&!this._longMonthsParse[r]&&(this._longMonthsParse[r]=new RegExp("^"+this.months(a,"").replace(".","")+"$","i"),this._shortMonthsParse[r]=new RegExp("^"+this.monthsShort(a,"").replace(".","")+"$","i")),n||this._monthsParse[r]||(i="^"+this.months(a,"")+"|^"+this.monthsShort(a,""),this._monthsParse[r]=new RegExp(i.replace(".",""),"i")),n&&"MMMM"===t&&this._longMonthsParse[r].test(e))return r;if(n&&"MMM"===t&&this._shortMonthsParse[r].test(e))return r;if(!n&&this._monthsParse[r].test(e))return r}},Hn.monthsRegex=function(e){return this._monthsParseExact?(d(this,"_monthsRegex")||Re.call(this),e?this._monthsStrictRegex:this._monthsRegex):(d(this,"_monthsRegex")||(this._monthsRegex=Ie),this._monthsStrictRegex&&e?this._monthsStrictRegex:this._monthsRegex)},Hn.monthsShortRegex=function(e){return this._monthsParseExact?(d(this,"_monthsRegex")||Re.call(this),e?this._monthsShortStrictRegex:this._monthsShortRegex):(d(this,"_monthsShortRegex")||(this._monthsShortRegex=Ne),this._monthsShortStrictRegex&&e?this._monthsShortStrictRegex:this._monthsShortRegex)},Hn.week=function(e){return qe(e,this._week.dow,this._week.doy).week},Hn.firstDayOfYear=function(){return this._week.doy},Hn.firstDayOfWeek=function(){return this._week.dow},Hn.weekdays=function(e,t){var n=i(this._weekdays)?this._weekdays:this._weekdays[e&&!0!==e&&this._weekdays.isFormat.test(t)?"format":"standalone"];return!0===e?Ge(n,this._week.dow):e?n[e.day()]:n},Hn.weekdaysMin=function(e){return!0===e?Ge(this._weekdaysMin,this._week.dow):e?this._weekdaysMin[e.day()]:this._weekdaysMin},Hn.weekdaysShort=function(e){return!0===e?Ge(this._weekdaysShort,this._week.dow):e?this._weekdaysShort[e.day()]:this._weekdaysShort},Hn.weekdaysParse=function(e,t,n){var r,a,i;if(this._weekdaysParseExact)return Qe.call(this,e,t,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),r=0;r<7;r++){if(a=h([2e3,1]).day(r),n&&!this._fullWeekdaysParse[r]&&(this._fullWeekdaysParse[r]=new RegExp("^"+this.weekdays(a,"").replace(".","\\.?")+"$","i"),this._shortWeekdaysParse[r]=new RegExp("^"+this.weekdaysShort(a,"").replace(".","\\.?")+"$","i"),this._minWeekdaysParse[r]=new RegExp("^"+this.weekdaysMin(a,"").replace(".","\\.?")+"$","i")),this._weekdaysParse[r]||(i="^"+this.weekdays(a,"")+"|^"+this.weekdaysShort(a,"")+"|^"+this.weekdaysMin(a,""),this._weekdaysParse[r]=new RegExp(i.replace(".",""),"i")),n&&"dddd"===t&&this._fullWeekdaysParse[r].test(e))return r;if(n&&"ddd"===t&&this._shortWeekdaysParse[r].test(e))return r;if(n&&"dd"===t&&this._minWeekdaysParse[r].test(e))return r;if(!n&&this._weekdaysParse[r].test(e))return r}},Hn.weekdaysRegex=function(e){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||rt.call(this),e?this._weekdaysStrictRegex:this._weekdaysRegex):(d(this,"_weekdaysRegex")||(this._weekdaysRegex=et),this._weekdaysStrictRegex&&e?this._weekdaysStrictRegex:this._weekdaysRegex)},Hn.weekdaysShortRegex=function(e){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||rt.call(this),e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(d(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=tt),this._weekdaysShortStrictRegex&&e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},Hn.weekdaysMinRegex=function(e){return this._weekdaysParseExact?(d(this,"_weekdaysRegex")||rt.call(this),e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(d(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=nt),this._weekdaysMinStrictRegex&&e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},Hn.isPM=function(e){return"p"===(e+"").toLowerCase().charAt(0)},Hn.meridiem=function(e,t,n){return e>11?n?"pm":"PM":n?"am":"AM"},ft("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var t=e%10;return e+(1===L(e%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th")}}),a.lang=H("moment.lang is deprecated. Use moment.locale instead.",ft),a.langData=H("moment.langData is deprecated. Use moment.localeData instead.",vt);var Dn=Math.abs;function On(e,t,n,r){var a=$t(t,n);return e._milliseconds+=r*a._milliseconds,e._days+=r*a._days,e._months+=r*a._months,e._bubble()}function xn(e){return e<0?Math.floor(e):Math.ceil(e)}function Cn(e){return 4800*e/146097}function Vn(e){return 146097*e/4800}function En(e){return function(){return this.as(e)}}var Pn=En("ms"),jn=En("s"),An=En("m"),Fn=En("h"),Nn=En("d"),In=En("w"),Rn=En("M"),Wn=En("Q"),Un=En("y");function Bn(e){return function(){return this.isValid()?this._data[e]:NaN}}var Kn=Bn("milliseconds"),qn=Bn("seconds"),Jn=Bn("minutes"),Gn=Bn("hours"),$n=Bn("days"),Xn=Bn("months"),Zn=Bn("years"),Qn=Math.round,er={ss:44,s:45,m:45,h:22,d:26,M:11};function tr(e,t,n,r,a){return a.relativeTime(t||1,!!n,e,r)}var nr=Math.abs;function rr(e){return(e>0)-(e<0)||+e}function ar(){if(!this.isValid())return this.localeData().invalidDate();var e,t,n=nr(this._milliseconds)/1e3,r=nr(this._days),a=nr(this._months);e=w(n/60),t=w(e/60),n%=60,e%=60;var i=w(a/12),o=a%=12,c=r,s=t,l=e,u=n?n.toFixed(3).replace(/\.?0+$/,""):"",d=this.asSeconds();if(!d)return"P0D";var m=d<0?"-":"",h=rr(this._months)!==rr(d)?"-":"",f=rr(this._days)!==rr(d)?"-":"",p=rr(this._milliseconds)!==rr(d)?"-":"";return m+"P"+(i?h+i+"Y":"")+(o?h+o+"M":"")+(c?f+c+"D":"")+(s||l||u?"T":"")+(s?p+s+"H":"")+(l?p+l+"M":"")+(u?p+u+"S":"")}var ir=Ft.prototype;return ir.isValid=function(){return this._isValid},ir.abs=function(){var e=this._data;return this._milliseconds=Dn(this._milliseconds),this._days=Dn(this._days),this._months=Dn(this._months),e.milliseconds=Dn(e.milliseconds),e.seconds=Dn(e.seconds),e.minutes=Dn(e.minutes),e.hours=Dn(e.hours),e.months=Dn(e.months),e.years=Dn(e.years),this},ir.add=function(e,t){return On(this,e,t,1)},ir.subtract=function(e,t){return On(this,e,t,-1)},ir.as=function(e){if(!this.isValid())return NaN;var t,n,r=this._milliseconds;if("month"===(e=E(e))||"quarter"===e||"year"===e)switch(t=this._days+r/864e5,n=this._months+Cn(t),e){case"month":return n;case"quarter":return n/3;case"year":return n/12}else switch(t=this._days+Math.round(Vn(this._months)),e){case"week":return t/7+r/6048e5;case"day":return t+r/864e5;case"hour":return 24*t+r/36e5;case"minute":return 1440*t+r/6e4;case"second":return 86400*t+r/1e3;case"millisecond":return Math.floor(864e5*t)+r;default:throw new Error("Unknown unit "+e)}},ir.asMilliseconds=Pn,ir.asSeconds=jn,ir.asMinutes=An,ir.asHours=Fn,ir.asDays=Nn,ir.asWeeks=In,ir.asMonths=Rn,ir.asQuarters=Wn,ir.asYears=Un,ir.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*L(this._months/12):NaN},ir._bubble=function(){var e,t,n,r,a,i=this._milliseconds,o=this._days,c=this._months,s=this._data;return i>=0&&o>=0&&c>=0||i<=0&&o<=0&&c<=0||(i+=864e5*xn(Vn(c)+o),o=0,c=0),s.milliseconds=i%1e3,e=w(i/1e3),s.seconds=e%60,t=w(e/60),s.minutes=t%60,n=w(t/60),s.hours=n%24,o+=w(n/24),a=w(Cn(o)),c+=a,o-=xn(Vn(a)),r=w(c/12),c%=12,s.days=o,s.months=c,s.years=r,this},ir.clone=function(){return $t(this)},ir.get=function(e){return e=E(e),this.isValid()?this[e+"s"]():NaN},ir.milliseconds=Kn,ir.seconds=qn,ir.minutes=Jn,ir.hours=Gn,ir.days=$n,ir.weeks=function(){return w(this.days()/7)},ir.months=Xn,ir.years=Zn,ir.humanize=function(e){if(!this.isValid())return this.localeData().invalidDate();var t=this.localeData(),n=function(e,t,n){var r=$t(e).abs(),a=Qn(r.as("s")),i=Qn(r.as("m")),o=Qn(r.as("h")),c=Qn(r.as("d")),s=Qn(r.as("M")),l=Qn(r.as("y")),u=a<=er.ss&&["s",a]||a0,u[4]=n,tr.apply(null,u)}(this,!e,t);return e&&(n=t.pastFuture(+this,n)),t.postformat(n)},ir.toISOString=ar,ir.toString=ar,ir.toJSON=ar,ir.locale=an,ir.localeData=cn,ir.toIsoString=H("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",ar),ir.lang=on,U("X",0,0,"unix"),U("x",0,0,"valueOf"),ue("x",ie),ue("X",/[+-]?\d+(\.\d{1,3})?/),fe("X",(function(e,t,n){n._d=new Date(1e3*parseFloat(e,10))})),fe("x",(function(e,t,n){n._d=new Date(L(e))})),a.version="2.24.0",t=Vt,a.fn=zn,a.min=function(){return jt("isBefore",[].slice.call(arguments,0))},a.max=function(){return jt("isAfter",[].slice.call(arguments,0))},a.now=function(){return Date.now?Date.now():+new Date},a.utc=h,a.unix=function(e){return Vt(1e3*e)},a.months=function(e,t){return Sn(e,t,"months")},a.isDate=l,a.locale=ft,a.invalid=v,a.duration=$t,a.isMoment=g,a.weekdays=function(e,t,n){return Yn(e,t,n,"weekdays")},a.parseZone=function(){return Vt.apply(null,arguments).parseZone()},a.localeData=vt,a.isDuration=Nt,a.monthsShort=function(e,t){return Sn(e,t,"monthsShort")},a.weekdaysMin=function(e,t,n){return Yn(e,t,n,"weekdaysMin")},a.defineLocale=pt,a.updateLocale=function(e,t){if(null!=t){var n,r,a=lt;null!=(r=ht(e))&&(a=r._config),t=O(a,t),(n=new x(t)).parentLocale=ut[e],ut[e]=n,ft(e)}else null!=ut[e]&&(null!=ut[e].parentLocale?ut[e]=ut[e].parentLocale:null!=ut[e]&&delete ut[e]);return ut[e]},a.locales=function(){return T(ut)},a.weekdaysShort=function(e,t,n){return Yn(e,t,n,"weekdaysShort")},a.normalizeUnits=E,a.relativeTimeRounding=function(e){return void 0===e?Qn:"function"==typeof e&&(Qn=e,!0)},a.relativeTimeThreshold=function(e,t){return void 0!==er[e]&&(void 0===t?er[e]:(er[e]=t,"s"===e&&(er.ss=t-1),!0))},a.calendarFormat=function(e,t){var n=e.diff(t,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"},a.prototype=zn,a.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"GGGG-[W]WW",MONTH:"YYYY-MM"},a}()}).call(this,n(309)(e))},function(e,t,n){"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE){0;try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(e){console.error(e)}}}(),e.exports=n(234)},function(e,t,n){var r; +/*! + Copyright (c) 2017 Jed Watson. + Licensed under the MIT License (MIT), see + http://jedwatson.github.io/classnames +*/!function(){"use strict";var n={}.hasOwnProperty;function a(){for(var e=[],t=0;t0&&void 0!==arguments[0]?arguments[0]:{};return Object.keys(e).reduce((function(t,n){var r=e[n];switch(n){case"class":t.className=r,delete t.class;break;default:t[n]=r}return t}),{})}var f=function(){function e(){o()(this,e),this.collection={}}return s()(e,[{key:"clear",value:function(){this.collection={}}},{key:"delete",value:function(e){return delete this.collection[e]}},{key:"get",value:function(e){return this.collection[e]}},{key:"has",value:function(e){return Boolean(this.collection[e])}},{key:"set",value:function(e,t){return this.collection[e]=t,this}},{key:"size",get:function(){return Object.keys(this.collection).length}}]),e}();function p(e,t,n){return n?u.createElement(e.tag,a()({key:t},h(e.attrs),n),(e.children||[]).map((function(n,r){return p(n,t+"-"+e.tag+"-"+r)}))):u.createElement(e.tag,a()({key:t},h(e.attrs)),(e.children||[]).map((function(n,r){return p(n,t+"-"+e.tag+"-"+r)})))}function v(e){return Object(l.generate)(e)[0]}function _(e,t){switch(t){case"fill":return e+"-fill";case"outline":return e+"-o";case"twotone":return e+"-twotone";default:throw new TypeError("Unknown theme type: "+t+", name: "+e)}}}).call(this,n(62))},function(e,t){e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var n=function(e,t){var n=e[1]||"",r=e[3];if(!r)return n;if(t&&"function"==typeof btoa){var a=(o=r,"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(o))))+" */"),i=r.sources.map((function(e){return"/*# sourceURL="+r.sourceRoot+e+" */"}));return[n].concat(i).concat([a]).join("\n")}var o;return[n].join("\n")}(t,e);return t[2]?"@media "+t[2]+"{"+n+"}":n})).join("")},t.i=function(e,n){"string"==typeof e&&(e=[[null,e,""]]);for(var r={},a=0;a=0&&d.splice(t,1)}function _(e){var t=document.createElement("style");if(void 0===e.attrs.type&&(e.attrs.type="text/css"),void 0===e.attrs.nonce){var r=function(){0;return n.nc}();r&&(e.attrs.nonce=r)}return y(t,e.attrs),p(e,t),t}function y(e,t){Object.keys(t).forEach((function(n){e.setAttribute(n,t[n])}))}function M(e,t){var n,r,a,i;if(t.transform&&e.css){if(!(i="function"==typeof t.transform?t.transform(e.css):t.transform.default(e.css)))return function(){};e.css=i}if(t.singleton){var o=u++;n=l||(l=_(t)),r=w.bind(null,n,o,!1),a=w.bind(null,n,o,!0)}else e.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(n=function(e){var t=document.createElement("link");return void 0===e.attrs.type&&(e.attrs.type="text/css"),e.attrs.rel="stylesheet",y(t,e.attrs),p(e,t),t}(t),r=z.bind(null,n,t),a=function(){v(n),n.href&&URL.revokeObjectURL(n.href)}):(n=_(t),r=L.bind(null,n),a=function(){v(n)});return r(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap)return;r(e=t)}else a()}}e.exports=function(e,t){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");(t=t||{}).attrs="object"==typeof t.attrs?t.attrs:{},t.singleton||"boolean"==typeof t.singleton||(t.singleton=o()),t.insertInto||(t.insertInto="head"),t.insertAt||(t.insertAt="bottom");var n=f(e,t);return h(n,t),function(e){for(var r=[],a=0;a=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n},g=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t},w=function(e){return"object"===(void 0===e?"undefined":p(e))&&e.constructor===Object},L=Object.freeze([]),z=Object.freeze({});function k(e){return"function"==typeof e}function H(e){return e.displayName||e.name||"Component"}function T(e){return e&&"string"==typeof e.styledComponentId}var S=void 0!==e&&(e.env.REACT_APP_SC_ATTR||e.env.SC_ATTR)||"data-styled",Y="undefined"!=typeof window&&"HTMLElement"in window,D="boolean"==typeof SC_DISABLE_SPEEDY&&SC_DISABLE_SPEEDY||void 0!==e&&(e.env.REACT_APP_SC_DISABLE_SPEEDY||e.env.SC_DISABLE_SPEEDY)||!1;var O=function(e){function t(n){v(this,t);for(var r=arguments.length,a=Array(r>1?r-1:0),i=1;i0?" Additional arguments: "+a.join(", "):"")));return g(o)}return M(t,e),t}(Error),x=/^[^\S\n]*?\/\* sc-component-id:\s*(\S+)\s+\*\//gm,C=function(e){var t=""+(e||""),n=[];return t.replace(x,(function(e,t,r){return n.push({componentId:t,matchIndex:r}),e})),n.map((function(e,r){var a=e.componentId,i=e.matchIndex,o=n[r+1];return{componentId:a,cssFromDOM:o?t.slice(i,o.matchIndex):t.slice(i)}}))},V=/^\s*\/\/.*$/gm,E=new a.a({global:!1,cascade:!0,keyframe:!1,prefix:!1,compress:!1,semicolon:!0}),P=new a.a({global:!1,cascade:!0,keyframe:!1,prefix:!0,compress:!1,semicolon:!1}),j=[],A=function(e){if(-2===e){var t=j;return j=[],t}},F=o()((function(e){j.push(e)})),N=void 0,I=void 0,R=void 0,W=function(e,t,n){return t>0&&-1!==n.slice(0,t).indexOf(I)&&n.slice(t-I.length,t)!==I?"."+N:e};P.use([function(e,t,n){2===e&&n.length&&n[0].lastIndexOf(I)>0&&(n[0]=n[0].replace(R,W))},F,A]),E.use([F,A]);var U=function(e){return E("",e)};function B(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"&",a=e.join("").replace(V,""),i=t&&n?n+" "+t+" { "+a+" }":a;return N=r,I=t,R=new RegExp("\\"+I+"\\b","g"),P(n||!t?"":t,i)}var K=function(){return n.nc},q=function(e,t,n){n&&((e[t]||(e[t]=Object.create(null)))[n]=!0)},J=function(e,t){e[t]=Object.create(null)},G=function(e){return function(t,n){return void 0!==e[t]&&e[t][n]}},$=function(e){var t="";for(var n in e)t+=Object.keys(e[n]).join(" ")+" ";return t.trim()},X=function(e){if(e.sheet)return e.sheet;for(var t=e.ownerDocument.styleSheets.length,n=0;n"+e()+""}},ne=function(e,t){return function(){var n,r=((n={})[S]=$(t),n["data-styled-version"]="4.4.1",n),a=K();return a&&(r.nonce=a),s.a.createElement("style",y({},r,{dangerouslySetInnerHTML:{__html:e()}}))}},re=function(e){return function(){return Object.keys(e)}},ae=function(e,t){return e.createTextNode(Q(t))},ie=function e(t,n){var r=void 0===t?Object.create(null):t,a=void 0===n?Object.create(null):n,i=function(e){var t=a[e];return void 0!==t?t:a[e]=[""]},o=function(){var e="";for(var t in a){var n=a[t][0];n&&(e+=Q(t)+n)}return e};return{clone:function(){var t=function(e){var t=Object.create(null);for(var n in e)t[n]=y({},e[n]);return t}(r),n=Object.create(null);for(var i in a)n[i]=[a[i][0]];return e(t,n)},css:o,getIds:re(a),hasNameForId:G(r),insertMarker:i,insertRules:function(e,t,n){i(e)[0]+=t.join(" "),q(r,e,n)},removeRules:function(e){var t=a[e];void 0!==t&&(t[0]="",J(r,e))},sealed:!1,styleTag:null,toElement:ne(o,r),toHTML:te(o,r)}},oe=function(e,t,n,r,a){if(Y&&!n){var i=function(e,t,n){var r=document;e?r=e.ownerDocument:t&&(r=t.ownerDocument);var a=r.createElement("style");a.setAttribute(S,""),a.setAttribute("data-styled-version","4.4.1");var i=K();if(i&&a.setAttribute("nonce",i),a.appendChild(r.createTextNode("")),e&&!t)e.appendChild(a);else{if(!t||!e||!t.parentNode)throw new O(6);t.parentNode.insertBefore(a,n?t:t.nextSibling)}return a}(e,t,r);return D?function(e,t){var n=Object.create(null),r=Object.create(null),a=void 0!==t,i=!1,o=function(t){var a=r[t];return void 0!==a?a:(r[t]=ae(e.ownerDocument,t),e.appendChild(r[t]),n[t]=Object.create(null),r[t])},c=function(){var e="";for(var t in r)e+=r[t].data;return e};return{clone:function(){throw new O(5)},css:c,getIds:re(r),hasNameForId:G(n),insertMarker:o,insertRules:function(e,r,c){for(var s=o(e),l=[],u=r.length,d=0;d0&&(i=!0,t().insertRules(e+"-import",l))},removeRules:function(o){var c=r[o];if(void 0!==c){var s=ae(e.ownerDocument,o);e.replaceChild(s,c),r[o]=s,J(n,o),a&&i&&t().removeRules(o+"-import")}},sealed:!1,styleTag:e,toElement:ne(c,n),toHTML:te(c,n)}}(i,a):function(e,t){var n=Object.create(null),r=Object.create(null),a=[],i=void 0!==t,o=!1,c=function(e){var t=r[e];return void 0!==t?t:(r[e]=a.length,a.push(0),J(n,e),r[e])},s=function(){var t=X(e).cssRules,n="";for(var i in r){n+=Q(i);for(var o=r[i],c=ee(a,o),s=c-a[o];s0&&(o=!0,t().insertRules(r+"-import",f)),a[u]+=h,q(n,r,l)},removeRules:function(c){var s=r[c];if(void 0!==s&&!1!==e.isConnected){var l=a[s];!function(e,t,n){for(var r=t-n,a=t;a>r;a-=1)e.deleteRule(a)}(X(e),ee(a,s)-1,l),a[s]=0,J(n,c),i&&o&&t().removeRules(c+"-import")}},sealed:!1,styleTag:e,toElement:ne(s,n),toHTML:te(s,n)}}(i,a)}return ie()},ce=/\s+/,se=void 0;se=Y?D?40:1e3:-1;var le=0,ue=void 0,de=function(){function e(){var t=this,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Y?document.head:null,r=arguments.length>1&&void 0!==arguments[1]&&arguments[1];v(this,e),this.getImportRuleTag=function(){var e=t.importRuleTag;if(void 0!==e)return e;var n=t.tags[0];return t.importRuleTag=oe(t.target,n?n.styleTag:null,t.forceServer,!0)},le+=1,this.id=le,this.forceServer=r,this.target=r?null:n,this.tagMap={},this.deferred={},this.rehydratedNames={},this.ignoreRehydratedNames={},this.tags=[],this.capacity=1,this.clones=[]}return e.prototype.rehydrate=function(){if(!Y||this.forceServer)return this;var e=[],t=[],n=!1,r=document.querySelectorAll("style["+S+'][data-styled-version="4.4.1"]'),a=r.length;if(!a)return this;for(var i=0;i0&&void 0!==arguments[0]&&arguments[0];ue=new e(void 0,t).rehydrate()},e.prototype.clone=function(){var t=new e(this.target,this.forceServer);return this.clones.push(t),t.tags=this.tags.map((function(e){for(var n=e.getIds(),r=e.clone(),a=0;a1?t-1:0),r=1;r=4;)t=1540483477*(65535&(t=255&e.charCodeAt(a)|(255&e.charCodeAt(++a))<<8|(255&e.charCodeAt(++a))<<16|(255&e.charCodeAt(++a))<<24))+((1540483477*(t>>>16)&65535)<<16),r=1540483477*(65535&r)+((1540483477*(r>>>16)&65535)<<16)^(t=1540483477*(65535&(t^=t>>>24))+((1540483477*(t>>>16)&65535)<<16)),n-=4,++a;switch(n){case 3:r^=(255&e.charCodeAt(a+2))<<16;case 2:r^=(255&e.charCodeAt(a+1))<<8;case 1:r=1540483477*(65535&(r^=255&e.charCodeAt(a)))+((1540483477*(r>>>16)&65535)<<16)}return((r=1540483477*(65535&(r^=r>>>13))+((1540483477*(r>>>16)&65535)<<16))^r>>>15)>>>0}var ge=52,we=function(e){return String.fromCharCode(e+(e>25?39:97))};function Le(e){var t="",n=void 0;for(n=e;n>ge;n=Math.floor(n/ge))t=we(n%ge)+t;return we(n%ge)+t}function ze(e,t){for(var n=0;n2&&void 0!==arguments[2]?arguments[2]:z,r=!!n&&e.theme===n.theme,a=e.theme&&!r?e.theme:t||n.theme;return a},Ye=/[[\].#*$><+~=|^:(),"'`-]+/g,De=/(^-|-$)/g;function Oe(e){return e.replace(Ye,"-").replace(De,"")}function xe(e){return"string"==typeof e&&!0}var Ce={childContextTypes:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDerivedStateFromProps:!0,propTypes:!0,type:!0},Ve={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},Ee=((ke={})[u.ForwardRef]={$$typeof:!0,render:!0},ke),Pe=Object.defineProperty,je=Object.getOwnPropertyNames,Ae=Object.getOwnPropertySymbols,Fe=void 0===Ae?function(){return[]}:Ae,Ne=Object.getOwnPropertyDescriptor,Ie=Object.getPrototypeOf,Re=Object.prototype,We=Array.prototype;function Ue(e,t,n){if("string"!=typeof t){var r=Ie(t);r&&r!==Re&&Ue(e,r,n);for(var a=We.concat(je(t),Fe(t)),i=Ee[e.$$typeof]||Ce,o=Ee[t.$$typeof]||Ce,c=a.length,s=void 0,l=void 0;c--;)if(l=a[c],!(Ve[l]||n&&n[l]||o&&o[l]||i&&i[l])&&(s=Ne(t,l)))try{Pe(e,l,s)}catch(e){}return e}return e}var Be=Object(c.createContext)(),Ke=Be.Consumer,qe=(function(e){function t(n){v(this,t);var r=g(this,e.call(this,n));return r.getContext=Object(d.a)(r.getContext.bind(r)),r.renderInner=r.renderInner.bind(r),r}M(t,e),t.prototype.render=function(){return this.props.children?s.a.createElement(Be.Consumer,null,this.renderInner):null},t.prototype.renderInner=function(e){var t=this.getContext(this.props.theme,e);return s.a.createElement(Be.Provider,{value:t},this.props.children)},t.prototype.getTheme=function(e,t){if(k(e))return e(t);if(null===e||Array.isArray(e)||"object"!==(void 0===e?"undefined":p(e)))throw new O(8);return y({},t,e)},t.prototype.getContext=function(e,t){return this.getTheme(e,t)}}(c.Component),function(){function e(){v(this,e),this.masterSheet=de.master,this.instance=this.masterSheet.clone(),this.sealed=!1}e.prototype.seal=function(){if(!this.sealed){var e=this.masterSheet.clones.indexOf(this.instance);this.masterSheet.clones.splice(e,1),this.sealed=!0}},e.prototype.collectStyles=function(e){if(this.sealed)throw new O(2);return s.a.createElement(Ge,{sheet:this.instance},e)},e.prototype.getStyleTags=function(){return this.seal(),this.instance.toHTML()},e.prototype.getStyleElement=function(){return this.seal(),this.instance.toReactElements()},e.prototype.interleaveWithNodeStream=function(e){throw new O(3)}}(),Object(c.createContext)()),Je=qe.Consumer,Ge=function(e){function t(n){v(this,t);var r=g(this,e.call(this,n));return r.getContext=Object(d.a)(r.getContext),r}return M(t,e),t.prototype.getContext=function(e,t){if(e)return e;if(t)return new de(t);throw new O(4)},t.prototype.render=function(){var e=this.props,t=e.children,n=e.sheet,r=e.target;return s.a.createElement(qe.Provider,{value:this.getContext(n,r)},t)},t}(c.Component),$e={};var Xe=function(e){function t(){v(this,t);var n=g(this,e.call(this));return n.attrs={},n.renderOuter=n.renderOuter.bind(n),n.renderInner=n.renderInner.bind(n),n}return M(t,e),t.prototype.render=function(){return s.a.createElement(Je,null,this.renderOuter)},t.prototype.renderOuter=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:de.master;return this.styleSheet=e,this.props.forwardedComponent.componentStyle.isStatic?this.renderInner():s.a.createElement(Ke,null,this.renderInner)},t.prototype.renderInner=function(e){var t=this.props.forwardedComponent,n=t.componentStyle,r=t.defaultProps,a=(t.displayName,t.foldedComponentIds),i=t.styledComponentId,o=t.target,s=void 0;s=n.isStatic?this.generateAndInjectStyles(z,this.props):this.generateAndInjectStyles(Se(this.props,e,r)||z,this.props);var l=this.props.as||this.attrs.as||o,u=xe(l),d={},h=y({},this.props,this.attrs),f=void 0;for(f in h)"forwardedComponent"!==f&&"as"!==f&&("forwardedRef"===f?d.ref=h[f]:"forwardedAs"===f?d.as=h[f]:u&&!Object(m.a)(f)||(d[f]=h[f]));return this.props.style&&this.attrs.style&&(d.style=y({},this.attrs.style,this.props.style)),d.className=Array.prototype.concat(a,i,s!==i?s:null,this.props.className,this.attrs.className).filter(Boolean).join(" "),Object(c.createElement)(l,d)},t.prototype.buildExecutionContext=function(e,t,n){var r=this,a=y({},t,{theme:e});return n.length?(this.attrs={},n.forEach((function(e){var t,n=e,i=!1,o=void 0,c=void 0;for(c in k(n)&&(n=n(a),i=!0),n)o=n[c],i||!k(o)||(t=o)&&t.prototype&&t.prototype.isReactComponent||T(o)||(o=o(a)),r.attrs[c]=o,a[c]=o})),a):a},t.prototype.generateAndInjectStyles=function(e,t){var n=t.forwardedComponent,r=n.attrs,a=n.componentStyle;n.warnTooManyClasses;return a.isStatic&&!r.length?a.generateAndInjectStyles(z,this.styleSheet):a.generateAndInjectStyles(this.buildExecutionContext(e,t,r),this.styleSheet)},t}(c.Component);function Ze(e,t,n){var r=T(e),a=!xe(e),i=t.displayName,o=void 0===i?function(e){return xe(e)?"styled."+e:"Styled("+H(e)+")"}(e):i,c=t.componentId,l=void 0===c?function(e,t,n){var r="string"!=typeof t?"sc":Oe(t),a=($e[r]||0)+1;$e[r]=a;var i=r+"-"+e.generateName(r+a);return n?n+"-"+i:i}(Te,t.displayName,t.parentComponentId):c,u=t.ParentComponent,d=void 0===u?Xe:u,m=t.attrs,f=void 0===m?L:m,p=t.displayName&&t.componentId?Oe(t.displayName)+"-"+t.componentId:t.componentId||l,v=r&&e.attrs?Array.prototype.concat(e.attrs,f).filter(Boolean):f,_=new Te(r?e.componentStyle.rules.concat(n):n,v,p),M=void 0,g=function(e,t){return s.a.createElement(d,y({},e,{forwardedComponent:M,forwardedRef:t}))};return g.displayName=o,(M=s.a.forwardRef(g)).displayName=o,M.attrs=v,M.componentStyle=_,M.foldedComponentIds=r?Array.prototype.concat(e.foldedComponentIds,e.styledComponentId):L,M.styledComponentId=p,M.target=r?e.target:e,M.withComponent=function(e){var r=t.componentId,a=b(t,["componentId"]),i=r&&r+"-"+(xe(e)?e:Oe(H(e)));return Ze(e,y({},a,{attrs:v,componentId:i,ParentComponent:d}),n)},Object.defineProperty(M,"defaultProps",{get:function(){return this._foldedDefaultProps},set:function(t){this._foldedDefaultProps=r?Object(h.a)(e.defaultProps,t):t}}),M.toString=function(){return"."+M.styledComponentId},a&&Ue(M,e,{attrs:!0,componentStyle:!0,displayName:!0,foldedComponentIds:!0,styledComponentId:!0,target:!0,withComponent:!0}),M}var Qe=function(e){return function e(t,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:z;if(!Object(u.isValidElementType)(n))throw new O(1,String(n));var a=function(){return t(n,r,Me.apply(void 0,arguments))};return a.withConfig=function(a){return e(t,n,y({},r,a))},a.attrs=function(a){return e(t,n,y({},r,{attrs:Array.prototype.concat(r.attrs,a).filter(Boolean)}))},a}(Ze,e)};["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","big","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","kbd","keygen","label","legend","li","link","main","map","mark","marquee","menu","menuitem","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","param","picture","pre","progress","q","rp","rt","ruby","s","samp","script","section","select","small","source","span","strong","style","sub","summary","sup","table","tbody","td","textarea","tfoot","th","thead","time","title","tr","track","u","ul","var","video","wbr","circle","clipPath","defs","ellipse","foreignObject","g","image","line","linearGradient","marker","mask","path","pattern","polygon","polyline","radialGradient","rect","stop","svg","text","tspan"].forEach((function(e){Qe[e]=Qe(e)}));!function(){function e(t,n){v(this,e),this.rules=t,this.componentId=n,this.isStatic=ze(t,L),de.master.hasId(n)||de.master.deferredInject(n,[])}e.prototype.createStyles=function(e,t){var n=B(ye(this.rules,e,t),"");t.inject(this.componentId,n)},e.prototype.removeStyles=function(e){var t=this.componentId;e.hasId(t)&&e.remove(t)},e.prototype.renderStyles=function(e,t){this.removeStyles(t),this.createStyles(e,t)}}();Y&&(window.scCGSHMRCache={});t.a=Qe}).call(this,n(62))},function(e,t,n){var r=n(13),a=n(14),i=n(69),o=n(24),c=n(20),s=function(e,t,n){var l,u,d,m=e&s.F,h=e&s.G,f=e&s.S,p=e&s.P,v=e&s.B,_=e&s.W,y=h?a:a[t]||(a[t]={}),M=y.prototype,b=h?r:f?r[t]:(r[t]||{}).prototype;for(l in h&&(n=t),n)(u=!m&&b&&void 0!==b[l])&&c(y,l)||(d=u?b[l]:n[l],y[l]=h&&"function"!=typeof b[l]?n[l]:v&&u?i(d,r):_&&b[l]==d?function(e){var t=function(t,n,r){if(this instanceof e){switch(arguments.length){case 0:return new e;case 1:return new e(t);case 2:return new e(t,n)}return new e(t,n,r)}return e.apply(this,arguments)};return t.prototype=e.prototype,t}(d):p&&"function"==typeof d?i(Function.call,d):d,p&&((y.virtual||(y.virtual={}))[l]=d,e&s.R&&M&&!M[l]&&o(M,l,d)))};s.F=1,s.G=2,s.S=4,s.P=8,s.B=16,s.W=32,s.U=64,s.R=128,e.exports=s},function(e,t,n){var r=n(19),a=n(33);e.exports=n(15)?function(e,t,n){return r.f(e,t,a(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t){e.exports=function(e){return"object"==typeof e?null!==e:"function"==typeof e}},function(e,t,n){var r=n(73),a=n(50);e.exports=function(e){return r(a(e))}},function(e,t,n){var r=n(53)("wks"),a=n(36),i=n(13).Symbol,o="function"==typeof i;(e.exports=function(e){return r[e]||(r[e]=o&&i[e]||(o?i:a)("Symbol."+e))}).store=r},function(e,t,n){var r=n(227);"string"==typeof r&&(r=[[e.i,r,""]]);var a={hmr:!0,transform:void 0,insertInto:void 0};n(18)(r,a);r.locals&&(e.exports=r.locals)},function(e,t,n){var r=n(25);e.exports=function(e){if(!r(e))throw TypeError(e+" is not an object!");return e}},function(e,t){e.exports=function(e){try{return!!e()}catch(e){return!0}}},function(e,t,n){try{var r=n(68)}catch(e){r=n(68)}var a=/\s+/,i=Object.prototype.toString;function o(e){if(!e||!e.nodeType)throw new Error("A DOM element reference is required");this.el=e,this.list=e.classList}e.exports=function(e){return new o(e)},o.prototype.add=function(e){if(this.list)return this.list.add(e),this;var t=this.array();return~r(t,e)||t.push(e),this.el.className=t.join(" "),this},o.prototype.remove=function(e){if("[object RegExp]"==i.call(e))return this.removeMatching(e);if(this.list)return this.list.remove(e),this;var t=this.array(),n=r(t,e);return~n&&t.splice(n,1),this.el.className=t.join(" "),this},o.prototype.removeMatching=function(e){for(var t=this.array(),n=0;n=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n}},function(e,t,n){"use strict";e.exports=n(294)},function(e,t,n){"use strict";var r=function(){};e.exports=r},function(e,t,n){"use strict"; +/* +object-assign +(c) Sindre Sorhus +@license MIT +*/var r=Object.getOwnPropertySymbols,a=Object.prototype.hasOwnProperty,i=Object.prototype.propertyIsEnumerable;function o(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,t){for(var n,c,s=o(e),l=1;l0?r:n)(e)}},function(e,t,n){var r=n(53)("keys"),a=n(36);e.exports=function(e){return r[e]||(r[e]=a(e))}},function(e,t,n){var r=n(14),a=n(13),i=a["__core-js_shared__"]||(a["__core-js_shared__"]={});(e.exports=function(e,t){return i[e]||(i[e]=void 0!==t?t:{})})("versions",[]).push({version:r.version,mode:n(35)?"pure":"global",copyright:"© 2019 Denis Pushkarev (zloirock.ru)"})},function(e,t){e.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(e,t){t.f=Object.getOwnPropertySymbols},function(e,t,n){var r=n(50);e.exports=function(e){return Object(r(e))}},function(e,t){e.exports={}},function(e,t,n){var r=n(29),a=n(262),i=n(54),o=n(52)("IE_PROTO"),c=function(){},s=function(){var e,t=n(71)("iframe"),r=i.length;for(t.style.display="none",n(263).appendChild(t),t.src="javascript:",(e=t.contentWindow.document).open(),e.write("