Browse Source

refactor: 合并kernel

wechat_public_accounts
travis 5 years ago
parent
commit
0f3083cb56
  1. 2
      .gitignore
  2. 1
      api/.gitignore
  3. 26
      api/assets/AppAsset.php
  4. 4
      api/config/.gitignore
  5. 1
      api/config/bootstrap.php
  6. 86
      api/config/main.php
  7. 66
      api/config/params.php
  8. 57
      api/controllers/AddressController.php
  9. 44
      api/controllers/AdminController.php
  10. 81
      api/controllers/CartController.php
  11. 67
      api/controllers/CollectionController.php
  12. 48
      api/controllers/CommentController.php
  13. 91
      api/controllers/CommonController.php
  14. 47
      api/controllers/GoodsController.php
  15. 79
      api/controllers/OrderController.php
  16. 42
      api/controllers/SiteController.php
  17. 27
      api/controllers/TakingSiteController.php
  18. 45
      api/controllers/UserController.php
  19. 154
      api/logic/AddressLogic.php
  20. 161
      api/logic/CartLogic.php
  21. 121
      api/logic/CollectionLogic.php
  22. 52
      api/logic/CommentLogic.php
  23. 222
      api/logic/ExpressLogic.php
  24. 225
      api/logic/Helper.php
  25. 67
      api/logic/Login.php
  26. 459
      api/logic/OrderLogic.php
  27. 40
      api/logic/UserLogic.php
  28. 2
      api/runtime/.gitignore
  29. 27
      api/views/site/error.php
  30. 5
      api/web/.gitignore
  31. 2
      api/web/assets/.gitignore
  32. 120
      api/web/css/site.css
  33. BIN
      api/web/favicon.ico
  34. 18
      api/web/index-test.php
  35. 17
      api/web/index.php
  36. 2
      api/web/robots.txt
  37. 3
      backend/config/main.php
  38. 74
      backend/controllers/SiteController.php
  39. 58
      backend/models/Cat.php
  40. 125
      backend/models/Category.php
  41. 126
      backend/models/CategorySearch.php
  42. 227
      backend/models/User.php
  43. 63
      backend/modules/file/logic/file/FileManager.php
  44. 2
      backend/modules/file/models/ars/File.php
  45. 5
      backend/modules/goods/controllers/CategoryController.php
  46. 12
      backend/modules/goods/controllers/GoodsController.php
  47. 5
      backend/modules/goods/controllers/ShopCategoryController.php
  48. 118
      backend/modules/goods/logic/goods/GoodsManager.php
  49. 26
      backend/modules/goods/migrations/m191207_004848_add_columns_is_taking_is_express_express_type_uniform_postage_in_table_atg_goods.php
  50. 23
      backend/modules/goods/migrations/m191209_091129_update_columns_in_table_atg_goods.php
  51. 20
      backend/modules/goods/migrations/m191209_091524_add_column_weight_in_table_atg_goods_sku.php
  52. 17
      backend/modules/goods/migrations/sql/update_goods.sql
  53. 58
      backend/modules/goods/models/ars/Goods.php
  54. 5
      backend/modules/goods/models/ars/GoodsSku.php
  55. 5
      backend/modules/goods/models/searchs/GoodsSearch.php
  56. 55
      backend/modules/goods/views/goods/_search.php
  57. 6
      backend/modules/goods/views/goods/create.php
  58. 90
      backend/modules/goods/views/goods/express.php
  59. 62
      backend/modules/goods/views/goods/goods.php
  60. 6
      backend/modules/goods/views/goods/update.php
  61. 2
      backend/modules/goods/views/goods/view.php
  62. 267
      backend/modules/shop/controllers/ExpressTemplateController.php
  63. 32
      backend/modules/shop/migrations/m191205_092426_drop_columns_province_city_area_basic_price_basic_count_extra_count_extra_price_in_table_ats_express_template.php
  64. 36
      backend/modules/shop/migrations/m191205_092942_create_table_ats_express_area.php
  65. 24
      backend/modules/shop/migrations/m191206_092733_add_column_about_goods_to_table_collection.php
  66. 22
      backend/modules/shop/migrations/m191206_162733_add_column_about_user_to_table_comment.php
  67. 3
      backend/modules/shop/models/ars/Address.php
  68. 10
      backend/modules/shop/models/ars/Collection.php
  69. 8
      backend/modules/shop/models/ars/Comment.php
  70. 101
      backend/modules/shop/models/ars/ExpressArea.php
  71. 27
      backend/modules/shop/models/ars/ExpressTemplate.php
  72. 30
      backend/modules/shop/models/ars/Order.php
  73. 187
      backend/modules/shop/models/searchs/ExpressAreaSearch.php
  74. 37
      backend/modules/shop/models/searchs/ExpressTemplateSearch.php
  75. 7
      backend/modules/shop/models/searchs/OrderSearch.php
  76. 141
      backend/modules/shop/views/express-template/_form.php
  77. 34
      backend/modules/shop/views/express-template/create.php
  78. 51
      backend/modules/shop/views/express-template/express_area_create.php
  79. 175
      backend/modules/shop/views/express-template/express_area_form.php
  80. 33
      backend/modules/shop/views/express-template/express_area_list.php
  81. 52
      backend/modules/shop/views/express-template/express_area_update.php
  82. 94
      backend/modules/shop/views/express-template/express_area_view.php
  83. 34
      backend/modules/shop/views/express-template/update.php
  84. 7
      backend/views/layouts/main.php
  85. 47
      backend/views/layouts/sidebar.php
  86. 7
      backend/web/css/site.css
  87. 1
      backend/web/index.php
  88. BIN
      backend/web/uploads/xls/15738696921690.jpg
  89. 2
      common/config/bootstrap.php
  90. 9
      common/config/main.php
  91. 59
      common/models/DailyActiveUser.php
  92. 249
      common/models/User.php
  93. 2
      composer.json
  94. 105
      composer.lock
  95. 3
      console/controllers/InitController.php
  96. 41
      console/migrations/m191122_011654_add_column_admin_id_in_table_user.php
  97. 26
      console/migrations/m191204_092644_rename_backend_user.php
  98. 52
      console/migrations/m191204_102644_create_table_province.php
  99. 83
      console/runtime/logs/app.log
  100. 0
      datadictionary.md

2
.gitignore

@ -37,5 +37,7 @@ phpunit.phar
vendor.zip vendor.zip
/vagrant /vagrant
/backend/web/uploads /backend/web/uploads
/api/web/uploads
dump.rdb dump.rdb
/console/runtime /console/runtime

1
api/.gitignore

@ -0,0 +1 @@
runtime

26
api/assets/AppAsset.php

@ -0,0 +1,26 @@
<?php
namespace backend\assets;
use yii\web\AssetBundle;
/**
* Main backend application asset bundle.
*/
class AppAsset extends AssetBundle
{
public $basePath = '@webroot';
public $baseUrl = '@web';
public $css = [
'css/site.css',
];
public $js = [
'js/common.js'
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap4\BootstrapAsset',
'yii\bootstrap4\BootstrapPluginAsset',
'iron\web\AdminlteAsset',
];
}

4
api/config/.gitignore

@ -0,0 +1,4 @@
codeception-local.php
main-local.php
params-local.php
test-local.php

1
api/config/bootstrap.php

@ -0,0 +1 @@
<?php

86
api/config/main.php

@ -0,0 +1,86 @@
<?php
$params = array_merge(
require __DIR__ . '/../../common/config/params.php', require __DIR__ . '/../../common/config/params-local.php', require __DIR__ . '/params.php', require __DIR__ . '/params-local.php'
);
return [
'id' => 'api',
'basePath' => dirname(__DIR__),
'controllerNamespace' => 'api\controllers',
'bootstrap' => ['log'],
'modules' => [],
'components' => [
'request' => [
'parsers' => [
'application/json' => 'yii\web\JsonParser',
],
'csrfParam' => '_csrf-api',
],
'session' => [
// this is the name of the session cookie used for login on the app
'name' => 'api',
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => true,
'identityCookie' => ['name' => '_identity-api', 'httpOnly' => true],
],
'errorHandler' => [
'errorAction' => 'site/error',
],
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
['class' => 'yii\rest\UrlRule', 'controller' => 'goods', 'pluralize' => false],
['class' => 'yii\rest\UrlRule', 'controller' => 'address', 'pluralize' => false],
['class' => 'yii\rest\UrlRule', 'controller' => 'taking-site'],
['class' => 'yii\rest\UrlRule', 'controller' => 'cart'],
['class' => 'yii\rest\UrlRule', 'controller' => 'comment',
'extraPatterns' => [
'DELETE ' => 'delete'
]],
['class' => 'yii\rest\UrlRule', 'controller' => 'order'],
['class' => 'yii\rest\UrlRule', 'controller' => 'collection',
'extraPatterns' => [
'DELETE ' => 'delete'
]
],
['class' => 'yii\rest\UrlRule',
'controller' => 'user',
'pluralize' => false,
'extraPatterns' => [
'GET token' => 'token'
]
],
[
'class' => 'yii\rest\UrlRule',
'controller' => 'admin',
'extraPatterns' => [
'GET menu' => 'menu',
'GET create' => 'create'
]
],
[
'class' => 'yii\rest\UrlRule',
'controller' => 'site',
'extraPatterns' => [
'GET index' => 'index',
]
],
],
],
],
'params' => $params,
];

66
api/config/params.php

@ -0,0 +1,66 @@
<?php
return [
'permissions' => [
"网站基本权限" => [
'首页(销售数据)' => '/site/index',
'用户注销' => '/site/logout',
'用户登录' => '/site/login',
],
"商品管理" => [
'商品列表' => '/antgoods/goods/index',
'商品新增' => '/antgoods/goods/create',
'商品修改' => '/antgoods/goods/update',
'商品查看' => '/antgoods/goods/view',
],
"商城分类" => [
'列表' => '/antgoods/shop-category/index',
'新增' => '/antgoods/shop-category/create',
'修改' => '/antgoods/shop-category/update',
'查看' => '/antgoods/shop-category/view',
],
"后台分类" => [
'列表' => '/antgoods/category/index',
'新增' => '/antgoods/category/create',
'修改' => '/antgoods/category/update',
'查看' => '/antgoods/category/view',
],
"品牌管理" => [
'列表' => '/antgoods/brand/index',
'新增' => '/antgoods/brand/create',
'修改' => '/antgoods/brand/update',
'查看' => '/antgoods/brand/view',
],
"供应商管理" => [
'列表' => '/antgoods/supplier/index',
'新增' => '/antgoods/supplier/create',
'修改' => '/antgoods/supplier/update',
'查看' => '/antgoods/supplier/view',
],
"属性管理" => [
'列表' => '/antgoods/attribute/index',
'新增' => '/antgoods/attribute/create',
'修改' => '/antgoods/attribute/update',
'查看' => '/antgoods/attribute/view',
]
],
'menus' => [
'商城管理' => [
'icon' => 'fa-store',
'items' => [
['运营数据', '/site',],
['基础配置', '/config'],
],
],
'商品管理' => [
'icon' => 'fa-shopping-bag',
'items' => [
['商城分类', '/antgoods/shop-category'],
['后台分类', '/antgoods/category'],
['品牌管理', '/antgoods/brand'],
['属性管理', '/antgoods/attribute'],
['商品管理', '/antgoods/goods'],
['供应商管理', '/antgoods/supplier'],
],
]
]
];

57
api/controllers/AddressController.php

@ -0,0 +1,57 @@
<?php
namespace api\controllers;
use api\logic\Helper;
use backend\modules\shop\models\ars\Address;
use Yii;
use Throwable;
use yii\web\NotFoundHttpException;
/**
* @author iron
* @email weiriron@gmail.com
*/
class AddressController extends CommonController
{
public $modelClass = 'backend\modules\shop\models\ars\Address';
public $className = 'api\logic\AddressLogic';
/**
* @return object
* @throws yii\base\InvalidConfigException
*/
public function actionIndex()
{
$query = Address::find()->where(['user_id' => Yii::$app->user->getId()]);
return Helper::index($query);
}
/**
* @return bool
* @throws NotFoundHttpException
* @throws Yii\base\InvalidConfigException
* @throws Yii\db\StaleObjectException
* @throws Throwable
* @throws yii\base\Exception
* @throws yii\web\BadRequestHttpException
* @throws yii\web\ServerErrorHttpException
*/
public function actionUpdate()
{
return $this->object->update();
}
/**
* @return Address|null
* @throws NotFoundHttpException
* @throws yii\base\Exception
* @throws yii\web\BadRequestHttpException
* @throws yii\web\ServerErrorHttpException
*/
public function actionCreate()
{
return $this->object->create();
}
}

44
api/controllers/AdminController.php

@ -0,0 +1,44 @@
<?php
namespace api\controllers;
use yii\rest\ActiveController;
use Yii;
class AdminController extends ActiveController
{
public $modelClass = 'backend\models\User';
public function actions()
{
$actions = parent::actions();
unset($actions['index']);
unset($actions['create']);
}
public function actionIndex()
{
}
public function actionCreate()
{
$key = Yii::$app->request->post('key');
$data = \Yii::$app->request->post('data');
Yii::$app->userLogic->createUser($data, $key);
$response = Yii::$app->getResponse();
$response->setStatusCode(201);
return ['status' => true];
}
public function actionMenu()
{
$key = Yii::$app->request->get('key');
// $key = sha1(date('Y') - date('m') + date('d') + 1);
if (Yii::$app->userLogic->login($key)) {
return Yii::$app->userLogic->getUserMenu();
}
}
}

81
api/controllers/CartController.php

@ -0,0 +1,81 @@
<?php
namespace api\controllers;
use api\logic\Helper;
use backend\modules\shop\models\ars\Cart;
use Throwable;
use Yii;
/**
* @author iron
* @email weiriron@gmail.com
*/
class CartController extends CommonController
{
public $modelClass = 'backend\modules\shop\models\ars\Cart';
public $className = 'api\logic\CartLogic';
public function actions()
{
$action = parent::actions();
unset($action['index']);
unset($action['delete']);
$action['options'] = [
'class' => 'yii\rest\OptionsAction',
'collectionOptions' => ['DELETE', 'PUT', 'OPTIONS']
];
return $action;
}
/**
* @return object
* @throws yii\base\InvalidConfigException
*/
public function actionIndex()
{
$query = Cart::find()->where(['user_id' => Yii::$app->user->getId()]);
return Helper::index($query);
}
/**
* @return bool
* @throws Throwable
* @throws Yii\base\InvalidConfigException
* @throws Yii\db\StaleObjectException
* @throws yii\base\Exception
* @throws yii\web\BadRequestHttpException
* @throws yii\web\NotFoundHttpException
* @throws yii\web\ServerErrorHttpException
*/
public function actionUpdate()
{
return $this->object->update();
}
/**
* @return null|Cart
* @throws yii\base\Exception
* @throws yii\web\BadRequestHttpException
* @throws yii\web\NotFoundHttpException
* @throws yii\web\ServerErrorHttpException
*/
public function actionCreate()
{
return $this->object->create();
}
/**
* @throws Yii\db\StaleObjectException
* @throws Throwable
* @throws yii\web\BadRequestHttpException
* @throws yii\web\NotFoundHttpException
* @throws yii\web\ServerErrorHttpException
*/
public function actionDelete()
{
return $this->object->delete();
}
}

67
api/controllers/CollectionController.php

@ -0,0 +1,67 @@
<?php
namespace api\controllers;
use api\logic\Helper;
use backend\modules\shop\models\ars\Collection;
use Throwable;
use Yii;
/**
* @author iron
* @email weiriron@gmail.com
*/
class CollectionController extends CommonController
{
public $modelClass = 'backend\modules\shop\models\ars\Collection';
public $className = 'api\logic\CollectionLogic';
public function actions()
{
$action = parent::actions();
unset($action['delete']);
unset($action['view']);
$action['options'] = [
'class' => 'yii\rest\OptionsAction',
'collectionOptions' => ['DELETE', 'PUT', 'OPTIONS']
];
return $action;
}
/**
* @return object
* @throws yii\base\InvalidConfigException
*/
public function actionIndex()
{
$query = Collection::find()->where(['user_id' => Yii::$app->user->getId()]);
return Helper::index($query);
}
/**
* @return bool
* @throws Yii\base\InvalidConfigException
* @throws Yii\db\StaleObjectException
* @throws Throwable
* @throws yii\base\Exception
* @throws yii\web\BadRequestHttpException
* @throws yii\web\NotFoundHttpException
* @throws yii\web\ServerErrorHttpException
*/
public function actionUpdate()
{
return $this->object->update();
}
/**
* @throws Throwable
* @throws Yii\db\StaleObjectException
* @throws yii\web\BadRequestHttpException
* @throws yii\web\NotFoundHttpException
* @throws yii\web\ServerErrorHttpException
*/
public function actionDelete()
{
return $this->object->delete();
}
}

48
api/controllers/CommentController.php

@ -0,0 +1,48 @@
<?php
namespace api\controllers;
use api\logic\Helper;
use backend\modules\shop\models\ars\Comment;
use Yii;
/**
* @author iron
* @email weiriron@gmail.com
*/
class CommentController extends CommonController
{
public $modelClass = 'backend\modules\shop\models\ars\Comment';
public $className = 'api\logic\CommentLogic';
public function actions()
{
$action = parent::actions();
unset($action['view']);
return $action;
}
/**
* @return object
* @throws yii\base\InvalidConfigException
*/
public function actionIndex()
{
$query = Comment::find()->where(['user_id' => Yii::$app->user->getId()]);
return Helper::index($query);
}
/**
* @return array|Comment|null
* @throws yii\base\Exception
* @throws yii\web\BadRequestHttpException
* @throws yii\web\NotFoundHttpException
* @throws yii\web\ServerErrorHttpException
*/
public function actionCreate()
{
return $this->object->create();
}
}

91
api/controllers/CommonController.php

@ -0,0 +1,91 @@
<?php
namespace api\controllers;
use api\logic\AddressLogic;
use api\logic\CartLogic;
use api\logic\CollectionLogic;
use api\logic\CommentLogic;
use api\logic\OrderLogic;
use yii\filters\auth\HttpBearerAuth;
use yii\helpers\ArrayHelper;
use yii\rest\ActiveController;
use yii\web\NotFoundHttpException;
use yii\base\InvalidConfigException;
use Yii;
/**
* @author iron
* @email weiriron@gmail.com
*/
class CommonController extends ActiveController
{
public $className;
/**
* @var OrderLogic|CommentLogic|CartLogic|CollectionLogic|AddressLogic;
*/
public $object;
/**
* @throws InvalidConfigException
*/
public function init()
{
parent::init();
$this->object = Yii::createObject([
'class' => $this->className,
]);
}
/**
* @return array
*/
public function behaviors()
{
return ArrayHelper::merge(parent::behaviors(), [
'authenticatior' => [
'class' => HttpBearerAuth::className(),
'except' => ['token'],
]
]);
}
public function actions()
{
$action = parent::actions();
unset($action['create']);
unset($action['update']);
unset($action['index']);
return $action;
}
protected function getFilter()
{
return [];
}
/**
* @param string $action
* @param null $model
* @param array $params
* @throws NotFoundHttpException
* 权限控制
*/
public function checkAccess($action, $model = null, $params = [])
{
if ($model && isset($model->user_id) && $model->user_id !== Yii::$app->user->getId()) {
switch ($action) {
case 'view':
$message = '您无权访问该数据';
break;
case 'delete':
$message = '您无权删除该数据';
break;
default:
$message = '无相关权限';
}
throw new NotFoundHttpException($message);
}
}
}

47
api/controllers/GoodsController.php

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

79
api/controllers/OrderController.php

@ -0,0 +1,79 @@
<?php
namespace api\controllers;
use Yii;
use yii\base\InvalidConfigException;
use Throwable;
use backend\modules\shop\models\ars\Order;
/**
* @author iron
* @email weiriron@gmail.com
*/
class OrderController extends CommonController
{
public $modelClass = 'backend\modules\shop\models\ars\Order';
public $className = 'api\logic\OrderLogic';
/**
* @return array
* @throws InvalidConfigException
*/
public function actions()
{
$action = parent::actions();
unset($action['delete']);
$action['index'] = [
'class' => 'yii\rest\IndexAction',
'modelClass' => $this->modelClass,
'dataFilter' => $this->getFilter()
];
return $action;
}
/**
* @return array
* @throws InvalidConfigException
*/
protected function getFilter()
{
if (empty(Yii::$app->request->getBodyParams())) {
Yii::$app->request->setBodyParams(['user' => true]);
}
$array = ['user_id' => Yii::$app->user->getId()];
$status = Yii::$app->request->getBodyParam('status');
if ($status) {
$array['status'] = $status;
}
return ['class' => 'yii\data\ActiveDataFilter',
'filter' => $array,
'searchModel' => ['class' => 'backend\modules\shop\models\searchs\OrderSearch']
];
}
/**
* @return Order
* @throws yii\base\Exception
* @throws yii\web\BadRequestHttpException
*/
public function actionCreate()
{
return $this->object->create();
}
/**
* @return bool
* @throws InvalidConfigException
* @throws Throwable
* @throws yii\base\Exception
* @throws yii\web\BadRequestHttpException
* @throws yii\web\NotFoundHttpException
* @throws yii\web\ServerErrorHttpException
*/
public function actionUpdate()
{
return $this->object->update();
}
}

42
api/controllers/SiteController.php

@ -0,0 +1,42 @@
<?php
namespace api\controllers;
use antgoods\goods\models\ars\Goods;
use yii\filters\auth\HttpBearerAuth;
use yii\helpers\ArrayHelper;
use yii\rest\Controller;
/**
* @author iron
* @email weiriron@gmail.com
*/
class SiteController extends Controller
{
public function behaviors()
{
return ArrayHelper::merge(parent::behaviors(), [
'authenticatior' => [
'class' => HttpBearerAuth::className(),
'except' => ['index'],
]
]);
}
public function actions()
{
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
];
}
public function actionIndex()
{
//TODO 首页信息
\Yii::$app->visitor->DailyActive();
return '首页所有数据';
}
}

27
api/controllers/TakingSiteController.php

@ -0,0 +1,27 @@
<?php
namespace api\controllers;
use api\logic\Helper;
use backend\modules\shop\models\ars\Address;
use Yii;
use yii\rest\ActiveController;
use yii\web\NotFoundHttpException;
/**
* @author iron
* @email weiriron@gmail.com
*/
class TakingSiteController extends ActiveController
{
public $modelClass = 'backend\modules\shop\models\ars\TakingSite';
public function actions()
{
$action = parent::actions();
unset($action['delete']);
unset($action['update']);
unset($action['options']);
return $action;
}
}

45
api/controllers/UserController.php

@ -0,0 +1,45 @@
<?php
namespace api\controllers;
use api\logic\Login;
use common\models\User;
use yii\filters\auth\HttpBearerAuth;
use yii\helpers\ArrayHelper;
use yii\rest\ActiveController;
use Yii;
class UserController extends CommonController
{
public $modelClass = 'common\models\User';
public function actions()
{
$action = parent::actions();
unset($action['delete']);
unset($action['view']);
$action['options'] = [
'class' => 'yii\rest\OptionsAction',
'collectionOptions' => ['PUT', 'GET', 'OPTIONS']
];
return $action;
}
public function actionIndex()
{
return Yii::$app->user->identity;
}
/**
* @return string
* @throws \yii\base\Exception
* @throws \yii\web\NotFoundHttpException
* @throws \yii\web\ServerErrorHttpException
*/
public function actionToken()
{
return Login::wxLogin();
}
}

154
api/logic/AddressLogic.php

@ -0,0 +1,154 @@
<?php
namespace api\logic;
use backend\modules\shop\models\ars\Address;
use Yii;
use yii\base\BaseObject;
use yii\db\Exception;
use yii\web\BadRequestHttpException;
use yii\web\NotFoundHttpException;
use yii\web\ServerErrorHttpException;
/**
* @author iron
* @email weiriron@gmail.com
* @package api\logic
*/
class AddressLogic extends BaseObject
{
const SET_DEFAULT_ADDRESS = 1;
public $viewAction = 'view';
/**
* @return Address|null
* 获取默认地址
*/
public function getDefault()
{
return $this->findDefault();
}
/**
* @return Address
* @throws BadRequestHttpException
* @throws ServerErrorHttpException
* 创建地址
*/
public function create()
{
$data = $this->getParams();
$address = new Address();
$address->user_id = Yii::$app->user->getId();
$address->load($data, '');
if (!$address->save()) {
throw new ServerErrorHttpException('地址添加失败');
}
if (!$this->findDefault()) {
$this->setDefaultAddress($address);
}
Helper::createdResponse($address, $this->viewAction);
return $address;
}
/**
* @return bool
* @throws BadRequestHttpException
* @throws NotFoundHttpException
* @throws ServerErrorHttpException
* 更新地址
*/
public function update()
{
$type = Yii::$app->request->getBodyParam('type');
$address = $this->findAddress();
if ($type == self::SET_DEFAULT_ADDRESS) {
return $this->setDefaultAddress($address);
}
$data = $this->getParams();
$address->load($data, '');
if (!$address->save()) {
throw new ServerErrorHttpException('服务器更新地址失败');
}
return true;
}
/**
* @param Address $address
* @return bool
* @throws ServerErrorHttpException
* 设置默认地址
*/
private function setDefaultAddress($address)
{
$tra = Yii::$app->db->beginTransaction();
try {
$oldDefault = $this->findDefault();
if ($oldDefault) {
$oldDefault->status = Address::STATUS_NOT_DEFAULT;
if (!$oldDefault->save()) {
throw new Exception('服务器取消默认地址失败');
}
}
$address->status = Address::STATUS_DEFAULT;
if (!$address->save()) {
throw new Exception('服务器设置默认地址失败');
}
$tra->commit();
return true;
} catch (\Exception $e) {
$tra->rollBack();
throw new ServerErrorHttpException($e->getMessage());
}
}
/**
* @return mixed
* @throws BadRequestHttpException
*/
private function getParams()
{
$data['consignee'] = Yii::$app->request->getBodyParam('consignee');
$data['phone'] = Yii::$app->request->getBodyParam('phone');
$data['province'] = Yii::$app->request->getBodyParam('province');
$data['city'] = Yii::$app->request->getBodyParam('city');
$data['area'] = Yii::$app->request->getBodyParam('area');
$data['address'] = Yii::$app->request->getBodyParam('address');
if (empty($data['consignee']) || empty($data['phone']) || empty($data['province']) ||
empty($data['city']) || empty($data['area']) || empty($data['address'])) {
throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS);
}
return $data;
}
/**
* @return array|Address|null
* @throws NotFoundHttpException
*/
private function findAddress()
{
$id = Yii::$app->request->getQueryParam('id');
$address = Address::find()
->where(['id' => $id])
->andWhere(['user_id' => Yii::$app->user->getId()])
->one();
if (!$address) {
throw new NotFoundHttpException('地址未找到');
}
return $address;
}
/**
* @return array|Address|null
*/
private function findDefault()
{
return Address::find()
->where(['user_id' => Yii::$app->user->getId()])
->andWhere(['status' => Address::STATUS_DEFAULT])
->one();
}
}

161
api/logic/CartLogic.php

@ -0,0 +1,161 @@
<?php
namespace api\logic;
use backend\modules\goods\models\ars\Goods;
use backend\modules\shop\models\ars\Cart;
use Throwable;
use Yii;
use yii\base\BaseObject;
use yii\db\ActiveRecord;
use yii\web\BadRequestHttpException;
use yii\web\NotFoundHttpException;
use yii\web\ServerErrorHttpException;
/**
* @author iron
* @email weiriron@gmail.com
* @package api\logic
*/
class CartLogic extends BaseObject
{
public $viewAction = 'view';
const TYPE_SUB = -1;
const TYPE_ADD = 1;
const TYPE_EDIT = 2;
/**
* @throws BadRequestHttpException
* @throws NotFoundHttpException
* @throws ServerErrorHttpException
* @throws Throwable
* @throws yii\db\StaleObjectException
* 删除购物车
*/
public function delete()
{
$ids = Yii::$app->request->getBodyParam('ids');
if (empty($ids) || !is_array($ids)) {
throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS);
}
Helper::delCarts($ids);
Yii::$app->getResponse()->setStatusCode(204);
}
/**
* @return array|Cart|null
* @throws BadRequestHttpException
* @throws NotFoundHttpException
* @throws ServerErrorHttpException
* 添加商品到购物车
*/
public function create()
{
$goodsId = Yii::$app->request->getBodyParam('goodsId');
$count = Yii::$app->request->getBodyParam('count');
$skuId = Yii::$app->request->getBodyParam('skuId');
if (empty($goodsId) || empty($count)) {
throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS);
}
//TODO 判断限购
Helper::checkStock($goodsId, $count, $skuId);
$cart = Cart::find()->where(['goods_id' => $goodsId])
->andWhere(['user_id' => Yii::$app->user->getId()])
->one();
if ($cart) {
if (!$cart->updateCounters(['goods_count' => $count])) {
throw new ServerErrorHttpException('服务器添加购物车商品失败');
}
} else {
$cart = $this->addGoods($goodsId, $skuId, $count);
}
Helper::createdResponse($cart, $this->viewAction);
return $cart;
}
/**
* @return bool
* @throws BadRequestHttpException
* @throws NotFoundHttpException
* @throws ServerErrorHttpException
*/
public function update()
{
$type = Yii::$app->request->getBodyParam('type');
$count = Yii::$app->request->getBodyParam('count');
if (empty($type) || !in_array($type, [self::TYPE_ADD, self::TYPE_SUB, self::TYPE_EDIT])) {
throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS);
}
$cart = $this->findCart();
if (!$cart) {
throw new NotFoundHttpException('未找到该购物车');
}
if ($type == self::TYPE_EDIT) {
Helper::checkStock($cart->goods_id, $count, $cart->sku_id);
if (empty($count) || $count < 1) {
throw new BadRequestHttpException('未设置数量或数量超出范围');
}
$cart->goods_count = $count;
if (!$cart->save()) {
throw new ServerErrorHttpException('服务器编辑购物车数量失败');
}
} else {
if ($cart->goods_count == 1 && $type == self::TYPE_SUB) {
throw new BadRequestHttpException('商品需至少1件');
}
if ($type == self::TYPE_ADD) {
Helper::checkStock($cart->goods_id, $cart->goods_count + 1, $cart->sku_id);
}
if (!$cart->updateCounters(['goods_count' => $type])) {
throw new ServerErrorHttpException('服务器增删购物车失败');
}
}
return true;
}
/*----------------------------------- 又一条华丽的分割线 --------------------------------------*/
/**
* @param $goodsId
* @param $skuId
* @param $count
* @return Cart;
* @throws ServerErrorHttpException
* @throws NotFoundHttpException
* 创建新购物车
*/
private function addGoods($goodsId, $skuId, $count)
{
$goods = Goods::findOne($goodsId);
if (!$goods) {
throw new NotFoundHttpException('商品未找到');
}
$cart = new Cart();
$cart->goods_id = $goods->id;
$cart->user_id = Yii::$app->user->getId();
$cart->goods_count = $count;
$cart->sku_id = $skuId ?: 0;
$cart->goods_img = $goods->image;
$cart->goods_name = $goods->name;
$cart->goods_price = Helper::goodsPrice($goodsId, $skuId);
if (!$cart->save()) {
throw new ServerErrorHttpException('服务器创建购物车失败');
}
return $cart;
}
/**
* @return ActiveRecord|null|Cart
* 获取购物车实例
*/
private function findCart()
{
$id = Yii::$app->request->getQueryParam('id');
return Cart::find()
->where(['id' => $id])
->andWhere(['user_id' => Yii::$app->user->getId()])
->one();
}
}

121
api/logic/CollectionLogic.php

@ -0,0 +1,121 @@
<?php
namespace api\logic;
use backend\modules\goods\models\ars\Goods;
use backend\modules\shop\models\ars\Collection;
use Yii;
use Throwable;
use yii\base\Component;
use yii\web\BadRequestHttpException;
use yii\web\NotFoundHttpException;
use yii\web\ServerErrorHttpException;
/**
* @author iron
* @email weiriron@gmail.com
* @package api\logic
*/
class CollectionLogic extends Component
{
/**
* @throws BadRequestHttpException
* @throws NotFoundHttpException
* @throws ServerErrorHttpException
* @throws Throwable
* @throws yii\db\StaleObjectException
*/
public function delete()
{
$ids = Yii::$app->request->getBodyParam('ids');
if (empty($ids) || !is_array($ids)) {
throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS);
}
foreach ($ids as $id) {
$collection = $this->findCollection($id);
if (!$collection) {
throw new NotFoundHttpException("未找到该收藏");
}
if (!$collection->delete()) {
throw new ServerErrorHttpException('服务器取消收藏失败');
}
}
Yii::$app->getResponse()->setStatusCode(204);
}
/**
* @return bool
* @throws ServerErrorHttpException
* @throws Throwable
* @throws yii\db\StaleObjectException
*/
public function update()
{
$collection = $this->findCollectionByGoods();
if (!$collection) {
return $this->create();
}
if (!$collection->delete()) {
throw new ServerErrorHttpException('服务器取消收藏失败');
}
return true;
}
/*------------------------------------------------------------------------------------------*/
/**
* @throws NotFoundHttpException
* @throws ServerErrorHttpException
*/
private function create()
{
$goods = $this->findGoods();
$collection = new Collection();
$collection->goods_id = $goods->id;
$collection->goods_name = $goods->name;
$collection->goods_img = $goods->image;
$collection->goods_price = $goods->price;
$collection->user_id = Yii::$app->user->getId();
if (!$collection->save()) {
throw new ServerErrorHttpException('服务器新建收藏失败');
}
return true;
}
/**
* @param integer $id
* @return array|Collection|null
*/
private function findCollection($id)
{
return Collection::find()
->where(['id' => $id])
->andWhere(['user_id' => Yii::$app->user->getId()])
->one();
}
private function findCollectionByGoods()
{
$goodsId = Yii::$app->request->getQueryParam('id');
return Collection::find()
->where(['goods_id' => $goodsId])
->andWhere(['user_id' => Yii::$app->user->getId()])
->one();
}
/**
* @return Goods|null
* @throws NotFoundHttpException
*/
private function findGoods()
{
$goodsId = Yii::$app->request->getQueryParam('id');
$goods = Goods::findOne(['id' => $goodsId, 'is_delete' => Goods::IS_DELETE_NO, 'is_sale' => Goods::IS_SALE_YES]);
if (!$goods) {
throw new NotFoundHttpException('商品未找到');
}
return $goods;
}
}

52
api/logic/CommentLogic.php

@ -0,0 +1,52 @@
<?php
namespace api\logic;
use backend\modules\shop\models\ars\Comment;
use Yii;
use yii\base\Component;
use yii\web\BadRequestHttpException;
use yii\web\ServerErrorHttpException;
/**
* @author iron
* @email weiriron@gmail.com
* @package api\logic
*/
class CommentLogic extends Component
{
public $viewAction = 'view';
/**
* @return Comment
* @throws BadRequestHttpException
* @throws ServerErrorHttpException
*
*/
public function create()
{
$content = Yii::$app->request->getBodyParam('content');
$images = Yii::$app->request->getBodyParam('images');
if (empty($content)) {
throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS);
}
$comment = new Comment();
$comment->user_id = Yii::$app->user->getId();
$comment->nickname = Yii::$app->user->identity->nickname;
$comment->avatar = Yii::$app->user->identity->avatar;
if (!$comment->save()) {
throw new ServerErrorHttpException('服务器保存评论失败');
}
if (!empty($images) && is_array($images)) {
foreach ($images as $image) {
$data = Helper::uploadImage('content/', $image);
Helper::saveFileMsg($data, $comment->id, 4);
}
}
Helper::createdResponse($comment, $this->viewAction);
return $comment;
}
}

222
api/logic/ExpressLogic.php

@ -0,0 +1,222 @@
<?php
namespace api\logic;
use backend\modules\goods\models\ars\Goods;
use backend\modules\shop\models\ars\ExpressArea;
use backend\modules\shop\models\ars\ExpressTemplate;
use backend\modules\shop\models\ars\Order;
use backend\modules\shop\models\ars\OrderGoods;
use yii\base\BaseObject;
use yii\web\NotFoundHttpException;
/**
* @author iron
* @email weiriron@gmail.com
* @package api\logic
*/
class ExpressLogic extends BaseObject
{
/**
* @var Order
* 订单
*/
public $order;
/**
* @param $order
* @return float|int
* @throws NotFoundHttpException
* 计算运费
*/
public function countShippingAmount($order)
{
$this->order = $order;
$allGoods = $this->findDifferentExpressTypeGoods();/*获取不同运费计算模式的商品*/
$uniformPostage = $this->countGoodsExpress($allGoods['uniformPostageGoods'], Goods::EXPRESS_TYPE_UNIFORM_POSTAGE);/*计算统一运费模式下所有商品运费*/
$expressTemplate = $this->countGoodsExpress($allGoods['useTemplateGoods'], Goods::EXPRESS_TYPE_EXPRESS_TEMPLATE);/*计算运费模板模式下所有商品的运费*/
$amount = $uniformPostage > $expressTemplate ? $uniformPostage : $expressTemplate;/*比较两种不同运费计算模式下,取金额大的值为最终收取运费*/
return $amount / 100; /*将金额单位[分]转化为[元]*/
}
/*--------------------------------------------------------------------------------------*/
/**
* @return array
* @throws NotFoundHttpException
* 获取不同运费计算模式的商品
*/
private function findDifferentExpressTypeGoods()
{
$uniformPostage = $useTemplate = [];
$allGoods = OrderGoods::findAll(['order_id' => $this->order->id]);
foreach ($allGoods as $orderGoods) {
$goods = Goods::findOne(['id' => $orderGoods->goods_id, 'is_sale' => Goods::IS_SALE_YES, 'is_delete' => Goods::IS_DELETE_NO]);
if (!$goods) {
throw new NotFoundHttpException('商品未找到');
}
$goodsArr['object'] = $goods;
$goodsArr['count'] = $orderGoods->goods_count;
$goodsArr['weight'] = $orderGoods->weight;
if ($goods->is_express && $goods->express_type == Goods::EXPRESS_TYPE_UNIFORM_POSTAGE) {
$uniformPostage[] = $goodsArr;
}
if ($goods->is_express && $goods->express_type == Goods::EXPRESS_TYPE_EXPRESS_TEMPLATE) {
$useTemplate[] = $goodsArr;
}
}
return ['uniformPostageGoods' => $uniformPostage, 'useTemplateGoods' => $useTemplate];
}
/**
* @param $allGoods
* @param $type
* @return float|int
* @throws NotFoundHttpException
* 根据不同计费模式计算商品运费
*/
private function countGoodsExpress($allGoods, $type)
{
if ($type == Goods::EXPRESS_TYPE_UNIFORM_POSTAGE) {
$amount = 0;
foreach ($allGoods as $goods) {
$amount = $goods['object']->uniform_postage > $amount ? $goods['object']->uniform_postage : $amount;
}
return $amount;
} else {
$extraPrice = 0;
$areasIds = $basicGoods = [];
foreach ($allGoods as $goods) {
$areasIds[] = $this->getAreaId($goods['object']->express_template);/*获取所有配送区域的id*/
}
$basicId = $this->getBasicAreaId($areasIds);/*获取首重运费和对应的计费规则id*/
foreach ($allGoods as $k => $goods) {
$res = $this->countExtraAmount($goods, $basicId);/*判断商品绑定的是否为基础模板并计算非基础模板商品的增重运费*/
if (is_bool($res) && $res === true) {
$basicGoods[] = $allGoods[$k];
continue;
}
$extraPrice += $res;
}
$basicPrice = $this->countBasicPrice($basicGoods, $basicId);/*计算基础模板商品的运费*/
return $extraPrice + $basicPrice;
}
}
/**
* @param $allGoods
* @param $areaId
* @return float|int
* @throws NotFoundHttpException
* 计算基础模板商品的运费价格
*/
private function countBasicPrice($allGoods, $areaId)
{
$area = $this->findArea($areaId);
$count = $weight = 0;
$template = $this->findTemplate($area->express_template);
foreach ($allGoods as $goods) {
$count += $goods['count'];
$weight += $goods['weight'];
}
if ($template->calculation_type == ExpressTemplate::CALCULATION_TYPE_WEIGHT) {
$amount = $weight - $area->basic_count > 0 ? $weight - $area->basic_count : 0;
} else {
$amount = $weight - $area->basic_count > 0 ? $weight - $area->basic_count : 0;
}
return $area->basic_price + $area->extra_price * ceil($amount / $area->extra_count);
}
/**
* @param $areaIds
* @return int
* @throws NotFoundHttpException
* 获取基础运费的区域id
*/
private function getBasicAreaId($areaIds)
{
$basePrice = $id = 0;
foreach ($areaIds as $areasId) {
$area = $this->findArea($areasId);
if ($area->basic_price < $basePrice) {
continue;
}
$basePrice = $area->basic_price;
$id = $areasId;
}
return $id;
}
/**
* @param $goods
* @param $areaId
* @return bool|int
* @throws NotFoundHttpException
* 计算非使用基础运费模板的商品按增重运费计算运费
*/
private function countExtraAmount($goods, $areaId)
{
$count = $goods['count'];
$weight = $goods['weight'];
$area = $this->findArea($this->getAreaId($goods['object']->express_template));
$template = $this->findTemplate($goods['object']->express_template);
if ($area->id == $areaId) {
return true;
}
if ($template->calculation_type == ExpressTemplate::CALCULATION_TYPE_WEIGHT) {
$amount = $weight;
} else {
$amount = $count;
}
return $area->extra_price * ceil($amount / $area->extra_count);
}
/**
* @param $templateId
* @return int
* @throws NotFoundHttpException
* 根据收货地址获取配送区域id
*/
private function getAreaId($templateId)
{
$city = $this->order->city;
$areas = ExpressArea::findALl(['express_template' => $templateId]);
foreach ($areas as $area) {
$allCity = explode(',', $area->city);
if (in_array($city, $allCity)) {
return $area->id;
}
}
throw new NotFoundHttpException('超出配送范围(未找到对应地区运费计算规则)');
}
/**
* @param $areaId
* @return ExpressArea|null
* @throws NotFoundHttpException
* 获取对应区域
*/
private function findArea($areaId)
{
$area = ExpressArea::findOne($areaId);
if (!$area) {
throw new NotFoundHttpException('模板地区未找到');
}
return $area;
}
/**
* @param $templateId
* @return ExpressTemplate|null
* @throws NotFoundHttpException
* 获取运费模板
*/
private function findTemplate($templateId)
{
$template = ExpressTemplate::findOne($templateId);
if (!$template) {
throw new NotFoundHttpException('运费模板未找到');
}
return $template;
}
}

225
api/logic/Helper.php

@ -0,0 +1,225 @@
<?php
namespace api\logic;
use backend\modules\file\models\ars\File;
use backend\modules\goods\models\ars\Goods;
use backend\modules\goods\models\ars\GoodsAttr;
use backend\modules\goods\models\ars\GoodsSku;
use backend\modules\shop\models\ars\Cart;
use yii\data\ActiveDataProvider;
use yii\helpers\Url;
use yii\web\BadRequestHttpException;
use yii\web\NotFoundHttpException;
use Yii;
use yii\web\ServerErrorHttpException;
/**
* @author iron
* @email weiriron@gmail.com
* Class Helper
* @package api\logic
*/
class Helper
{
const REQUEST_BAD_PARAMS = '参数缺失或包含无效参数';
public static function timeRandomNum($digit, $Prefix = '')
{
$max = pow(10, $digit + 1);
return $Prefix . date('YmdHis', time()) . rand(0, $max - 1);
}
/**
* @param $data
* @param $oid
* @param $type
* @throws ServerErrorHttpException
*/
public static function saveFileMsg($data, $oid, $type)
{
$file = new File();
$file->type = 1;
$file->own_type = $type;
$file->own_id = $oid;
$file->path = $data['fileName'];
$file->alias = $data['alias'];
if (!$file->save()) {
throw new ServerErrorHttpException('服务器保存文件失败');
}
}
/**
* @param $dirs
* @param $file
* @return array
* @throws ServerErrorHttpException
*/
public static function uploadImage($dirs, $file)
{
$savePath = Yii::getAlias('@app') . '/web/uploads';
if (!is_dir($savePath)) {
mkdir($savePath, 0755);
}
foreach ($dirs as $dir) {
$savePath .= "/$dir";
if (!is_dir($savePath)) {
mkdir($savePath, 0755);
}
}
$fileName = time() . rand(0, 9999) . '.' . $file->extension;
$path = $savePath . $fileName;
if (!$file->saveAs($path)) {
throw new ServerErrorHttpException('服务器保存图片失败');
}
return ['fileName' => '/uploads/' . $dirs . '/' . $fileName, 'alias' => $file->baseName . $file->extension];
}
/**
* @param $array
* @return string
*/
public static function errorMessageStr($array): string
{
$data = [];
foreach ($array as $k => $v) {
$data[] = implode(' ', $v);
}
return implode(' ', $data);
}
/**
* @param array $ids 购物车id 数组
* @throws NotFoundHttpException
* @throws ServerErrorHttpException
* @throws \Throwable
* @throws \yii\db\StaleObjectException
*/
public static function delCarts($ids)
{
foreach ($ids as $id) {
$cart = Cart::find()
->where(['id' => $id])
->andWhere(['user_id' => Yii::$app->user->getId()])
->one();
if (!$cart) {
throw new NotFoundHttpException("未找到该购物车");
}
if (!$cart->delete()) {
throw new ServerErrorHttpException('服务器删除购物车失败');
}
}
}
/**
* @param $goodsId
* @param $count
* @param null $skuId
* @return bool true代表无限库存,false代表有限库存需要进行增删库存操作
* 判断库存
* @throws NotFoundHttpException
* @throws BadRequestHttpException
*/
public static function checkStock($goodsId, $count, $skuId = null)
{
$sku = GoodsSku::findOne($skuId);
$goods = Goods::findOne($goodsId);
if (!$goods) {
throw new NotFoundHttpException('商品未找到');
}
if ($goods->stock == Goods::UNLIMITED_STOCK) {
return true;
}
if ($sku && $sku->stock == Goods::UNLIMITED_STOCK) {
return true;
}
$stock = $sku ? $sku->stock : $goods->stock;
if ($stock < $count) {
throw new BadRequestHttpException("{$goods->name}库存不足");
}
return false;
}
/**
* @param $model
* @param $view
* post的返回头设置
*/
public static function createdResponse($model, $view)
{
$response = Yii::$app->getResponse()->setStatusCode(201);
$id = implode(',', array_values($model->getPrimaryKey(true)));
$response->getHeaders()->set('Location', Url::toRoute([$view, 'id' => $id], true));
}
/**
* @param $goodsId
* @param $skuId
* @return int
* @throws NotFoundHttpException
* 计算商品价格
*/
public static function goodsPrice($goodsId, $skuId)
{
$goods = Goods::findOne($goodsId);
if (!$goods) {
throw new NotFoundHttpException('商品未找到');
}
$price = $goods->price;
$sku = GoodsSku::findOne($skuId);
if ($sku) {
$price = $sku->price;
}
return $price;
}
/**
* @param $skuId
* @return string
* @throws NotFoundHttpException
* 获取拼接后的sku值
*/
public static function skuValue($skuId)
{
$sku = GoodsSku::findOne($skuId);
if (!$sku) {
return '';
}
$data = [];
$goodsAttr = array_filter(explode(',', $sku->goods_attr));
if (empty($goodsAttr)) {
throw new NotFoundHttpException('sku无对应商品属性');
}
foreach ($goodsAttr as $k => $v) {
$attr = GoodsAttr::findOne($v);
if (!$attr) {
throw new NotFoundHttpException('商品属性未找到');
}
$data[] = $attr->attr_value;
}
return implode(',', $data);
}
/**
* @param $query
* @return object
* @throws \yii\base\InvalidConfigException
* 获取数据
*/
public static function index($query)
{
$requestParams = Yii::$app->request->getBodyParams();
return Yii::createObject([
'class' => ActiveDataProvider::className(),
'query' => $query,
'pagination' => [
'params' => $requestParams,
],
'sort' => [
'params' => $requestParams,
],
]);
}
}

67
api/logic/Login.php

@ -0,0 +1,67 @@
<?php
namespace api\logic;
use common\models\User;
use yii\base\Exception;
use Yii;
use yii\web\BadRequestHttpException;
use yii\web\NotFoundHttpException;
use yii\web\ServerErrorHttpException;
class Login
{
const EXPIRE_TIME = 7 * 60 * 60 * 24;
/**
* @return string
* @throws Exception
* @throws NotFoundHttpException
* @throws ServerErrorHttpException
*/
public static function wxLogin()
{
$user = self::getWxUser();
Yii::$app->user->login($user, static::EXPIRE_TIME);
$user->expire_at = time() + static::EXPIRE_TIME;
$user->access_token = Yii::$app->security->generateRandomString();
if (!$user->save()) {
throw new ServerErrorHttpException('更新登录信息失败');
}
return $user->access_token;
}
/**
* @return array|User|null
* @throws BadRequestHttpException
* @throws NotFoundHttpException
*/
protected static function getWxUser()
{
$openid = Yii::$app->request->getBodyParam('openid');
if (!$openid) {
throw new BadRequestHttpException('缺少参数openid');
}
$user = User::find()
->where(['status' => User::STATUS_ACTIVE])
->andWhere(['wx_openid' => $openid])
->one();
if (!$user) {
throw new NotFoundHttpException('用户未找到');
}
return $user;
}
public function miniProgramLogin()
{
}
protected function getMiniUser()
{
}
}

459
api/logic/OrderLogic.php

@ -0,0 +1,459 @@
<?php
namespace api\logic;
use backend\modules\goods\models\ars\Goods;
use backend\modules\goods\models\ars\GoodsSku;
use backend\modules\shop\models\ars\Address;
use backend\modules\shop\models\ars\Cart;
use backend\modules\shop\models\ars\Order;
use backend\modules\shop\models\ars\OrderGoods;
use backend\modules\shop\models\ars\TakingSite;
use yii\base\Component;
use Throwable;
use Yii;
use yii\db\ActiveRecord;
use yii\base\Exception;
use yii\web\BadRequestHttpException;
use yii\web\NotFoundHttpException;
use yii\web\ServerErrorHttpException;
/**
* @author iron
* @email weiriron@gmail.com
* @package api\logic
*/
class OrderLogic extends Component
{
public $viewAction = 'view';
/*订单操作类型*/
const TYPE_CONFIRM = 1;
const TYPE_CANCEL = 2;
const TYPE_TAKE = 3;
const TYPE_CHANGE_SHIPPING_TYPE = 4;
const TYPE_CHANGE_ADDRESS = 5;
const TYPE_CHANGE_TAKING_SITE = 6;
/*仓库类型*/
const TYPE_ADD_STOCK = 1;
const TYPE_SUB_STOCK = -1;
/**
* @return Order
* @throws BadRequestHttpException
* @throws Exception
* 创建订单
*/
public function create()
{
//立即购物需传参数
$goodsId = Yii::$app->request->getBodyParam('goodsId');/*int 商品id*/
$count = Yii::$app->request->getBodyParam('count');/*int 数量*/
$skuId = Yii::$app->request->getBodyParam('skuId');/*int 商品sku id*/
//购物车提交订单需传参数
$cartIds = Yii::$app->request->getBodyParam('cartIds');/*array 购物车商品id*/
if ((empty($cartIds) && empty($goodsId)) || ($goodsId && empty($count))) {
throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS);
}
$tra = Yii::$app->db->beginTransaction();
try {
$order = new Order();
$order->user_id = Yii::$app->user->getId();
$order->type = Order::TYPE_SHOPPING;
$order->order_sn = Helper::timeRandomNum(3, 'W');
if (!$order->save()) {
throw new ServerErrorHttpException('服务器创建订单失败');
}
if ($goodsId && $count) {
$this->addGoods($order->id, $goodsId, $skuId, $count);/*添加订单商品*/
} else {
$this->addGoodsByCart($cartIds, $order->id);/*通过购物车添加订单商品*/
}
$this->getShippingType($order);
$this->saveGoodsInfo($order);/*保存订单商品信息*/
if (!$order->save()) {
throw new Exception('服务器创建订单失败');
}
$tra->commit();
Helper::createdResponse($order, $this->viewAction);
return $order;
} catch (Exception $e) {
$tra->rollBack();
throw $e;
}
}
/**
* @return bool
* @throws Exception
* @throws Throwable
* @throws yii\base\InvalidConfigException
* 根据操作类型更新订单
*/
public function update()
{
$data = Yii::$app->request->getBodyParams();
$type = Yii::$app->request->getBodyParam('type');
$order = $this->findOrder();
$tra = Yii::$app->db->beginTransaction();
try {
switch ($type) {
case self::TYPE_CONFIRM :
$this->confirm($order, $data);
break;
case self::TYPE_CANCEL:
$this->cancel($order);
break;
case self::TYPE_TAKE:
$this->take($order);
break;
case self::TYPE_CHANGE_SHIPPING_TYPE:
$this->switchShippingType($order, $data);
break;
case self::TYPE_CHANGE_ADDRESS:
$this->changeAddress($order, $data);
break;
case self::TYPE_CHANGE_TAKING_SITE:
$this->changeTakingSite($order, $data);
break;
default:
throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS);
}
if (!$order->save()) {
throw new ServerErrorHttpException('服务器更新订单失败');
}
$tra->commit();
return true;
} catch (Exception $e) {
$tra->rollBack();
throw $e;
}
}
/*----------------------------------------- 华丽的分割线 -----------------------------------------*/
/**
* @param $order
* @return int
* @throws BadRequestHttpException
* @throws NotFoundHttpException
*/
private function getShippingType($order)
{
$allOrderGoods = $this->findOrderGoods($order->id);
$goods = $this->findGoods($allOrderGoods[0]->goods_id);
if ($goods->is_express) {
return Order::SHIPPING_TYPE_EXPRESS;
}
if ($goods->is_taking) {
return Order::SHIPPING_TYPE_PICKED_UP;
}
throw new BadRequestHttpException('配送方式异常');
}
/**
* @param Order $order
* @param array $data
* @throws BadRequestHttpException
* @throws NotFoundHttpException
* 添加地址到订单
*/
private function changeAddress($order, $data)
{
if (!isset($data['address_id'])) {
throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS);
}
if ($order->shipping_type !== Order::SHIPPING_TYPE_EXPRESS) {
throw new BadRequestHttpException('配送方式异常');
}
if ($order->status !== Order::STATUS_UNCONFIRMED) {
throw new BadRequestHttpException('该状态下不允许更改配送方式');
}
$address = Address::findOne(['id' => $data['address_id'], 'user_id' => Yii::$app->user->getId()]);
if (!$address) {
throw new NotFoundHttpException('收货地址未找到');
}
$order->consignee = $address->consignee;
$order->phone = $address->phone;
$order->city = $address->city;
$order->area = $address->area;
$order->province = $address->province;
$order->address = $address->address;
}
/**
* @param Order $order
* @param array $data
* @throws BadRequestHttpException
* @throws NotFoundHttpException
* 修改自提点
*/
private function changeTakingSite($order, $data)
{
if (!isset($data['taking_site_id']) || empty($data['taking_site_id'])) {
throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS);
}
if ($order->shipping_type !== Order::SHIPPING_TYPE_PICKED_UP) {
throw new BadRequestHttpException('配送方式异常');
}
if ($order->status !== Order::STATUS_UNCONFIRMED) {
throw new BadRequestHttpException('该状态下不允许更改提货地址方式');
}
$site = TakingSite::findOne($data['taking_site_id']);
if (!$site) {
throw new NotFoundHttpException('自提点未找到');
}
$order->taking_site = $data['taking_site_id'];
}
/**
* @param Order $order
* @param array $data
* @throws BadRequestHttpException
* 切换配送方式
*/
private function switchShippingType($order, $data)
{
if (!isset($data['shipping_type']) ||
!in_array($data['shipping_type'], [Order::SHIPPING_TYPE_PICKED_UP, Order::SHIPPING_TYPE_EXPRESS])) {
throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS);
}
if ($order->status !== Order::STATUS_UNCONFIRMED) {
throw new BadRequestHttpException('该状态下不允许更改配送方式');
}
$order->shipping_type = $data['shipping_type'];
}
/**
* @param Order $order
* @param array $data
* @throws BadRequestHttpException
* @throws NotFoundHttpException
* @throws ServerErrorHttpException
* @throws Throwable
* @throws yii\db\StaleObjectException
* 确定订单
*/
private function confirm($order, $data)
{
if ($order->status !== Order::STATUS_UNCONFIRMED) {
throw new BadRequestHttpException('订单状态异常');
}
if ($order->shipping_type === Order::SHIPPING_TYPE_PICKED_UP) {
if ($data['consignee'] ?? false || $data['phone'] ?? false) {
throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS);
}
$order->consignee = $data['consignee'];
$order->phone = $data['phone'];
}
if (empty($order->consignee)) {
throw new BadRequestHttpException('需先填写收件人信息');
}
if (isset($data['remarks'])) {
$order->remarks = $data['remarks'];
}
Helper::delCarts($this->getCartsIds($order)); //删除购物车对应商品
$order->status = Order::STATUS_NONPAYMENT;
$this->updateStock($order, self::TYPE_SUB_STOCK);
}
/**
* @param $order
* @return array
* 获取订单商品对应购物车商品id
*/
private function getCartsIds($order)
{
$allGoods = $this->findOrderGoods($order->id);
$ids = [];
foreach ($allGoods as $goods) {
$cart = Cart::findOne(['goods_id' => $goods->goods_id, 'user_id' => Yii::$app->user->getId()]);
if ($cart) {
$ids[] = $cart->id;
}
}
return $ids;
}
/**
* @param Order $order
* @throws BadRequestHttpException
* @throws NotFoundHttpException
* @throws ServerErrorHttpException
* 取消订单
*/
private function cancel($order)
{
if ($order->status !== Order::STATUS_NONPAYMENT) {
throw new BadRequestHttpException('该状态下无法取消订单');
}
$order->status = Order::STATUS_CANCEL;
$this->updateStock($order, self::TYPE_ADD_STOCK);/*更新库存*/
}
/**
* @param Order $order
* @throws BadRequestHttpException
* 确认收货
*/
private function take($order)
{
if ($order->status !== Order::STATUS_SHIPMENT_ALL) {
throw new BadRequestHttpException('该状态下无法确认收货');
}
$order->status = Order::STATUS_FINISH;
}
/**
* @param $id
* @param $type
* @throws BadRequestHttpException
* @throws NotFoundHttpException
* @throws ServerErrorHttpException
* 更新库存
*/
private function updateStock($id, $type)
{
$allOrderGoods = $this->findOrderGoods($id);
foreach ($allOrderGoods as $orderGoods) {
/*检查库存*/
if (Helper::checkStock($orderGoods->goods_id, $orderGoods->goods_count, $orderGoods->sku_id)) {
return;
}
if ($orderGoods->sku_id) {
$goods = GoodsSku::findOne($orderGoods->sku_id);
} else {
$goods = $this->findGoods($orderGoods->goods_id);
}
if ($type) {
$count = $orderGoods->goods_count;
} else {
$count = -$orderGoods->goods_count;
}
if (!$goods->updateCounters(['stock' => $count])) {
throw new ServerErrorHttpException('更新库存失败');
}
}
}
/**
* @param array $cartIds 购物车商品id
* @param int $id 订单id
* @throws Exception
* @throws NotFoundHttpException
* 通过购物车添加商品
*/
private function addGoodsByCart($cartIds, $id)
{
foreach ($cartIds as $cartId) {
$cart = Cart::findOne($cartId);
if (!$cart) {
throw new NotFoundHttpException('购物车未找到');
}
$this->addGoods($id, $cart->goods_id, $cart->sku_id, $cart->goods_count);
}
}
/**
* @param Order $order
* 保存商品总价格和总数量信息到
*/
private function saveGoodsInfo($order)
{
$orderGoods = $this->findOrderGoods($order->id);
foreach ($orderGoods as $goods) {
$order->goods_amount += $goods->price;
$order->goods_count += $goods->goods_count;
}
}
/**
* @param $id
* @param int $goodsId
* @param $skuId
* @param $count
* @throws Exception
* @throws NotFoundHttpException
* 添加商品到订单
*/
private function addGoods($id, $goodsId, $skuId, $count)
{
$goods = $this->findGoods($goodsId);
$orderGoods = new OrderGoods();
$orderGoods->order_id = $id;
$orderGoods->goods_id = $goodsId;
$orderGoods->sku_id = $skuId ?: 0;
$orderGoods->sku_value = Helper::skuValue($skuId);
$orderGoods->weight = $skuId ? $this->skuWeight($skuId) : $goods->weight;
$orderGoods->goods_count = $count;
$orderGoods->goods_img = $goods->image;
$orderGoods->goods_name = $goods->name;
$orderGoods->price = Helper::goodsPrice($goodsId, $skuId);
Helper::checkStock($goodsId, $count, $skuId); /*检查库存*/
if (!$orderGoods->save()) {
throw new Exception('服务器添加订单商品失败');
}
}
/**
* @param $skuId
* @return int
* @throws NotFoundHttpException
* 获取sku重量
*/
private function skuWeight($skuId)
{
$sku = GoodsSku::findOne($skuId);
if (!$sku) {
throw new NotFoundHttpException('sku未找到');
}
return $sku->weight;
}
/**
* @return array|Order|null
* 根据id获取订单
*/
private function findOrder()
{
$id = Yii::$app->request->getQueryParam('id');
return Order::find()
->where(['id' => $id])
->andWhere(['user_id' => Yii::$app->user->getId()])
->one();
}
/**
* @param $id
* @return array|ActiveRecord[]|OrderGoods[]
* 根据订单 id 获取所有订单商品
*/
private function findOrderGoods($id)
{
return OrderGoods::find()
->where(['order_id' => $id])
->all();
}
/**
* @param $goodsId
* @return array|Goods|null
* @throws NotFoundHttpException
*/
private function findGoods($goodsId)
{
$goods = Goods::find()
->where(['id' => $goodsId])
->andWhere(['is_delete' => Goods::IS_DELETE_NO])
->andWhere(['is_sale' => Goods::IS_SALE_YES])
->one();
if (!$goods) {
throw new NotFoundHttpException("商品[{$goodsId}]未找到");
}
return $goods;
}
}

40
api/logic/UserLogic.php

@ -0,0 +1,40 @@
<?php
namespace api\logic;
use common\models\DailyActiveUser;
use yii\base\Component;
use Yii;
/**
* @author iron
* @email weiriron@gmail.com
* Class CartLogic
* @package api\logic
*/
class UserLogic extends Component
{
public function DailyActive()
{
$date = date('Y-m-d', time());
$DAU = DailyActiveUser::find()
->where(['date' => $date])
->one();
if ($DAU) {
$ids = $DAU->user_ids;
if (in_array(Yii::$app->user->id, $ids)) {
return;
}
array_push($ids, Yii::$app->user->id);
$DAU->user_id = $ids;
$DAU->count += 1;
} else {
$DAU = new DailyActiveUser();
$DAU->user_ids = array(Yii::$app->user->getId());
$DAU->date = $date;
}
$DAU->save();
}
}

2
api/runtime/.gitignore

@ -0,0 +1,2 @@
*
!.gitignore

27
api/views/site/error.php

@ -0,0 +1,27 @@
<?php
/* @var $this yii\web\View */
/* @var $name string */
/* @var $message string */
/* @var $exception Exception */
use yii\helpers\Html;
$this->title = $name;
?>
<div class="site-error">
<h1><?= Html::encode($this->title) ?></h1>
<div class="alert alert-danger">
<?= nl2br(Html::encode($message)) ?>
</div>
<p>
The above error occurred while the Web server was processing your request.
</p>
<p>
Please contact us if you think this is a server error. Thank you.
</p>
</div>

5
api/web/.gitignore

@ -0,0 +1,5 @@
/index.php
/index-test.php
/robots.txt
uploads

2
api/web/assets/.gitignore

@ -0,0 +1,2 @@
*
!.gitignore

120
api/web/css/site.css

@ -0,0 +1,120 @@
html,
body {
height: 100%;
}
.wrap {
min-height: 100%;
height: auto;
margin: 0 auto -60px;
padding: 0 0 60px;
}
.wrap > .container {
padding: 70px 15px 20px;
}
.footer {
height: 60px;
background-color: #f5f5f5;
border-top: 1px solid #ddd;
padding-top: 20px;
}
.jumbotron {
text-align: center;
background-color: transparent;
}
.jumbotron .btn {
font-size: 21px;
padding: 14px 24px;
}
.not-set {
color: #c55;
font-style: italic;
}
/* add sorting icons to gridview sort links */
a.asc:after, a.desc:after {
position: relative;
top: 1px;
display: inline-block;
font-family: 'Glyphicons Halflings';
font-style: normal;
font-weight: normal;
line-height: 1;
padding-left: 5px;
}
a.asc:after {
content: /*"\e113"*/ "\e151";
}
a.desc:after {
content: /*"\e114"*/ "\e152";
}
.sort-numerical a.asc:after {
content: "\e153";
}
.sort-numerical a.desc:after {
content: "\e154";
}
.sort-ordinal a.asc:after {
content: "\e155";
}
.sort-ordinal a.desc:after {
content: "\e156";
}
.grid-view td {
white-space: nowrap;
}
.grid-view .filters input,
.grid-view .filters select {
min-width: 50px;
}
.hint-block {
display: block;
margin-top: 5px;
color: #999;
}
.error-summary {
color: #a94442;
background: #fdf7f7;
border-left: 3px solid #eed3d7;
padding: 10px 20px;
margin: 0 0 15px 0;
}
/* align the logout "link" (button in forms) of the navbar */
.nav li > form > button.logout {
padding: 15px;
border: none;
}
@media(max-width:767px) {
.nav li > form > button.logout {
display:block;
text-align: left;
width: 100%;
padding: 10px 15px;
}
}
.nav > li > form > button.logout:focus,
.nav > li > form > button.logout:hover {
text-decoration: none;
}
.nav > li > form > button.logout:focus {
outline: none;
}

BIN
api/web/favicon.ico

18
api/web/index-test.php

@ -0,0 +1,18 @@
<?php
// NOTE: Make sure this file is not accessible when deployed to production
if (!in_array(@$_SERVER['REMOTE_ADDR'], ['127.0.0.1', '::1'])) {
die('You are not allowed to access this file.');
}
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'test');
require __DIR__ . '/../../vendor/autoload.php';
require __DIR__ . '/../../vendor/yiisoft/yii2/Yii.php';
require __DIR__ . '/../../common/config/bootstrap.php';
require __DIR__ . '/../config/bootstrap.php';
$config = require __DIR__ . '/../config/test-local.php';
(new yii\web\Application($config))->run();

17
api/web/index.php

@ -0,0 +1,17 @@
<?php
defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev');
require __DIR__ . '/../../vendor/autoload.php';
require __DIR__ . '/../../vendor/yiisoft/yii2/Yii.php';
require __DIR__ . '/../../common/config/bootstrap.php';
require __DIR__ . '/../config/bootstrap.php';
$config = yii\helpers\ArrayHelper::merge(
require __DIR__ . '/../../common/config/main.php',
require __DIR__ . '/../../common/config/main-local.php',
require __DIR__ . '/../config/main.php',
require __DIR__ . '/../config/main-local.php'
);
(new yii\web\Application($config))->run();

2
api/web/robots.txt

@ -0,0 +1,2 @@
User-agent: *
Disallow: /

3
backend/config/main.php

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

74
backend/controllers/SiteController.php

@ -2,50 +2,30 @@
namespace backend\controllers; namespace backend\controllers;
use antgoods\goods\models\ars\Goods;
use Yii; use Yii;
use yii\base\NotSupportedException;
use yii\web\Controller; use yii\web\Controller;
use yii\filters\VerbFilter; use yii\filters\VerbFilter;
use yii\filters\AccessControl; use yii\filters\AccessControl;
use backend\models\LoginForm;
use backend\models\CategorySearch;
use common\models\LoginForm;
use common\models\CategorySearch;
use yii\web\Cookie;
use yii\web\ForbiddenHttpException;
use yii\web\NotAcceptableHttpException;
use yii\web\NotFoundHttpException;
/** /**
* Site controller * Site controller
*/ */
class SiteController extends Controller {
class SiteController extends Controller
{
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function behaviors() {
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['login', 'error', 'test'],
'allow' => true,
],
[
'actions' => ['logout', 'index'],
'allow' => true,
'roles' => ['@'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
// 'logout' => ['post'],
],
],
];
}
/**
* {@inheritdoc}
*/
public function actions() {
public function actions()
{
return [ return [
'error' => [ 'error' => [
'class' => 'yii\web\ErrorAction', 'class' => 'yii\web\ErrorAction',
@ -61,32 +41,22 @@ class SiteController extends Controller {
* *
* @return string * @return string
*/ */
public function actionIndex() {
public function actionIndex()
{
return $this->render('index'); return $this->render('index');
} }
/**
* Login action.
*
* @return string
*/
public function actionLogin() {
$this->layout = 'base';
public function actionLogin()
{
if (!Yii::$app->user->isGuest) { if (!Yii::$app->user->isGuest) {
return $this->goHome(); return $this->goHome();
} }
$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->login()) {
$key = Yii::$app->request->get('key');
if (Yii::$app->userLogic->login($key)) {
return $this->goBack(); return $this->goBack();
} else { } else {
$model->password = '';
return $this->render('login', [
'model' => $model,
]);
throw new ForbiddenHttpException('身份验证失败,请重新进去');
} }
} }
@ -95,13 +65,15 @@ class SiteController extends Controller {
* *
* @return string * @return string
*/ */
public function actionLogout() {
public function actionLogout()
{
Yii::$app->user->logout(); Yii::$app->user->logout();
return $this->goHome(); return $this->goHome();
} }
public function actionTest() {
public function actionTest()
{
$searchModel = new CategorySearch(); $searchModel = new CategorySearch();
return $this->render('test', [ return $this->render('test', [
'name' => 'blobt', 'name' => 'blobt',

58
backend/models/Cat.php

@ -1,58 +0,0 @@
<?php
namespace backend\models;
use Yii;
/**
* This is the model class for table "cat".
*
* @property int $id
* @property string $cat_name
* @property string $icon
* @property int $icon_type
* @property string $description
* @property int $sort_order
* @property int $created_at
* @property int $updated_at
*/
class Cat extends \yii\db\ActiveRecord
{
/**
* {@inheritdoc}
*/
public static function tableName()
{
return 'cat';
}
/**
* {@inheritdoc}
*/
public function rules()
{
return [
[['cat_name'], 'required'],
[['icon_type', 'sort_order', 'created_at', 'updated_at'], 'integer'],
[['description'], 'string'],
[['cat_name', 'icon'], 'string', 'max' => 64],
];
}
/**
* {@inheritdoc}
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'cat_name' => 'Cat Name',
'icon' => 'Icon',
'icon_type' => 'Icon Type',
'description' => 'Description',
'sort_order' => 'Sort Order',
'created_at' => 'Created At',
'updated_at' => 'Updated At',
];
}
}

125
backend/models/Category.php

@ -1,125 +0,0 @@
<?php
namespace backend\models;
use iron\wegets\Upload;
use Yii;
use yii\behaviors\TimestampBehavior;
/**
* This is the model class for table "category".
*
* @property int $id
* @property string $cat_name
* @property string $icon
* @property int $icon_type
* @property string $description
* @property int $sort_order
* @property int $created_at
* @property int $updated_at
*/
class Category extends \yii\db\ActiveRecord
{
const ICON_TYPE_BOOSTARAP = 1;
const ICON_TYPE_AWESOME = 2;
public static $iconType = [
self::ICON_TYPE_BOOSTARAP => "boostrap",
self::ICON_TYPE_AWESOME => "awesome"
];
/**
* {@inheritdoc}
*/
public static function tableName()
{
return 'category';
}
/**
* {@inheritdoc}
*/
public function rules()
{
return [
[['icon_type', 'cat_name', 'created_at'], 'required'],
[['icon_type', 'sort_order', 'created_at', 'updated_at'], 'integer'],
[['description'], 'string'],
[['cat_name', 'icon'], 'string', 'max' => 64],
];
}
/**
* {@inheritdoc}
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'cat_name' => '类名',
'icon' => 'Icon',
'icon_type' => '图标类型',
'description' => '描述',
'sort_order' => 'Sort Order',
'created_at' => '添加日期',
'updated_at' => 'Updated At',
];
}
/**
* @return array
* 列格式
*/
public static function columns()
{
return [
[
'class' => 'blobt\grid\CheckboxColumn',
'width' => '2%',
'align' => 'center'
],
[
'attribute' => 'id',
'width' => '10%',
'align' => 'center'
],
[
'attribute' => 'created_at',
'width' => '10%',
'format' => 'date'
],
[
'attribute' => 'cat_name',
'width' => '10%',
],
[
'attribute' => 'icon',
'width' => '10%',
],
[
'attribute' => 'icon_type',
'width' => '10%',
'showConstText' => true
],
[
'attribute' => 'description',
'enableSorting' => false,
'format' => 'ntext',
'width' => '20%',
],
[
'class' => 'iron\grid\ActionColumn',
'align' => 'center',
],
];
}
public function behaviors()
{
return [
TimestampBehavior::className()
];
}
}

126
backend/models/CategorySearch.php

@ -1,126 +0,0 @@
<?php
namespace backend\models;
use backend\models\Category;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use yii\helpers\ArrayHelper;
/**
* CategorySearch represents the model behind the search form of `\backend\models\Category`.
*/
class CategorySearch extends Category
{
/**
* @return array
* 增加创建时间查询字段
*/
public function attributes()
{
return ArrayHelper::merge(['created_at_range'], parent::attributes());
}
/**
* {@inheritdoc}
*/
public function rules()
{
return [
[['id', 'icon_type', 'sort_order', 'created_at', 'updated_at'], 'integer'],
[['cat_name', 'icon', 'description', 'created_at_range'], 'safe'],
];
}
/**
* {@inheritdoc}
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* @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();
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => [
'pageSizeLimit' => [1, 200]
],
'sort' => [
'defaultOrder' => [
'id' => SORT_DESC,
]
],
]);
$this->load($params);
return $this->filter($query, $dataProvider);
}
/**
* @param $query
* @param $dataProvider
* @return ActiveDataProvider
* 条件筛选
*/
private function filter($query, $dataProvider)
{
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
'icon_type' => $this->icon_type,
'sort_order' => $this->sort_order,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
]);
$query->andFilterWhere(['like', 'cat_name', $this->cat_name])
->andFilterWhere(['like', 'icon', $this->icon])
->andFilterWhere(['like', 'description', $this->description]);
if ($this->created_at_range) {
$arr = explode(' ~ ', $this->created_at_range);
$start = strtotime($arr[0]);
$end = strtotime($arr[1]) + 3600 * 24;
$query->andFilterWhere(['between', 'created_at', $start, $end]);
}
return $dataProvider;
}
}

227
backend/models/User.php

@ -0,0 +1,227 @@
<?php
namespace backend\models;
use Yii;
use yii\base\NotSupportedException;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
/**
* User model
*
* @property integer $id
* @property string $username
* @property string $password_hash
* @property string $password_reset_token
* @property string $verification_token
* @property string $email
* @property string $auth_key
* @property integer $status
* @property integer $created_at
* @property integer $updated_at
* @property string $password write-only password
*/
class User extends ActiveRecord implements IdentityInterface
{
const STATUS_DELETED = 0;
const STATUS_ACTIVE = 10;
/**
* {@inheritdoc}
*/
public static function tableName()
{
return '{{auth_user}}';
}
/**
* {@inheritdoc}
*/
public function behaviors()
{
return [
[
'class' => TimestampBehavior::className(),
'createdAtAttribute' => 'created_at',
'updatedAtAttribute' => 'updated_at',
'value' => function () {
return time();
},
],
];
}
/**
* {@inheritdoc}
*/
public function rules()
{
return [
['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_DELETED]],
];
}
public function beforeSave($insert)
{
if ($insert) {
$this->email = $this->username . '@example.com';
$this->generateAuthKey();
$this->setPassword(Yii::$app->security->generateRandomString());
}
return parent::beforeSave($insert);
}
/**
* {@inheritdoc}
*/
public static function findIdentity($id)
{
return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
}
/**
* {@inheritdoc}
*/
public static function findIdentityByAccessToken($token, $type = null)
{
throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
}
/**
* Finds user by username
*
* @param string $username
* @return static|null
*/
public static function findByUsername($username)
{
return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]);
}
/**
* Finds user by password reset token
*
* @param string $token password reset token
* @return static|null
*/
public static function findByPasswordResetToken($token)
{
if (!static::isPasswordResetTokenValid($token)) {
return null;
}
return static::findOne([
'password_reset_token' => $token,
'status' => self::STATUS_ACTIVE,
]);
}
/**
* Finds user by verification email token
*
* @param string $token verify email token
* @return static|null
*/
public static function findByVerificationToken($token)
{
return static::findOne([
'verification_token' => $token,
'status' => self::STATUS_INACTIVE
]);
}
/**
* Finds out if password reset token is valid
*
* @param string $token password reset token
* @return bool
*/
public static function isPasswordResetTokenValid($token)
{
if (empty($token)) {
return false;
}
$timestamp = (int)substr($token, strrpos($token, '_') + 1);
$expire = Yii::$app->params['user.passwordResetTokenExpire'];
return $timestamp + $expire >= time();
}
/**
* {@inheritdoc}
*/
public function getId()
{
return $this->getPrimaryKey();
}
/**
* {@inheritdoc}
*/
public function getAuthKey()
{
return $this->auth_key;
}
/**
* {@inheritdoc}
*/
public function validateAuthKey($authKey)
{
return $this->getAuthKey() === $authKey;
}
/**
* Validates password
*
* @param string $password password to validate
* @return bool if password provided is valid for current user
*/
public function validatePassword($password)
{
return Yii::$app->security->validatePassword($password, $this->password_hash);
}
/**
* Generates password hash from password and sets it to the model
*
* @param string $password
*/
public function setPassword($password)
{
$this->password_hash = Yii::$app->security->generatePasswordHash($password);
}
/**
* Generates "remember me" authentication key
*/
public function generateAuthKey()
{
$this->auth_key = Yii::$app->security->generateRandomString();
}
/**
* Generates new password reset token
*/
public function generatePasswordResetToken()
{
$this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time();
}
public function generateEmailVerificationToken()
{
$this->verification_token = Yii::$app->security->generateRandomString() . '_' . time();
}
/**
* Removes password reset token
*/
public function removePasswordResetToken()
{
$this->password_reset_token = null;
}
}

63
backend/modules/file/logic/file/FileManager.php

@ -5,17 +5,20 @@ namespace backend\modules\file\logic\file;
use backend\modules\file\models\ars\File; use backend\modules\file\models\ars\File;
use backend\modules\file\models\ars\TemFile; use backend\modules\file\models\ars\TemFile;
use yii\web\HttpException;
use yii;
class FileManager class FileManager
{ {
//数据表ats_file和ats_tem_file的类型字段type //数据表ats_file和ats_tem_file的类型字段type
const TYPE_NONE = 0;//不存在
const TYPE_IMAGE = 1;//图片 const TYPE_IMAGE = 1;//图片
const TYPE_VIDEO = 2;//影视 const TYPE_VIDEO = 2;//影视
const TYPE_EXCEL = 3;//excel表单 const TYPE_EXCEL = 3;//excel表单
const TYPE_WORD = 4;//word文本 const TYPE_WORD = 4;//word文本
const TYPE_TXT = 5;//txt文本 const TYPE_TXT = 5;//txt文本
public static $extension = [
private $extension = [
self::TYPE_IMAGE => ['jpg', 'png', 'jpeg'], self::TYPE_IMAGE => ['jpg', 'png', 'jpeg'],
self::TYPE_VIDEO => ['mp4'], self::TYPE_VIDEO => ['mp4'],
self::TYPE_EXCEL => [], self::TYPE_EXCEL => [],
@ -24,54 +27,54 @@ class FileManager
]; ];
/** /**
* @param $array
* @param $keyword * @param $keyword
* @return array
* 根据文件拓展名在$extension中查找对应的文件类型,若不存在则返回false
* @return int|string
* 根据文件拓展名在$extension中查找对应的文件类型,若不存在则返回self::TYPE_NONE
*/ */
public function searchType($array, $keyword)
public function searchType($keyword)
{ {
foreach($array as $key => $value){
foreach ($value as $k => $v) {
if($v == $keyword){
return ['status' => true, 'info' => '操作成功', 'type' => $key];
}
foreach($this->extension as $key => $type){
if (in_array($keyword, $type)) {
return $key;
} }
} }
return ['status' => false, 'info' => '操作失败'];
return self::TYPE_NONE;
} }
/** /**
* @param $temFIleIdArr
* @param $temFileIdArr
* @param $ownId * @param $ownId
* @param $ownType * @param $ownType
* @return array
* @return array|bool
* @throws \Exception
* 根据临时文件id将临时文件保存在文件中 * 根据临时文件id将临时文件保存在文件中
*/ */
public function saveTemFileToFile($temFIleIdArr, $ownId, $ownType)
public function saveTemFileToFile($temFileIdArr, $ownId, $ownType)
{ {
if(!$temFIleIdArr || !$ownId) {
return ['status' => false, 'info' => '参数错误'];
if(empty($temFileIdArr) || !$ownId) {
return false;
} }
$tra = Yii::$app->db->beginTransaction();
try {
$firstFileId = 0; $firstFileId = 0;
foreach ($temFIleIdArr as $key => $value) {
foreach ($temFileIdArr as $key => $value) {
$temFile = TemFile::findOne($value); $temFile = TemFile::findOne($value);
if(!$temFile) {
return ['status' => false, 'info' => '存在查找不到的文件'];
}
if ($temFile) {
$res = self::saveNewFile($temFile, $ownId, $ownType); $res = self::saveNewFile($temFile, $ownId, $ownType);
if(!$res['status']) {
return ['status' => false, 'info' => '存在文件保存失败'];
}
if ($key == 0) { if ($key == 0) {
$firstFileId = $res['file_id']; $firstFileId = $res['file_id'];
} }
} }
}
$tra->commit();
return ['status' => true, 'info' => '保存成功', 'first_file_id' => $firstFileId]; return ['status' => true, 'info' => '保存成功', 'first_file_id' => $firstFileId];
} catch (\Exception $e) {
$tra->rollBack();
throw new \Exception($e->getMessage());
}
} }
/** /**
@ -79,6 +82,7 @@ class FileManager
* @param $ownId * @param $ownId
* @param $ownType * @param $ownType
* @return array * @return array
* @throws HttpException
* 创建新的文件 * 创建新的文件
*/ */
private function saveNewFile($temFile, $ownId, $ownType) private function saveNewFile($temFile, $ownId, $ownType)
@ -93,13 +97,14 @@ class FileManager
if($newFile->save()) { if($newFile->save()) {
return ['status' => true, 'info' => '操作成功', 'file_id' => $newFile->id]; return ['status' => true, 'info' => '操作成功', 'file_id' => $newFile->id];
} else { } else {
return ['status' => false, 'info' => '操作失败'];
throw new HttpException('500', 'File保存失败');
} }
} }
/** /**
* @param $fileIdArr * @param $fileIdArr
* @return array
* @return bool
* @throws HttpException
* 删除file表中的文件 * 删除file表中的文件
*/ */
public function deleteFile($fileIdArr) public function deleteFile($fileIdArr)
@ -109,12 +114,12 @@ class FileManager
$fileModel = File::findOne($value); $fileModel = File::findOne($value);
if($fileModel){ if($fileModel){
$fileModel->is_delete = File::IS_DELETE_YES; $fileModel->is_delete = File::IS_DELETE_YES;
if($fileModel->save()){
return ['status' => false, 'info' => '操作失败'];
if(!$fileModel->save()){
throw new HttpException('500', '文件删除失败');
} }
} }
} }
} }
return ['status' => true, 'info' => '操作成功'];
return true;
} }
} }

2
backend/modules/file/models/ars/File.php

@ -26,9 +26,11 @@ class File extends \yii\db\ActiveRecord
const OWN_TYPE_GOODS_INDEX = 1;//商品首页 const OWN_TYPE_GOODS_INDEX = 1;//商品首页
const OWN_TYPE_GOODS_DETAILS = 2;//商品详情 const OWN_TYPE_GOODS_DETAILS = 2;//商品详情
const OWN_TYPE_CATEGORY_ICON = 3;//类目图标 const OWN_TYPE_CATEGORY_ICON = 3;//类目图标
const OWN_TYPE_COMMENT = 4;//评论图片
//is_delete //is_delete
const IS_DELETE_YES = 1;//已删除 const IS_DELETE_YES = 1;//已删除
const IS_DELETE_NO = 0;//未删除 const IS_DELETE_NO = 0;//未删除
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */

5
backend/modules/goods/controllers/CategoryController.php

@ -201,10 +201,7 @@ class CategoryController extends Controller
$model->user_id = Yii::$app->user->identity->id; $model->user_id = Yii::$app->user->identity->id;
$model->name = $file_name; $model->name = $file_name;
$file_manager = new \backend\modules\file\logic\file\FileManager(); $file_manager = new \backend\modules\file\logic\file\FileManager();
$type_res = $file_manager->searchType(\backend\modules\file\logic\file\FileManager::$extension, pathinfo($data['path'])['extension']);
if ($type_res['status']) {
$model->type = $type_res['type'];
}
$model->type = $file_manager->searchType(pathinfo($data['path'])['extension']);
$model->alias = $data['alias']; $model->alias = $data['alias'];
$model->path = $data['path']; $model->path = $data['path'];
$model->save(); $model->save();

12
backend/modules/goods/controllers/GoodsController.php

@ -11,6 +11,7 @@ use Yii;
use backend\modules\goods\models\ars\Goods; use backend\modules\goods\models\ars\Goods;
use backend\modules\goods\models\searchs\GoodsSearch; use backend\modules\goods\models\searchs\GoodsSearch;
use yii\web\Controller; use yii\web\Controller;
use yii\web\HttpException;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter; use yii\filters\VerbFilter;
use backend\modules\goods\logic\goods\GoodsManager; use backend\modules\goods\logic\goods\GoodsManager;
@ -96,6 +97,9 @@ class GoodsController extends Controller
$model = new Goods(); $model = new Goods();
$model->is_sale = Goods::IS_SALE_YES; $model->is_sale = Goods::IS_SALE_YES;
$model->stock = -1; $model->stock = -1;
$model->is_taking = Goods::IS_TAKING_NO;
$model->is_express = Goods::IS_EXPRESS_YES;
$model->express_type = Goods::EXPRESS_TYPE_EXPRESS_TEMPLATE;
if ($model->load(Yii::$app->request->post()) && $model->validate()) { if ($model->load(Yii::$app->request->post()) && $model->validate()) {
//商品封面图和商品详情图上传保存处理 //商品封面图和商品详情图上传保存处理
$res = GoodsManager::updateGoods(Yii::$app->request->post(), $model); $res = GoodsManager::updateGoods(Yii::$app->request->post(), $model);
@ -132,6 +136,9 @@ class GoodsController extends Controller
return $this->redirect('index'); return $this->redirect('index');
} }
} }
$model->uniform_postage /= 100;
$model->market_price /= 100;
$model->price /= 100;
$attributeModel = GoodsManager::getAttribute($id); $attributeModel = GoodsManager::getAttribute($id);
$checkAttr = GoodsManager::getSkuInfo($id); $checkAttr = GoodsManager::getSkuInfo($id);
$filterAttributeModel = GoodsManager::getFilterAttribute($id); $filterAttributeModel = GoodsManager::getFilterAttribute($id);
@ -211,10 +218,7 @@ class GoodsController extends Controller
$model->user_id = Yii::$app->user->identity->id; $model->user_id = Yii::$app->user->identity->id;
$model->name = $file_name; $model->name = $file_name;
$file_manager = new \backend\modules\file\logic\file\FileManager(); $file_manager = new \backend\modules\file\logic\file\FileManager();
$type_res = $file_manager->searchType(\backend\modules\file\logic\file\FileManager::$extension, pathinfo($data['path'])['extension']);
if ($type_res['status']) {
$model->type = $type_res['type'];
}
$model->type = $file_manager->searchType(pathinfo($data['path'])['extension']);
$model->alias = $data['alias']; $model->alias = $data['alias'];
$model->path = $data['path']; $model->path = $data['path'];
$model->save(); $model->save();

5
backend/modules/goods/controllers/ShopCategoryController.php

@ -212,10 +212,7 @@ class ShopCategoryController extends Controller
$model->user_id = Yii::$app->user->identity->id; $model->user_id = Yii::$app->user->identity->id;
$model->name = $file_name; $model->name = $file_name;
$file_manager = new \backend\modules\file\logic\file\FileManager(); $file_manager = new \backend\modules\file\logic\file\FileManager();
$type_res = $file_manager->searchType(\backend\modules\file\logic\file\FileManager::$extension, pathinfo($data['path'])['extension']);
if ($type_res['status']) {
$model->type = $type_res['type'];
}
$model->type = $file_manager->searchType(pathinfo($data['path'])['extension']);
$model->alias = $data['alias']; $model->alias = $data['alias'];
$model->path = $data['path']; $model->path = $data['path'];
$model->save(); $model->save();

118
backend/modules/goods/logic/goods/GoodsManager.php

@ -10,6 +10,7 @@ use backend\modules\goods\models\ars\GoodsSku;
use backend\modules\goods\models\ars\Goods; use backend\modules\goods\models\ars\Goods;
use backend\modules\goods\models\ars\FilterAttr; use backend\modules\goods\models\ars\FilterAttr;
use backend\modules\goods\models\ars\Category; use backend\modules\goods\models\ars\Category;
use yii\web\HttpException;
class GoodsManager class GoodsManager
{ {
@ -19,10 +20,13 @@ class GoodsManager
* @param array $oldFileIdArr * @param array $oldFileIdArr
* @param int $fileType * @param int $fileType
* @return array * @return array
* @throws \Exception
* 保存新文件,删除不需要的文件操作 * 保存新文件,删除不需要的文件操作
*/ */
public static function saveFile($newFileIdArr, $goodsModel, $oldFileIdArr = [], $fileType = 1) public static function saveFile($newFileIdArr, $goodsModel, $oldFileIdArr = [], $fileType = 1)
{ {
$tra = Yii::$app->db->beginTransaction();
try {
//需要新建的文件id //需要新建的文件id
$createFileIdArr = array_diff($newFileIdArr, $oldFileIdArr); $createFileIdArr = array_diff($newFileIdArr, $oldFileIdArr);
@ -48,7 +52,12 @@ class GoodsManager
} }
} }
$tra->commit();
return ['status' => true, 'info' => '操作成功', 'first_file_id' => $firstFileId]; return ['status' => true, 'info' => '操作成功', 'first_file_id' => $firstFileId];
} catch (\Exception $e) {
$tra->rollBack();
throw new \Exception($e->getMessage());
}
} }
/** /**
@ -57,49 +66,51 @@ class GoodsManager
* @param null $coverImageOldIdStr * @param null $coverImageOldIdStr
* @param null $detailImageOldIdStr * @param null $detailImageOldIdStr
* @return array * @return array
* @throws \Throwable
* @throws \Exception
* 创建修改商品操作 * 创建修改商品操作
*/ */
public static function updateGoods($data, $model, $coverImageOldIdStr = null, $detailImageOldIdStr = null) public static function updateGoods($data, $model, $coverImageOldIdStr = null, $detailImageOldIdStr = null)
{ {
$attribute = $data['attribute']; $attribute = $data['attribute'];
$filterAttribute = $data['filterattribute']; $filterAttribute = $data['filterattribute'];
$model->uniform_postage *= 100;
$model->market_price *= 100;
$model->price *= 100;
$tra = Yii::$app->db->beginTransaction(); $tra = Yii::$app->db->beginTransaction();
try { try {
if (!$model->save()) { if (!$model->save()) {
throw new Exception('');
throw new \Exception('商品保存失败');
} }
$saveCoverImageRes = self::saveFile(explode(',', $model->coverImageId), $model, explode(',', $coverImageOldIdStr)); $saveCoverImageRes = self::saveFile(explode(',', $model->coverImageId), $model, explode(',', $coverImageOldIdStr));
$saveDetailImageRes = self::saveFile(explode(',', $model->detailImageId), $model, explode(',', $detailImageOldIdStr), File::OWN_TYPE_GOODS_DETAILS); $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) { if($saveCoverImageRes['first_file_id'] !== 0) {
$model->image = $saveCoverImageRes['first_file_id']; $model->image = $saveCoverImageRes['first_file_id'];
if (!$model->save()) { if (!$model->save()) {
throw new Exception('图片保存失败');
throw new \Exception('图片保存失败');
} }
} }
} else {
throw new Exception('图片保存失败');
}
self::addAttributeOperating(['id' => $model->id, 'attribute' => $attribute]); self::addAttributeOperating(['id' => $model->id, 'attribute' => $attribute]);
self::addFilterAttributeOperating(['id' => $model->id, 'filterAttribute' => $filterAttribute]); self::addFilterAttributeOperating(['id' => $model->id, 'filterAttribute' => $filterAttribute]);
$tra->commit(); $tra->commit();
return ['status' => true]; return ['status' => true];
} catch (\yii\base\Exception $e) { } catch (\yii\base\Exception $e) {
$tra->rollBack(); $tra->rollBack();
return ['status' => false, 'info' => $e->getMessage()];
throw new \Exception($e->getMessage());
} }
} }
/** /**
* @param $data * @param $data
* @return bool * @return bool
* @throws Exception
* @throws \Exception
* 创建修改商品属性操作 * 创建修改商品属性操作
*/ */
public static function addAttributeOperating($data)
private static function addAttributeOperating($data)
{ {
$tra = Yii::$app->db->beginTransaction();
try {
if (!$data['attribute']) { if (!$data['attribute']) {
$tra->commit();
return true; return true;
} }
$data['attribute'] = json_decode($data['attribute'], true); $data['attribute'] = json_decode($data['attribute'], true);
@ -108,6 +119,7 @@ class GoodsManager
if ($goodsAttr) { //如果商品有旧的属性 if ($goodsAttr) { //如果商品有旧的属性
if (count($data['attribute']) == 0 && is_array($data['attribute'])) { //如果传上来的是空数组,删除该商品下的全部属性 if (count($data['attribute']) == 0 && is_array($data['attribute'])) { //如果传上来的是空数组,删除该商品下的全部属性
self::delAttribute($goodsAttr); self::delAttribute($goodsAttr);
$tra->commit();
return true; return true;
} }
foreach ($goodsAttr as $key => $value) { //把旧的商品属性保存到一个数组 foreach ($goodsAttr as $key => $value) { //把旧的商品属性保存到一个数组
@ -117,6 +129,7 @@ class GoodsManager
$newAttr = self::addAttribute($data['attribute'], $data['id']); //添加新的商品属性 $newAttr = self::addAttribute($data['attribute'], $data['id']); //添加新的商品属性
$delAttr = array_diff(array_keys($oldAttr), array_keys($newAttr)); //找出需要删除的goodsAttrId $delAttr = array_diff(array_keys($oldAttr), array_keys($newAttr)); //找出需要删除的goodsAttrId
if (!$delAttr) { if (!$delAttr) {
$tra->commit();
return true; return true;
} }
foreach ($delAttr as $value) { foreach ($delAttr as $value) {
@ -124,23 +137,29 @@ class GoodsManager
if ($model) { if ($model) {
$model->is_delete = GoodsAttr::IS_DELETE_YES; $model->is_delete = GoodsAttr::IS_DELETE_YES;
if (!$model->save()) { if (!$model->save()) {
throw new Exception('goodsAttribute delete false');
throw new \Exception('goodsAttribute delete false');
} }
} }
} }
$tra->commit();
return true;
} catch (\Exception $e) {
$tra->rollBack();
throw new \Exception($e->getMessage());
}
} }
/** /**
* @param $goodsAttr * @param $goodsAttr
* @throws Exception
* @throws \Exception
* 删除商品属性 * 删除商品属性
*/ */
public static function delAttribute($goodsAttr)
private static function delAttribute($goodsAttr)
{ {
foreach ($goodsAttr as $key => $value) { foreach ($goodsAttr as $key => $value) {
$value->is_delete = GoodsAttr::IS_DELETE_YES; $value->is_delete = GoodsAttr::IS_DELETE_YES;
if (!$value->save()) { if (!$value->save()) {
throw new Exception('goods attribute delete false');
throw new \Exception('goods attribute delete false');
} }
} }
} }
@ -149,10 +168,10 @@ class GoodsManager
* @param $attribute * @param $attribute
* @param $goodsId * @param $goodsId
* @return array * @return array
* @throws Exception
* @throws \Exception
* 保存商品属性 * 保存商品属性
*/ */
public static function addAttribute($attribute, $goodsId)
private static function addAttribute($attribute, $goodsId)
{ {
$newAttr = []; $newAttr = [];
if (!$attribute) { if (!$attribute) {
@ -169,7 +188,7 @@ class GoodsManager
$goodsAttrModel->goods_id = $goodsId; $goodsAttrModel->goods_id = $goodsId;
$goodsAttrModel->attr_value = $v; $goodsAttrModel->attr_value = $v;
if (!$goodsAttrModel->save()) { if (!$goodsAttrModel->save()) {
throw new Exception('goodsAttribute save false');
throw new \Exception('goodsAttribute save false');
} }
$newAttr[$goodsAttrModel->id] = $goodsAttrModel->attr_value; //新增的数据 $newAttr[$goodsAttrModel->id] = $goodsAttrModel->attr_value; //新增的数据
} }
@ -284,7 +303,7 @@ class GoodsManager
$data['id'] = $sku->id; $data['id'] = $sku->id;
$data['price'] = $sku->price; $data['price'] = $sku->price;
$data['stock'] = $sku->stock; $data['stock'] = $sku->stock;
$data['weight'] = $sku->weight;
$data['weight'] = $sku->weight/1000;
return $data; return $data;
} }
@ -306,29 +325,18 @@ class GoodsManager
if ($attribute && $attribute->type == Attribute::TYPE_ATTR) { if ($attribute && $attribute->type == Attribute::TYPE_ATTR) {
$ret['name'] = $attribute->name; $ret['name'] = $attribute->name;
$ret['id'] = $attribute->id; $ret['id'] = $attribute->id;
$ret['attrValue'] = self::getAttrValue($attribute->id, $id);
$ret['attrValue'] = GoodsAttr::find()
->select(['id', 'attr_value'])
->where(['goods_id' => $id])
->andWhere(['attr_id' => $attribute->id])
->asArray()
->all();
$attributes[] = $ret; $attributes[] = $ret;
} }
} }
return $attributes; return $attributes;
} }
/**
* @param $attrId
* @param $goodsId
* @return GoodsAttr[]|GoodsSku[]|array|File[]|\backend\modules\file\models\ars\TemFile[]|\yii\db\ActiveRecord[]
* 获取属性值
*/
public static function getAttrValue($attrId, $goodsId)
{
return GoodsAttr::find()
->select(['id', 'attr_value'])
->where(['goods_id' => $goodsId])
->andWhere(['attr_id' => $attrId])
->asArray()
->all();
}
/** /**
* @param $type * @param $type
* @param $goodsId * @param $goodsId
@ -356,11 +364,15 @@ class GoodsManager
/** /**
* @param $sku * @param $sku
* @throws \yii\db\Exception
* @param $type
* @param $goodsId
* @throws \Exception
* 添加或更新sku数据 * 添加或更新sku数据
*/ */
public static function AddOrUpdateData($sku, $type, $goodsId) public static function AddOrUpdateData($sku, $type, $goodsId)
{ {
$tra = Yii::$app->db->beginTransaction();
try {
$goodsModel = Goods::findOne($goodsId); $goodsModel = Goods::findOne($goodsId);
if ($sku['id'] > 0) { if ($sku['id'] > 0) {
$goodsSku = GoodsSku::findOne($sku['id']); $goodsSku = GoodsSku::findOne($sku['id']);
@ -371,12 +383,12 @@ class GoodsManager
$attr = new GoodsAttr(); $attr = new GoodsAttr();
} }
if (!$attr || !$goodsSku || !$goodsModel) { if (!$attr || !$goodsSku || !$goodsModel) {
throw new \yii\db\Exception('系统异常');
throw new \Exception('参数错误');
} }
if ($type == Goods::SKU_MODE_MANUAL) { if ($type == Goods::SKU_MODE_MANUAL) {
$attr->attr_value = $sku['value']; $attr->attr_value = $sku['value'];
if (!$attr->save()) { if (!$attr->save()) {
throw new \yii\db\Exception('手动属性修改失败');
throw new \Exception('手动属性修改失败');
} }
$goodsSku->goods_attr = (string)$attr->id; $goodsSku->goods_attr = (string)$attr->id;
$goodsSku->is_manaul = 1; $goodsSku->is_manaul = 1;
@ -386,15 +398,20 @@ class GoodsManager
$goodsSku->goods_id = $goodsId; $goodsSku->goods_id = $goodsId;
$goodsSku->price = $sku['price']; $goodsSku->price = $sku['price'];
$goodsSku->stock = $sku['stock']; $goodsSku->stock = $sku['stock'];
$goodsSku->weight = $sku['weight'];
$goodsSku->weight = $sku['weight']*1000;
$goodsSku->goods_sn = $goodsModel->sn; $goodsSku->goods_sn = $goodsModel->sn;
if (!$goodsSku->save()) { if (!$goodsSku->save()) {
throw new \yii\db\Exception('保存失败,请检查是否有重复规格');
throw new \Exception('保存失败,请检查是否有重复规格');
} }
$goods = Goods::findOne($goodsId); $goods = Goods::findOne($goodsId);
$goods->sku_mode = $type; $goods->sku_mode = $type;
if (!$goods->save()) { if (!$goods->save()) {
throw new \yii\db\Exception('商品sku类型修改失败');
throw new \Exception('商品sku类型修改失败');
}
$tra->commit();
} catch (\Exception $e) {
$tra->rollBack();
throw new \Exception($e->getMessage());
} }
} }
@ -433,9 +450,10 @@ class GoodsManager
* @param $data * @param $data
* @return bool * @return bool
* @throws Exception * @throws Exception
* @throws HttpException
* 创建修改商品筛选属性操作 * 创建修改商品筛选属性操作
*/ */
public static function addFilterAttributeOperating($data)
private static function addFilterAttributeOperating($data)
{ {
if (!$data['filterAttribute']) { if (!$data['filterAttribute']) {
return true; return true;
@ -462,7 +480,7 @@ class GoodsManager
if ($model) { if ($model) {
$model->is_delete = FilterAttr::IS_DELETE_YES; $model->is_delete = FilterAttr::IS_DELETE_YES;
if (!$model->save()) { if (!$model->save()) {
throw new Exception('goodsAttribute delete false');
throw new \Exception('goodsAttribute delete false');
} }
} }
} }
@ -470,15 +488,15 @@ class GoodsManager
/** /**
* @param $goodsFilterAttr * @param $goodsFilterAttr
* @throws Exception
* @throws HttpException
* 删除商品筛选属性 * 删除商品筛选属性
*/ */
public static function delFilterAttribute($goodsFilterAttr)
private static function delFilterAttribute($goodsFilterAttr)
{ {
foreach ($goodsFilterAttr as $key => $value) { foreach ($goodsFilterAttr as $key => $value) {
$value->is_delete = FilterAttr::IS_DELETE_YES; $value->is_delete = FilterAttr::IS_DELETE_YES;
if (!$value->save()) { if (!$value->save()) {
throw new Exception('goods attribute delete false');
throw new \Exception('goods attribute delete false');
} }
} }
} }
@ -487,10 +505,10 @@ class GoodsManager
* @param $attribute * @param $attribute
* @param $goodsId * @param $goodsId
* @return array * @return array
* @throws Exception
* @throws \Exception
* 保存商品筛选属性 * 保存商品筛选属性
*/ */
public static function addFilterAttribute($attribute, $goodsId)
private static function addFilterAttribute($attribute, $goodsId)
{ {
$newAttr = []; $newAttr = [];
if (!$attribute) { if (!$attribute) {
@ -507,7 +525,7 @@ class GoodsManager
$goodsFilterAttrModel->goods_id = $goodsId; $goodsFilterAttrModel->goods_id = $goodsId;
$goodsFilterAttrModel->attr_value = $v; $goodsFilterAttrModel->attr_value = $v;
if (!$goodsFilterAttrModel->save()) { if (!$goodsFilterAttrModel->save()) {
throw new Exception('goodsAttribute save false');
throw new \Exception('goodsAttribute save false');
} }
$newAttr[$goodsFilterAttrModel->id] = $goodsFilterAttrModel->attr_value; //新增的数据 $newAttr[$goodsFilterAttrModel->id] = $goodsFilterAttrModel->attr_value; //新增的数据
} }
@ -549,7 +567,7 @@ class GoodsManager
/** /**
* @param $goodsModel * @param $goodsModel
* @return bool * @return bool
*
* 判断该商品的sku是否存在已选属性,存在则返回true,表示不得删除
*/ */
public static function judgeGoodsCategory($goodsModel) public static function judgeGoodsCategory($goodsModel)
{ {

26
backend/modules/goods/migrations/m191207_004848_add_columns_is_taking_is_express_express_type_uniform_postage_in_table_atg_goods.php

@ -0,0 +1,26 @@
<?php
use yii\db\Migration;
/**
* Class m191207_004848_add_columns_is_taking_is_express_express_type_uniform_postage_in_table_atg_goods
*/
class m191207_004848_add_columns_is_taking_is_express_express_type_uniform_postage_in_table_atg_goods extends Migration
{
public function up()
{
$this->addColumn('atg_goods', 'is_taking', $this->tinyInteger(1)->defaultValue(0)->notNull()->comment('是否自提'));
$this->addColumn('atg_goods', 'is_express', $this->tinyInteger(1)->defaultValue(0)->notNull()->comment('是否快递发货'));
$this->addColumn('atg_goods', 'express_type', $this->tinyInteger(2)->defaultValue(0)->comment('快递运费方式'));
$this->addColumn('atg_goods', 'uniform_postage', $this->integer(20)->defaultValue(0)->comment('统一邮费'));
}
public function down()
{
$this->dropColumn('atg_goods', 'is_taking');
$this->dropColumn('atg_goods', 'is_express');
$this->dropColumn('atg_goods', 'express_type');
$this->dropColumn('atg_goods', 'uniform_postage');
return true;
}
}

23
backend/modules/goods/migrations/m191209_091129_update_columns_in_table_atg_goods.php

@ -0,0 +1,23 @@
<?php
use yii\db\Migration;
/**
* Class m191209_091129_update_columns_in_table_atg_goods
*/
class m191209_091129_update_columns_in_table_atg_goods extends Migration
{
public function up()
{
$sql = file_get_contents(__DIR__."/sql/update_goods.sql");
$this->execute($sql);
}
/**
* {@inheritdoc}
*/
public function down()
{
return true;
}
}

20
backend/modules/goods/migrations/m191209_091524_add_column_weight_in_table_atg_goods_sku.php

@ -0,0 +1,20 @@
<?php
use yii\db\Migration;
/**
* Class m191209_091524_add_column_weight_in_table_atg_goods_sku
*/
class m191209_091524_add_column_weight_in_table_atg_goods_sku extends Migration
{
public function up()
{
$this->addColumn('atg_goods_sku', 'weight', $this->integer(8)->defaultValue("0")->unsigned()->comment('重量'));
}
public function down()
{
$this->dropColumn('atg_goods_sku', 'weight');
return true;
}
}

17
backend/modules/goods/migrations/sql/update_goods.sql

@ -0,0 +1,17 @@
ALTER TABLE `atg_goods` DROP `weight`;
ALTER TABLE `atg_goods` DROP `length`;
ALTER TABLE `atg_goods` DROP `width`;
ALTER TABLE `atg_goods` DROP `height`;
ALTER TABLE `atg_goods` DROP `diameter`;
ALTER TABLE `atg_goods` DROP `sold_count`;
ALTER TABLE `atg_goods` DROP `market_price`;
ALTER TABLE `atg_goods` DROP `price`;
ALTER TABLE `atg_goods` ADD COLUMN `weight` mediumint(8) UNSIGNED DEFAULT NULL COMMENT '重量';
ALTER TABLE `atg_goods` ADD COLUMN `length` mediumint(8) UNSIGNED DEFAULT NULL COMMENT '长度';
ALTER TABLE `atg_goods` ADD COLUMN `width` mediumint(8) UNSIGNED DEFAULT NULL COMMENT '宽度';
ALTER TABLE `atg_goods` ADD COLUMN `height` mediumint(8) UNSIGNED DEFAULT NULL COMMENT '高度';
ALTER TABLE `atg_goods` ADD COLUMN `diameter` mediumint(8) UNSIGNED DEFAULT NULL COMMENT '直径';
ALTER TABLE `atg_goods` ADD COLUMN `sold_count` int(10) UNSIGNED DEFAULT NULL COMMENT '已售数量';
ALTER TABLE `atg_goods` ADD COLUMN `market_price` int(20) UNSIGNED DEFAULT NULL COMMENT '市场价';
ALTER TABLE `atg_goods` ADD COLUMN `price` int(20) UNSIGNED DEFAULT NULL COMMENT '销售价';

58
backend/modules/goods/models/ars/Goods.php

@ -47,6 +47,10 @@ use backend\modules\goods\models\ars\Supplier;
* @property int $created_at 创建时间 * @property int $created_at 创建时间
* @property int $updated_at 更新时间 * @property int $updated_at 更新时间
* @property int $sku_mode sku类型 * @property int $sku_mode sku类型
* @property int $is_taking 是否自提
* @property int $is_express 是否快递发货
* @property int $express_type 快递运费方式
* @property int $uniform_postage 统一邮费
*/ */
class Goods extends \yii\db\ActiveRecord class Goods extends \yii\db\ActiveRecord
{ {
@ -62,13 +66,38 @@ class Goods extends \yii\db\ActiveRecord
//该商品是否开放销售is_sale //该商品是否开放销售is_sale
const IS_SALE_NO = 0;//否 const IS_SALE_NO = 0;//否
const IS_SALE_YES = 1;//是 const IS_SALE_YES = 1;//是
//sku类型
//类型sku
const SKU_MODE_ATTR = 1;//SKU类型属性 const SKU_MODE_ATTR = 1;//SKU类型属性
const SKU_MODE_MANUAL = 2;//SKU类型手写 const SKU_MODE_MANUAL = 2;//SKU类型手写
//是否自提is_taking
const IS_TAKING_NO = 0; //否
const IS_TAKING_YES = 1; //是
//是否快递发货is_express
const IS_EXPRESS_NO = 0; //否
const IS_EXPRESS_YES = 1; //是
//快递运费计算方式express_type
const EXPRESS_TYPE_UNIFORM_POSTAGE = 1; //统一邮费
const EXPRESS_TYPE_EXPRESS_TEMPLATE = 2; //运费模板
public static $isTaking = [
self::IS_TAKING_NO => '否',
self::IS_TAKING_YES => '是'
];
public static $isExpress = [
self::IS_EXPRESS_NO => '否',
self::IS_EXPRESS_YES => '是'
];
public static $expressType = [
self::EXPRESS_TYPE_UNIFORM_POSTAGE => '统一邮费',
self::EXPRESS_TYPE_EXPRESS_TEMPLATE => '运费模板'
];
public static $isSale = [ public static $isSale = [
self::IS_SALE_NO => '不在售', self::IS_SALE_NO => '不在售',
self::IS_SALE_YES => '在售' self::IS_SALE_YES => '在售'
]; ];
//无限库存
const UNLIMITED_STOCK = -1;
public $ruleVerify = 0;//规则验证是否通过 public $ruleVerify = 0;//规则验证是否通过
/** /**
* {@inheritdoc} * {@inheritdoc}
@ -78,13 +107,28 @@ class Goods extends \yii\db\ActiveRecord
return 'atg_goods'; return 'atg_goods';
} }
public function fields()
{
$fields = parent::fields();
unset($fields['is_sale']);
unset($fields['sort_order']);
unset($fields['pid']);
unset($fields['cat_id']);
unset($fields['brand_id']);
unset($fields['shop_cat_id']);
unset($fields['is_delete']);
unset($fields['express_template']);
unset($fields['model_id']);
return $fields;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function rules() public function rules()
{ {
return [ return [
[['pid', 'cat_id', 'brand_id', 'shop_cat_id', 'supplier_id', 'weight', 'length', 'width', 'height', 'diameter', 'sold_count', 'limit_count', 'stock', 'stock_warn', 'market_price', 'price', 'image', 'model_id', 'is_sale', 'sort_order', 'bouns_points', 'experience_points', 'is_delete', 'express_template', 'sku_mode'], 'integer'],
[['pid', 'cat_id', 'brand_id', 'shop_cat_id', 'supplier_id', 'weight', 'length', 'width', 'height', 'diameter', 'sold_count', 'limit_count', 'stock', 'stock_warn', 'image', 'model_id', 'is_sale', 'sort_order', 'bouns_points', 'experience_points', 'is_delete', 'express_template', 'sku_mode', 'is_taking', 'is_express', 'express_type'], 'integer'],
[['cat_id', 'brand_id', 'shop_cat_id', 'name'], 'required'], [['cat_id', 'brand_id', 'shop_cat_id', 'name'], 'required'],
[['sn'], 'checkExist'], [['sn'], 'checkExist'],
[['description', 'coverImageId', 'detailImageId'], 'string'], [['description', 'coverImageId', 'detailImageId'], 'string'],
@ -93,7 +137,8 @@ class Goods extends \yii\db\ActiveRecord
[['code'], 'string', 'max' => 50], [['code'], 'string', 'max' => 50],
[['unit'], 'string', 'max' => 16], [['unit'], 'string', 'max' => 16],
[['brief'], 'string', 'max' => 255], [['brief'], 'string', 'max' => 255],
[['weight', 'length', 'width', 'height', 'diameter', 'sold_count', 'market_price', 'price'], 'checkNegative'],
[['weight', 'length', 'width', 'height', 'diameter', 'sold_count', 'market_price', 'price', 'uniform_postage'], 'checkNegative'],
[['uniform_postage', 'market_price', 'price'], 'safe']
]; ];
} }
@ -164,9 +209,14 @@ class Goods extends \yii\db\ActiveRecord
'bouns_points' => '奖励积分', 'bouns_points' => '奖励积分',
'experience_points' => '经验值', 'experience_points' => '经验值',
'is_delete' => '是否删除,1为已删除', 'is_delete' => '是否删除,1为已删除',
'express_template' => '配送详情id',
'express_template' => '配送详情',
'created_at' => '创建时间', 'created_at' => '创建时间',
'updated_at' => '更新时间', 'updated_at' => '更新时间',
'sku_mode' => 'sku类型',
'is_taking' => '是否自提',
'is_express' => '是否快递发货',
'express_type' => '快递运费方式',
'uniform_postage' => '统一邮费',
]; ];
} }

5
backend/modules/goods/models/ars/GoodsSku.php

@ -24,6 +24,7 @@ use yii\behaviors\TimestampBehavior;
* @property int $created_at 创建时间 * @property int $created_at 创建时间
* @property int $updated_at 更新时间 * @property int $updated_at 更新时间
* @property int $is_manaul 是否手动 * @property int $is_manaul 是否手动
* @property int $weight 重量
*/ */
class GoodsSku extends \yii\db\ActiveRecord class GoodsSku extends \yii\db\ActiveRecord
{ {
@ -48,9 +49,10 @@ class GoodsSku extends \yii\db\ActiveRecord
{ {
return [ return [
[['goods_id', 'goods_sn'], 'required'], [['goods_id', 'goods_sn'], 'required'],
[['goods_id', 'diameter', 'sold_count', 'stock', 'market_price', 'price', 'model_id', 'is_sale', 'sort_order', 'is_delete', 'is_manaul'], 'integer'],
[['goods_id', 'sold_count', 'stock', 'market_price', 'price', 'model_id', 'is_sale', 'sort_order', 'is_delete', 'is_manaul'], 'integer'],
[['goods_code'], 'string', 'max' => 50], [['goods_code'], 'string', 'max' => 50],
[['goods_sn', 'goods_attr'], 'string', 'max' => 60], [['goods_sn', 'goods_attr'], 'string', 'max' => 60],
[['weight'], 'safe']
]; ];
} }
@ -75,6 +77,7 @@ class GoodsSku extends \yii\db\ActiveRecord
'is_delete' => '是否删除,1为已删除', 'is_delete' => '是否删除,1为已删除',
'created_at' => '创建时间', 'created_at' => '创建时间',
'updated_at' => '更新时间', 'updated_at' => '更新时间',
'weight' => '重量',
]; ];
} }

5
backend/modules/goods/models/searchs/GoodsSearch.php

@ -63,7 +63,7 @@ class GoodsSearch extends Goods
'width'=>'10%', 'width'=>'10%',
'format' => 'raw', 'format' => 'raw',
'value' => function ($model) { 'value' => function ($model) {
return $model->image ?
return $model->imageFile ?
Html::img(['/'.$model->imageFile->path], ['style' => 'width:80px']) Html::img(['/'.$model->imageFile->path], ['style' => 'width:80px'])
: '<div class="table_not_setting">未设置</div>'; : '<div class="table_not_setting">未设置</div>';
@ -129,7 +129,7 @@ class GoodsSearch extends Goods
'icon' => 'trash', 'icon' => 'trash',
'title' => '删除', 'title' => '删除',
'contents' => '确定删除?' 'contents' => '确定删除?'
]
],
], ],
], ],
]; ];
@ -223,7 +223,6 @@ class GoodsSearch extends Goods
'created_at' => $this->created_at, 'created_at' => $this->created_at,
'updated_at' => $this->updated_at, 'updated_at' => $this->updated_at,
]); ]);
$query->andFilterWhere(['like', 'name', $this->name]) $query->andFilterWhere(['like', 'name', $this->name])
->andFilterWhere(['like', 'sn', $this->sn]) ->andFilterWhere(['like', 'sn', $this->sn])
->andFilterWhere(['like', 'code', $this->code]) ->andFilterWhere(['like', 'code', $this->code])

55
backend/modules/goods/views/goods/_search.php

@ -3,6 +3,9 @@
use yii\helpers\Html; use yii\helpers\Html;
use yii\widgets\ActiveForm; use yii\widgets\ActiveForm;
use \blobt\widgets\DateRangePicker; use \blobt\widgets\DateRangePicker;
use linyao\widgets\Select2;
use backend\modules\goods\models\ars\Category;
use backend\modules\goods\models\ars\ShopCategory;
/* @var $this yii\web\View */ /* @var $this yii\web\View */
/* @var $model common\models\searchs\GoodsSearch */ /* @var $model common\models\searchs\GoodsSearch */
@ -29,6 +32,58 @@ use \blobt\widgets\DateRangePicker;
]) ])
?> ?>
</div> </div>
<div class="col">
<?= $form->field($model, 'name', [
"template" => "{input}{error}",
"inputOptions" => [
"placeholder" => "商品名称",
"class" => "form-control",
],
"errorOptions" => [
"class" => "error-tips"
]
])
?>
</div>
<div class="col">
<?= $form->field($model, 'sn', [
"template" => "{input}{error}",
"inputOptions" => [
"placeholder" => "商品唯一货号",
"class" => "form-control",
],
"errorOptions" => [
"class" => "error-tips"
]
])
?>
</div>
<div class="col">
<?= $form->field($model, 'cat_id', [
"template" => "{input}{error}",
"inputOptions" => [
"placeholder" => "后台商品类别",
"class" => "form-control",
],
"errorOptions" => [
"class" => "error-tips"
]
])->dropDownList(Category::modelColumn(), ['prompt' => '后台商品类别']);
?>
</div>
<div class="col">
<?= $form->field($model, 'shop_cat_id', [
"template" => "{input}{error}",
"inputOptions" => [
"placeholder" => "前端商品类别",
"class" => "form-control",
],
"errorOptions" => [
"class" => "error-tips"
]
])->dropDownList(ShopCategory::modelColumn(), ['prompt' => '前端商品类别']);
?>
</div>
<div class="col"> <div class="col">
<?= $form->field($model, "created_at_range", [ <?= $form->field($model, "created_at_range", [
"template" => "{input}{error}", "template" => "{input}{error}",

6
backend/modules/goods/views/goods/create.php

@ -42,6 +42,12 @@ Yii::$app->params['bsVersion'] = '4.x';
'attrValue' => [], 'attrValue' => [],
]), ]),
], ],
[
'label' => '<i class="fas fa-shipping-fast"></i> 物流信息',
'content' => $this->render('express', ['model' => $model,
'form' => $form,
]),
],
[ [
'label' => '<i class="fas fa-ad"></i> 详情上传', 'label' => '<i class="fas fa-ad"></i> 详情上传',
'content' => $this->render('new_editor', ['model' => $model, 'content' => $this->render('new_editor', ['model' => $model,

90
backend/modules/goods/views/goods/express.php

@ -0,0 +1,90 @@
<?php
use yii\helpers\Url;
use blobt\widgets\Icheck;
use backend\modules\goods\models\ars\Goods;
use linyao\widgets\Select2;
use backend\modules\shop\models\ars\ExpressTemplate;
/* @var $this yii\web\View */
/* @var $model backend\modules\goods\models\ars\Goods */
/* @var $form yii\widgets\ActiveForm */
?>
<?= $form->field($model, 'is_taking')->widget(Icheck::className(), ['items' => Goods::$isTaking, 'type' => 'radio']) ?>
<?= $form->field($model, 'is_express')->widget(Icheck::className(), ['items' => Goods::$isExpress, 'type' => 'radio']) ?>
<fieldset id="isExpress" style="display: <?= $model->is_express == Goods::IS_EXPRESS_NO ? 'none' : 'block' ?>">
<?= $form->field($model, 'express_type')->widget(Icheck::className(), ['items' => Goods::$expressType, 'type' => 'radio']) ?>
<fieldset id="uniformPostage" style="display: <?= $model->express_type == Goods::EXPRESS_TYPE_UNIFORM_POSTAGE ? 'block' : 'none' ?>">
<?= $form->field($model, 'uniform_postage')->textInput() ?>
</fieldset>
<fieldset id="expressTemplate" style="display: <?= $model->express_type == Goods::EXPRESS_TYPE_EXPRESS_TEMPLATE ? 'block' : 'none' ?>">
<?= $form->field($model, 'express_template')->widget(Select2::className(), ["items" => ExpressTemplate::modelColumn()]) ?>
</fieldset>
</fieldset>
<?php
$js =<<<JS
$(document).ready(function(){
if(!$("#goods-uniform_postage").val()){
$("#goods-uniform_postage").val("0.00")
}else{
$("#goods-uniform_postage").val(toFixeds($("#goods-uniform_postage").val(), 2));
}
$("input:radio[name='Goods[is_express]']").on('ifChecked', function(event){
if ($(this).val() === '1') {
$("#isExpress").show();
} else {
$("#isExpress").hide();
}
})
$("input:radio[name='Goods[express_type]']").on('ifChecked', function(event){
if ($(this).val() === '1') {
$("#uniformPostage").show();
$("#expressTemplate").hide();
} else {
$("#expressTemplate").show();
$("#uniformPostage").hide();
}
})
$("#goods-uniform_postage").blur(function(){
if(!$(this).val()){
$(this).val("0.00")
}
if(isNaN($(this).val())){
$(this).val("0.00")
}
if($(this).val().indexOf('-') != -1){
$(this).val("0.00")
}
var basicPrice = $(this).val();
$(this).val(toFixeds($(this).val(), 2));
})
//金额补全
function toFixeds(val, pre) {
const num = parseFloat(val);
// eslint-disable-next-line no-restricted-globals
if (isNaN(num)) {
return false;
}
const p = 10 ** pre;
const value = num * p;
let f = (Math.round(value) / p).toString();
let rs = f.indexOf('.');
if (rs < 0) {
rs = f.length;
f += '.';
}
while (f.length <= rs + pre) {
f += '0';
}
return f;
}
})
JS;
$this->registerJs($js);
?>

62
backend/modules/goods/views/goods/goods.php

@ -62,3 +62,65 @@ use backend\modules\goods\models\ars\Goods;
<?= Html::submitButton('保存', ['class' => 'btn btn-success']) ?> <?= Html::submitButton('保存', ['class' => 'btn btn-success']) ?>
<?= Html::a('返回', ['index'], ['class' => 'btn btn-info']) ?> <?= Html::a('返回', ['index'], ['class' => 'btn btn-info']) ?>
</div> </div>
<?php
$js =<<<JS
$(document).ready(function(){
if(!$("#goods-market_price").val()){
$("#goods-market_price").val("0.00")
}else{
$("#goods-market_price").val(toFixeds($("#goods-market_price").val(), 2));
}
if(!$("#goods-price").val()){
$("#goods-price").val("0.00")
}else{
$("#goods-price").val(toFixeds($("#goods-price").val(), 2));
}
$("#goods-market_price").blur(function(){
if(!$(this).val()){
$(this).val("0.00")
}
if(isNaN($(this).val())){
$(this).val("0.00")
}
if($(this).val().indexOf('-') != -1){
$(this).val("0.00")
}
$(this).val(toFixeds($(this).val(), 2));
})
$("#goods-price").blur(function(){
if(!$(this).val()){
$(this).val("0.00")
}
if(isNaN($(this).val())){
$(this).val("0.00")
}
if($(this).val().indexOf('-') != -1){
$(this).val("0.00")
}
$(this).val(toFixeds($(this).val(), 2));
})
//金额补全
function toFixeds(val, pre) {
const num = parseFloat(val);
// eslint-disable-next-line no-restricted-globals
if (isNaN(num)) {
return false;
}
const p = 10 ** pre;
const value = num * p;
let f = (Math.round(value) / p).toString();
let rs = f.indexOf('.');
if (rs < 0) {
rs = f.length;
f += '.';
}
while (f.length <= rs + pre) {
f += '0';
}
return f;
}
})
JS;
$this->registerJs($js);
?>

6
backend/modules/goods/views/goods/update.php

@ -44,6 +44,12 @@ Yii::$app->params['bsVersion'] = '4.x';
'goodsModel' => $model, 'goodsModel' => $model,
]), ]),
], ],
[
'label' => '<i class="fas fa-shipping-fast"></i> 物流信息',
'content' => $this->render('express', ['model' => $model,
'form' => $form,
]),
],
[ [
'label' => '<i class="fas fa-ad"></i> 详情上传', 'label' => '<i class="fas fa-ad"></i> 详情上传',
'content' => $this->render('new_editor', ['model' => $model, 'content' => $this->render('new_editor', ['model' => $model,

2
backend/modules/goods/views/goods/view.php

@ -77,7 +77,7 @@ $this->params['breadcrumbs'][] = $this->title;
['attribute' => 'image', ['attribute' => 'image',
'format' => 'raw', 'format' => 'raw',
'value' => function ($model) { 'value' => function ($model) {
return $model->image ?
return $model->imageFile ?
Html::img(['/'.$model->imageFile->path], ['style' => 'width:80px']) Html::img(['/'.$model->imageFile->path], ['style' => 'width:80px'])
: '<div class="table_not_setting">未设置</div>'; : '<div class="table_not_setting">未设置</div>';

267
backend/modules/shop/controllers/ExpressTemplateController.php

@ -4,15 +4,18 @@ namespace backend\modules\shop\controllers;
use backend\modules\shop\models\ars\City; use backend\modules\shop\models\ars\City;
use backend\modules\shop\models\ars\Province; use backend\modules\shop\models\ars\Province;
use backend\modules\shop\models\searchs\ExpressAreaSearch;
use Yii; use Yii;
use backend\modules\shop\models\ars\ExpressTemplate; use backend\modules\shop\models\ars\ExpressTemplate;
use backend\modules\shop\models\searchs\ExpressTemplateSearch; use backend\modules\shop\models\searchs\ExpressTemplateSearch;
use yii\caching\Cache;
use yii\web\Controller; use yii\web\Controller;
use yii\web\NotFoundHttpException; use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter; use yii\filters\VerbFilter;
use yii\web\Response; use yii\web\Response;
use yii\widgets\ActiveForm; use yii\widgets\ActiveForm;
use backend\modules\shop\models\ars\ExpressArea;
use backend\modules\goods\models\ars\Goods;
/** /**
* ExpressTemplateController implements the CRUD actions for ExpressTemplate model. * ExpressTemplateController implements the CRUD actions for ExpressTemplate model.
@ -71,52 +74,13 @@ class ExpressTemplateController extends Controller
public function actionCreate() public function actionCreate()
{ {
$model = new ExpressTemplate(); $model = new ExpressTemplate();
$model->calculation_type = ExpressTemplate::CALCULATION_TYPE_NUMBER;
$model->basic_count = 1;
$model->basic_price = '0.00';
if (Yii::$app->request->isPost) {
$data = Yii::$app->request->post('ExpressTemplate');
if (Yii::$app->request->isAjax) {
$model->load($data, '');
Yii::$app->response->format = Response::FORMAT_JSON;
$data = ActiveForm::validate($model);
$data['status'] = 2;
return $data;
}
if (Yii::$app->request->post('area') == null) {
return $this->redirect(Yii::$app->request->referrer . '?status=1');
}
$cityIds = array_keys(Yii::$app->request->post('area'));
$data['city'] = implode(',', $cityIds);
$model->load($data, '');
$model->basic_price *= 100;
$model->extra_price *= 100;
if ($model->calculation_type == ExpressTemplate::CALCULATION_TYPE_WEIGHT) {
$model->basic_count *= 10;
$model->extra_count *= 10;
} else {
$model->basic_count *= 1;
$model->extra_count *= 1;
}
$model->save();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect('index'); return $this->redirect('index');
} }
$data = [];
$provinces = Province::find()->cache(0)->all();
foreach ($provinces as $k => $v) {
$data[$k]['province'] = $v->name;
$cities = City::find()->cache(0)
->where(['province_id' => $v->province_id])
->all();
foreach ($cities as $city) {
$data[$k]['city'][] = ['id' => $city->city_id, 'name' => $city->name];
}
}
return $this->render('create', [ return $this->render('create', [
'model' => $model, 'model' => $model,
'data' => $data
]); ]);
} }
@ -130,36 +94,13 @@ class ExpressTemplateController extends Controller
public function actionUpdate($id) public function actionUpdate($id)
{ {
$model = $this->findModel($id); $model = $this->findModel($id);
$model->basic_price /= 100;
$model->extra_price /= 100;
if ($model->calculation_type == ExpressTemplate::CALCULATION_TYPE_WEIGHT) {
$model->basic_count /= 10;
$model->extra_count /= 10;
}
$data = Yii::$app->request->post('ExpressTemplate');
if ($data) {
if (Yii::$app->request->post('area') == null) {
return $this->redirect(Yii::$app->request->referrer . '&status=1');
}
$cityIds = array_keys(Yii::$app->request->post('area'));
$data['city'] = implode(',', $cityIds);
$model->load($data, '');
$model->save();
return $this->render('view', ['model' => ExpressTemplate::findOne($model->id)]);
}
$data = [];
$provinces = Province::find()->cache(0)->all();
foreach ($provinces as $k => $v) {
$data[$k]['province'] = $v->name;
$cities = City::find()->cache(0)
->where(['province_id' => $v->province_id])
->all();
foreach ($cities as $city) {
$data[$k]['city'][] = ['id' => $city->city_id, 'name' => $city->name];
}
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect('index');
} }
return $this->render('update', [ return $this->render('update', [
'model' => $model, 'data' => $data, 'cities' => explode(',', $model->city)
'model' => $model,
]); ]);
} }
@ -172,7 +113,13 @@ class ExpressTemplateController extends Controller
*/ */
public function actionDelete($id) public function actionDelete($id)
{ {
$this->findModel($id)->delete();
if (Goods::find()->where(['express_template' => $id])->count() == 0) {
$expressTemplateModel = $this->findModel($id);
ExpressArea::deleteAll(['express_template' => $expressTemplateModel->id]);
$expressTemplateModel->delete();
} else {
Yii::$app->session->setFlash('error', '该模板已被使用');
}
return $this->redirect(['index']); return $this->redirect(['index']);
} }
@ -213,4 +160,184 @@ class ExpressTemplateController extends Controller
'columns' => $searchModel->columns() 'columns' => $searchModel->columns()
]); ]);
} }
/**
* @return string
* 运费区域列表
*/
public function actionExpressAreaList($id)
{
$expressTemplate = ExpressTemplate::findOne($id);
$searchModel = new ExpressAreaSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams, $id);
return $this->render('express_area_list', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'columns' => $searchModel->columns(),
'expressTemplate' => $expressTemplate
]);
}
/**
* @return array|mixed|string|Response
* 运费区域模板区域创建方法
*/
public function actionExpressAreaCreate()
{
$expressTemplateId = Yii::$app->request->get('expressTemplateId');
$expressTemplateModel = ExpressTemplate::findOne($expressTemplateId);
$model = new ExpressArea();
$model->basic_count = 1;
$model->basic_price = '0.00';
$model->express_template = $expressTemplateModel->id;
if (Yii::$app->request->isPost) {
$data = Yii::$app->request->post('ExpressArea');
if (Yii::$app->request->isAjax) {
$model->load($data, '');
Yii::$app->response->format = Response::FORMAT_JSON;
$data = ActiveForm::validate($model);
$data['status'] = 2;
return $data;
}
if (Yii::$app->request->post('area') == null) {
return $this->redirect(Yii::$app->request->referrer . '?status=1');
}
$cityIds = array_keys(Yii::$app->request->post('area'));
$data['city'] = implode(',', $cityIds);
$model->load($data, '');
$model->basic_price *= 100;
$model->extra_price *= 100;
if ($expressTemplateModel->calculation_type == ExpressTemplate::CALCULATION_TYPE_WEIGHT) {
$model->basic_count *= 1000;
$model->extra_count *= 1000;
} else {
$model->basic_count *= 1;
$model->extra_count *= 1;
}
$model->save();
return $this->redirect('express-area-list?id='.$model->express_template);
}
$data = [];
$expressAreas = ExpressArea::find()->select(['city'])->where(['express_template' => $expressTemplateModel->id])->all();
$expressAresCityIdArr = [];
if ($expressAreas) {
foreach ($expressAreas as $expressAreaCity) {
$cityIdArr = explode(',', $expressAreaCity->city);
$expressAresCityIdArr = array_unique(array_merge($cityIdArr, $expressAresCityIdArr));
}
}
$provinces = Province::find()->cache(0)->all();
$j = 0;
foreach ($provinces as $k => $v) {
$cities = City::find()
->where(['province_id' => $v->province_id])
->andWhere(['not in', 'city_id', $expressAresCityIdArr])
->all();
if ($cities) {
$data[$j]['province'] = $v->name;
foreach ($cities as $city) {
$data[$j]['city'][] = ['id' => $city->city_id, 'name' => $city->name];
}
$j++;
}
}
if (empty($data)) {
Yii::$app->session->setFlash('error', '已无地区选择');
return $this->redirect('express-area-list?id='.$expressTemplateModel->id);
}
return $this->render('express_area_create', [
'model' => $model,
'data' => $data,
'expressTemplateModel' => $expressTemplateModel
]);
}
/**
* @return array|mixed|string|Response
* 运费区域模板区域更新方法
*/
public function actionExpressAreaUpdate($id)
{
$model = ExpressArea::findOne($id);
$expressTemplateModel = ExpressTemplate::findOne($model->express_template);
$model->basic_price /= 100;
$model->extra_price /= 100;
if ($expressTemplateModel->calculation_type == ExpressTemplate::CALCULATION_TYPE_WEIGHT) {
$model->basic_count /= 10;
$model->extra_count /= 10;
}
$data = Yii::$app->request->post('ExpressArea');
if ($data) {
if (Yii::$app->request->post('area') == null) {
return $this->redirect(Yii::$app->request->referrer . '&status=1');
}
$cityIds = array_keys(Yii::$app->request->post('area'));
$data['city'] = implode(',', $cityIds);
$model->load($data, '');
$model->basic_price *= 100;
$model->extra_price *= 100;
if ($expressTemplateModel->calculation_type == ExpressTemplate::CALCULATION_TYPE_WEIGHT) {
$model->basic_count *= 1000;
$model->extra_count *= 1000;
} else {
$model->basic_count *= 1;
$model->extra_count *= 1;
}
$model->save();
return $this->redirect('express-area-list?id='.$model->express_template);
}
$data = [];
$expressAreas = ExpressArea::find()->select(['city'])->where(['express_template' => $expressTemplateModel->id])->andWhere(['!=', 'id', $id])->all();
$expressAresCityIdArr = [];
if ($expressAreas) {
foreach ($expressAreas as $expressAreaCity) {
$cityIdArr = explode(',', $expressAreaCity->city);
$expressAresCityIdArr = array_unique(array_merge($cityIdArr, $expressAresCityIdArr));
}
}
$provinces = Province::find()->cache(0)->all();
$j = 0;
foreach ($provinces as $k => $v) {
$cities = City::find()
->where(['province_id' => $v->province_id])
->andWhere(['not in', 'city_id', $expressAresCityIdArr])
->all();
if ($cities) {
$data[$j]['province'] = $v->name;
foreach ($cities as $city) {
$data[$j]['city'][] = ['id' => $city->city_id, 'name' => $city->name];
}
$j++;
}
}
return $this->render('express_area_update', [
'model' => $model, 'data' => $data, 'cities' => explode(',', $model->city), 'expressTemplateModel' => $expressTemplateModel
]);
}
/**
* @param $id
* @return string
* 运费区域模板区域查看方法
*/
public function actionExpressAreaView($id)
{
$expressAreaModel = ExpressArea::findOne($id);
$expressTemplateModel = ExpressTemplate::findOne($expressAreaModel->express_template);
return $this->render('express_area_view', [
'model' => $expressAreaModel,
'expressTemplateModel' => $expressTemplateModel
]);
}
public function actionExpressAreaDelete($id)
{
$expressAreaModel = ExpressArea::findOne($id);
$expressTemplateId = $expressAreaModel->express_template;
$expressAreaModel->delete();
return $this->redirect('express-area-list?id='.$expressTemplateId);
}
} }

32
backend/modules/shop/migrations/m191205_092426_drop_columns_province_city_area_basic_price_basic_count_extra_count_extra_price_in_table_ats_express_template.php

@ -0,0 +1,32 @@
<?php
use yii\db\Migration;
/**
* Class m191205_092426_drop_columns_province_city_area_basic_price_basic_count_extra_count_extra_price_in_table_ats_express_template
*/
class m191205_092426_drop_columns_province_city_area_basic_price_basic_count_extra_count_extra_price_in_table_ats_express_template extends Migration
{
public function up()
{
$this->dropColumn('ats_express_template', 'province');
$this->dropColumn('ats_express_template', 'city');
$this->dropColumn('ats_express_template', 'area');
$this->dropColumn('ats_express_template', 'extra_price');
$this->dropColumn('ats_express_template', 'basic_price');
$this->dropColumn('ats_express_template', 'basic_count');
$this->dropColumn('ats_express_template', 'extra_count');
}
public function down()
{
$this->addColumn('ats_express_template', 'province', $this->text()->comment('省份'));
$this->addColumn('ats_express_template', 'city', $this->text()->comment('城市'));
$this->addColumn('ats_express_template', 'area', $this->text()->comment('区域'));
$this->addColumn('ats_express_template', 'extra_price', $this->integer(20)->defaultValue(null)->comment('续重运费'));
$this->addColumn('ats_express_template', 'basic_price', $this->integer(20)->defaultValue(null)->comment('基本运费'));
$this->addColumn('ats_express_template', 'basic_count', $this->integer(20)->defaultValue(null)->comment('基本数量'));
$this->addColumn('ats_express_template', 'extra_count', $this->integer(20)->defaultValue(null)->comment('续重数量'));
return true;
}
}

36
backend/modules/shop/migrations/m191205_092942_create_table_ats_express_area.php

@ -0,0 +1,36 @@
<?php
use yii\db\Migration;
/**
* Class m191205_092942_create_table_ats_express_area
*/
class m191205_092942_create_table_ats_express_area extends Migration
{
public function up()
{
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB COMMENT="快递区域价格表"';
$this->createTable('ats_express_area', [
'id' => $this->primaryKey(),
'province' => $this->text()->comment('省份'),
'city' => $this->text()->comment('城市'),
'area' => $this->text()->comment('区域'),
'express_template' => $this->integer(11)->defaultValue(null)->comment('运费模板id'),
'extra_price' => $this->integer(20)->defaultValue(null)->comment('续重运费'),
'basic_price' => $this->integer(20)->defaultValue(null)->comment('基本运费'),
'basic_count' => $this->integer(20)->defaultValue(null)->comment('基本数量'),
'extra_count' => $this->integer(20)->defaultValue(null)->comment('续重数量'),
'updated_at'=>$this->integer(11)->defaultValue(null)->comment('更新时间'),
'created_at'=>$this->integer(11)->defaultValue(null)->comment('创建时间'),
],$tableOptions);
}
/**
* {@inheritdoc}
*/
public function down()
{
$this->dropTable('ats_express_area');
return true;
}
}

24
backend/modules/shop/migrations/m191206_092733_add_column_about_goods_to_table_collection.php

@ -0,0 +1,24 @@
<?php
use yii\db\Migration;
/**
* Class m191205_062533_update_columns_basic_amount_extra_amount_calculation_in_table_ats_express_template
*/
class m191206_092733_add_column_about_goods_to_table_collection extends Migration
{
public function up()
{
$this->addColumn('ats_collection', 'goods_name', $this->string(120)->notNull()->defaultValue('')->comment('商品名称'));
$this->addColumn('ats_collection', 'goods_img', $this->integer(11)->comment('商品图片'));
$this->addColumn('ats_collection', 'goods_price', $this->integer(20)->notNull()->defaultValue(0)->comment('商品价格'));
}
public function down()
{
$this->dropColumn('ats_collection', 'goods_name');
$this->dropColumn('ats_collection', 'goods_img');
$this->dropColumn('ats_collection', 'goods_price');
return true;
}
}

22
backend/modules/shop/migrations/m191206_162733_add_column_about_user_to_table_comment.php

@ -0,0 +1,22 @@
<?php
use yii\db\Migration;
/**
* Class m191205_062533_update_columns_basic_amount_extra_amount_calculation_in_table_ats_express_template
*/
class m191206_162733_add_column_about_user_to_table_comment extends Migration
{
public function up()
{
$this->addColumn('ats_comment', 'nickname', $this->string(120)->notNull()->defaultValue('')->comment('昵称'));
$this->addColumn('ats_comment', 'avatar', $this->integer(11)->comment('头像'));
}
public function down()
{
$this->dropColumn('ats_comment', 'nickname');
$this->dropColumn('ats_comment', 'avatar');
return true;
}
}

3
backend/modules/shop/models/ars/Address.php

@ -22,6 +22,9 @@ use yii\behaviors\TimestampBehavior;
*/ */
class Address extends \yii\db\ActiveRecord class Address extends \yii\db\ActiveRecord
{ {
const STATUS_DEFAULT = 1;
const STATUS_NOT_DEFAULT = 0;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */

10
backend/modules/shop/models/ars/Collection.php

@ -13,6 +13,9 @@ use yii\behaviors\TimestampBehavior;
* @property int $goods_id 商品id * @property int $goods_id 商品id
* @property int $updated_at 更新时间 * @property int $updated_at 更新时间
* @property int $created_at 创建时间 * @property int $created_at 创建时间
* @property string $goods_name 商品名称
* @property int $goods_img 商品图片
* @property int $goods_price 商品价格
*/ */
class Collection extends \yii\db\ActiveRecord class Collection extends \yii\db\ActiveRecord
{ {
@ -30,8 +33,8 @@ class Collection extends \yii\db\ActiveRecord
public function rules() public function rules()
{ {
return [ return [
[['user_id', 'goods_id'], 'required'],
[['user_id', 'goods_id'], 'integer'],
[['user_id', 'goods_id', 'goods_img', 'goods_price'], 'integer'],
[['goods_name'], 'string', 'max' => 120],
]; ];
} }
@ -46,6 +49,9 @@ class Collection extends \yii\db\ActiveRecord
'goods_id' => '商品id', 'goods_id' => '商品id',
'updated_at' => '更新时间', 'updated_at' => '更新时间',
'created_at' => '创建时间', 'created_at' => '创建时间',
'goods_name' => '商品名称',
'goods_img' => '商品图片',
'goods_price' => '商品价格',
]; ];
} }

8
backend/modules/shop/models/ars/Comment.php

@ -16,6 +16,8 @@ use yii\behaviors\TimestampBehavior;
* @property int $status 状态:1为显示,0为不显示 * @property int $status 状态:1为显示,0为不显示
* @property int $updated_at 更新时间 * @property int $updated_at 更新时间
* @property int $created_at 创建时间 * @property int $created_at 创建时间
* @property string $nickname 昵称
* @property int $avatar 头像
*/ */
class Comment extends \yii\db\ActiveRecord class Comment extends \yii\db\ActiveRecord
{ {
@ -33,9 +35,9 @@ class Comment extends \yii\db\ActiveRecord
public function rules() public function rules()
{ {
return [ return [
[['user_id'], 'required'],
[['user_id', 'order_goods_id', 'star', 'status'], 'integer'],
[['user_id', 'order_goods_id', 'star', 'status', 'avatar'], 'integer'],
[['content'], 'string'], [['content'], 'string'],
[['nickname'], 'string', 'max' => 120],
]; ];
} }
@ -53,6 +55,8 @@ class Comment extends \yii\db\ActiveRecord
'status' => '状态:1为显示,0为不显示', 'status' => '状态:1为显示,0为不显示',
'updated_at' => '更新时间', 'updated_at' => '更新时间',
'created_at' => '创建时间', 'created_at' => '创建时间',
'nickname' => '昵称',
'avatar' => '头像',
]; ];
} }

101
backend/modules/shop/models/ars/ExpressArea.php

@ -0,0 +1,101 @@
<?php
namespace backend\modules\shop\models\ars;
use Yii;
use yii\behaviors\TimestampBehavior;
/**
* This is the model class for table "ats_express_area".
*
* @property int $id
* @property string $province 省份
* @property string $city 城市
* @property string $area 区域
* @property int $express_template 运费模板id
* @property int $extra_price 续重运费
* @property int $basic_price 基本运费
* @property int $basic_count 基本数量
* @property int $extra_count 续重数量
* @property int $updated_at 更新时间
* @property int $created_at 创建时间
*/
class ExpressArea extends \yii\db\ActiveRecord
{
public static $formList = [
1 => [
"basic_count"=>"基本重量(KG)",
"basic_price"=>"基本运费(元)",
"extra_count"=>"续重重量(KG)",
"extra_price"=>"续重运费(元)"
],
2 => [
"basic_count"=>"基本数量(件)",
"basic_price"=>"基本运费(元)",
"extra_count"=>"续重数量(件)",
"extra_price"=>"续重运费(元)"
]
];
/**
* {@inheritdoc}
*/
public static function tableName()
{
return 'ats_express_area';
}
/**
* {@inheritdoc}
*/
public function rules()
{
return [
[['province', 'city', 'area'], 'string'],
[['express_template'], 'integer'],
[['extra_price', 'basic_price', 'basic_count', 'extra_count'], 'safe'],
[['extra_price', 'basic_price', 'basic_count', 'extra_count'], 'number'],
];
}
/**
* {@inheritdoc}
*/
public function attributeLabels()
{
return [
'id' => 'id',
'province' => '省份',
'city' => '城市',
'area' => '区域',
'express_template' => '运费模板id',
'extra_price' => '续重运费',
'basic_price' => '基本运费',
'basic_count' => '基本数量',
'extra_count' => '续重数量',
'updated_at' => '更新时间',
'created_at' => '创建时间',
];
}
/**
* @author linyao
* @email 602604991@qq.com
* @created Nov 8, 2019
*
* 行为存储创建时间和更新时间
*/
public function behaviors()
{
return [
[
'class' => TimestampBehavior::className(),
'createdAtAttribute' => 'created_at',
'updatedAtAttribute' => 'updated_at',
'value' => function() {
return time();
},
],
];
}
}

27
backend/modules/shop/models/ars/ExpressTemplate.php

@ -10,15 +10,8 @@ use yii\behaviors\TimestampBehavior;
* *
* @property int $id * @property int $id
* @property string $name 名称 * @property string $name 名称
* @property string $province 省份
* @property string $city 城市
* @property string $area 区域
* @property int $extra_price 续重运费
* @property int $updated_at 更新时间 * @property int $updated_at 更新时间
* @property int $created_at 创建时间 * @property int $created_at 创建时间
* @property int $basic_price 基本运费
* @property int $basic_count 基本数量
* @property int $extra_count 续重数量
* @property int $calculation_type 计算方式 * @property int $calculation_type 计算方式
*/ */
class ExpressTemplate extends \yii\db\ActiveRecord class ExpressTemplate extends \yii\db\ActiveRecord
@ -46,10 +39,8 @@ class ExpressTemplate extends \yii\db\ActiveRecord
{ {
return [ return [
[['name'], 'required'], [['name'], 'required'],
[['province', 'city', 'area'], 'string'],
[['calculation_type'], 'integer'], [['calculation_type'], 'integer'],
[['name'], 'string', 'max' => 255],
[['extra_price', 'basic_price', 'basic_count', 'extra_count'], 'safe']
[['name'], 'string', 'max' => 255]
]; ];
} }
@ -61,15 +52,8 @@ class ExpressTemplate extends \yii\db\ActiveRecord
return [ return [
'id' => 'id', 'id' => 'id',
'name' => '名称', 'name' => '名称',
'province' => '省份',
'city' => '城市',
'area' => '区域',
'extra_price' => '续重运费',
'updated_at' => '更新时间', 'updated_at' => '更新时间',
'created_at' => '创建时间', 'created_at' => '创建时间',
'basic_price' => '基本运费',
'basic_count' => '基本数量',
'extra_count' => '续重数量',
'calculation_type' => '计算方式', 'calculation_type' => '计算方式',
]; ];
} }
@ -95,4 +79,13 @@ class ExpressTemplate extends \yii\db\ActiveRecord
], ],
]; ];
} }
/**
* @return array
* 数据键值对
*/
public static function modelColumn()
{
return $column = self::find()->select(['name'])->indexBy('id')->column();
}
} }

30
backend/modules/shop/models/ars/Order.php

@ -65,13 +65,20 @@ class Order extends \yii\db\ActiveRecord
return 'ats_order'; return 'ats_order';
} }
public function fields()
{
$fields = parent::fields();
unset($fields['user_id']);
unset($fields['payment_sn']);
return $fields;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function rules() public function rules()
{ {
return [ return [
[['user_id'], 'required'],
[['user_id', 'status', 'type', 'goods_count', 'goods_amount', 'shipping_amount', 'shipping_type', 'taking_site', 'pay_type', 'pay_at', 'payment_amount', 'receivables', 'discount_amount'], 'integer'], [['user_id', 'status', 'type', 'goods_count', 'goods_amount', 'shipping_amount', 'shipping_type', 'taking_site', 'pay_type', 'pay_at', 'payment_amount', 'receivables', 'discount_amount'], 'integer'],
[['discount_description', 'address'], 'string'], [['discount_description', 'address'], 'string'],
[['order_sn', 'invoice_id'], 'string', 'max' => 64], [['order_sn', 'invoice_id'], 'string', 'max' => 64],
@ -118,6 +125,27 @@ class Order extends \yii\db\ActiveRecord
]; ];
} }
public function beforeSave($insert)
{
$address = Yii::createObject([
'class' => 'api\logic\AddressLogic',
]);
if ($insert) {
$default = $address->getDefault();
$this->province = $default['province'] ?? '';
$this->city = $default['city'] ?? '';
$this->area = $default['area'] ?? '';
}
if (!$insert && $this->status == self::STATUS_UNCONFIRMED && $this->type == self::TYPE_SHOPPING) {
$express = Yii::createObject([
'class' => 'api\logic\ExpressLogic',
]);
$this->shipping_amount = $express->countShippingAmount($this);
$this->receivables = $this->goods_amount + $this->shipping_amount;
$this->payment_amount = $this->receivables - $this->discount_amount;
}
return parent::beforeSave($insert);
}
/** /**
* @author linyao * @author linyao

187
backend/modules/shop/models/searchs/ExpressAreaSearch.php

@ -0,0 +1,187 @@
<?php
namespace backend\modules\shop\models\searchs;
use backend\modules\shop\models\ars\City;
use backend\modules\shop\models\ars\Province;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use yii\helpers\ArrayHelper;
use backend\modules\shop\models\ars\ExpressArea;
use yii;
use yii\bootstrap4\Html;
/**
* ExpressAreaSearch represents the model behind the search form of `backend\modules\shop\models\ars\ExpressArea`.
*/
class ExpressAreaSearch extends ExpressArea
{
/**
* @return array
* 增加创建时间查询字段
*/
public function attributes()
{
return ArrayHelper::merge(['created_at_range'], parent::attributes());
}
/**
* {@inheritdoc}
*/
public function rules()
{
return [
[['id', 'express_template', 'extra_price', 'basic_price', 'basic_count', 'extra_count', 'updated_at', 'created_at'], 'integer'],
[['province', 'city', 'area'], 'safe'],
['created_at_range','safe'],
];
}
/**
* {@inheritdoc}
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* @return array
* 列格式
*/
public function columns()
{
return [
[
'class' => 'blobt\grid\CheckboxColumn',
'width' => '2%',
'align' => 'center'
],
'id',
['attribute' => 'city',
'value' => function ($model) {
$expressAreas = ExpressArea::findOne($model->id);
$expressAresCityIdArr = explode(',', $expressAreas->city);
$cities = [];
$provinces = Province::find()->cache(0)->all();
foreach ($provinces as $k => $v) {
$cityId = City::find()
->select(['city_id'])
->where(['province_id' => $v->province_id])
->column();
if (empty(array_diff($cityId, $expressAresCityIdArr))) {
$cities[] = $v->name;
}else{
foreach (\backend\modules\shop\models\ars\City::find()->andWhere(['in', 'city_id', array_diff($cityId, array_diff($cityId, $expressAresCityIdArr))])->all() as $city) {
$cities[] = $city->name;
}
}
}
return implode(' , ', $cities);
},
],
[
'class' => 'iron\grid\ActionColumn',
'align' => 'center',
'config' => [
[
'name' => 'express-area-view',
'icon' => 'list',
'title' => '详情',
],
[
'name' => 'express-area-update',
'icon' => 'pencil',
'title' => '修改'
],
[
'name' => 'express-area-delete',
'icon' => 'trash',
'title' => '删除',
'contents' => '确定删除?'
]
],
],
];
}
/**
* @param $params
* @return ActiveDataProvider
* 不分页的所有数据
*/
public function allData($params)
{
$query = ExpressArea::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => false,
'sort' => false
]);
$this->load($params);
return $this->filter($query, $dataProvider);
}
/**
* Creates data provider instance with search query applied
*
* @param array $params
*
* @return ActiveDataProvider
*/
public function search($params, $expressTemplateId)
{
$query = ExpressArea::find()->where(['express_template' => $expressTemplateId]);
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => [
'pageSizeLimit' => [1, 200]
],
'sort' => [
'defaultOrder' => [
'id' => SORT_DESC,
]
],
]);
$this->load($params);
return $this->filter($query, $dataProvider);
}
/**
* @param $query
* @param $dataProvider
* @return ActiveDataProvider
* 条件筛选
*/
private function filter($query, $dataProvider){
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
'express_template' => $this->express_template,
'extra_price' => $this->extra_price,
'basic_price' => $this->basic_price,
'basic_count' => $this->basic_count,
'extra_count' => $this->extra_count,
'updated_at' => $this->updated_at,
'created_at' => $this->created_at,
]);
$query->andFilterWhere(['like', 'province', $this->province])
->andFilterWhere(['like', 'city', $this->city])
->andFilterWhere(['like', 'area', $this->area]);
if ($this->created_at_range) {
$arr = explode(' ~ ', $this->created_at_range);
$start = strtotime($arr[0]);
$end = strtotime($arr[1]) + 3600 * 24;
$query->andFilterWhere(['between', 'created_at', $start, $end]);
}
return $dataProvider;
}
}

37
backend/modules/shop/models/searchs/ExpressTemplateSearch.php

@ -26,8 +26,8 @@ class ExpressTemplateSearch extends ExpressTemplate
public function rules() public function rules()
{ {
return [ return [
[['id', 'calculation_type', 'basic_price', 'basic_count', 'extra_price', 'extra_count', 'updated_at', 'created_at'], 'integer'],
[['name', 'province', 'city', 'area'], 'safe'],
[['id', 'calculation_type', 'updated_at', 'created_at'], 'integer'],
[['name'], 'safe'],
['created_at_range','safe'], ['created_at_range','safe'],
]; ];
} }
@ -54,9 +54,33 @@ class ExpressTemplateSearch extends ExpressTemplate
], ],
'id', 'id',
'name', 'name',
[
'attribute' => 'calculation_type',
'value' => function ($model) {
return ExpressTemplate::$calculationType[$model->calculation_type];
}
],
[ [
'class' => 'iron\grid\ActionColumn', 'class' => 'iron\grid\ActionColumn',
'align' => 'center', 'align' => 'center',
'config' => [
[
'name' => 'update',
'icon' => 'pencil',
'title' => '修改'
],
[
'name' => 'express-area-list',
'icon' => 'hard-drive',
'title' => '配送区域'
],
[
'name' => 'delete',
'icon' => 'trash',
'title' => '删除',
'contents' => '确定删除?'
]
],
], ],
]; ];
} }
@ -122,18 +146,11 @@ class ExpressTemplateSearch extends ExpressTemplate
$query->andFilterWhere([ $query->andFilterWhere([
'id' => $this->id, 'id' => $this->id,
'calculation_type' => $this->calculation_type, 'calculation_type' => $this->calculation_type,
'basic_price' => $this->basic_price,
'basic_count' => $this->basic_count,
'extra_price' => $this->extra_price,
'extra_count' => $this->extra_count,
'updated_at' => $this->updated_at, 'updated_at' => $this->updated_at,
'created_at' => $this->created_at, 'created_at' => $this->created_at,
]); ]);
$query->andFilterWhere(['like', 'name', $this->name])
->andFilterWhere(['like', 'province', $this->province])
->andFilterWhere(['like', 'city', $this->city])
->andFilterWhere(['like', 'area', $this->area]);
$query->andFilterWhere(['like', 'name', $this->name]);
if ($this->created_at_range) { if ($this->created_at_range) {
$arr = explode(' ~ ', $this->created_at_range); $arr = explode(' ~ ', $this->created_at_range);
$start = strtotime($arr[0]); $start = strtotime($arr[0]);

7
backend/modules/shop/models/searchs/OrderSearch.php

@ -22,6 +22,7 @@ class OrderSearch extends Order
{ {
return ArrayHelper::merge(['created_at_range'], parent::attributes()); return ArrayHelper::merge(['created_at_range'], parent::attributes());
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
@ -42,6 +43,7 @@ class OrderSearch extends Order
// bypass scenarios() implementation in the parent class // bypass scenarios() implementation in the parent class
return Model::scenarios(); return Model::scenarios();
} }
/** /**
* @return array * @return array
* 列格式 * 列格式
@ -169,6 +171,7 @@ class OrderSearch extends Order
], ],
]; ];
} }
/** /**
* @param $params * @param $params
* @return ActiveDataProvider * @return ActiveDataProvider
@ -214,13 +217,15 @@ class OrderSearch extends Order
$this->load($params); $this->load($params);
return $this->filter($query, $dataProvider); return $this->filter($query, $dataProvider);
} }
/** /**
* @param $query * @param $query
* @param $dataProvider * @param $dataProvider
* @return ActiveDataProvider * @return ActiveDataProvider
* 条件筛选 * 条件筛选
*/ */
private function filter($query, $dataProvider){
private function filter($query, $dataProvider)
{
if (!$this->validate()) { if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails // uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1'); // $query->where('0=1');

141
backend/modules/shop/views/express-template/_form.php

@ -2,144 +2,31 @@
use blobt\widgets\Icheck; use blobt\widgets\Icheck;
use backend\modules\shop\models\ars\ExpressTemplate; use backend\modules\shop\models\ars\ExpressTemplate;
use yii\bootstrap4\ActiveForm;
use yii\bootstrap4\Html;
/* @var $this yii\web\View */ /* @var $this yii\web\View */
/* @var $model backend\modules\shop\models\ars\ExpressTemplate */ /* @var $model backend\modules\shop\models\ars\ExpressTemplate */
/* @var $form yii\widgets\ActiveForm */ /* @var $form yii\widgets\ActiveForm */
?> ?>
<?php
$status = Yii::$app->request->get('status');
if ($status == 1) {
?>
<div class="alert alert-warning alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
<p style="color: #2e2e2e">必须至少选择一个城市为配送区域</p>
</div>
<?php } ?>
<?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?>
<div class="order-form">
<?= $form->field($model, 'calculation_type')->widget(Icheck::className(), ["items" => ExpressTemplate::$calculationType, 'type' => "radio"]) ?>
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'basic_count')->textInput() ?>
<?= $form->field($model, 'basic_price')->textInput() ?>
<?= $form->field($model, 'extra_count')->textInput() ?>
<?= $form->field($model, 'extra_price')->textInput() ?>
<?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?>
<?php <?php
$js=<<<JS
const formList = [//切换时,class对应的标题
{
"field-expresstemplate-basic_count":"基本重量(KG)",
"field-expresstemplate-basic_price":"基本运费(元)",
"field-expresstemplate-extra_count":"续重重量(KG)",
"field-expresstemplate-extra_price":"续重运费(元)"
},
{
"field-expresstemplate-basic_count":"基本数量(件)",
"field-expresstemplate-basic_price":"基本运费(元)",
"field-expresstemplate-extra_count":"续重数量(件)",
"field-expresstemplate-extra_price":"续重运费(元)"
}
]
const udfVal = [//初始值
[0.1,"0.00"],
[1,"0.00"]
]
var calType = 1;//初始的计算方式0:计重 1:计件
function updateTypeChangeCalType(type){//当切换计算方式
$.each(formList[type],function(index,value){ //更改文字标题
$("." + index).children("label").html(value)
});
$("#expresstemplate-basic_count").val(udfVal[type][0])//重置初始值
$("#expresstemplate-basic_price").val(udfVal[type][1])
$("#expresstemplate-extra_count").val(0)
$("#expresstemplate-extra_price").val(udfVal[type][1])
calType = type;
if ($isCreate) {
echo $form->field($model, 'calculation_type')->widget(Icheck::className(), ["items" => ExpressTemplate::$calculationType, 'type' => "radio"]);
} }
function changeCalType(type){//当切换计算方式
$.each(formList[type],function(index,value){ //更改文字标题
$("." + index).children("label").html(value)
});
?>
if(!$("#expresstemplate-basic_count").val()){
$("#expresstemplate-basic_count").val(udfVal[type][0])//重置初始值
}
if(!$("#expresstemplate-basic_price").val()){
$("#expresstemplate-basic_price").val(udfVal[type][1])
}
if(!$("#expresstemplate-extra_count").val()){
$("#expresstemplate-extra_count").val(0)
}
if(!$("#expresstemplate-extra_price").val()){
$("#expresstemplate-extra_price").val(udfVal[type][1])
}
calType = type;
}
$(document).ready(function(){
$("#expresstemplate-basic_count").blur(function(){
if (calType == 0) {
if($(this).val() < 0.1){
$(this).val(0.1)
}
var basiccount = $(this).val();
$(this).val(Math.floor(basiccount * 10) / 10);
} else{
if($(this).val() < 1){
$(this).val(1)
}
var basiccount = $(this).val();
$(this).val(Math.floor(basiccount * 1) / 1);
}
})
$("#expresstemplate-basic_price").blur(function(){
if($(this).val().indexOf('-') != -1){
$(this).val("0.00")
}
var basicPrice = $(this).val();
$(this).val(basicPrice.toString().match(/^\d+(?:\.\d{0,2})?/));
})
$("#expresstemplate-extra_count").blur(function(){
if (calType == 0) {
if($(this).val() < 0){
$(this).val(0)
}
var basiccount = $(this).val();
$(this).val(Math.floor(basiccount * 10) / 10);
} else{
if($(this).val() < 0){
$(this).val(0)
}
var basiccount = $(this).val();
$(this).val(Math.floor(basiccount * 1) / 1);
}
})
$("#expresstemplate-extra_price").blur(function(){
if($(this).val().indexOf('-') != -1){
$(this).val("0.00")
}
var basicPrice = $(this).val();
$(this).val(basicPrice.toString().match(/^\d+(?:\.\d{0,2})?/));
})
<div class="form-group">
<?= Html::submitButton('保存', ['class' => 'btn btn-success']) ?>
<?= Html::a('返回', ['index'], ['class' => 'btn btn-info']) ?>
</div>
$("input:radio[name='ExpressTemplate[calculation_type]']").on('ifChecked', function(event){
updateTypeChangeCalType($(this).val()-1)
})
changeCalType(calType)
})
JS;
$this->registerJs($js)
<?php ActiveForm::end(); ?>
?>
</div>

34
backend/modules/shop/views/express-template/create.php

@ -13,38 +13,10 @@ $this->params['breadcrumbs'][] = $this->title;
Yii::$app->params['bsVersion'] = '4.x'; Yii::$app->params['bsVersion'] = '4.x';
?> ?>
<div class="express-template-create"> <div class="express-template-create">
<div class="express-template-form">
<?php
$form = ActiveForm::begin(['options' => ['class' => 'container-fluid']]);
echo TabsX::widget([
'bordered' => true,
'items' => [
[
'label' => '<i class="fas fa-user"></i> 基本信息',
'content' => $this->render('_form', [
<?= $this->render('_form', [
'model' => $model, 'model' => $model,
'form' => $form,
]),
],
[
'label' => '<i class="fas fa-globe"></i> 选择配送区域',
'content' => $this->render('area', ['data' => $data, 'form' => $form, 'cities' => []
]),
],
],
'position' => TabsX::POS_ABOVE,
'encodeLabels' => false
]);
?>
'isCreate' => true
]) ?>
<div class="form-group">
<?= Html::submitButton('保存', ['class' => 'btn btn-success']) ?>
<?= Html::a('返回', ['index'], ['class' => 'btn btn-info']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div> </div>

51
backend/modules/shop/views/express-template/express_area_create.php

@ -0,0 +1,51 @@
<?php
use yii\bootstrap4\Html;
use yii\bootstrap4\ActiveForm;
use kartik\tabs\TabsX;
/* @var $this yii\web\View */
/* @var $model backend\modules\shop\models\ars\ExpressTemplate */
$this->title = '创建区域运费模板';
$this->params['breadcrumbs'][] = ['label' => '运费区域模板', 'url' => ['express_area_list', ['id' => $expressTemplateModel->id]]];
$this->params['breadcrumbs'][] = $this->title;
Yii::$app->params['bsVersion'] = '4.x';
?>
<div class="express-template-create">
<div class="express-template-form">
<?php
$form = ActiveForm::begin(['options' => ['class' => 'container-fluid']]);
echo TabsX::widget([
'bordered' => true,
'items' => [
[
'label' => '<i class="fas fa-user"></i> 基本信息',
'content' => $this->render('express_area_form', [
'model' => $model,
'form' => $form,
'expressTemplateModel' => $expressTemplateModel
]),
],
[
'label' => '<i class="fas fa-globe"></i> 选择配送区域',
'content' => $this->render('area', ['data' => $data, 'form' => $form, 'cities' => []
]),
],
],
'position' => TabsX::POS_ABOVE,
'encodeLabels' => false
]);
?>
<div class="form-group">
<?= Html::submitButton('保存', ['class' => 'btn btn-success']) ?>
<?= Html::a('返回', ['express-area-list', 'id' => $expressTemplateModel->id], ['class' => 'btn btn-info']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>

175
backend/modules/shop/views/express-template/express_area_form.php

@ -0,0 +1,175 @@
<?php
use blobt\widgets\Icheck;
use backend\modules\shop\models\ars\ExpressTemplate;
/* @var $this yii\web\View */
/* @var $model backend\modules\shop\models\ars\ExpressTemplate */
/* @var $form yii\widgets\ActiveForm */
?>
<?php
$status = Yii::$app->request->get('status');
if ($status == 1) {
?>
<div class="alert alert-warning alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
<p style="color: #2e2e2e">必须至少选择一个城市为配送区域</p>
</div>
<?php } ?>
<?= $form->field($model, 'express_template')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'basic_count')->textInput() ?>
<?= $form->field($model, 'basic_price')->textInput() ?>
<?= $form->field($model, 'extra_count')->textInput() ?>
<?= $form->field($model, 'extra_price')->textInput() ?>
<?php
$js=<<<JS
const formList = [//切换时,class对应的标题
{
"field-expressarea-basic_count":"基本重量(KG)",
"field-expressarea-basic_price":"基本运费(元)",
"field-expressarea-extra_count":"续重重量(KG)",
"field-expressarea-extra_price":"续重运费(元)"
},
{
"field-expressarea-basic_count":"基本数量(件)",
"field-expressarea-basic_price":"基本运费(元)",
"field-expressarea-extra_count":"续重数量(件)",
"field-expressarea-extra_price":"续重运费(元)"
}
]
const udfVal = [//初始值
[0.1,"0.00"],
[1,"0.00"]
]
var calType = {$expressTemplateModel->calculation_type}-1;//初始的计算方式0:计重 1:计件
function updateTypeChangeCalType(type){//当切换计算方式
$.each(formList[type],function(index,value){ //更改文字标题
$("." + index).children("label").html(value)
});
$("#expressarea-basic_count").val(udfVal[type][0])//重置初始值
$("#expressarea-basic_price").val(udfVal[type][1])
$("#expressarea-extra_count").val(0)
$("#expressarea-extra_price").val(udfVal[type][1])
calType = type;
}
function changeCalType(type){//当切换计算方式
$.each(formList[type],function(index,value){ //更改文字标题
$("." + index).children("label").html(value)
});
if(!$("#expressarea-basic_count").val()){
$("#expressarea-basic_count").val(udfVal[type][0])//重置初始值
}
if(!$("#expressarea-basic_price").val()){
$("#expressarea-basic_price").val(udfVal[type][1])
}
if(!$("#expressarea-extra_count").val()){
$("#expressarea-extra_count").val(0)
}
if(!$("#expressarea-extra_price").val()){
$("#expressarea-extra_price").val(udfVal[type][1])
}
calType = type;
}
//金额补全
function toFixeds(val, pre) {
const num = parseFloat(val);
// eslint-disable-next-line no-restricted-globals
if (isNaN(num)) {
return false;
}
const p = 10 ** pre;
const value = num * p;
let f = (Math.round(value) / p).toString();
let rs = f.indexOf('.');
if (rs < 0) {
rs = f.length;
f += '.';
}
while (f.length <= rs + pre) {
f += '0';
}
return f;
}
$(document).ready(function(){
$("#expressarea-basic_count").blur(function(){
if(isNaN($(this).val())){
$(this).val(1)
}
if (calType == 0) {
if($(this).val() < 0.1){
$(this).val(1)
}
var basiccount = $(this).val();
$(this).val(toFixeds($(this).val(), 1));
} else{
if($(this).val() < 1){
$(this).val(1)
}
var basiccount = $(this).val();
$(this).val(Math.floor(basiccount * 1) / 1);
}
})
$("#expressarea-basic_price").blur(function(){
if(isNaN($(this).val())){
$(this).val("0.00")
}
if($(this).val().indexOf('-') != -1){
$(this).val("0.00")
}
var basicPrice = $(this).val();
$(this).val(toFixeds($(this).val(), 2));
})
$("#expressarea-extra_count").blur(function(){
if(isNaN($(this).val())){
$(this).val(0)
}
if (calType == 0) {
if($(this).val() < 0){
$(this).val(0)
}
var basiccount = $(this).val();
$(this).val(toFixeds($(this).val(), 1));
} else{
if($(this).val() < 0){
$(this).val(0)
}
var basiccount = $(this).val();
$(this).val(Math.floor(basiccount * 1) / 1);
}
})
$("#expressarea-extra_price").blur(function(){
if(isNaN($(this).val())){
$(this).val("0.00")
}
if($(this).val().indexOf('-') != -1){
$(this).val("0.00")
}
var basicPrice = $(this).val();
$(this).val(toFixeds($(this).val(), 2));
})
$("input:radio[name='ExpressArea[calculation_type]']").on('ifChecked', function(event){
updateTypeChangeCalType($(this).val()-1)
})
changeCalType(calType)
})
JS;
$this->registerJs($js)
?>

33
backend/modules/shop/views/express-template/express_area_list.php

@ -0,0 +1,33 @@
<?php
use yii\helpers\Html;
use iron\grid\GridView;
/* @var $this yii\web\View */
/* @var $searchModel backend\modules\shop\models\searchs\ExpressAreaSearch */
/* @var $dataProvider yii\data\ActiveDataProvider */
$this->title = '运费区域模板:'.$expressTemplate->name;
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="row">
<div class="col-12">
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filter' => $this->render("_search", ['model' => $searchModel]),
'batch' => [
[
"label" => "删除",
"url" => "express-area/deletes"
],
],
'columns' => $columns,
'batchTemplate' => '',
'create' => '',
'export' => '',
'content' => Html::a('创建', ['express-area-create', 'expressTemplateId' => $expressTemplate->id], ['class' => 'btn btn-default']).
Html::a('返回', ['index'], ['class' => 'btn btn-default'])
]);
?>
</div>
</div>

52
backend/modules/shop/views/express-template/express_area_update.php

@ -0,0 +1,52 @@
<?php
use yii\bootstrap4\Html;
use yii\bootstrap4\ActiveForm;
use kartik\tabs\TabsX;
/* @var $this yii\web\View */
/* @var $model backend\modules\shop\models\ars\ExpressTemplate */
$this->title = '编辑区域运费模板';
$this->params['breadcrumbs'][] = ['label' => '运费模板', 'url' => ['index']];
$this->params['breadcrumbs'][] = ['label' => '区域运费模板:'.$expressTemplateModel->name, 'url' => ['express-area-list', 'id' => $expressTemplateModel->id]];
$this->params['breadcrumbs'][] = '编辑区域运费模板';
Yii::$app->params['bsVersion'] = '4.x';
?>
<div class="express-template-update">
<div class="express-template-form">
<?php
$form = ActiveForm::begin(['options' => ['class' => 'container-fluid']]);
echo TabsX::widget([
'bordered' => true,
'items' => [
[
'label' => '<i class="fas fa-user"></i> 基本信息',
'content' => $this->render('express_area_form', [
'model' => $model,
'form' => $form,
'expressTemplateModel' => $expressTemplateModel
]),
],
[
'label' => '<i class="fas fa-globe"></i> 选择配送区域',
'content' => $this->render('area', ['data' => $data, 'form' => $form, 'cities' => $cities
]),
],
],
'position' => TabsX::POS_ABOVE,
'encodeLabels' => false
]);
?>
<div class="form-group">
<?= Html::submitButton('保存', ['class' => 'btn btn-success']) ?>
<?= Html::a('返回', ['express-area-list', 'id' => $expressTemplateModel->id], ['class' => 'btn btn-info']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div>

94
backend/modules/shop/views/express-template/express_area_view.php

@ -0,0 +1,94 @@
<?php
use backend\modules\shop\models\ars\City;
use backend\modules\shop\models\ars\ExpressArea;
use backend\modules\shop\models\ars\Province;
use yii\helpers\Html;
use yii\widgets\DetailView;
use backend\modules\shop\models\ars\ExpressTemplate;
/* @var $this yii\web\View */
/* @var $model backend\modules\shop\models\ars\ExpressTemplate */
$this->title = $model->id;
$this->params['breadcrumbs'][] = ['label' => '运费模板', 'url' => ['index']];
$this->params['breadcrumbs'][] = ['label' => '运费区域模板:'.$expressTemplateModel->name, 'url' => ['express-area-list?id='.$expressTemplateModel->id]];
$this->params['breadcrumbs'][] = $this->title;
\yii\web\YiiAsset::register($this);
?>
<div class="express-template-view">
<p>
<?= Html::a('返回列表', ['express-area-list?id='.$expressTemplateModel->id], ['class' => 'btn btn-success']) ?>
</p>
<?= DetailView::widget([
'model' => $model,
'attributes' => [
'id',
[
'attribute' => 'basic_count',
'label' => ExpressArea::$formList[$expressTemplateModel->calculation_type]['basic_count'],
'value' => function ($model) {
$expressTemplateModel = ExpressTemplate::findOne($model->express_template);
if ($expressTemplateModel->calculation_type == ExpressTemplate::CALCULATION_TYPE_WEIGHT) {
return $model->basic_count /= 10;
} else {
return $model->basic_count;
}
}
],
[
'attribute' => 'basic_price',
'label' => ExpressArea::$formList[$expressTemplateModel->calculation_type]['basic_price'],
'value' => function ($model) {
return $model->basic_price /= 100;
}
],
[
'attribute' => 'extra_count',
'label' => ExpressArea::$formList[$expressTemplateModel->calculation_type]['extra_count'],
'value' => function ($model) {
$expressTemplateModel = ExpressTemplate::findOne($model->express_template);
if ($expressTemplateModel->calculation_type == ExpressTemplate::CALCULATION_TYPE_WEIGHT) {
return $model->extra_count /= 10;
} else {
return $model->extra_count;
}
}
],
[
'attribute' => 'extra_price',
'label' => ExpressArea::$formList[$expressTemplateModel->calculation_type]['extra_price'],
'value' => function ($model) {
return $model->extra_price /= 100;
}
],
'updated_at:datetime',
'created_at:datetime',
['attribute' => 'city',
'value' => function ($model) {
$expressAreas = ExpressArea::findOne($model->id);
$expressAresCityIdArr = explode(',', $expressAreas->city);
$cities = [];
$provinces = Province::find()->cache(0)->all();
foreach ($provinces as $k => $v) {
$cityId = City::find()
->select(['city_id'])
->where(['province_id' => $v->province_id])
->column();
if (empty(array_diff($cityId, $expressAresCityIdArr))) {
$cities[] = $v->name;
}else{
foreach (\backend\modules\shop\models\ars\City::find()->andWhere(['in', 'city_id', array_diff($cityId, array_diff($cityId, $expressAresCityIdArr))])->all() as $city) {
$cities[] = $city->name;
}
}
}
return implode(' , ', $cities);
},
],
],
]) ?>
</div>

34
backend/modules/shop/views/express-template/update.php

@ -14,38 +14,10 @@ $this->params['breadcrumbs'][] = 'Update ';
Yii::$app->params['bsVersion'] = '4.x'; Yii::$app->params['bsVersion'] = '4.x';
?> ?>
<div class="express-template-update"> <div class="express-template-update">
<div class="express-template-form">
<?php
$form = ActiveForm::begin(['options' => ['class' => 'container-fluid']]);
echo TabsX::widget([
'bordered' => true,
'items' => [
[
'label' => '<i class="fas fa-user"></i> 基本信息',
'content' => $this->render('_form', [
<?= $this->render('_form', [
'model' => $model, 'model' => $model,
'form' => $form,
]),
],
[
'label' => '<i class="fas fa-globe"></i> 选择配送区域',
'content' => $this->render('area', ['data' => $data, 'form' => $form, 'cities' => $cities
]),
],
],
'position' => TabsX::POS_ABOVE,
'encodeLabels' => false
]);
?>
'isCreate' => false
]) ?>
<div class="form-group">
<?= Html::submitButton('保存', ['class' => 'btn btn-success']) ?>
<?= Html::a('返回', ['index'], ['class' => 'btn btn-info']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
</div> </div>

7
backend/views/layouts/main.php

@ -31,16 +31,12 @@ AppAsset::register($this);
<body class="hold-transition skin-blue-light sidebar-mini"> <body class="hold-transition skin-blue-light sidebar-mini">
<?php $this->beginBody() ?> <?php $this->beginBody() ?>
<div class="wrapper"> <div class="wrapper">
<?= $this->render('header') ?>
<?= $this->render('sidebar') ?>
<div class="content-wrapper">
<?php <?php
if (Yii::$app->session->hasFlash('error') || Yii::$app->session->hasFlash('success')) { if (Yii::$app->session->hasFlash('error') || Yii::$app->session->hasFlash('success')) {
echo Alert::widget(); echo Alert::widget();
} }
?> ?>
<div class="content">
<section class="content-header"> <section class="content-header">
<?= $this->render('breadcrumb') ?> <?= $this->render('breadcrumb') ?>
</section> </section>
@ -49,7 +45,6 @@ AppAsset::register($this);
</section> </section>
</div> </div>
<?= $this->render('footer') ?>
</div> </div>
<?php $this->endBody() ?> <?php $this->endBody() ?>
</body> </body>

47
backend/views/layouts/sidebar.php

@ -1,47 +0,0 @@
<?php
use iron\widgets\Menu;
?>
<aside class="main-sidebar sidebar-dark-info elevation-4">
<a href="#" class="brand-link">
<img src="/img/logo.jpeg" alt="AdminLTE" class="brand-image img-circle elevation-3"
style="opacity: .8">
<span class="brand-text font-weight-light">AdminLTE 3</span>
</a>
<!-- sidebar: style can be found in sidebar.less -->
<section class="sidebar">
<?php
echo Menu::widget([
'items' => [
// ['label' => 'MAIN NAVIGATION', 'is_header' => true],
['label' => '商城管理', 'url' => '#', 'icon' => 'far fa-store', 'items' => [
['label' => '运营数据', 'url' => ['site/index', 'tag' => 'new']],
['label' => '基础配置', 'url' => ['config/index', 'tag' => 'new']],
]
],
['label' => '商品管理', 'url' => '#', 'icon' => 'far fa-box', 'items' => [
['label' => '后台商品分类', 'url' => ['/goods/category/index']],
['label' => '规格管理', 'url' => ['/goods/attribute/index']],
['label' => '前端商品分类', 'url' => ['/goods/shop-category/index']],
['label' => '品牌管理', 'url' => ['/goods/brand/index']],
['label' => '供应商管理', 'url' => ['/goods/supplier/index']],
['label' => '商品列表', 'url' => ['/goods/goods/index']],
]
],
['label' => '订单管理', 'url' => '#', 'icon' => 'far fa-list-alt', 'items' => [
['label' => '订单列表', 'url' => ['/shop/order/index', 'tag' => 'new']],
],
],
['label' => '配送服务', 'url' => '#', 'icon' => 'far fa-shipping-fast', 'items' => [
['label' => '上门自提', 'url' => ['/shop/taking-site/index']],
['label' => '运费模板', 'url' => ['/shop/express-template/index']],
]
],
]
]);
?>
</section>
<!-- /.sidebar -->
</aside>

7
backend/web/css/site.css

@ -50,3 +50,10 @@
.icheck-label-group label{ .icheck-label-group label{
margin-right: 20px; margin-right: 20px;
} }
body::-webkit-scrollbar{
width: 1px;
height: 1px;
}
body{
margin:10px;
}

1
backend/web/index.php

@ -1,5 +1,4 @@
<?php <?php
defined('YII_DEBUG') or define('YII_DEBUG', true); defined('YII_DEBUG') or define('YII_DEBUG', true);
defined('YII_ENV') or define('YII_ENV', 'dev'); defined('YII_ENV') or define('YII_ENV', 'dev');

BIN
backend/web/uploads/xls/15738696921690.jpg

Before

Width: 1024  |  Height: 759  |  Size: 159 KiB

2
common/config/bootstrap.php

@ -2,3 +2,5 @@
Yii::setAlias('@common', dirname(__DIR__)); Yii::setAlias('@common', dirname(__DIR__));
Yii::setAlias('@console', dirname(dirname(__DIR__)) . '/console'); Yii::setAlias('@console', dirname(dirname(__DIR__)) . '/console');
Yii::setAlias('@backend', dirname(dirname(__DIR__)) . '/backend'); Yii::setAlias('@backend', dirname(dirname(__DIR__)) . '/backend');
Yii::setAlias('@goods', dirname(dirname(__DIR__)) . '/goods');
Yii::setAlias('@api', dirname(dirname(__DIR__)) . '/api');

9
common/config/main.php

@ -12,9 +12,18 @@ return [
'timeZone' => 'Asia/Shanghai', 'timeZone' => 'Asia/Shanghai',
'language' => 'zh-CN', 'language' => 'zh-CN',
'components' => [ 'components' => [
'userLogic' => ['class' => 'iron\logic\UserManager'],
'cache' => [ 'cache' => [
'class' => 'yii\caching\FileCache', 'class' => 'yii\caching\FileCache',
], ],
'mongodb' => [
'class' => '\yii\mongodb\Connection',
'dsn' => 'mongodb://127.0.0.1:27017/love',
'options' => [
// "username" => "",
// "password" => ""
]
],
'authManager' => [ 'authManager' => [
'class' => 'yii\rbac\DbManager', 'class' => 'yii\rbac\DbManager',
], ],

59
common/models/DailyActiveUser.php

@ -0,0 +1,59 @@
<?php
namespace common\models;
/**
* Created by PhpStorm.
* User: iron
* Date: 19-1-15
* Time: 下午7:40
*
* @property int $admin_id 管理员id
* @property string $admin_name 管理员名
* @property string $ip 客户端ip
* @property string $admin_agent 客户端版本
* @property string $path 访问路径
* @property string $method http方法
* @property array $params 各类参数
* @property int $created_at 创建时间
*/
use yii\mongodb\ActiveRecord;
class DailyActiveUser extends ActiveRecord
{
/**
* @return string the name of the index associated with this ActiveRecord class.
*/
public static function collectionName()
{
return 'daily_active_user';
}
/**
* @return array list of attribute names.
*/
public function attributes()
{
return ['_id', 'date', 'created_at', 'user_ids', 'count'];
}
public function rules()
{
return [
['count','default','value'=>1],
['created_at','default','value'=>time()]
];
}
public function attributeLabels()
{
return [
'date' => '日期',
'created_at' => '创建时间',
'user_ids' => '用户id',
'count' => '数量'
];
}
}

249
common/models/User.php

@ -1,50 +1,71 @@
<?php <?php
namespace common\models; namespace common\models;
use Yii; use Yii;
use yii\base\NotSupportedException;
use yii\behaviors\TimestampBehavior; use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface; use yii\web\IdentityInterface;
use yii\web\NotFoundHttpException;
use yii\web\UnauthorizedHttpException;
/** /**
* User model
* This is the model class for table "user".
* *
* @property integer $id
* @property string $username
* @property int $id
* @property string $username 用户名
* @property string $auth_key
* @property string $password_hash * @property string $password_hash
* @property string $password_reset_token * @property string $password_reset_token
* @property string $verification_token
* @property string $email
* @property string $auth_key
* @property integer $status
* @property integer $created_at
* @property integer $updated_at
* @property string $password write-only password
*/
class User extends ActiveRecord implements IdentityInterface
* @property string $name 姓名
* @property int $sex 性别
* @property string $phone 联系方式
* @property string $email 邮箱
* @property int $role 角色
* @property int $status 状态
* @property string $access_token 令牌
* @property int $expire_at 令牌过期时间
* @property string $nickname 昵称
* @property string $avatar 头像
* @property string $wx_openid 微信openid
* @property string $mini_openid 小程序openid
* @property string $unionid 微信联合id
* @property string $session_key 小程序会话秘钥
* @property string $member_code 会员编号
* @property int $exp_point 经验值
* @property int $consume_point 消费积分
* @property int $created_at 创建时间
* @property int $updated_at 更新时间
*/
class User extends \yii\db\ActiveRecord implements IdentityInterface
{ {
const STATUS_DELETED = 0;
const STATUS_INACTIVE = 9;
const STATUS_ACTIVE = 10;
const STATUS_DELETED = 0;
const STATUS_ACTIVE = 1;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public static function tableName() public static function tableName()
{ {
return '{{%user}}';
return 'user';
} }
/**
* {@inheritdoc}
*/
public function behaviors()
public function fields()
{ {
return [
TimestampBehavior::className(),
];
$fields = parent::fields();
unset($fields['auth_key']);
unset($fields['password_hash']);
unset($fields['password_reset_token']);
unset($fields['role']);
unset($fields['status']);
unset($fields['access_token']);
unset($fields['expire_at']);
unset($fields['wx_openid']);
unset($fields['mini_openid']);
unset($fields['session_key']);
unset($fields['created_at']);
unset($fields['updated_at']);
return $fields;
} }
/** /**
@ -53,88 +74,104 @@ class User extends ActiveRecord implements IdentityInterface
public function rules() public function rules()
{ {
return [ return [
['status', 'default', 'value' => self::STATUS_INACTIVE],
['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_INACTIVE, self::STATUS_DELETED]],
[['auth_key', 'password_hash'], 'required'],
[['sex', 'role', 'status', 'expire_at', 'exp_point', 'consume_point'], 'integer'],
[['username', 'password_hash', 'password_reset_token', 'email', 'access_token', 'avatar'], 'string', 'max' => 255],
[['auth_key', 'wx_openid', 'mini_openid'], 'string', 'max' => 32],
[['name', 'nickname', 'session_key'], 'string', 'max' => 120],
[['phone'], 'string', 'max' => 13],
[['unionid'], 'string', 'max' => 60],
[['member_code'], 'string', 'max' => 20],
]; ];
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public static function findIdentity($id)
public function attributeLabels()
{ {
return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
return [
'id' => 'id',
'username' => 'username',
'auth_key' => 'auth_key',
'password_hash' => 'password_hash',
'password_reset_token' => 'password_reset_token',
'name' => 'name',
'sex' => 'sex',
'phone' => '联系方式',
'email' => 'email',
'role' => 'role',
'status' => 'status',
'access_token' => 'access_token',
'expire_at' => 'expire_at',
'nickname' => 'nickname',
'avatar' => 'avatar',
'wx_openid' => '公众号openid',
'mini_openid' => '小程序openid',
'unionid' => 'unionid',
'session_key' => '小程序解密密钥',
'member_code' => '会员编号',
'exp_point' => '经验值',
'consume_point' => '消费积分',
'created_at' => '创建时间',
'updated_at' => '更新时间',
];
} }
/**
* {@inheritdoc}
*/
public static function findIdentityByAccessToken($token, $type = null)
{
throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
}
/** /**
* Finds user by username
* @author linyao
* @email 602604991@qq.com
* @created Nov 8, 2019
* *
* @param string $username
* @return static|null
* 行为存储创建时间和更新时间
*/ */
public static function findByUsername($username)
public function behaviors()
{ {
return static::findOne(['username' => $username, 'status' => self::STATUS_ACTIVE]);
return [
[
'class' => TimestampBehavior::className(),
'createdAtAttribute' => 'created_at',
'updatedAtAttribute' => 'updated_at',
'value' => function () {
return time();
},
],
];
} }
/** /**
* Finds user by password reset token
*
* @param string $token password reset token
* @return static|null
* @inheritDoc
*/ */
public static function findByPasswordResetToken($token)
public static function findIdentity($id)
{ {
if (!static::isPasswordResetTokenValid($token)) {
return null;
}
return static::findOne([
'password_reset_token' => $token,
'status' => self::STATUS_ACTIVE,
]);
}
/**
* Finds user by verification email token
*
* @param string $token verify email token
* @return static|null
*/
public static function findByVerificationToken($token) {
return static::findOne([
'verification_token' => $token,
'status' => self::STATUS_INACTIVE
]);
return static::findOne(['id' => $id, 'status' => self::STATUS_ACTIVE]);
} }
/** /**
* Finds out if password reset token is valid
*
* @param string $token password reset token
* @return bool
* @param mixed $token
* @param null $type
* @return array|\yii\db\ActiveRecord|IdentityInterface|null
* @throws NotFoundHttpException
* @throws UnauthorizedHttpException
*/ */
public static function isPasswordResetTokenValid($token)
public static function findIdentityByAccessToken($token, $type = null)
{ {
if (empty($token)) {
return false;
$user = static::find()
->where(['access_token' => $token, 'status' => self::STATUS_ACTIVE])
->one();
if (!$user) {
throw new NotFoundHttpException('user not found');
}
if ($user->expire_at < time()) {
throw new UnauthorizedHttpException('access - token expired ', -1);
} else {
return $user;
} }
$timestamp = (int) substr($token, strrpos($token, '_') + 1);
$expire = Yii::$app->params['user.passwordResetTokenExpire'];
return $timestamp + $expire >= time();
} }
/** /**
* {@inheritdoc}
* @inheritDoc
*/ */
public function getId() public function getId()
{ {
@ -142,7 +179,7 @@ class User extends ActiveRecord implements IdentityInterface
} }
/** /**
* {@inheritdoc}
* @inheritDoc
*/ */
public function getAuthKey() public function getAuthKey()
{ {
@ -150,60 +187,10 @@ class User extends ActiveRecord implements IdentityInterface
} }
/** /**
* {@inheritdoc}
* @inheritDoc
*/ */
public function validateAuthKey($authKey) public function validateAuthKey($authKey)
{ {
return $this->getAuthKey() === $authKey; return $this->getAuthKey() === $authKey;
} }
/**
* Validates password
*
* @param string $password password to validate
* @return bool if password provided is valid for current user
*/
public function validatePassword($password)
{
return Yii::$app->security->validatePassword($password, $this->password_hash);
}
/**
* Generates password hash from password and sets it to the model
*
* @param string $password
*/
public function setPassword($password)
{
$this->password_hash = Yii::$app->security->generatePasswordHash($password);
}
/**
* Generates "remember me" authentication key
*/
public function generateAuthKey()
{
$this->auth_key = Yii::$app->security->generateRandomString();
}
/**
* Generates new password reset token
*/
public function generatePasswordResetToken()
{
$this->password_reset_token = Yii::$app->security->generateRandomString() . '_' . time();
}
public function generateEmailVerificationToken()
{
$this->verification_token = Yii::$app->security->generateRandomString() . '_' . time();
}
/**
* Removes password reset token
*/
public function removePasswordResetToken()
{
$this->password_reset_token = null;
}
} }

2
composer.json

@ -15,6 +15,8 @@
"yiisoft/yii2": "~2.0.14", "yiisoft/yii2": "~2.0.14",
"yiisoft/yii2-bootstrap4": "~2.0.6", "yiisoft/yii2-bootstrap4": "~2.0.6",
"yiisoft/yii2-redis": "^2.0.0", "yiisoft/yii2-redis": "^2.0.0",
"yiisoft/yii2-mongodb": "~2.1.0",
"yiisoft/yii2-httpclient": "^2.0@dev",
"moonlandsoft/yii2-phpexcel": "*", "moonlandsoft/yii2-phpexcel": "*",
"kartik-v/yii2-tabs-x": "^1.2@dev", "kartik-v/yii2-tabs-x": "^1.2@dev",
"kartik-v/yii2-editable": "^1.7@dev", "kartik-v/yii2-editable": "^1.7@dev",

105
composer.lock

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "f679ebe17a306b33afd5dede1cb05dfb",
"content-hash": "687669f68148fd8fc648686c605f5952",
"packages": [ "packages": [
{ {
"name": "antkaz/yii2-vue", "name": "antkaz/yii2-vue",
@ -1434,6 +1434,108 @@
], ],
"time": "2019-07-16T13:22:50+00:00" "time": "2019-07-16T13:22:50+00:00"
}, },
{
"name": "yiisoft/yii2-httpclient",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/yiisoft/yii2-httpclient.git",
"reference": "05ecc99868352cf840173bfd8fe67bfd84b5f295"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yiisoft/yii2-httpclient/zipball/05ecc99868352cf840173bfd8fe67bfd84b5f295",
"reference": "05ecc99868352cf840173bfd8fe67bfd84b5f295",
"shasum": ""
},
"require": {
"yiisoft/yii2": "~2.0.13"
},
"require-dev": {
"phpunit/phpunit": "4.8.27|~5.7.21|^6.2"
},
"type": "yii2-extension",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-4": {
"yii\\httpclient\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Paul Klimov",
"email": "klimov.paul@gmail.com"
}
],
"description": "HTTP client extension for the Yii framework",
"keywords": [
"curl",
"http",
"httpclient",
"yii2"
],
"time": "2019-10-08T09:48:57+00:00"
},
{
"name": "yiisoft/yii2-mongodb",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/yiisoft/yii2-mongodb.git",
"reference": "f14578beb63500bf56841ae599620b76a62dc5c2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yiisoft/yii2-mongodb/zipball/f14578beb63500bf56841ae599620b76a62dc5c2",
"reference": "f14578beb63500bf56841ae599620b76a62dc5c2",
"shasum": ""
},
"require": {
"ext-mongodb": ">=1.0.0",
"yiisoft/yii2": "~2.0.14"
},
"require-dev": {
"phpunit/phpunit": "4.8.27|~5.7.21|^6.2"
},
"type": "yii2-extension",
"extra": {
"branch-alias": {
"dev-master": "2.1.x-dev"
}
},
"autoload": {
"psr-4": {
"yii\\mongodb\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Paul Klimov",
"email": "klimov.paul@gmail.com"
}
],
"description": "MongoDB extension for the Yii framework",
"keywords": [
"GridFS",
"active-record",
"mongo",
"mongodb",
"yii2"
],
"time": "2019-11-22T09:25:40+00:00"
},
{ {
"name": "yiisoft/yii2-redis", "name": "yiisoft/yii2-redis",
"version": "dev-master", "version": "dev-master",
@ -1770,6 +1872,7 @@
"aliases": [], "aliases": [],
"minimum-stability": "dev", "minimum-stability": "dev",
"stability-flags": { "stability-flags": {
"yiisoft/yii2-httpclient": 20,
"kartik-v/yii2-tabs-x": 20, "kartik-v/yii2-tabs-x": 20,
"kartik-v/yii2-editable": 20, "kartik-v/yii2-editable": 20,
"kartik-v/yii2-widget-depdrop": 20, "kartik-v/yii2-widget-depdrop": 20,

3
console/controllers/InitController.php

@ -7,8 +7,7 @@ use yii\console\Controller;
use yii\helpers\Console; use yii\helpers\Console;
use yii\db\Query; use yii\db\Query;
use yii\helpers\ArrayHelper; use yii\helpers\ArrayHelper;
use common\models\User;
use common\models\Category;
use backend\models\User;
/** /**
* Description of RbacsetController * Description of RbacsetController

41
console/migrations/m191122_011654_add_column_admin_id_in_table_user.php

@ -0,0 +1,41 @@
<?php
use yii\db\Migration;
/**
* Class m191122_011654_create_table_user_admin
*/
class m191122_011654_add_column_admin_id_in_table_user extends Migration
{
/**
* {@inheritdoc}
*/
public function safeUp()
{
$this->addColumn('user','admin_id',$this->integer(11)->notNull()->defaultValue(0));
}
/**
* {@inheritdoc}
*/
public function safeDown()
{
$this->dropColumn('user','admin_id');
return true;
}
/*
// Use up()/down() to run migration code without a transaction.
public function up()
{
}
public function down()
{
echo "m191122_011654_create_table_user_admin cannot be reverted.\n";
return false;
}
*/
}

26
console/migrations/m191204_092644_rename_backend_user.php

@ -0,0 +1,26 @@
<?php
use yii\db\Migration;
/**
* Class m191111_102644_create_table_province
*/
class m191204_092644_rename_backend_user extends Migration
{
/**
* {@inheritdoc}
*/
public function up()
{
$sql = 'alter table user rename to auth_user ';
$this->execute($sql);
}
/**
* {@inheritdoc}
*/
public function down()
{
return true;
}
}

52
console/migrations/m191204_102644_create_table_province.php

@ -0,0 +1,52 @@
<?php
use yii\db\Migration;
/**
* Class m191111_102644_create_table_province
*/
class m191204_102644_create_table_province extends Migration
{
/**
* {@inheritdoc}
*/
public function up()
{
$tableOptions = 'CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB COMMENT="用户"';
$this->createTable('user', [
'id' => $this->primaryKey(),
'username'=>$this->string(255)->comment('用户名'),
'auth_key'=>$this->string(32)->notNull()->comment(''),
'password_hash'=>$this->string(255)->notNull()->comment(''),
'password_reset_token'=>$this->string(255)->defaultValue(null)->comment(''),
'name'=>$this->string(120)->comment('姓名'),
'sex'=>$this->integer(1)->comment('性别'),
'phone'=>$this->string(13)->comment('联系方式'),
'email'=>$this->string(255)->comment('邮箱'),
'role'=>$this->tinyInteger(1)->defaultValue(1)->comment('角色'),
'status'=>$this->tinyInteger(1)->defaultValue(1)->comment('状态'),
'access_token'=>$this->string(255)->comment('令牌'),
'expire_at'=>$this->integer(11)->comment('令牌过期时间'),
'nickname'=>$this->string(120)->comment('昵称'),
'avatar'=>$this->string(255)->comment('头像'),
'wx_openid'=>$this->string(32)->comment('微信openid'),
'mini_openid'=>$this->string(32)->comment('小程序openid'),
'unionid'=>$this->string(60)->comment('微信联合id'),
'session_key'=>$this->string(120)->comment('小程序会话秘钥'),
'member_code'=>$this->string(20)->comment('会员编号'),
'exp_point'=>$this->integer(20)->comment('经验值'),
'consume_point'=>$this->integer(20)->defaultValue(null)->comment('消费积分'),
'created_at'=>$this->integer(11)->notNull()->comment('创建时间'),
'updated_at'=>$this->integer(11)->notNull()->comment('更新时间'),
],$tableOptions);
}
/**
* {@inheritdoc}
*/
public function down()
{
$this->dropTable("user");
return true;
}
}

83
console/runtime/logs/app.log
File diff suppressed because it is too large
View File

0
datadictionary.md

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save