joway 2 år sedan
förälder
incheckning
460badb854
100 ändrade filer med 12596 tillägg och 9134 borttagningar
  1. 15 0
      backendApi/config/menu.php
  2. 2 2
      backendApi/config/params.php
  3. 8 0
      backendApi/config/urlManagerRules.php
  4. 1 1
      backendApi/modules/v1/controllers/BaseController.php
  5. 51 0
      backendApi/modules/v1/controllers/BonusController.php
  6. 160 5
      backendApi/modules/v1/controllers/ConfigController.php
  7. 35 1
      backendApi/modules/v1/controllers/ShopController.php
  8. 13 0
      backendApi/modules/v1/controllers/SiteController.php
  9. 5 5
      backendApi/modules/v1/controllers/UserController.php
  10. 3 3
      backendApi/modules/v1/models/lists/bonus/BalanceList.php
  11. 1 1
      backendApi/modules/v1/models/lists/bonus/FlowBonusList.php
  12. 1 0
      backendApi/modules/v1/models/lists/log/AdminHandleList.php
  13. 122 0
      backendApi/modules/v1/models/lists/shop/FlowRemainPvList.php
  14. 2 2
      backendApi/modules/v1/models/lists/shop/GoodsList.php
  15. 36 2
      backendApi/modules/v1/models/lists/shop/OrderList.php
  16. 1 1
      backendApi/modules/v1/models/lists/shop/OrderShopList.php
  17. 3 0
      backendApi/modules/v1/models/lists/shop/PackageList.php
  18. 104 0
      backendApi/modules/v1/models/lists/shop/RemainPvList.php
  19. 20 6
      backendApi/modules/v1/models/lists/user/IndexList.php
  20. 36 0
      backendEle/src/router/index.js
  21. 166 0
      backendEle/src/views/bonus/perf-adjustment.vue
  22. 53 1
      backendEle/src/views/config/base.vue
  23. 2 39
      backendEle/src/views/config/bonus-opt.vue
  24. 2 2
      backendEle/src/views/config/transfer.vue
  25. 324 313
      backendEle/src/views/finance/withdraw.vue
  26. 90 0
      backendEle/src/views/shop/flow-remain-pv.vue
  27. 265 232
      backendEle/src/views/shop/goods-add.vue
  28. 384 356
      backendEle/src/views/shop/index.vue
  29. 129 112
      backendEle/src/views/shop/order-list.vue
  30. 101 102
      backendEle/src/views/shop/package-add.vue
  31. 271 284
      backendEle/src/views/shop/package.vue
  32. 90 0
      backendEle/src/views/shop/remain-pv.vue
  33. 5 1
      common/components/SwooleAsyncTimer.php
  34. 8 1
      common/config/params.php
  35. 54 0
      common/helpers/DingTalk.php
  36. 16 0
      common/helpers/Excel.php
  37. 56 0
      common/helpers/LoggerTool.php
  38. 13 122
      common/helpers/bonus/BonusCalc.php
  39. 172 22
      common/helpers/bonus/BonusSend.php
  40. 2 1
      common/helpers/bonus/CalcCache.php
  41. 118 20
      common/helpers/bonus/PerfCalc.php
  42. 3 32
      common/helpers/bonus/PreparePerfCalc.php
  43. 1 1
      common/helpers/user/Balance.php
  44. 1 1
      common/helpers/user/Info.php
  45. 38 0
      common/libs/taskQueue/TaskFunc.php
  46. 245 0
      common/models/BaiduRegion.php
  47. 3 3
      common/models/BalanceAudit.php
  48. 1 0
      common/models/Config.php
  49. 1 1
      common/models/DeclarationPackage.php
  50. 25 0
      common/models/FlowRemainPv.php
  51. 26 0
      common/models/Order.php
  52. 27 2
      common/models/Period.php
  53. 22 0
      common/models/RemainPv.php
  54. 70 10
      common/models/User.php
  55. 10 0
      common/models/UserInfo.php
  56. 7 3
      common/models/UserNetwork.php
  57. 57 0
      common/models/UserNetworkHidden.php
  58. 19 0
      common/models/UserPerf.php
  59. 33 24
      common/models/Withdraw.php
  60. 8 5
      common/models/forms/DecPackageForm.php
  61. 7 3
      common/models/forms/DeclarationForm.php
  62. 7 0
      common/models/forms/DeclarationLoopForm.php
  63. 6 1
      common/models/forms/DeclarationUpgradeForm.php
  64. 5 5
      common/models/forms/ExcelOrderShopForm.php
  65. 93 10
      common/models/forms/OrderForm.php
  66. 136 0
      common/models/forms/PerfAdjustmentForm.php
  67. 19 10
      common/models/forms/TransferForm.php
  68. 3 3
      common/models/forms/WithdrawForm.php
  69. 3 0
      composer.json
  70. 51 0
      console/controllers/ToolController.php
  71. 1 1
      frontendApi/config/params.php
  72. 1 0
      frontendApi/config/urlManagerRules.php
  73. 5 2
      frontendApi/modules/v1/controllers/AtlasController.php
  74. 1037 1029
      frontendApi/modules/v1/controllers/BonusController.php
  75. 27 0
      frontendApi/modules/v1/controllers/DashboardController.php
  76. 6 4
      frontendApi/modules/v1/controllers/OauthController.php
  77. 17 9
      frontendApi/modules/v1/controllers/ShopController.php
  78. 15 0
      frontendApi/modules/v1/controllers/SiteController.php
  79. 11 10
      frontendApi/modules/v1/controllers/UserController.php
  80. 10 3
      frontendEle/src/views/dashboard/index.vue
  81. 64 66
      frontendEle/src/views/finance/transfer-add.vue
  82. 144 146
      frontendEle/src/views/finance/withdraw-add.vue
  83. 2 9
      frontendEle/src/views/shop/order-list.vue
  84. 259 260
      frontendEle/src/views/user/dec.vue
  85. 4 0
      sql/2047.sql
  86. 4 0
      sql/upgrade/1035.sql
  87. 5 0
      vendor/autoload.php
  88. 141 14
      vendor/composer/ClassLoader.php
  89. 2 1
      vendor/composer/autoload_classmap.php
  90. 6 6
      vendor/composer/autoload_files.php
  91. 1 1
      vendor/composer/autoload_namespaces.php
  92. 3 1
      vendor/composer/autoload_psr4.php
  93. 13 29
      vendor/composer/autoload_real.php
  94. 16 5
      vendor/composer/autoload_static.php
  95. 6097 5779
      vendor/composer/installed.json
  96. 27 8
      vendor/composer/installed.php
  97. 608 0
      vendor/monolog/monolog/CHANGELOG.md
  98. 19 0
      vendor/monolog/monolog/LICENSE
  99. 112 0
      vendor/monolog/monolog/README.md
  100. 72 0
      vendor/monolog/monolog/UPGRADE.md

+ 15 - 0
backendApi/config/menu.php

@@ -39,6 +39,12 @@ return [
             ['name'=>'添加商品', 'class'=>'', 'icon'=>'', 'controller'=>'shop', 'action'=>'goods-add', 'routePath'=>'shop/goods-add', 'show'=>0,],
             ['name'=>'编辑商品', 'class'=>'', 'icon'=>'', 'controller'=>'shop', 'action'=>'goods-edit', 'routePath'=>'shop/goods-edit', 'show'=>0,],
             ['name'=>'删除商品', 'class'=>'', 'icon'=>'', 'controller'=>'shop', 'action'=>'goods-delete', 'routePath'=>'shop/goods-delete', 'show'=>0,],
+            ['name'=>'商品状态', 'class'=>'', 'icon'=>'', 'controller'=>'shop', 'action'=>'goods-status', 'routePath'=>'shop/goods-status', 'show'=>0,],
+            ['name'=>'套餐管理', 'class'=>'', 'icon'=>'', 'controller'=>'shop', 'action'=>'package-get', 'routePath'=>'shop/package-get', 'show'=>0,],
+            ['name'=>'添加套餐', 'class'=>'', 'icon'=>'', 'controller'=>'shop', 'action'=>'package-add', 'routePath'=>'shop/package-add', 'show'=>0,],
+            ['name'=>'编辑套餐', 'class'=>'', 'icon'=>'', 'controller'=>'shop', 'action'=>'package-edit', 'routePath'=>'shop/package-edit', 'show'=>0,],
+            ['name'=>'删除套餐', 'class'=>'', 'icon'=>'', 'controller'=>'shop', 'action'=>'package-delete', 'routePath'=>'shop/package-delete', 'show'=>0,],
+            ['name'=>'商品状态', 'class'=>'', 'icon'=>'', 'controller'=>'shop', 'action'=>'package-status', 'routePath'=>'shop/package-status', 'show'=>0,],
             // 新添加的商品操作 ---stop
             ['name'=>'商品列表导出', 'class'=>'', 'icon'=>'', 'controller'=>'shop', 'action'=>'goods-list-export', 'routePath'=>'shop/goods-list-export', 'show'=>0,],
             ['name'=>'套餐管理', 'class'=>'', 'icon'=>'', 'controller'=>'shop', 'action'=>'package', 'routePath'=>'shop/package', 'show'=>1,],
@@ -47,9 +53,13 @@ return [
             ['name'=>'订单列表', 'class'=>'', 'icon'=>'', 'controller'=>'shop', 'action'=>'order-list', 'routePath'=>'shop/order-list', 'show'=>1,],
             ['name'=>'订单列表导出', 'class'=>'', 'icon'=>'', 'controller'=>'shop', 'action'=>'order-list-export', 'routePath'=>'shop/order-list-export', 'show'=>0,],
             ['name'=>'订单发货', 'class'=>'', 'icon'=>'', 'controller'=>'shop', 'action'=>'order-delivery', 'routePath'=>'shop/order-delivery', 'show'=>0,],
+            ['name'=>'剩余PV', 'class'=>'', 'icon'=>'', 'controller'=>'shop', 'action'=>'remain-pv', 'routePath'=>'shop/remain-pv', 'show'=>1,], // 剩余BV
+            ['name'=>'剩余PV流水', 'class'=>'', 'icon'=>'', 'controller'=>'shop', 'action'=>'flow-remain-pv', 'routePath'=>'shop/flow-remain-pv', 'show'=>1,], // 剩余BV流水
             ['name'=>'外部商城订单列表', 'class'=>'', 'icon'=>'', 'controller'=>'shop', 'action'=>'order-shop-list', 'routePath'=>'shop/order-shop-list', 'show'=>1,],
             ['name'=>'外部商城报单列表', 'class'=>'', 'icon'=>'', 'controller'=>'shop', 'action'=>'order-dec-list', 'routePath'=>'shop/order-dec-list', 'show'=>1,],
             ['name'=>'外部商城达标订单列表', 'class'=>'', 'icon'=>'', 'controller'=>'shop', 'action'=>'order-standard-list', 'routePath'=>'shop/order-standard-list', 'show'=>1,],
+            ['name'=>'上传', 'class'=>'', 'icon'=>'', 'controller'=>'shop', 'action'=>'upload', 'routePath'=>'shop/upload', 'show'=>0,],
+
         ]
     ],
     'user'=>[
@@ -253,6 +263,7 @@ return [
 //            ['name'=>'管理奖贴向上追溯', 'class'=>'', 'icon'=>'', 'controller'=>'bonus', 'action'=>'trace-up-gl', 'routePath'=>'bonus/trace-up-gl', 'show'=>1,],
 //            ['name'=>'管理奖向上追溯导出', 'class'=>'', 'icon'=>'', 'controller'=>'bonus', 'action'=>'trace-up-gl-export', 'routePath'=>'bonus/trace-up-gl-export', 'show'=>0,],
             ['name'=>'用户业绩', 'class'=>'', 'icon'=>'', 'controller'=>'bonus', 'action'=>'user-perf', 'routePath'=>'bonus/user-perf', 'show'=>1,],
+            ['name'=>'业绩调整', 'class'=>'', 'icon'=>'', 'controller'=>'bonus', 'action'=>'perf-adjustment', 'routePath'=>'bonus/perf-adjustment', 'show'=>1,],
 //            ['name'=>'荣衔业绩', 'class'=>'', 'icon'=>'', 'controller'=>'bonus', 'action'=>'yc-perf', 'routePath'=>'bonus/yc-perf', 'show'=>1,],
             ['name'=>'达标业绩', 'class'=>'', 'icon'=>'', 'controller'=>'bonus', 'action'=>'perf-standard', 'routePath'=>'bonus/perf-standard', 'show'=>1,],
             ['name'=>'达标业绩导出', 'class'=>'', 'icon'=>'', 'controller'=>'bonus', 'action'=>'perf-standard-export', 'routePath'=>'bonus/perf-standard-export', 'show'=>0,],
@@ -323,6 +334,10 @@ return [
 //            ['name'=>'提现管理-付款失败', 'class'=>'', 'icon'=>'', 'controller'=>'finance', 'action'=>'withdraw-4', 'routePath'=>'finance/withdraw-4', 'show'=>0,],
 //            ['name'=>'提现管理-提现退回', 'class'=>'', 'icon'=>'', 'controller'=>'finance', 'action'=>'withdraw-7', 'routePath'=>'finance/withdraw-7', 'show'=>0,],
             ['name'=>'审核提现信息', 'class'=>'', 'icon'=>'', 'controller'=>'finance', 'action'=>'withdraw-status', 'routePath'=>'finance/withdraw-status', 'show'=>0,],
+            ['name'=>'提现审核', 'class'=>'', 'icon'=>'', 'controller'=>'finance', 'action'=>'withdraw-status-audit', 'routePath'=>'finance/withdraw-status-audit', 'show'=>0,],
+            ['name'=>'提现退回', 'class'=>'', 'icon'=>'', 'controller'=>'finance', 'action'=>'withdraw-status-return', 'routePath'=>'finance/withdraw-status-return', 'show'=>0,],
+            ['name'=>'提现付款', 'class'=>'', 'icon'=>'', 'controller'=>'finance', 'action'=>'withdraw-status-pay', 'routePath'=>'finance/withdraw-status-pay', 'show'=>0,],
+            ['name'=>'提现取消', 'class'=>'', 'icon'=>'', 'controller'=>'finance', 'action'=>'withdraw-status-cancel', 'routePath'=>'finance/withdraw-status-cancel', 'show'=>0,],
             //['name'=>'发票信息添加', 'class'=>'', 'icon'=>'', 'controller'=>'finance', 'action'=>'invoice-audit-add', 'routePath'=>'finance/invoice-audit-add', 'show'=>0,],
             //['name'=>'发票信息编辑', 'class'=>'', 'icon'=>'', 'controller'=>'finance', 'action'=>'invoice-audit-edit', 'routePath'=>'finance/invoice-audit-edit', 'show'=>0,],
             //['name'=>'标记付款失败批量1导入', 'class'=>'', 'icon'=>'', 'controller'=>'finance', 'action'=>'import-withdraws-to-excel-table', 'routePath'=>'finance/import-withdraws-to-excel-table', 'show'=>0,],

+ 2 - 2
backendApi/config/params.php

@@ -1,6 +1,6 @@
 <?php
 return [
     'adminEmail' => 'admin@example.com',
-    'noCheckTokenActions' => ['v1/oauth/login', 'v1/oauth/no-login-modify-password', 'v1/oauth/refresh-access-token', 'v1/oauth/refresh-refresh-token', 'v1/oauth/refresh-token', 'v1/site/days-diff', 'v1/site/page-data', 'v1/site/captcha'],
-    'noCheckPermissionActions' => ['oauth/login', 'oauth/no-login-modify-password', 'oauth/refresh-access-token', 'oauth/refresh-refresh-token', 'oauth/refresh-token', 'oauth/info', 'site/base-info', 'site/days-diff', 'site/page-data', 'site/captcha', 'user/full-info', 'user/filter-user', 'user/generate-user-name', 'reconsume/cant-deduct-date', 'user/get-sub-com', 'user/chk-relation', 'user/get-period-num', 'user/company-bank-get', 'user/main-divide', 'user/chk-del-user', 'reconsume/deduct-audit-add', 'finance/perf-apply-get','file/upload-excel', 'user/move-net-type', 'user/move-get', 'user/reg-info-audit-get', 'user/status-audit-get', 'user/status-audit-get-statuses', 'user/close-login-get', 'user/close-dec-get', 'atlas/main-user-info', 'reconsume/change-audit-get', 'reconsume/cant-deduct-month', 'finance/change-balance-type', 'finance/balance-audit-get', 'file/token', 'finance/perf-audit-get', 'finance/invoice-audit-get', 'finance/withdraw-get', 'finance/deal-type-get', 'ad/upload', 'config/reg-type-get', 'config/pact-get', 'user/reg-info-audit-add-opt', 'reconsume/get-flow-deal-type', 'user/status-close-get', 'finance/mult-point'],
+    'noCheckTokenActions' => ['v1/oauth/login', 'v1/oauth/no-login-modify-password', 'v1/oauth/refresh-access-token', 'v1/oauth/refresh-refresh-token', 'v1/oauth/refresh-token', 'v1/site/days-diff', 'v1/site/page-data', 'v1/site/captcha', 'v1/site/send-notice'],
+    'noCheckPermissionActions' => ['oauth/login', 'oauth/no-login-modify-password', 'oauth/refresh-access-token', 'oauth/refresh-refresh-token', 'oauth/refresh-token', 'oauth/info', 'site/base-info', 'site/days-diff', 'site/page-data', 'site/captcha', 'site/send-notice', 'user/full-info', 'user/filter-user', 'user/generate-user-name', 'reconsume/cant-deduct-date', 'user/get-sub-com', 'user/chk-relation', 'user/get-period-num', 'user/company-bank-get', 'user/main-divide', 'user/chk-del-user', 'reconsume/deduct-audit-add', 'finance/perf-apply-get','file/upload-excel', 'user/move-net-type', 'user/move-get', 'user/reg-info-audit-get', 'user/status-audit-get', 'user/status-audit-get-statuses', 'user/close-login-get', 'user/close-dec-get', 'atlas/main-user-info', 'reconsume/change-audit-get', 'reconsume/cant-deduct-month', 'finance/change-balance-type', 'finance/balance-audit-get', 'file/token', 'finance/perf-audit-get', 'finance/invoice-audit-get', 'finance/withdraw-get', 'finance/deal-type-get', 'ad/upload', 'config/reg-type-get', 'config/pact-get', 'user/reg-info-audit-add-opt', 'reconsume/get-flow-deal-type', 'user/status-close-get', 'finance/mult-point'],
 ];

+ 8 - 0
backendApi/config/urlManagerRules.php

@@ -17,6 +17,7 @@ return [
             'GET days-diff' => 'days-diff',
             'GET page-data' => 'page-data',
             'GET captcha' => 'captcha',
+            'GET send-notice' => 'send-notice',
         ],
     ],
     [
@@ -63,6 +64,8 @@ return [
             'GET order-standard-list' => 'order-standard-list',
             'POST import-order-standard-to-excel-table' => 'import-order-standard-to-excel-table',
             'POST import-order-standard' => 'import-order-standard',
+            'GET remain-pv' => 'remain-pv',
+            'GET flow-remain-pv' => 'flow-remain-pv',
         ],
     ],
     [
@@ -294,6 +297,10 @@ return [
             'POST,GET transfer' => 'transfer',
             'POST,GET score' => 'score',
             'POST,GET user-online' => 'user-online',
+            'GET region' => 'region',
+            'GET region-js' => 'region-js',
+            'GET init-region-xls' => 'init-region-xls',
+            'GET renew-region-cache' => 'renew-region-cache',
         ],
     ],
     [
@@ -402,6 +409,7 @@ return [
             'GET yc-perf' => 'yc-perf',
             'GET period-perf' => 'period-perf',
             'GET period-perf-export' => 'period-perf-export',
+            'GET,POST perf-adjustment' => 'perf-adjustment',
         ],
     ],
     [

+ 1 - 1
backendApi/modules/v1/controllers/BaseController.php

@@ -405,4 +405,4 @@ class BaseController extends \yii\rest\ActiveController {
             'request' => $request,
         ];
     }
-}
+}

+ 51 - 0
backendApi/modules/v1/controllers/BonusController.php

@@ -46,6 +46,7 @@ use common\helpers\user\Info;
 use common\helpers\user\Perf;
 use common\models\CalcBonus;
 use common\models\CFLXAudit;
+use common\models\forms\PerfAdjustmentForm;
 use common\models\forms\ResendQYForm;
 use common\models\forms\SendCFAndLXForm;
 use common\models\PerfMonth;
@@ -55,6 +56,7 @@ use common\models\ResendQYAudit;
 use common\models\User;
 use common\models\UserInfo;
 use common\models\UserNetwork;
+use common\models\UserPerf;
 use Yii;
 use common\helpers\Form;
 use common\models\Config;
@@ -2824,4 +2826,53 @@ class BonusController extends BaseController {
         }
         return static::notice('导出开始,请到文件管理-导出文件查看');
     }
+
+    /**
+     * 查询安置网下级会员和业绩、修改业绩
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionPerfAdjustment()
+    {
+        // 查询业绩
+        if (\Yii::$app->request->isGet) {
+            $memberCode = Yii::$app->request->get('memberCode');
+            $userId = Info::getUserIdByUserName(trim($memberCode));
+
+            // 查询传入会员的综合业绩
+            $perfMarket = UserPerf::getPerfMarket($userId);
+            if ($perfMarket) {
+                // 查询传入会员的安置网下级
+                $memberList = UserNetwork::getFirstFloorChildren($userId);
+                $memberList = array_column($memberList, NULL, 'RELATIVE_LOCATION');
+                // 1市场
+                $surplus1LUserName = (isset($memberList[1]) && $memberList[1]['USER_ID']) ? Info::getUserNameByUserId($memberList[1]['USER_ID']) : '';
+                // 2市场
+                $surplus2LUserName = (isset($memberList[2]) && $memberList[2]['USER_ID']) ? Info::getUserNameByUserId($memberList[2]['USER_ID']) : '';
+                // 3市场
+                $surplus3LUserName = (isset($memberList[3]) && $memberList[3]['USER_ID']) ? Info::getUserNameByUserId($memberList[3]['USER_ID']) : '';
+
+                // 会员编号
+                $perfMarket['USER_NAME'] = $memberCode;
+                $perfMarket['SURPLUS_1L_USER_NAME'] = $surplus1LUserName;
+                $perfMarket['SURPLUS_2L_USER_NAME'] = $surplus2LUserName;
+                $perfMarket['SURPLUS_3L_USER_NAME'] = $surplus3LUserName;
+
+                return static::notice(['allData' => $perfMarket]);
+            }
+
+            return static::notice('暂无数据', 400);
+        } else if (\Yii::$app->request->isPost) {
+            $formModel = new PerfAdjustmentForm();
+            $formModel->scenario = 'perfAdjustment';
+            $post = \Yii::$app->request->post();
+            if ($formModel->load($post, '') && $formModel->perfAdjustment()) {
+                return static::notice('成功');
+            } else {
+                return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
+            }
+        } else {
+            return static::notice('非法请求', 400);
+        }
+    }
 }

+ 160 - 5
backendApi/modules/v1/controllers/ConfigController.php

@@ -47,6 +47,8 @@ use common\models\UserClose;
 use common\models\UserInfo;
 use common\models\UserNetwork;
 use common\models\UserRelation;
+use common\models\BaiduRegion;
+use common\models\Region;
 use common\models\WithdrawLevel;
 use Yii;
 use common\models\Config;
@@ -117,11 +119,11 @@ class ConfigController extends BaseController {
         // 获取会员报单级别的相关参数
         $decLevel = DeclarationLevel::find()->orderBy('SORT ASC')->asArray()->all();
         // 获取会员聘级相关参数
-        $empLevel = EmployLevel::getAllDataWithNumIndex();
+        // $empLevel = EmployLevel::getAllDataWithNumIndex();
         $result = [
             'config' => $configs,
             'decLevel' => $decLevel,
-            'empLevel' => $empLevel,
+            // 'empLevel' => $empLevel,
         ];
         return static::notice($result);
     }
@@ -814,9 +816,9 @@ class ConfigController extends BaseController {
         // Log::adminHandle('更新服务协议');
         $date = \Yii::$app->formatter->asDatetime($now);
         $content = "<?php" . PHP_EOL . "/**
- * 配置文件
- * @date {$date}
- */" . PHP_EOL;
+    * 配置文件
+    * @date {$date}
+    */" . PHP_EOL;
         $content .= "return ";
         $content .= var_export($data, true);
         $content .= ";";
@@ -870,4 +872,157 @@ class ConfigController extends BaseController {
         return static::notice($user_info);
     }
 
+    public static function actionInitRegionXls() {
+        BaiduRegion::deleteAll();
+        BaiduRegion::importXls(0,1000);
+        return static::notice('导入成功');
+    }
+
+    public static function actionRegion() {
+        // 开始查找bd区划,先找县级和以上
+//        $bdProv = BaiduRegion::_getBdProv();
+//        foreach ($bdProv as $prov) {
+//
+//        }
+
+        $bdCity = BaiduRegion::_getBdCity();
+        print_r("检查新增地市".PHP_EOL);
+        foreach ($bdCity as $city) {
+            $p = BaiduRegion::_checkInNc($city['CITY_CODE']);
+            if (!$p) {
+                print_r($city['CITY_NAME'].'找不到,添加'.PHP_EOL);
+//                print_r($city);
+                if(BaiduRegion::addNcRegion($region_code=$city['CITY_CODE'], $region_name=$city['CITY_NAME'], $pid=$city['PROV_CODE'], $deep=3)){
+                    print_r("添加成功".PHP_EOL);
+                }else{
+                    $regionM = Region::findOne(["REGION_CODE"=>$city['CITY_CODE']]);
+                    $regionM->STATUS = 1;
+                    $regionM->save();
+                    print_r("启用成功".PHP_EOL);
+                }
+            }
+        }
+
+        $bdCounty = BaiduRegion::_getBdCounty();
+//        print_r("检查新增县".PHP_EOL);
+        foreach ($bdCounty as $county) {
+            $p = BaiduRegion::_checkInNc($county['COUNTY_CODE']);
+            if (!$p){
+                print_r($county['COUNTY_NAME'].' 区县找不到,添加'.PHP_EOL);
+//                print_r($county);
+                if(BaiduRegion::addNcRegion($region_code=$county['COUNTY_CODE'], $region_name=$county['COUNTY_NAME'], $pid=$county['CITY_CODE'], $deep=4)){
+//                    print_r("添加成功".PHP_EOL);
+                }else{
+                    $regionM = Region::findOne(["REGION_CODE"=>$county['COUNTY_CODE']]);
+                    $regionM->STATUS = 1;
+                    $regionM->save();
+//                    print_r("启用成功".PHP_EOL);
+                }
+            }
+        }
+
+        $bdTown = BaiduRegion::_getBdTown(); // 只取省直辖县,直筒子市的乡镇
+        print_r("检查新增地乡镇".PHP_EOL);
+        foreach ($bdTown as $town) {
+            $p = BaiduRegion::_checkInNc($town['TOWN_CODE']);
+//            print_r($p);
+            if (!$p) {
+                print_r($town['TOWN_CODE'].$town['TOWN_NAME'].' 镇 找不到,添加'.PHP_EOL);
+//                print_r($town);
+                if(BaiduRegion::addNcRegion($region_code=$town['TOWN_CODE'], $region_name=$town['TOWN_NAME'], $pid=$town['COUNTY_CODE'], $deep=5)){
+//                    print_r("添加成功".PHP_EOL);
+                }else{
+                    $regionM = Region::findOne(["REGION_CODE"=>$town['TOWN_CODE']]);
+                    $regionM->STATUS = 1;
+                    $regionM->save();
+//                    print_r("启用成功".PHP_EOL);
+                }
+            }
+        }
+
+        $ncAllRegion = BaiduRegion::_getAllNcRegion();
+
+        foreach ($ncAllRegion as $ncRegi) {
+            if(strlen($ncRegi['REGION_CODE'])==9){
+                $model = Region::findOne(["REGION_CODE"=>$ncRegi['REGION_CODE'], "STATUS"=>1]);
+                $model->DEEP = 5;
+                $model->save();
+                $ncRegi['DEEP'] = 5;
+            }
+            $t = BaiduRegion::_checkInBd($ncRegi['REGION_CODE'], $ncRegi['REGION_NAME'], $ncRegi['PID'], $ncRegi['DEEP']);
+            if(!$t){
+//                print_r($ncRegi['REGION_CODE'].$ncRegi['REGION_NAME']." 在百度没有,标记删除".$ncRegi['DEEP'].PHP_EOL);
+                $regionM = Region::findOne(["REGION_CODE"=>$ncRegi['REGION_CODE'], "STATUS"=>1]);
+                $regionM->STATUS = '0';
+                $regionM->save();
+            } else {
+                if($t['REGION_NAME']!=$ncRegi['REGION_NAME']) {
+//                    print_r($ncRegi['REGION_CODE'] . $ncRegi['REGION_NAME'] . " 更名,需修改" . PHP_EOL);
+                    $regionM = Region::findOne(["REGION_CODE"=>$ncRegi['REGION_CODE'], "STATUS"=>1]);
+                    $regionM->REGION_NAME = $t['REGION_NAME'];
+                    $regionM->save();
+                }
+                if($t['PID']!=$ncRegi['PID']){
+//                    print_r($ncRegi['REGION_CODE'] . $ncRegi['REGION_NAME'] . " 上级".$ncRegi['PID']."需修改". $t['PID'] . PHP_EOL);
+                    $regionM = Region::findOne(["REGION_CODE"=>$ncRegi['REGION_CODE'], "STATUS"=>1]);
+                    $regionM->PID = $t['PID'];
+                    $regionM->save();
+                }
+            }
+        }
+
+        return static::notice('更新成功');
+    }
+
+    public function actionRegionJs() {
+        $ncProv = BaiduRegion::_getAllNcProv();
+//        print_r($ncProv);
+
+        $prov_list = [];
+        $ar_region_array = [
+            '86' => $prov_list
+        ];
+
+        foreach ($ncProv as $prov) {
+            $ar_region_array['86'][$prov['REGION_CODE']] = $prov['REGION_NAME'];
+            $ar_region_array[$prov['REGION_CODE']] = [];
+        }
+
+        // 普通地市,直筒子市
+        $ncCity = BaiduRegion::_getAllNcCity();
+        foreach($ncCity as $city){
+            $ar_region_array[$city['PID']][$city['REGION_CODE']] = $city['REGION_NAME'];
+            $ncCounty = BaiduRegion::_getAllNcCountyByCity($city['REGION_CODE']);
+            foreach ($ncCounty as $county) {
+                $ar_region_array[$city['REGION_CODE']][$county['REGION_CODE']] = $county['REGION_NAME'];
+            }
+        }
+
+        // 直辖县级市
+        $ncHighCounty = BaiduRegion::_getAllNcCounty();
+        foreach ($ncHighCounty as $county) {
+            $ar_region_array[$county['PID']][$county['REGION_CODE']] = $county['REGION_NAME'];
+            $ncTown = BaiduRegion::_getAllNcTownByCity($county['REGION_CODE']);
+            foreach ($ncTown as $town) {
+                $ar_region_array[$county['REGION_CODE']][$town['REGION_CODE']] = $town['REGION_NAME'];
+            }
+        }
+
+        $ar_region_data = json_encode($ar_region_array,JSON_UNESCAPED_UNICODE);
+        $str = (string)$ar_region_data;
+        $str = "const AR_REGION_DATA = ".$str;
+
+        file_put_contents("/Volumes/HDD/workshop/old/ar.upload.ming/cdn/jsdata/ar_region_data.js", $str);
+
+        return static::notice('生成JS成功');
+    }
+
+    public function actionRenewRegionCache() {
+        if(Region::updateToCache()){
+            return static::notice('刷新成功');
+        } else {
+            return static::notice('刷新失败');
+        }
+    }
+
 }

+ 35 - 1
backendApi/modules/v1/controllers/ShopController.php

@@ -18,6 +18,8 @@ use backendApi\modules\v1\models\lists\shop\OrderShopList;
 use backendApi\modules\v1\models\lists\shop\OrderStandardList;
 use backendApi\modules\v1\models\lists\shop\PackageList;
 use common\helpers\bonus\CalcCache;
+use backendApi\modules\v1\models\lists\shop\RemainPvList;
+use backendApi\modules\v1\models\lists\shop\FlowRemainPvList;
 use common\helpers\Cache;
 use common\helpers\Date;
 use common\helpers\Form;
@@ -253,7 +255,7 @@ class ShopController extends BaseController {
             });
         }
         $package = DeclarationPackage::findOneAsArray('ID=:ID', [':ID' => $id]);
-        return static::notice(['id' => $package['ID'], 'packageName' => $package['PACKAGE_NAME'],'packageNo' => $package['PACKAGE_NO'], 'amount' => $package['AMOUNT'], 'amountPv' => $package['PV'], 'levelId' => $package['LEVEL_ID'], 'packageContent' => $package['PACKAGE_CONTENT'],'storenums' => $package['STORE_NUMS'],'statusdate'=>$package['STATUS_DATE'],'packagedate'=>$package['PACKAGE_DATE'],'packagestatusdate'=>$package['PACKAGE_STATUS_DATE']]);
+        return static::notice(['id' => $package['ID'], 'packageName' => $package['PACKAGE_NAME'],'packageNo' => $package['PACKAGE_NO'], 'amount' => $package['AMOUNT'], 'amountPv' => $package['PV'], 'levelId' => $package['LEVEL_ID'], 'packageContent' => $package['PACKAGE_CONTENT'],'storenums' => $package['STORE_NUMS'],'statusdate'=>$package['STATUS_DATE'],'packagedate'=>$package['PACKAGE_DATE'],'packagestatusdate'=>$package['PACKAGE_STATUS_DATE'],'sort'=>$package['SORT']]);
     }
 
     /**
@@ -650,4 +652,36 @@ class ShopController extends BaseController {
         return static::notice('非法请求', 400);
     }
 
+
+    /*
+     * 剩余BV页
+     *
+     */
+    public function actionRemainPv()
+    {
+        $filter = $this->filterCondition([
+            'USER_NAME' => 'U.USER_NAME',
+        ]);
+        $condition = $filter['condition'];
+        $params = $filter['params'];
+        $listObj = new RemainPvList();
+        $data = $listObj->getList(['condition'=>$condition, 'params'=>$params]);
+        return static::notice($data);
+    }
+
+    /*
+     * 剩余BV流水
+     *
+     */
+    public function actionFlowRemainPv()
+    {
+        $filter = $this->filterCondition([
+            'USER_NAME' => 'U.USER_NAME',
+        ]);
+        $condition = $filter['condition'];
+        $params = $filter['params'];
+        $listObj = new FlowRemainPvList();
+        $data = $listObj->getList(['condition'=>$condition, 'params'=>$params]);
+        return static::notice($data);
+    }
 }

+ 13 - 0
backendApi/modules/v1/controllers/SiteController.php

@@ -147,4 +147,17 @@ class SiteController extends BaseController
         return $menuResult;
     }
 
+    /**
+     * 发送钉钉测试信息
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionSendNotice()
+    {
+        $data = [
+            'code' => 400,
+            'message' => 'autoSendDingTalk',
+        ];
+        return static::notice(['data' => $data['bug监控正常运行,没有发现异常.']]);
+    }
 }

+ 5 - 5
backendApi/modules/v1/controllers/UserController.php

@@ -109,7 +109,7 @@ class UserController extends BaseController
             'DEC_LV_UPDATED_AT' => 'U.DEC_LV_UPDATED_AT',
             'LAST_DEC_LV_NAME' => 'U.LAST_DEC_LV',
             'EMP_LV_NAME' => 'U.EMP_LV',
-//            'HIGHEST_EMP_LV_NAME' => 'UI.HIGHEST_EMP_LV',
+            'LAST_EMP_LV_NAME' => 'U.LAST_EMP_LV',
 //            'HIGHEST_EMP_LV_PERIOD' => 'UI.HIGHEST_EMP_LV_PERIOD',
             'REC_USER_NAME' => 'RU.USER_NAME',
             'CON_USER_NAME' => 'CU.USER_NAME',
@@ -149,7 +149,7 @@ class UserController extends BaseController
         ]);
         $condition = $filter['condition'];
         $params = $filter['params'];
-        $condition .= ' AND UI.DELETED=0 ';
+        $condition .= ' AND U.DELETED=0 ';
         $listObj = new IndexList();
         $data = $listObj->getList(['condition' => $condition, 'params' => $params]);
         return static::notice($data);
@@ -270,7 +270,7 @@ class UserController extends BaseController
         ]);
         $condition = $filter['condition'];
         $params = $filter['params'];
-        $condition .= ' AND UI.DELETED=0 AND U.REG_FROM=0';
+        $condition .= ' AND U.DELETED=0 AND U.REG_FROM=0';
         $listObj = new IndexList();
         $data = $listObj->getList(['condition' => $condition, 'params' => $params]);
         return static::notice($data);
@@ -1489,7 +1489,7 @@ class UserController extends BaseController
         ]);
         $condition = $filter['condition'];
         $params = $filter['params'];
-        $condition .= ' AND UI.DELETED=0';
+        $condition .= ' AND U.DELETED=0';
         $data = UserInfo::lists($condition, $params, [
             'orderBy' => 'UI.CREATED_AT DESC',
             'from' => UserInfo::tableName() . ' AS UI',
@@ -2229,4 +2229,4 @@ class UserController extends BaseController
         }
         return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
     }
-}
+}

+ 3 - 3
backendApi/modules/v1/models/lists/bonus/BalanceList.php

@@ -133,7 +133,7 @@ class BalanceList extends \common\libs\dataList\DataList implements DataListInte
 //                    'headerOther' => ['width' => '150'],
 //                ],
                 'BONUS' => [
-                    'header' => '会员奖金余额',
+                    'header' => '奖金账户',
                     'value' => function($row) {
                         return (new Price([
                             'value' => $row['BONUS'],
@@ -148,7 +148,7 @@ class BalanceList extends \common\libs\dataList\DataList implements DataListInte
                     ],
                 ],
                 'RECONSUME_POINTS' => [
-                    'header' => '会员复销点数',
+                    'header' => '复消积分',
                     'value' => function($row) {
                         return (new Price([
                             'value' => $row['RECONSUME_POINTS'],
@@ -178,7 +178,7 @@ class BalanceList extends \common\libs\dataList\DataList implements DataListInte
                     ],
                 ],
                 'CASH' => [
-                    'header' => '会员余额',
+                    'header' => '充值账户',
                     'value' => function($row) {
                         return (new Price([
                             'value' => $row['CASH'],

+ 1 - 1
backendApi/modules/v1/models/lists/bonus/FlowBonusList.php

@@ -100,7 +100,7 @@ class FlowBonusList extends \common\libs\dataList\DataList implements DataListIn
                     ],
                 ],
                 'LAST_EMP_LV_NAME' => [
-                    'header' => '聘级',
+                    'header' => '最新聘级',
                     'headerOther' => [
                         'width' => '130',
                     ],

+ 1 - 0
backendApi/modules/v1/models/lists/log/AdminHandleList.php

@@ -155,6 +155,7 @@ class AdminHandleList extends \common\libs\dataList\DataList implements DataList
                 ['id'=>'添加体系','name'=>'添加体系'],
                 ['id'=>'编辑体系','name'=>'编辑体系'],
                 ['id'=>'恢复体系','name'=>'恢复体系'],
+                ['id'=>'调整业绩','name'=>'调整业绩'],
             ];
             $this->filterTypes = [
                 'opt_type' => ['isUserTable'=>false, 'name'=>'操作类型', 'other'=> 'select', 'selectData'=> $selectData],

+ 122 - 0
backendApi/modules/v1/models/lists/shop/FlowRemainPvList.php

@@ -0,0 +1,122 @@
+<?php
+
+namespace backendApi\modules\v1\models\lists\shop;
+
+use common\helpers\Cache;
+use common\helpers\user\Info;
+use common\libs\dataList\column\Price;
+use common\libs\dataList\DataListInterface;
+use common\libs\dataList\column\DateTime;
+use common\models\FlowRemainPv;
+use Yii;
+
+class FlowRemainPvList extends \common\libs\dataList\DataList implements DataListInterface {
+    /**
+     * 列表名称
+     * @return string
+     */
+    public function getListName() {
+        return '剩余BV流水';
+    }
+
+    /**
+     * 列表筛选到的数据
+     * @throws \yii\base\Exception
+     */
+    public function dataHandle() {
+        $this->listData = FlowRemainPv::lists($this->condition, $this->params, [
+            'select' => 'FR.*,U.USER_NAME,U.REAL_NAME,U.IS_DEC',
+            'orderBy' => 'FR.UPDATED_AT DESC,FR.ID DESC',
+            'from' => FlowRemainPv::tableName() . ' AS FR',
+            'join' => [
+                ['LEFT JOIN', \common\models\User::tableName() . ' AS U', 'FR.USER_ID=U.ID'],
+            ],
+            'page' => $this->page,
+            'pageSize' => $this->pageSize,
+        ]);
+        foreach ($this->listData['list'] as $key => $value) {
+//            $this->listData['list'][$key]['LAST_STATUS_NAME'] = \Yii::$app->params['userStatus'][$value['LAST_STATUS']]['label'] ?? '';
+        }
+
+    }
+
+    /**
+     * 要展示和导出的所有字段
+     * @return array
+     */
+    public function getColumn() {
+        if (!$this->columns) {
+            $this->columns = [
+                'ID' => null,
+                'PERIOD_NUM' => [
+                    'header' => '期数', // 期数
+                    'headerOther' => [
+                        'width' => '150',
+                    ],
+                ],
+                'USER_NAME' => [
+                    'header' => '会员编号',//会员编号
+                    'headerOther' => [
+                        'width' => '150',
+                    ],
+                    'valueOther' => [
+                        'tag' => ['type' => 'info', 'size' => 'small', 'class' => 'no-border']
+                    ],
+                ],
+                'REAL_NAME' => [
+                    'header' => '会员姓名',//会员姓名
+                    'headerOther' => [
+                        'width' => '120',
+                    ],
+                    'valueOther' => [
+                        'tag' => ['type' => 'success', 'size' => 'small', 'class' => 'no-border']
+                    ],
+                ],
+                'REMAIN_PV_FLOW' => [
+                    'header' => '剩余PV流水',
+                    'headerOther' => [
+                        'width' => '150',
+                        'prop' => 'REMAIN_PV_FLOW',
+                    ],
+                ],
+                'REMAIN_PV_TOTAL' => [
+                    'header' => '总剩余PV',
+                    'headerOther' => [
+                        'width' => '150',
+                        'prop' => 'REMAIN_PV_TOTAL',
+                    ],
+                ],
+                'UPDATED_AT' => [
+                    'header' => '更新时间',//创建时间
+                    'value' => function ($row) {
+                        return (new DateTime([
+                            'value' => $row['UPDATED_AT'],
+                        ]))->result();
+                    },
+                    'headerOther' => ['width' => '170'],
+                ],
+                'ORDER_SN' => [
+                    'header' => '订单编号',
+                    'headerOther' => ['width' => '190'],
+                ]
+            ];
+        }
+        return $this->columns;
+    }
+
+    /**
+     * 前台用于筛选的类型集合
+     * @return mixed
+     */
+    public function getFilterTypes() {
+        if (!$this->filterTypes) {
+            $this->filterTypes = [
+                'UPDATED_AT' => ['isUserTable' => false, 'name' => '更新时间', 'other' => 'date'], // 创建时间
+                'PERIOD_NUM' => ['isUserTable' => false, 'name' => '期数'], // 期数
+                'USER_NAME' => ['isUserTable' => false, 'name' => '会员编号'], // 会员编号
+                'REAL_NAME' => ['isUserTable' => false, 'name' => '会员姓名'], // 会员姓名
+            ];
+        }
+        return $this->filterTypes;
+    }
+}

+ 2 - 2
backendApi/modules/v1/models/lists/shop/GoodsList.php

@@ -197,7 +197,7 @@ class GoodsList extends \common\libs\dataList\DataList implements DataListInterf
             $this->filterTypes = [
                 //'TYPE' => ['isUserTable' => false, 'name' => '商品来源', 'other' => 'select', 'selectData' => [['id' => 1, 'name' => '国内商品'], ['id' => 2, 'name' => '进口商品']]],
                 'GIFT_TYPE' => ['isUserTable' => false, 'name' => '商品类型', 'other' => 'select', 'selectData' => [['id' => 1, 'name' => '报单区'], ['id' => 2, 'name' => '复消区'], ['id' => 3, 'name' => '工作室报单'], ['id' => 4, 'name' => '工作室复消']]],
-                'STATUS'=> ['name'=> '状态', 'other'=> 'select', 'selectData'=> [['id'=> 0, 'name'=> '已下架'],['id'=> 1, 'name'=> '已上架']]],
+                'STATUS'=> ['name'=> '状态', 'other'=> 'select', 'selectData'=> [['id'=> 1, 'name'=> '已上架'],['id'=> 0, 'name'=> '已下架'],]],
                 'GOODS_NAME'=> ['name'=> '商品名称'],
                 'GOODS_NO'=> ['name'=> '商品编号'],
                 'SELL_TYPE'=> ['name'=> '复消购买方式', 'other'=> 'select', 'selectData'=> [['id'=> 1, 'name'=> '余额购买'],['id'=> 2, 'name'=> '积分购买']]],
@@ -207,4 +207,4 @@ class GoodsList extends \common\libs\dataList\DataList implements DataListInterf
         }
         return $this->filterTypes;
     }
-}
+}

+ 36 - 2
backendApi/modules/v1/models/lists/shop/OrderList.php

@@ -167,13 +167,39 @@ class OrderList extends \common\libs\dataList\DataList implements DataListInterf
                     'headerOther' => ['width' => '120'],
                     'value' => function ($row) {
                             if($row['ORDER_TYPE']=='ZC'){
-                                $orderType = '单';
+                                $orderType = '单';
                             }else{
-                                $orderType = ($row['PAY_TYPE']=='cash') ? '重消' : '积分';
+//                                $orderType = ($row['PAY_TYPE']=='cash') ? '重消' : '积分';
+                                $orderType = '复消';
                             }
                         return $orderType;
                     },
                 ],
+                'PAY_TYPE' => [
+                    'header' => '支付方式',
+                    'value' => function ($row) {
+                        switch ($row['PAY_TYPE']) {
+                            case 'cash':
+                                return '充值账户';
+                            case 'exchange':
+                                return '兑换点数';
+                            default:
+                                return '复消积分';
+                        }
+                    },
+                    'headerOther' => ['width' => '120'],
+                ],
+                'IS_AUTO' => [
+                    'header' => 'Is Auto', // 是否自动
+                    'value' => function ($row) {
+                        switch ($row['IS_AUTO']) {
+                            case 1:
+                                return 'Yes';
+                            case 0:
+                                return 'No';
+                        }
+                    },
+                ],
                 'WAREHOUSE' => [
                     'header' => '发货仓',
                 ],
@@ -301,6 +327,14 @@ class OrderList extends \common\libs\dataList\DataList implements DataListInterf
                 'MOBILE'=> ['name'=> '联系方式1'],
                 'PERIOD_NUM'=> ['name'=> '期数'],
                 'CREATED_AT'=> ['name'=> '创建时间', 'other'=>'date'],
+                'IS_AUTO' => [
+                    'name'=>'自动',
+                    'other'=> 'select',
+                    'selectData'=> [
+                        ['id'=>1, 'name'=>'是'],
+                        ['id'=>0, 'name'=>'否'],
+                    ]
+                ]
             ];
         }
         return $this->filterTypes;

+ 1 - 1
backendApi/modules/v1/models/lists/shop/OrderShopList.php

@@ -61,7 +61,7 @@ class OrderShopList extends \common\libs\dataList\DataList implements DataListIn
                     'header' => '订单类型',
                     'headerOther' => ['width' => '120'],
                     'value' => function ($row) {
-                        return $row['PAY_TYPE']=='cash' ? '重消订单' : '积分订单';
+                        return $row['PAY_TYPE']=='cash' ? '复消' : '积分';
                     },
                 ],
                 'CONSIGNEE' => [

+ 3 - 0
backendApi/modules/v1/models/lists/shop/PackageList.php

@@ -96,6 +96,9 @@ class PackageList extends \common\libs\dataList\DataList implements DataListInte
                         'width' => '110',
                     ],
                 ],
+                'SORT' => [
+                    'header' => '排序',
+                ],
                 'STATUS_DATE' => [
                     'header' => '是否开启限时',
                     'value' => function($row) {

+ 104 - 0
backendApi/modules/v1/models/lists/shop/RemainPvList.php

@@ -0,0 +1,104 @@
+<?php
+
+namespace backendApi\modules\v1\models\lists\shop;
+
+use common\helpers\Cache;
+use common\helpers\user\Info;
+use common\libs\dataList\column\Price;
+use common\libs\dataList\DataListInterface;
+use common\libs\dataList\column\DateTime;
+use common\models\RemainPv;
+use Yii;
+
+class RemainPvList extends \common\libs\dataList\DataList implements DataListInterface {
+    /**
+     * 列表名称
+     * @return string
+     */
+    public function getListName() {
+        return '剩余BV';
+    }
+
+    /**
+     * 列表筛选到的数据
+     * @throws \yii\base\Exception
+     */
+    public function dataHandle() {
+        $this->listData = RemainPv::lists($this->condition, $this->params, [
+            'select' => 'FR.*,U.USER_NAME,U.REAL_NAME,U.IS_DEC',
+            'orderBy' => 'FR.UPDATED_AT DESC,FR.ID DESC',
+            'from' => RemainPv::tableName() . ' AS FR',
+            'join' => [
+                ['LEFT JOIN', \common\models\User::tableName() . ' AS U', 'FR.USER_ID=U.ID'],
+            ],
+            'page' => $this->page,
+            'pageSize' => $this->pageSize,
+        ]);
+        foreach ($this->listData['list'] as $key => $value) {
+//            $this->listData['list'][$key]['LAST_STATUS_NAME'] = \Yii::$app->params['userStatus'][$value['LAST_STATUS']]['label'] ?? '';
+        }
+
+    }
+
+    /**
+     * 要展示和导出的所有字段
+     * @return array
+     */
+    public function getColumn() {
+        if (!$this->columns) {
+            $this->columns = [
+                'ID' => null,
+                'USER_NAME' => [
+                    'header' => '会员编号',//会员编号
+                    'headerOther' => [
+                        'width' => '150',
+                    ],
+                    'valueOther' => [
+                        'tag' => ['type' => 'info', 'size' => 'small', 'class' => 'no-border']
+                    ],
+                ],
+                'REAL_NAME' => [
+                    'header' => '会员姓名',//会员姓名
+                    'headerOther' => [
+                        'width' => '120',
+                    ],
+                    'valueOther' => [
+                        'tag' => ['type' => 'success', 'size' => 'small', 'class' => 'no-border']
+                    ],
+                ],
+                'REMAIN_PV' => [
+                    'header' => '剩余PV',
+                    'headerOther' => [
+                        'width' => '150',
+                        'prop' => 'REMAIN_PV',
+                    ],
+                ],
+                'UPDATED_AT' => [
+                    'header' => '更新时间',//创建时间
+                    'value' => function ($row) {
+                        return (new DateTime([
+                            'value' => $row['UPDATED_AT'],
+                        ]))->result();
+                    },
+                    'headerOther' => ['width' => '170'],
+                ],
+            ];
+        }
+        return $this->columns;
+    }
+
+    /**
+     * 前台用于筛选的类型集合
+     * @return mixed
+     */
+    public function getFilterTypes() {
+        if (!$this->filterTypes) {
+            $this->filterTypes = [
+                'UPDATED_AT' => ['isUserTable' => false, 'name' => '更新时间', 'other' => 'date'], // 创建时间
+                'USER_NAME' => ['isUserTable' => false, 'name' => '会员编号'], // 会员编号
+                'REAL_NAME' => ['isUserTable' => false, 'name' => '会员姓名'], // 会员姓名
+            ];
+        }
+        return $this->filterTypes;
+    }
+}

+ 20 - 6
backendApi/modules/v1/models/lists/user/IndexList.php

@@ -6,6 +6,7 @@ use common\helpers\http\BackendToFrontendApi;
 use common\helpers\user\Info;
 use common\libs\dataList\DataListInterface;
 use common\models\DecRole;
+use common\models\EmployLevel;
 use common\models\OpenBank;
 use common\models\Region;
 use common\models\User;
@@ -31,7 +32,7 @@ class IndexList extends \common\libs\dataList\DataList implements DataListInterf
      */
     public function dataHandle()
     {
-        $this->condition .= ' AND UN.USER_ID=UI.USER_ID AND UN.PARENT_UID=UI.CON_UID';
+//        $this->condition .= ' AND UN.PARENT_UID=UI.CON_UID';
         $this->listData = User::lists($this->condition, $this->params, [
             'select' => 'U.*,
                 UI.USER_ID, UI.ZC_PV, UI.CON_UID, UI.REC_UID, UI.CON_NUM, UI.REC_NUM, UI.NETWORK_DEEP, 
@@ -46,11 +47,11 @@ class IndexList extends \common\libs\dataList\DataList implements DataListInterf
                 RU.USER_NAME REC_USER_NAME,RU.REAL_NAME REC_REAL_NAME,
                 DU.USER_NAME DEC_USER_NAME
                 ',
-            'orderBy' => 'UI.CREATED_AT DESC, UI.ID DESC',
+            'orderBy' => 'U.CREATED_AT DESC',
             'from' => User::tableName() . ' AS U',
             'join' => [
-                ['LEFT JOIN', UserInfo::tableName() . ' AS UI', 'UI.USER_ID=U.ID'],
-                ['LEFT JOIN', UserNetwork::tableName() . ' AS UN', 'UI.USER_ID=UN.USER_ID'],
+                ['LEFT JOIN', UserInfo::tableName() . ' AS UI', 'U.ID=UI.USER_ID'],
+                ['LEFT JOIN', UserNetwork::tableName() . ' AS UN', 'U.ID=UN.USER_ID'],
                 ['LEFT JOIN', User::tableName() . ' AS CU', 'UI.CON_UID=CU.ID'],
                 ['LEFT JOIN', User::tableName() . ' AS RU', 'UI.REC_UID=RU.ID'],
                 ['LEFT JOIN', User::tableName() . ' AS DU', 'U.DEC_ID=DU.ID'],
@@ -170,7 +171,19 @@ class IndexList extends \common\libs\dataList\DataList implements DataListInterf
                         'width' => '130',
                     ],
                     'value' => function($row) use($empLevelConfig) {
-                        return isset($empLevelConfig[$row['EMP_LV']])?$empLevelConfig[$row['EMP_LV']]['LEVEL_NAME']:'';
+                        return isset($empLevelConfig[$row['EMP_LV']])?$empLevelConfig[$row['EMP_LV']]['LEVEL_NAME']:$empLevelConfig[EmployLevel::getDefaultLevelId()]['LEVEL_NAME'];
+                    },
+                    'valueOther' => [
+                        'tag'=>['type'=>'warning', 'size' => 'small', 'class'=>'no-border']
+                    ],
+                ],
+                'LAST_EMP_LV_NAME' => [
+                    'header' => '最新聘级',
+                    'headerOther' => [
+                        'width' => '130',
+                    ],
+                    'value' => function($row) use($empLevelConfig) {
+                        return isset($empLevelConfig[$row['LAST_EMP_LV']])?$empLevelConfig[$row['LAST_EMP_LV']]['LEVEL_NAME']:$empLevelConfig[EmployLevel::getDefaultLevelId()]['LEVEL_NAME'];
                     },
                     'valueOther' => [
                         'tag'=>['type'=>'warning', 'size' => 'small', 'class'=>'no-border']
@@ -587,6 +600,7 @@ class IndexList extends \common\libs\dataList\DataList implements DataListInterf
 //                'DEC_LV_UPDATED_AT'=> ['name'=> '实时调整日期', 'other'=> 'date'],
 //                'LAST_DEC_LV_NAME'=> ['name'=> '结算时会员级别', 'other'=> 'decLevel'],
                 'EMP_LV_NAME'=> ['name'=> '最高聘级', 'other'=> 'empLevel'],
+                'LAST_EMP_LV_NAME'=> ['name'=> '最新聘级', 'other'=> 'empLevel'],
 //                'HIGHEST_EMP_LV_NAME'=> ['name'=> '历史最高聘级', 'other'=> 'empLevel'],
 //                'HIGHEST_EMP_LV_PERIOD'=> ['name'=> '首次达到历史最高聘级的期数'],
                 'REC_USER_NAME'=> ['name'=> '推荐编号'],
@@ -629,4 +643,4 @@ class IndexList extends \common\libs\dataList\DataList implements DataListInterf
         }
         return $this->filterTypes;
     }
-}
+}

+ 36 - 0
backendEle/src/router/index.js

@@ -157,6 +157,30 @@ export const constantRouterMap = [
             },
 
         },
+      {
+        path: '/shop/remain-pv',
+        component: _import('shop/remain-pv'),
+        name: 'shop_remain-pv',
+        meta: {
+          title: '剩余PV', // 剩余BV
+          breadcrumb: [
+            {title: '首页', path: '/dashboard/index'}, // Dashboard
+            {title: '商城管理', path: '/shop/index'} // 商城管理
+          ],
+        },
+      },
+      {
+        path: '/shop/flow-remain-pv',
+        component: _import('shop/flow-remain-pv'),
+        name: 'shop_flow-remain-pv',
+        meta: {
+          title: '剩余PV流水', // 剩余BV流水
+          breadcrumb: [
+            {title: '首页', path: '/dashboard/index'}, // Dashboard
+            {title: '商城管理', path: '/shop/index'} // 商城管理
+          ],
+        },
+      },
     ],
   },
   {
@@ -1176,6 +1200,18 @@ export const constantRouterMap = [
           ],
         },
       },
+      {
+        path: '/bonus/perf-adjustment',
+        component: _import('bonus/perf-adjustment'),
+        name: 'bonus-perf-adjustment',
+        meta: {
+          title: '业绩调整',
+          breadcrumb: [
+            {title: '首页', path: '/dashboard/index'},
+            {title: '奖金管理', path: '/bonus/period'},
+          ],
+        },
+      },
       {
         path: '/bonus/score-month',
         component: _import('bonus/score-month'),

+ 166 - 0
backendEle/src/views/bonus/perf-adjustment.vue

@@ -0,0 +1,166 @@
+<template>
+  <div v-loading="loading">
+    <div class="white-box">
+      <div class="filter-user" @keyup.enter="getData()">
+        <el-input v-model="memberCode" size="small" style="width:400px;" prefix-icon="el-icon-user-solid">
+          <template slot="prepend">会员编号</template>
+        </el-input>
+        <el-button type="primary" icon="el-icon-search" size="small" @click="getData()">确定</el-button>
+      </div>
+
+      <div style="margin-top: 45px;">
+        <el-row>
+          <el-col :span="15" v-show="show">
+            <div class="grid-content bg-purple" style="width: 100%;">
+              <el-card class="box-card" shadow="hover" style="margin: 15px;">
+                <el-form :model="perfForm" status-icon ref="perfForm" label-width="100px" width="100%" class="demo-ruleForm">
+                  <el-form-item label="会员编号" prop="USER_NAME" v-show="false">
+                    <el-input type="text" size="small" v-model="perfForm.USER_ID"></el-input>
+                    <el-input type="text" size="small" v-model="perfForm.USER_NAME"></el-input>
+                  </el-form-item>
+
+                  <el-divider><i class="el-icon-s-data"></i> 一市场业绩</el-divider>
+                  <el-form-item label="会员编号" prop="SURPLUS_1L_USER_NAME">
+                    <el-input type="text" size="small" v-model="perfForm.SURPLUS_1L_USER_NAME" autocomplete="off" readonly prefix-icon="el-icon-user"></el-input>
+                  </el-form-item>
+                  <el-form-item label="综合结余" prop="SURPLUS_1L">
+                    <el-input type="text" size="small" v-model="perfForm.SURPLUS_1L" autocomplete="off" prefix-icon="el-icon-s-data"></el-input>
+                  </el-form-item>
+                  <el-form-item label="首单结余" prop="SURPLUS_1L_ZC">
+                    <el-input type="text" size="small" v-model="perfForm.SURPLUS_1L_ZC" autocomplete="off" prefix-icon="el-icon-s-data"></el-input>
+                  </el-form-item>
+                  <el-form-item label="复消结余" prop="SURPLUS_1L_FX">
+                    <el-input type="text" size="small" v-model="perfForm.SURPLUS_1L_FX" autocomplete="off" prefix-icon="el-icon-s-data"></el-input>
+                  </el-form-item>
+
+                  <el-divider><i class="el-icon-s-data"></i> 二市场业绩</el-divider>
+                  <el-form-item label="会员编号" prop="SURPLUS_2L_USER_NAME">
+                    <el-input type="text" size="small" v-model="perfForm.SURPLUS_2L_USER_NAME" autocomplete="off" readonly prefix-icon="el-icon-user"></el-input>
+                  </el-form-item>
+                  <el-form-item label="综合结余" prop="SURPLUS_2L">
+                    <el-input type="text" size="small" v-model="perfForm.SURPLUS_2L" autocomplete="off" prefix-icon="el-icon-s-data"></el-input>
+                  </el-form-item>
+                  <el-form-item label="首单结余" prop="SURPLUS_2L_ZC">
+                    <el-input type="text" size="small" v-model="perfForm.SURPLUS_2L_ZC" autocomplete="off" prefix-icon="el-icon-s-data"></el-input>
+                  </el-form-item>
+                  <el-form-item label="复消结余" prop="SURPLUS_2L_FX">
+                    <el-input type="text" size="small" v-model="perfForm.SURPLUS_2L_FX" autocomplete="off" prefix-icon="el-icon-s-data"></el-input>
+                  </el-form-item>
+
+                  <el-divider><i class="el-icon-s-data"></i> 三市场业绩</el-divider>
+                  <el-form-item label="会员编号" prop="SURPLUS_3L_USER_NAME">
+                    <el-input type="text" size="small" v-model="perfForm.SURPLUS_3L_USER_NAME" autocomplete="off" readonly prefix-icon="el-icon-user"></el-input>
+                  </el-form-item>
+                  <el-form-item label="综合结余" prop="SURPLUS_3L">
+                    <el-input type="text" size="small" v-model="perfForm.SURPLUS_3L" autocomplete="off" prefix-icon="el-icon-s-data"></el-input>
+                  </el-form-item>
+                  <el-form-item label="首单结余" prop="SURPLUS_3L_ZC">
+                    <el-input type="text" size="small" v-model="perfForm.SURPLUS_3L_ZC" autocomplete="off" prefix-icon="el-icon-s-data"></el-input>
+                  </el-form-item>
+                  <el-form-item label="复消结余" prop="SURPLUS_3L_FX">
+                    <el-input type="text" size="small" v-model="perfForm.SURPLUS_3L_FX" autocomplete="off" prefix-icon="el-icon-s-data"></el-input>
+                  </el-form-item>
+
+                  <el-form-item>
+                    <el-button type="primary" size="small" @click="handlePerfAdjustment('perfForm')">确定</el-button>
+                  </el-form-item>
+                </el-form>
+              </el-card>
+            </div>
+          </el-col>
+        </el-row>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import network from '@/utils/network'
+
+export default {
+  name: 'bonus-perf-adjustment',
+  data() {
+    return {
+      loading: false,
+      memberCode: '',
+      show: false,
+      perfForm: {
+        USER_ID: '',
+        USER_NAME: '',
+        SURPLUS_1L: '',
+        SURPLUS_1L_ZC: '',
+        SURPLUS_1L_FX: '',
+        SURPLUS_1L_USER_NAME: '',
+        SURPLUS_2L: '',
+        SURPLUS_2L_ZC: '',
+        SURPLUS_2L_FX: '',
+        SURPLUS_2L_USER_NAME: '',
+        SURPLUS_3L: '',
+        SURPLUS_3L_ZC: '',
+        SURPLUS_3L_FX: '',
+        SURPLUS_3L_USER_NAME: '',
+      },
+    }
+  },
+  methods: {
+    // 查询安置网的下级会员和业绩
+    getData() {
+      if (!this.memberCode.length) {
+        this.$message({
+          message: '请输入会员编号',
+          type: 'info'
+        });
+        return false;
+      }
+
+      // 清除上一次的填充结果
+      this.$refs['perfForm'].resetFields();
+      this.show = false;
+
+      return network.getData(`bonus/perf-adjustment`, { memberCode : this.memberCode }).then(response => {
+        this.perfForm = response.allData;
+        this.show = true;
+        this.loading = false;
+      }).catch(error => {
+        this.$message({
+          message: error,
+          type: 'warning'
+        });
+
+        this.loading = false;
+      })
+    },
+    // 修改会员业绩
+    handlePerfAdjustment(formName) {
+      this.$confirm('确认修改会员业绩?', '提示', { //
+        confirmButtonText: '确认',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        this.loading = true;
+        return network.postData(`bonus/perf-adjustment`, this.perfForm).then(response => {
+          this.$message({
+            message: response,
+            type: 'success'
+          });
+          this.loading = false;
+
+          // 刷新数据
+          this.getData();
+        }).catch(error => {
+          this.$message({
+            message: error,
+            type: 'warning'
+          });
+          this.loading = false;
+        });
+      })
+    },
+  }
+}
+</script>
+
+<style>
+  .filter-user { font-size: 14px; margin-bottom: 20px; }
+  .filter-user:after { content: ''; display: table;  clear: both; }
+</style>

+ 53 - 1
backendEle/src/views/config/base.vue

@@ -55,6 +55,14 @@
         <el-form-item>
           <el-button type="primary" @click="onSubmit" :loading="submitButtonStat">更新</el-button>
         </el-form-item>
+        <el-form-item label="行政区划">
+          <el-button type="primary" @click="initRegionXls" :loading="initRegionXlsStat">导入地址xls</el-button>
+          <el-button type="primary" @click="renewRegion" :loading="renewRegionStat">刷新地址表</el-button>
+          <el-button type="primary" @click="genRegionJs" :loading="genRegionJsStat">生成js</el-button>
+        </el-form-item>
+        <el-form-item label="行政区划缓存">
+          <el-button type="primary" @click="renewRegionCache" :loading="renewReginCacheStat">更新Redis</el-button>
+        </el-form-item>
       </el-form>
     </div>
   </div>
@@ -73,6 +81,9 @@ export default {
       loading: true,
       submitButtonStat: false,
       configData: null,
+      initRegionXlsStat: false,
+      renewRegionStat: false,
+      genRegionJsStat: false,
     }
   },
   computed: {
@@ -85,6 +96,47 @@ export default {
     }
   },
   methods: {
+    renewRegionCache () {
+      network.getData('config/renew-region-cache').then(response => {
+        this.$message({
+          message: response,
+          type: 'success'
+        })
+      }).catch(response => {
+        console.log(2)
+      })
+    },
+    initRegionXls () {
+      network.getData('config/init-region-xls').then(response => {
+        this.$message({
+          message: response,
+          type: 'success'
+        })
+      }).catch(response => {
+        console.log(2)
+      })
+    },
+    renewRegion () {
+      network.getData('config/region').then(response => {
+        this.$message({
+          message: response,
+          type: 'success'
+        })
+      }).catch(response => {
+        console.log(2)
+      })
+    },
+    genRegionJs () {
+      network.getData('config/region-js').then(response => {
+        let data = JSON.parse(response)
+        this.$message({
+          message: response,
+          type: 'success'
+        })
+      }).catch(response => {
+        console.log(2)
+      })
+    },
     onSubmit () {
       this.submitButtonStat = true
       console.log(this.form)
@@ -116,4 +168,4 @@ export default {
   font-size:13px;
   margin-left:10px;
 }
-</style>
+</style>

+ 2 - 39
backendEle/src/views/config/bonus-opt.vue

@@ -112,44 +112,7 @@
         </div>
       </div>
     </div>
-    <div class="panel" v-if="permission.hasPermission(`config/bonus-dec-level`)">
-      <div class="panel-heading">
-        管理奖
-      </div>
-      <div class="panel-wrapper">
-        <div class="panel-body">
-          <el-table :data="decLevelTableData" stripe style="width: 100%;">
-            <el-table-column prop="LEVEL_NAME" label="级别名称"></el-table-column>
-            <el-table-column label="奇数代数(推广1人)">
-              <template slot-scope="scope">
-                <el-input v-model="scope.row.GL_ODD_DEEP_ONE" min="0" max="100">
-                  <template slot="append">代</template>
-                </el-input>
-              </template>
-            </el-table-column>
-            <el-table-column label="奇数代数(推广2人)">
-              <template slot-scope="scope">
-                <el-input v-model="scope.row.GL_ODD_DEEP_TWO" min="0" max="100">
-                  <template slot="append">代</template>
-                </el-input>
-              </template>
-            </el-table-column>
-            <el-table-column label="奇数代数(推广3人)">
-              <template slot-scope="scope">
-                <el-input v-model="scope.row.GL_ODD_DEEP_THREE" min="0" max="100">
-                  <template slot="append">代</template>
-                </el-input>
-              </template>
-            </el-table-column>
-          </el-table>
-        </div>
-        <div class="panel-footer">
-          <el-button type="primary" @click="onGLSubmit" :loading="glSubmitButtonStat" style="float: right;">保存
-          </el-button>
-        </div>
-      </div>
-    </div>
-    <div class="panel" v-if="permission.hasPermission(`config/bonus-emp-level`)">
+    <!-- <div class="panel" v-if="permission.hasPermission(`config/bonus-emp-level`)">
       <div class="panel-heading">
         荣衔奖和积分配置
       </div>
@@ -185,7 +148,7 @@
           </el-button>
         </div>
       </div>
-    </div>
+    </div> -->
   </div>
 </template>
 

+ 2 - 2
backendEle/src/views/config/transfer.vue

@@ -96,7 +96,7 @@
         },
         loading: true,
         submitButtonStat: false,
-        allWallet:{'bonus':'会员账户','cash':'现金钱包','point':'复销点数'}
+        allWallet:{'bonus':'奖金账户','cash':'充值账户','point':'复消积分'}
       }
     },
     methods: {
@@ -133,4 +133,4 @@
 
 <style scoped>
 
-</style>
+</style>

+ 324 - 313
backendEle/src/views/finance/withdraw.vue

@@ -4,10 +4,10 @@
       <el-tabs v-model="filterStatus" @tab-click="handleFilterStatusClick">
         <el-tab-pane label="全部" name="-1" :lazy="true"></el-tab-pane>
         <el-tab-pane label="待审核" name="0" :lazy="true"></el-tab-pane>
-        <el-tab-pane label="已审核" name="2" :lazy="true"></el-tab-pane>
-        <el-tab-pane label="待付款" name="3" :lazy="true"></el-tab-pane>
+<!--        <el-tab-pane label="已审核" name="2" :lazy="true"></el-tab-pane>-->
+        <el-tab-pane label="待复核" name="3" :lazy="true"></el-tab-pane>
         <el-tab-pane label="已付款" name="6" :lazy="true"></el-tab-pane>
-        <el-tab-pane label="付款失败" name="4" :lazy="true"></el-tab-pane>
+<!--        <el-tab-pane label="付款失败" name="4" :lazy="true"></el-tab-pane>-->
         <el-tab-pane label="已退回" name="7" :lazy="true"></el-tab-pane>
       </el-tabs>
       <div class="filter-box">
@@ -33,7 +33,7 @@
         <el-table-column fixed="right" label="操作" width="180">
           <template slot-scope="scope">
             <el-dropdown size="small" trigger="click"
-                         v-if="scope.row.AUDIT_STATUS!=='7' && (permission.hasPermission(`finance/withdraw-status`))">
+                         v-if="scope.row.AUDIT_STATUS!=='6' && scope.row.AUDIT_STATUS!=='7' && (permission.hasPermission(`finance/withdraw-status`))">
               <el-button type="primary" size="small" @click.stop="">
                 操作该数据<i class="el-icon-arrow-down el-icon--right"></i>
               </el-button>
@@ -43,40 +43,45 @@
                 <!--v-show="(scope.row.AUDIT_STATUS==='0'||scope.row.AUDIT_STATUS==='1') && (permission.hasPermission(`finance/invoice-audit-add`)||permission.hasPermission(`finance/invoice-audit-edit`))">-->
                 <!--补录发票信息-->
                 <!--</el-dropdown-item>-->
-                <el-dropdown-item command="status"
-                                  @click.native="handleStatusShow(scope.row, 2, '确定对当前提现进行审核通过操作?')"
-                                  v-show="scope.row.AUDIT_STATUS==='0' && permission.hasPermission(`finance/withdraw-status`)">
-                  审核通过
-                </el-dropdown-item>
-                <el-dropdown-item command="status"
-                                  @click.native="handleStatusShow(scope.row, 3, '确定对当前提现进行设为待付款操作?')"
-                                  v-show="scope.row.AUDIT_STATUS === '2' && permission.hasPermission(`finance/withdraw-status`)">
-                  设为待付款
-                </el-dropdown-item>
+<!--                <el-dropdown-item command="status"-->
+<!--                                  @click.native="handleStatusShow(scope.row, 3, '确定对当前提现进行审核通过操作?')"-->
+<!--                                  v-show="scope.row.AUDIT_STATUS==='0' && permission.hasPermission(`finance/withdraw-status`)">-->
+<!--                  审核通过-->
+<!--                </el-dropdown-item>-->
+<!--                <el-dropdown-item command="status"-->
+<!--                                  @click.native="handleStatusShow(scope.row, 3, '确定对当前提现进行设为待复核操作?')"-->
+<!--                                  v-show="scope.row.AUDIT_STATUS === '2' && permission.hasPermission(`finance/withdraw-status`)">-->
+<!--                  设为待复核-->
+<!--                </el-dropdown-item>-->
                 <el-dropdown-item command="status"
                                   @click.native="handleStatusShow(scope.row, 6, '确定对当前提现进行设为已付款操作?')"
-                                  v-show="scope.row.AUDIT_STATUS === '3' && permission.hasPermission(`finance/withdraw-status`)">
-                  设为已付款
+                                  v-show="scope.row.AUDIT_STATUS === '3' && permission.hasPermission(`finance/withdraw-status-pay`)">
+                  付款
                 </el-dropdown-item>
                 <el-dropdown-item command="status"
-                                  @click.native="handleStatusShow(scope.row, 3, '确定对当前提现进行设为待付款操作?')"
-                                  v-show="scope.row.AUDIT_STATUS === '4' && permission.hasPermission(`finance/withdraw-status`)">
-                  设为待付款
-                </el-dropdown-item>
-                <el-dropdown-item command="status"
-                                  @click.native="handleStatusShow(scope.row, 4, '确定对当前提现进行设为付款失败操作?', '付款失败备注')"
-                                  v-show="scope.row.AUDIT_STATUS === '6' && permission.hasPermission(`finance/withdraw-status`)">
-                  设为付款失败
+                                  @click.native="handleStatusShow(scope.row, 3, '确定对当前提现进行设为待复核操作?')"
+                                  v-show="scope.row.AUDIT_STATUS === '0' && permission.hasPermission(`finance/withdraw-status-audit`)">
+                  审核通过
                 </el-dropdown-item>
+<!--                <el-dropdown-item command="status"-->
+<!--                                  @click.native="handleStatusShow(scope.row, 4, '确定对当前提现进行设为付款失败操作?', '付款失败备注')"-->
+<!--                                  v-show="scope.row.AUDIT_STATUS === '6' && permission.hasPermission(`finance/withdraw-status`)">-->
+<!--                  设为付款失败-->
+<!--                </el-dropdown-item>-->
                 <el-dropdown-item command="status"
                                   @click.native="handleStatusShow(scope.row, 7, '确定对当前提现进行设为提现退回操作?', '提现退回备注')"
-                                  v-show="scope.row.AUDIT_STATUS === '0' && permission.hasPermission(`finance/withdraw-status`)">
-                  设为提现退回
+                                  v-show="scope.row.AUDIT_STATUS === '0' && permission.hasPermission(`finance/withdraw-status-return`)">
+                  退回
                 </el-dropdown-item>
                 <el-dropdown-item command="status"
                                   @click.native="handleStatusShow(scope.row, 7, '该会员已提供发票,请确认是否处理提现退回?', '提现退回备注')"
-                                  v-show="(scope.row.AUDIT_STATUS === '1'||scope.row.AUDIT_STATUS === '2'||scope.row.AUDIT_STATUS === '3') && permission.hasPermission(`finance/withdraw-status`)">
-                  设为提现退回
+                                  v-show="(scope.row.AUDIT_STATUS === '1'||scope.row.AUDIT_STATUS === '2') && permission.hasPermission(`finance/withdraw-status-return`)">
+                  退回
+                </el-dropdown-item>
+                <el-dropdown-item command="status"
+                                  @click.native="handleStatusShow(scope.row, 0, '确定对当前提现取消审核,并设为“待审核”?', '取消审核备注')"
+                                  v-show="scope.row.AUDIT_STATUS === '3' && permission.hasPermission(`finance/withdraw-status-cancel`)">
+                  取消审核
                 </el-dropdown-item>
               </el-dropdown-menu>
             </el-dropdown>
@@ -86,27 +91,27 @@
       <div class="white-box-footer">
 
         <el-dropdown size="small" trigger="click" @command="handleMuli"
-                     v-if="filterStatus!=='-1' && filterStatus!=='7' && (permission.hasPermission(`finance/withdraw-status`))">
+                     v-if="filterStatus!=='-1' && filterStatus!=='6' && filterStatus!=='7' && (permission.hasPermission(`finance/withdraw-status`))">
           <el-button type="primary" size="small">
             所选数据<i class="el-icon-arrow-down el-icon--right"></i>
           </el-button>
           <el-dropdown-menu v-if="filterStatus==='0'" slot="dropdown">
-            <el-dropdown-item command="2">批量审核通过</el-dropdown-item>
-            <el-dropdown-item command="7">批量退回</el-dropdown-item>
-          </el-dropdown-menu>
-          <el-dropdown-menu v-else-if="filterStatus==='2'" slot="dropdown">
-            <el-dropdown-item command="3">批量设为待付款</el-dropdown-item>
+            <el-dropdown-item command="3" v-show="permission.hasPermission(`finance/withdraw-status-audit`)">批量审核通过</el-dropdown-item>
+            <el-dropdown-item command="7" v-show="permission.hasPermission(`finance/withdraw-status-return`)">批量退回</el-dropdown-item>
           </el-dropdown-menu>
+<!--          <el-dropdown-menu v-else-if="filterStatus==='2'" slot="dropdown">-->
+<!--            <el-dropdown-item command="3">批量设为待复核</el-dropdown-item>-->
+<!--          </el-dropdown-menu>-->
           <el-dropdown-menu v-else-if="filterStatus==='3'" slot="dropdown">
-            <el-dropdown-item command="6">批量设为已付款</el-dropdown-item>
-            <el-dropdown-item command="7">批量退回</el-dropdown-item>
-          </el-dropdown-menu>
-          <el-dropdown-menu v-else-if="filterStatus==='6'" slot="dropdown">
-            <el-dropdown-item command="4">批量设为付款失败</el-dropdown-item>
-          </el-dropdown-menu>
-          <el-dropdown-menu v-else-if="filterStatus==='4'" slot="dropdown">
-            <el-dropdown-item command="3">批量设为待付款</el-dropdown-item>
+            <el-dropdown-item command="6" v-show="permission.hasPermission(`finance/withdraw-status-pay`)">批量设为已付款</el-dropdown-item>
+            <el-dropdown-item command="0" v-show="permission.hasPermission(`finance/withdraw-status-cancel`)">批量取消审核</el-dropdown-item>
           </el-dropdown-menu>
+<!--          <el-dropdown-menu v-else-if="filterStatus==='6'" slot="dropdown">-->
+<!--            <el-dropdown-item command="4">批量设为付款失败</el-dropdown-item>-->
+<!--          </el-dropdown-menu>-->
+<!--          <el-dropdown-menu v-else-if="filterStatus==='4'" slot="dropdown">-->
+<!--            <el-dropdown-item command="3">批量设为待复核</el-dropdown-item>-->
+<!--          </el-dropdown-menu>-->
         </el-dropdown>
 
         <el-button type="success" size="small" @click="handleExport"
@@ -127,7 +132,7 @@
             </el-form-item>
             <el-form-item label="注册类型">
               <el-select v-model="form.baseInfo.REG_TYPE" placeholder="请选择注册类型" :disabled="true">
-                <el-option v-for="(item,key) in regTypes" :label="item.TYPE_NAME" :value="item.ID"
+                <el-option v-for="(item, key) in regTypes" :label="item.TYPE_NAME" :value="item.ID"
                            :key="item.ID"></el-option>
               </el-select>
             </el-form-item>
@@ -159,7 +164,7 @@
                   type="warning" :closable="false">
           </el-alert>
           <el-form :model="auditForm" label-width="150px" style="width:500px;" v-loading="dialogAuditLoading">
-            <el-form-item label="预计付款日期" v-show="filterStatus==='2' || filterStatus==='4'">
+            <el-form-item label="预计付款日期" v-show="planPayDateVisible">
               <el-date-picker
                       v-model="auditForm.planPaidAt"
                       type="date"
@@ -202,93 +207,94 @@ import baseInfo from '@/utils/baseInfo'
 import Pagination from '@/components/Pagination'
 import filterHelper from '../../utils/filterHelper'
 export default {
-    name: 'finance_withdraw',
-    components: {FilterUser, Pagination},
+  name: 'finance_withdraw',
+  components: {FilterUser, Pagination},
 
-    data() {
-        return {
-            activeName: 'all',
-            tableHeaders: null,
-            baseDecLevels: baseInfo.decLevels(),
+  data () {
+    return {
+      activeName: 'all',
+      tableHeaders: null,
+      baseDecLevels: baseInfo.decLevels(),
 
-            allData: null,
-            tableData: null,
-            loading: true,
-            multipleSelection: [],
-            currentPage: 1,
-            totalPages: 1,
-            totalCount: 1,
-            pageSize: 20,
-            tool: tool,
-            permission: permission,
-            regTypes: baseInfo.regTypes(),
-            dialogEditFormVisible: false,
-            dialogEditLoading: false,
-            dialogAuditFormVisible: false,
-            dialogAuditLoading: false,
-            dialogAddInvoiceVisible: false,
-            dialogAddInvoiceLoading: false,
-            auditId: null,
-            form: {
-                id: null,
-                baseInfo: {USER_NAME: null, REG_TYPE: null},
-                amount: null,
-                planPaidAt: null,
-                paidAt: new Date(),
-                createRemark: null,
-            },
-            invoiceForm: {
-                id: null,
-                withdrawId: null,
-                withdrawSn: null,
-                invoiceCode: null,
-                invoiceNum: null,
-                invoiceDate: null,
-                amount: null,
-                taxRate: null,
-                purchaserName: null,
-                purchaserRegisterNum: null,
-                purchaserAddress: null,
-                purchaserBank: null,
-                sellerName: null,
-                sellerRegisterNum: null,
-                sellerAddress: null,
-                sellerBank: null,
-                itemName: null,
-                invoiceRemark: null,
-                createRemark: null,
-            },
-            pickerOptions0: {
-                disabledDate(time) {
-                    return time.getTime() < Date.now();
-                }
-            },
-            pickerOptions1: {
-                disabledDate(time) {
-                    return time.getTime() < Date.now() - 8.64e7;
-                }
-            },
-            auditRemark: '',
-            auditForm: {
-                auditTips: '',
-                auditStatus: null,
-                selectedIds: [],
-                planPaidAt: null,
-                createRemark: null,
-                withdrawAudit: '',
-            },
-            auditTips: '',
-            filterTypes: {},
-            filterModel: {},
-            excelForm: {
-                rowCount: '',
-            },
-            filterStatus: '0',
+      allData: null,
+      tableData: null,
+      loading: true,
+      multipleSelection: [],
+      currentPage: 1,
+      totalPages: 1,
+      totalCount: 1,
+      pageSize: 20,
+      tool: tool,
+      permission: permission,
+      regTypes: baseInfo.regTypes(),
+      dialogEditFormVisible: false,
+      dialogEditLoading: false,
+      dialogAuditFormVisible: false,
+      dialogAuditLoading: false,
+      dialogAddInvoiceVisible: false,
+      dialogAddInvoiceLoading: false,
+      planPayDateVisible: false,
+      auditId: null,
+      form: {
+        id: null,
+        baseInfo: {USER_NAME: null, REG_TYPE: null},
+        amount: null,
+        planPaidAt: null,
+        paidAt: new Date(),
+        createRemark: null
+      },
+      invoiceForm: {
+        id: null,
+        withdrawId: null,
+        withdrawSn: null,
+        invoiceCode: null,
+        invoiceNum: null,
+        invoiceDate: null,
+        amount: null,
+        taxRate: null,
+        purchaserName: null,
+        purchaserRegisterNum: null,
+        purchaserAddress: null,
+        purchaserBank: null,
+        sellerName: null,
+        sellerRegisterNum: null,
+        sellerAddress: null,
+        sellerBank: null,
+        itemName: null,
+        invoiceRemark: null,
+        createRemark: null
+      },
+      pickerOptions0: {
+        disabledDate (time) {
+          return time.getTime() < Date.now()
         }
-    },
+      },
+      pickerOptions1: {
+        disabledDate (time) {
+          return time.getTime() < Date.now() - 8.64e7
+        }
+      },
+      auditRemark: '',
+      auditForm: {
+        auditTips: '',
+        auditStatus: null,
+        selectedIds: [],
+        planPaidAt: null,
+        createRemark: null,
+        withdrawAudit: ''
+      },
+      auditTips: '',
+      filterTypes: {},
+      filterModel: {},
+      excelForm: {
+        rowCount: ''
+      },
+      filterStatus: '0'
+    }
+  },
   mounted () {
-      this.getData();
-   /* if (permission.hasPermission(`finance/withdraw-7`)) {
+    this.getData()
+  /* if (permission.hasPermission(`finance/withdraw-7`)) {
       this.activeName = 'seven'
     }
     if (permission.hasPermission(`finance/withdraw-4`)) {
@@ -311,197 +317,202 @@ export default {
     }
     if (permission.hasPermission(`finance/withdraw-0`) && permission.hasPermission(`finance/withdraw-1`) && permission.hasPermission(`finance/withdraw-2`) && permission.hasPermission(`finance/withdraw-3`) && permission.hasPermission(`finance/withdraw-6`) && permission.hasPermission(`finance/withdraw-4`) && permission.hasPermission(`finance/withdraw-7`)) {
       this.activeName = 'all'
-    }*/
+} */
   },
 
-      methods: {
-          handleMuli(command) {
-              if (this.multipleSelection.length < 1) {
-                  this.$message({
-                      message: '请选择要操作的记录',
-                      type: 'warning'
-                  })
-                  return;
-              }
-              this.handleAudit(null, command)
-          },
-          handleAudit(row = null, status) {
-              let title = ''
-              if (status === '2') {
-                  title = '确定要通过审核?备注:'
-              }else if(status === '3'){
-                  title = '确定要设为待付款?备注:'
-              }else if(status === '4'){
-                  title = '确定要设为付款失败?备注:'
-              }else if(status === '6'){
-                  title = '确定要设为已付款?备注:'
-              }else if(status === '7'){
-                  title = '确定要设为已退回?备注:'
-              }
-              this.handleStatusShow(row,status,title);
-          },
-          handleExpand(row, event, column) {
-              this.$refs.multipleTable.toggleRowExpansion(row)
-          },
-          handleExport() {
-              this.$confirm('确定要导出当前表格中的提现数据吗?', '提示', {
-                  confirmButtonText: '确定',
-                  cancelButtonText: '取消',
-                  type: 'warning'
-              }).then(() => {
-                  return network.getData('finance/withdraw-export', this.filterModel)
-              }).then(response => {
-                  this.$message({
-                      message: response,
-                      type: 'success'
-                  })
-              }).catch(response => {
-              })
-          },
-          handleAdd() {
-              this.$router.push({path: `/finance/withdraw-add`})
-          },
-          handleExcel() {
-          },
-          handleExcelPaidFalse() {
-              window.open(CDN_BASE_URL + `/files/bonus_withdraw_paid_false.xlsx`)
-          },
-          handleEditShow(row) {
-              this.dialogEditLoading = true
-              this.auditId = row.ID
-              this.dialogEditFormVisible = true
-              let vueObj = this
-              network.getData('finance/withdraw-get', {id: this.auditId}).then(response => {
-                  vueObj.dialogEditLoading = false
-                  vueObj.form = response
-              })
-          },
-          handleEdit() {
-              this.dialogEditFormVisible = false
-              this.$message({
-                  message: '正在修改数据',
-                  type: 'info'
-              })
-              this.loading = true
-              let path = 'finance/withdraw-edit'
-              network.postData(path, this.form).then(response => {
-                  this.$message({
-                      message: response,
-                      type: 'success'
-                  })
-                  this.getData(this.currentPage, this.pageSize)
-              }).catch(response => {
-              })
-          },
-          handleStatusShow(row, status, title, remark = '备注') {
-              this.auditForm = {
-                  auditTips: '',
-                  auditStatus: null,
-                  selectedIds: [],
-                  planPaidAt: null,
-                  paidAt: new Date(),
-                  remark: null,
-              }
-              if (row === null) {
-                  for (let val of this.multipleSelection) {
-                      this.auditForm.selectedIds.push(val.ID)
-                  }
-              } else {
-                  this.auditForm.selectedIds.push(row.ID)
-              }
-              if (this.auditForm.selectedIds.length === 0) {
-                  this.$message({
-                      message: '请选择数据',
-                      type: 'warning'
-                  })
-                  return
-              }
-              this.auditRemark = remark
-              this.dialogAuditFormVisible = true
-              this.auditForm.auditTips = title
-              this.auditForm.auditStatus = status
-          },
-          handleStatus() {
-              network.postData('finance/mult-point', {opType: 2}).then(response => {
-                  this.auditForm.withdrawAudit = response.withdrawAudit
-                  this.$confirm('确定要对所选数据修改状态吗?', '提示', {
-                      confirmButtonText: '确定',
-                      cancelButtonText: '取消',
-                      type: 'warning'
-                  }).then(() => {
-                      return network.postData('finance/withdraw-status', this.auditForm)
-                  }).then(response => {
-                      this.dialogAuditFormVisible = false
-                      this.$message({
-                          message: response,
-                          type: 'success'
-                      })
-                      this.getData(this.currentPage, this.pageSize)
-                  }).catch(response => {
-                      this.dialogAuditFormVisible = false
-                  })
-              })
-          },
-          handleAddInvoiceShow(row) {
-              this.dialogAddInvoiceVisible = true
-              this.auditId = row.INVOICE_ID
-              this.dialogAddInvoiceLoading = true
-              let vueObj = this
-              network.getData('finance/invoice-audit-get', {id: this.auditId}).then(response => {
-                  vueObj.dialogAddInvoiceLoading = false
-                  vueObj.invoiceForm = response
-                  this.invoiceForm.withdrawSn = row.SN
-                  this.invoiceForm.withdrawId = row.ID
-              })
-          },
-          handleAddInvoice() {
-              let path = 'finance/invoice-audit-add'
-              if (this.invoiceForm.id) path = 'finance/invoice-audit-edit'
-              network.postData(path, this.invoiceForm).then(response => {
-                  this.$message({
-                      message: response,
-                      type: 'success'
-                  })
-                  this.dialogAddInvoiceVisible = false
-                  this.getData(this.currentPage, this.pageSize)
-              }).catch(response => {
-              })
-          },
-          handleSelectionChange(val) {
-              this.multipleSelection = val
-          },
-          handleCurrentChange(page) {
-              this.getData(page, this.pageSize)
-          },
-          handleSizeChange(pageSize) {
-              this.getData(this.currentPage, pageSize)
-          },
-          handleFilterStatusClick(tab, event) {
-              filterHelper.clearFilterOption(this)
-              this.getData()
-          },
-          handleFilterUser(filterData) {
-              filterHelper.handleFilterUser(this, filterData)
-          },
-          handleFilter() {
-              this.getData()
-          },
-          getData(page, pageSize) {
-              let filterData = this.filterModel
-              filterData.filterStatus = this.filterStatus != '-1' ? `=,${this.filterStatus}` : ''
-              let vueObj = this
-              network.getPageData(this, 'finance/withdraw', page, pageSize, filterData, function (response) {
-                  vueObj.allData = response
-                  vueObj.filterTypes = response.filterTypes
-              })
-          },
-          onMessageCallback() {
-              this.getData(this.currentPage, this.pageSize)
-          },
+  methods: {
+    handleMuli (command) {
+      if (this.multipleSelection.length < 1) {
+        this.$message({
+          message: '请选择要操作的记录',
+          type: 'warning'
+        })
+        return
+      }
+      this.handleAudit(null, command)
+    },
+    handleAudit (row = null, status) {
+      let title = ''
+      if (status === '2') {
+        title = '确定要通过审核?备注:'
+      } else if (status === '3') {
+        title = '确定要设为待复核?备注:'
+      } else if (status === '4') {
+        title = '确定要设为付款失败?备注:'
+      } else if (status === '6') {
+        title = '确定要设为已付款?备注:'
+      } else if (status === '7') {
+        title = '确定要设为已退回?备注:'
+      }
+      this.handleStatusShow(row, status, title)
+    },
+    handleExpand (row, event, column) {
+      this.$refs.multipleTable.toggleRowExpansion(row)
+    },
+    handleExport () {
+      this.$confirm('确定要导出当前表格中的提现数据吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        return network.getData('finance/withdraw-export', this.filterModel)
+      }).then(response => {
+        this.$message({
+          message: response,
+          type: 'success'
+        })
+      }).catch(response => {
+      })
+    },
+    handleAdd () {
+      this.$router.push({path: `/finance/withdraw-add`})
+    },
+    handleExcel () {
+    },
+    handleExcelPaidFalse () {
+      window.open(CDN_BASE_URL + `/files/bonus_withdraw_paid_false.xlsx`)
+    },
+    handleEditShow (row) {
+      this.dialogEditLoading = true
+      this.auditId = row.ID
+      this.dialogEditFormVisible = true
+      let vueObj = this
+      network.getData('finance/withdraw-get', {id: this.auditId}).then(response => {
+        vueObj.dialogEditLoading = false
+        vueObj.form = response
+      })
+    },
+    handleEdit () {
+      this.dialogEditFormVisible = false
+      this.$message({
+        message: '正在修改数据',
+        type: 'info'
+      })
+      this.loading = true
+      let path = 'finance/withdraw-edit'
+      network.postData(path, this.form).then(response => {
+        this.$message({
+          message: response,
+          type: 'success'
+        })
+        this.getData(this.currentPage, this.pageSize)
+      }).catch(response => {
+      })
+    },
+    handleStatusShow (row, status, title, remark = '备注') {
+      this.auditForm = {
+        auditTips: '',
+        auditStatus: null,
+        selectedIds: [],
+        planPaidAt: null,
+        paidAt: new Date(),
+        remark: null
       }
+      if (row === null) {
+        for (let val of this.multipleSelection) {
+          this.auditForm.selectedIds.push(val.ID)
+        }
+      } else {
+        this.auditForm.selectedIds.push(row.ID)
+      }
+      if (this.auditForm.selectedIds.length === 0) {
+        this.$message({
+          message: '请选择数据',
+          type: 'warning'
+        })
+        return
+      }
+      this.auditRemark = remark
+      this.dialogAuditFormVisible = true
+      this.auditForm.auditTips = title
+      this.auditForm.auditStatus = status
+      if (status == '3') {
+        this.planPayDateVisible = true
+      } else {
+        this.planPayDateVisible = false
+      }
+    },
+    handleStatus () {
+      network.postData('finance/mult-point', {opType: 2}).then(response => {
+        this.auditForm.withdrawAudit = response.withdrawAudit
+        this.$confirm('确定要对所选数据修改状态吗?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          return network.postData('finance/withdraw-status', this.auditForm)
+        }).then(response => {
+          this.dialogAuditFormVisible = false
+          this.$message({
+            message: response,
+            type: 'success'
+          })
+          this.getData(this.currentPage, this.pageSize)
+        }).catch(response => {
+          this.dialogAuditFormVisible = false
+        })
+      })
+    },
+    handleAddInvoiceShow (row) {
+      this.dialogAddInvoiceVisible = true
+      this.auditId = row.INVOICE_ID
+      this.dialogAddInvoiceLoading = true
+      let vueObj = this
+      network.getData('finance/invoice-audit-get', {id: this.auditId}).then(response => {
+        vueObj.dialogAddInvoiceLoading = false
+        vueObj.invoiceForm = response
+        this.invoiceForm.withdrawSn = row.SN
+        this.invoiceForm.withdrawId = row.ID
+      })
+    },
+    handleAddInvoice () {
+      let path = 'finance/invoice-audit-add'
+      if (this.invoiceForm.id) path = 'finance/invoice-audit-edit'
+      network.postData(path, this.invoiceForm).then(response => {
+        this.$message({
+          message: response,
+          type: 'success'
+        })
+        this.dialogAddInvoiceVisible = false
+        this.getData(this.currentPage, this.pageSize)
+      }).catch(response => {
+      })
+    },
+    handleSelectionChange (val) {
+      this.multipleSelection = val
+    },
+    handleCurrentChange (page) {
+      this.getData(page, this.pageSize)
+    },
+    handleSizeChange (pageSize) {
+      this.getData(this.currentPage, pageSize)
+    },
+    handleFilterStatusClick (tab, event) {
+      filterHelper.clearFilterOption(this)
+      this.getData()
+    },
+    handleFilterUser (filterData) {
+      filterHelper.handleFilterUser(this, filterData)
+    },
+    handleFilter () {
+      this.getData()
+    },
+    getData (page, pageSize) {
+      let filterData = this.filterModel
+      filterData.filterStatus = this.filterStatus != '-1' ? `=,${this.filterStatus}` : ''
+      let vueObj = this
+      network.getPageData(this, 'finance/withdraw', page, pageSize, filterData, function (response) {
+        vueObj.allData = response
+        vueObj.filterTypes = response.filterTypes
+      })
+    },
+    onMessageCallback () {
+      this.getData(this.currentPage, this.pageSize)
+    }
+  }
 }
 </script>
 
 <style scoped>
 
-</style>
+</style>

+ 90 - 0
backendEle/src/views/shop/flow-remain-pv.vue

@@ -0,0 +1,90 @@
+<template>
+  <div v-loading="loading">
+    <div class="white-box">
+      <div class="filter-box">
+        <filter-user :filter-types="filterTypes" @select-value="handleFilterUser"></filter-user>
+      </div>
+      <el-table class="table-box" ref="multipleTable" :data="tableData" stripe style="width: 100%;" :height="tool.getTableHeight()">
+        <el-table-column v-for="(tableHeader, key) in tableHeaders" :key="key" :label="tableHeader.header" :width="tableHeader.other.width ? tableHeader.other.width : ''" :prop="tableHeader.other.prop ? tableHeader.other.prop : null">
+          <template slot-scope="scope">
+            <template v-if="scope.row[tableHeader.index].other.tag" >
+              <el-tag :type="scope.row[tableHeader.index].other.tag.type ? scope.row[tableHeader.index].other.tag.type : null" :size="scope.row[tableHeader.index].other.tag.size ? scope.row[tableHeader.index].other.tag.size : null" :class="scope.row[tableHeader.index].other.tag.class ? scope.row[tableHeader.index].other.tag.class : null" >{{scope.row[tableHeader.index].value}}</el-tag>
+            </template>
+            <template v-else>
+              <div v-html="scope.row[tableHeader.index].value"></div>
+            </template>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="white-box-footer">
+        <pagination :total="totalCount" :page_size="pageSize" @size-change="handleSizeChange" @current-change="handleCurrentChange"></pagination>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import network from '@/utils/network'
+import tool from '@/utils/tool'
+import baseInfo from '@/utils/baseInfo'
+import FilterUser from '../../components/FilterUser'
+import permission from '@/utils/permission'
+import Pagination from '@/components/Pagination'
+import filterHelper from '@/utils/filterHelper'
+
+export default {
+  name: 'shop_flow-remain-pv',
+  components: {FilterUser, Pagination},
+  mounted () {
+    this.getData()
+  },
+  data () {
+    return {
+      tableHeaders: null,
+      tableData: null,
+      loading: true,
+      multipleSelection: [],
+      currentPage: 1,
+      totalPages: 1,
+      totalCount: 1,
+      pageSize: 20,
+      tool: tool,
+      permission: permission,
+      baseDecLevels: baseInfo.decLevels(),
+      baseEmpLevels: baseInfo.empLevels(),
+      filterTypes: null,
+      filterModel: {}
+    }
+  },
+  methods: {
+    handleCurrentChange (page) {
+      this.getData(page, this.pageSize)
+    },
+    handleSizeChange (pageSize) {
+      this.getData(this.currentPage, pageSize)
+    },
+    handleFilterUser (filterData) {
+      filterHelper.handleFilterUser(this, filterData)
+    },
+    getData (page, pageSize) {
+      network.getPageData(this, 'shop/flow-remain-pv', page, pageSize, this.filterModel, response => {
+        this.filterTypes = response.filterTypes
+      })
+    }
+  }
+}
+
+</script>
+
+<style scoped>
+  .table-box .el-form-item__label {
+    width: 100px;
+    color: #99a9bf;
+  }
+
+  .table-box .el-form-item {
+    width: 30%;
+    margin-right: 0;
+    margin-bottom: 0;
+  }
+</style>

+ 265 - 232
backendEle/src/views/shop/goods-add.vue

@@ -1,245 +1,278 @@
 <template>
-    <div v-loading="loading">
-        <div class="white-box">
-            <el-form ref="form"  label-width="250px" class="form-page">
-
-                <el-form-item label="商品名称">
-                    <el-input v-model="form.goodsName"></el-input>
-                </el-form-item>
-                <!-- <el-form-item label="商品来源">
-                    <el-select v-model="form.type" placeholder="请选择商品来源">
-                        <el-option v-for="(item,index) in goodsType" :key="index" :label="item.name"
-                                   :value="index"></el-option>
-                    </el-select>
-                </el-form-item> -->
-                <el-form-item label="会员折扣">
-                    <el-input v-model="form.sellDiscount"></el-input>
-                </el-form-item>
-                <el-form-item label="商品类型">
-                    <el-checkbox  v-for="(value,key) in GiftTypeArr" v-model="form.giftType[key-1]" :key="key" >{{value.name}}</el-checkbox>
-                </el-form-item>
-                <!-- <el-form-item label="复消购买方式">
-                    <el-checkbox  v-for="(value,key) in sellType" v-model="form.sellType[key-1]" :key="key" >{{value.name}}</el-checkbox>
-                </el-form-item> -->
-
-                <el-form-item label="商品编号">
-                    <el-input v-model="form.goodsNo"></el-input>
-                </el-form-item>
-                <el-form-item label="单位">
-                    <el-input v-model="form.unit"></el-input>
-                </el-form-item>
-                <el-form-item label="市场价格">
-                    <el-input v-model="form.marketPrice"></el-input>
-                </el-form-item>
-                <el-form-item label="销售价格">
-                    <el-input v-model="form.sellPrice"></el-input>
-                </el-form-item>
-                <el-form-item label="价格PV	">
-                    <el-input v-model="form.pricePv"></el-input>
-                </el-form-item>
-                <!-- <el-form-item label="兑换积分">
-                    <el-input v-model="form.point"></el-input>
-                </el-form-item> -->
-                <el-form-item label="库存">
-                    <el-input v-model="form.storeNums"></el-input>
-                </el-form-item>
-                <el-form-item label="商品详情">
-                    <el-input
-                            type="textarea"
-                            :rows="2"
-                            placeholder="请输入内容"
-                            v-model="form.content">
-                    </el-input>
-                </el-form-item>
-                <el-form-item label="排序">
-                    <el-input v-model="form.sort"></el-input>
-                </el-form-item>
-                <el-form-item label="上传图片">
-                    <div class='up_load'>
-                        <leo-uploader
-                            @on-success='upLoadSuccess'
-                            :request-route="'shop/upload'"
-                        ></leo-uploader>
-                    </div>
-                </el-form-item>
-                <el-form-item>
-                    <el-button type="primary" @click="addSubmit" :loading="submitButtonStat">添加</el-button>
-                </el-form-item>
-            </el-form>
-        </div>
-    </div>
+  <div v-loading="loading">
+    <div class="white-box">
+      <el-form ref="form"  label-width="250px" class="form-page">
+        <el-form-item label="商品名称">
+          <el-input v-model="form.goodsName"></el-input>
+        </el-form-item>
+      <!-- <el-form-item label="商品来源">
+          <el-select v-model="form.type" placeholder="请选择商品来源">
+              <el-option v-for="(item,index) in goodsType" :key="index" :label="item.name"
+                         :value="index"></el-option>
+          </el-select>
+      </el-form-item> -->
+        <el-form-item label="会员折扣">
+            <el-input v-model="form.sellDiscount"></el-input>
+        </el-form-item>
+<!--                <el-form-item label="商品类型">-->
+<!--                    <el-checkbox  v-for="(value,key) in GiftTypeArr" v-model="form.giftType[key-1]" :key="key" >{{value.name}}</el-checkbox>-->
+<!--                </el-form-item>-->
+        <el-form-item label="商品类型">
+          <el-checkbox  v-for="(value,index) in GiftTypeArr" v-model="form.giftType[index-1]" :key="index" v-show="(index-1)%2!=0">{{value.name}}</el-checkbox>
+        </el-form-item>
+        <el-form-item label="报单类型">
+          <el-radio-group v-model="form.reconsumeType">
+              <el-radio v-for="(value,index) in GiftTypeArr" :label="index" :key="index" v-show="(index-1)%2==0">{{value.name}}</el-radio>
+              <el-radio :label="null">无</el-radio>
+            </el-radio-group>
+          </el-form-item>
+          <!-- <el-form-item label="复消购买方式">
+              <el-checkbox  v-for="(value,key) in sellType" v-model="form.sellType[key-1]" :key="key" >{{value.name}}</el-checkbox>
+          </el-form-item> -->
+          <el-form-item label="PV分期">
+<!--                    <el-checkbox v-model="form.pvSplit"></el-checkbox>-->
+            <el-select v-model="form.pvSplit" placeholder="">
+              <el-option
+                v-for="item in pvSplitOptions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value">
+              </el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="商品编号">
+              <el-input v-model="form.goodsNo"></el-input>
+          </el-form-item>
+          <el-form-item label="单位">
+              <el-input v-model="form.unit"></el-input>
+          </el-form-item>
+          <el-form-item label="市场价格">
+              <el-input v-model="form.marketPrice"></el-input>
+          </el-form-item>
+          <el-form-item label="销售价格">
+              <el-input v-model="form.sellPrice"></el-input>
+          </el-form-item>
+          <el-form-item label="价格PV	">
+              <el-input v-model="form.pricePv"></el-input>
+          </el-form-item>
+          <!-- <el-form-item label="兑换积分">
+              <el-input v-model="form.point"></el-input>
+          </el-form-item> -->
+          <el-form-item label="库存">
+              <el-input v-model="form.storeNums"></el-input>
+          </el-form-item>
+          <el-form-item label="商品详情">
+            <el-input
+                    type="textarea"
+                    :rows="2"
+                    placeholder="请输入内容"
+                    v-model="form.content">
+            </el-input>
+          </el-form-item>
+          <el-form-item label="排序">
+              <el-input v-model="form.sort"></el-input>
+          </el-form-item>
+          <el-form-item label="上传图片">
+              <div class='up_load'>
+                  <leo-uploader
+                      @on-success='upLoadSuccess'
+                      :request-route="'shop/upload'"
+                  ></leo-uploader>
+              </div>
+          </el-form-item>
+          <el-form-item>
+              <el-button type="primary" @click="addSubmit" :loading="submitButtonStat">添加</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+  </div>
 </template>
 
 <script>
-    import store from '@/utils/vuexStore'
-    import network from '@/utils/network'
-    import tool from '@/utils/tool'
-    import baseInfo from '../../utils/baseInfo'
-    import LeoUploader from '@/components/Uploader';
-    export default {
-        name: "goods-add",
-        components:{LeoUploader},
-        mounted () {
-            this.getData();
-            this.getFileToken();
-        },
-        data(){
-            return{
-                dialogImageUrl: '',
-                dialogVisible: false,
-                disabled: false,
-                loading: false,
-                file:null,
-                uploadToken:'',
-                form:{
-                    goodsName:'',
-                    type:'',
-                    giftType:[false,false,false,false],
-                    sellType:[false,false],
-                    goodsNo:'',
-                    unit:'',
-                    marketPrice:'',
-                    sellPrice:'',
-                    pricePv:'',
-                    point:'',
-                    storeNums:'',
-                    content:'',
-                    sort:'',
-                    discount:'',
-                    cover:'',
-                    textarea:'',
-                    sellDiscount:'',
-                },
-                submitButtonStat: false,
-                goodsType:[],
-                GiftTypeArr:[],
-                sellType:null,
-                width:'100px',
-                height:'100px',
-            }
+import store from '@/utils/vuexStore'
+import network from '@/utils/network'
+import tool from '@/utils/tool'
+import baseInfo from '../../utils/baseInfo'
+import LeoUploader from '@/components/Uploader';
+export default {
+  name: 'goods-add',
+  components: {LeoUploader},
+  mounted () {
+    this.getData()
+    this.getFileToken()
+  },
+  data(){
+    return {
+      dialogImageUrl: '',
+      dialogVisible: false,
+      disabled: false,
+      loading: false,
+      file: null,
+      uploadToken: '',
+      pvSplitOptions: [
+        {
+          value: '0',
+          label: 'No'
         },
-        watch:{
-            dialogVisible(newVal,oldVal){
-                console.log(newVal,oldVal)
-            }
-        },
-        methods: {
-            handleRemove(file) {
-                console.log(file);
-            },
-            upLoadSuccess(file){
-                this.form.cover=file;
-                this.form.cover = tool.getLocaleLink(file, '/files/');
-                this.form.coverOrigin = file
-                this.img_show=false;
-            },
-            handlePictureCardPreview(file) {
-                this.dialogImageUrl = file.url;
-                this.dialogVisible = true;
-                this.file=file;
-                // console.log(file);
-
-            },
-            handleDownload(file) {
-                console.log(file);
-            },
-            getFile(){
-                let data={
-                    uploadToken:this.uploadToken,
-                    file:this.file
-                }
-                if(this.uploadToken){
-                    network.postData('shop/upload',data)
-                    .then(response=>{
-                        console.log(response);
-                    })
-                }
-            },
-            getFileToken(){
-                network.getData('shop/upload').then(response=>{
-                   this.uploadToken=response;
-                })
-            },
-            getData (page, pageSize) {
-                let filterData = this.filterModel
-                let vueObj = this
-                network.getPageData(this, 'shop/goods-add', page, pageSize, this.filterModel, response=>{
-                    console.log(response)
-                    this.goodsType=response.goodsType
-                    this.GiftTypeArr=response.giftType
-                    this.sellType=response.sellType
-                    this.form.sellType=this.form.sellType.map((item,index)=>{
-                      return response.sellType.some(val=>(index+1).toString()==val)
-                    })
-                })
-            },addSubmit() {
-                this.submitButtonStat = true
-                let path = 'shop/goods-add';
+        {
+          value: '1',
+          label: 'Yes'
+        }],
+      form: {
+        goodsName: '',
+        type: '',
+        giftType: [false, false, false, false],
+        sellType: [false, false],
+        goodsNo: '',
+        unit: '',
+        marketPrice: '',
+        sellPrice: '',
+        pvSplit: '0',
+        pricePv: '',
+        point: '',
+        storeNums: '',
+        content: '',
+        sort: '',
+        discount: '',
+        cover: '',
+        textarea: '',
+        sellDiscount: '',
+        reconsumeType: null
+      },
+      submitButtonStat: false,
+      goodsType: [],
+      GiftTypeArr: [],
+      sellType: null,
+      width: '100px',
+      height: '100px'
+    }
+  },
+  watch: {
+    dialogVisible (newVal, oldVal) {
+      console.log(newVal, oldVal)
+    }
+  },
+  methods: {
+    handleRemove (file) {
+      console.log(file)
+    },
+    upLoadSuccess (file) {
+      this.form.cover = file
+      this.form.cover = tool.getLocaleLink(file, '/files/')
+      this.form.coverOrigin = file
+      this.img_show = false
+    },
+    handlePictureCardPreview (file) {
+      this.dialogImageUrl = file.url
+      this.dialogVisible = true
+      this.file = file
+      // console.log(file);
+    },
+    handleDownload (file) {
+      console.log(file)
+    },
+    getFile () {
+      let data = {
+        uploadToken: this.uploadToken,
+        file: this.file
+      }
+      if (this.uploadToken) {
+        network.postData('shop/upload', data)
+          .then(response => {
+            console.log(response)
+          })
+      }
+    },
+    getFileToken () {
+      network.getData('shop/upload').then(response => {
+        this.uploadToken = response
+      })
+    },
+    getData (page, pageSize) {
+      let filterData = this.filterModel
+      let vueObj = this
+      network.getPageData(this, 'shop/goods-add', page, pageSize, this.filterModel, response => {
+        console.log(response)
+        this.goodsType = response.goodsType
+        this.GiftTypeArr = response.giftType
+        this.sellType = response.sellType
+        this.form.sellType = this.form.sellType.map((item, index) => {
+          return response.sellType.some(val => (index + 1).toString() == val)
+        })
+      })
+    },
+    addSubmit () {
+      this.submitButtonStat = true
+      let path = 'shop/goods-add'
 
-                let sellType =[]
-                this.form.sellType.map((item,index)=>{
-                  if(item){
-                    sellType.push((index+1).toString())
-                  }
-                });
+      let sellType = []
+      this.form.sellType.map((item, index) => {
+        if (item) {
+          sellType.push((index + 1).toString())
+        }
+      })
 
-                let sen_gift=[];
-                this.form.giftType.map((item,index)=>{
-                    if(item){
-                        sen_gift.push((index+1).toString())
-                    }
-                })
+      let sen_gift = []
+      this.form.giftType.map((item, index) => {
+        if (item) {
+          sen_gift.push((index + 1).toString())
+        }
+      })
+      if (this.form.reconsumeType == 0 || this.form.reconsumeType == 2) { // 复消类型,单选
+        sen_gift.push((this.form.reconsumeType + 1).toString())
+      }
 
-                let postData = {
-                    goodsName: this.form.goodsName,
-                    sellDiscount: this.form.sellDiscount,
-                    discount: this.form.type.discount,
-                    type: this.form.type,
-                    giftType: sen_gift,
-                    sellType: sellType,
-                    goodsNo: this.form.goodsNo,
-                    unit: this.form.unit,
-                    marketPrice: this.form.marketPrice,
-                    sellPrice: this.form.sellPrice,
-                    pricePv: this.form.pricePv,
-                    // point: this.form.point,
-                    storeNums: this.form.storeNums,
-                    content: this.form.content,
-                    sort: this.form.sort,
-                    cover: this.form.cover,
-                }
+      let postData = {
+        goodsName: this.form.goodsName,
+        sellDiscount: this.form.sellDiscount,
+        discount: this.form.type.discount,
+        type: this.form.type,
+        giftType: sen_gift,
+        sellType: sellType,
+        pvSplit: this.form.pvSplit,
+        goodsNo: this.form.goodsNo,
+        unit: this.form.unit,
+        marketPrice: this.form.marketPrice,
+        sellPrice: this.form.sellPrice,
+        pricePv: this.form.pricePv,
+        // point: this.form.point,
+        storeNums: this.form.storeNums,
+        content: this.form.content,
+        sort: this.form.sort,
+        cover: this.form.cover
+      }
 
-                return network.postData(path, postData).then(response => {
-                    console.log(response);
-                    this.$message({
-                        message: response,
-                        type: 'success'
-                    })
-                    this.submitButtonStat = false
-                    this.$router.go(-1)
-                }).catch(() => {
-                    this.submitButtonStat = false
-                })
-            },
-           /*
-            handleEdit() {
-                this.dialogEditFormVisible = false
-                this.$message({
-                    message: '正在修改数据',
-                    type: 'info'
-                })
-                let path = 'finance/deal-type-edit'
-                network.postData(path, this.form).then(response => {
-                    this.$message({
-                        message: response,
-                        type: 'success'
-                    })
-                    this.getData(this.currentPage, this.pageSize)
-                }).catch(response => {
-                })
-            },*/
-        }
+      return network.postData(path, postData).then(response => {
+        console.log(response)
+        this.$message({
+          message: response,
+          type: 'success'
+        })
+        this.submitButtonStat = false
+        this.$router.go(-1)
+      }).catch(() => {
+        this.submitButtonStat = false
+      })
     }
+    /*
+    handleEdit() {
+        this.dialogEditFormVisible = false
+        this.$message({
+            message: '正在修改数据',
+            type: 'info'
+        })
+        let path = 'finance/deal-type-edit'
+        network.postData(path, this.form).then(response => {
+            this.$message({
+                message: response,
+                type: 'success'
+            })
+            this.getData(this.currentPage, this.pageSize)
+        }).catch(response => {
+        })
+    }, */
+  }
+}
 </script>
 
 <style scoped>

+ 384 - 356
backendEle/src/views/shop/index.vue

@@ -67,7 +67,6 @@
         <el-dialog title="修改套餐" :visible.sync="dialogEditFormVisible">
             <el-form :model="form" label-width="250px" class="form-dialog" v-loading="dialogEditLoading">
 
-
                     <el-form-item label="商品名称">
                         <el-input v-model="form.goodsName"></el-input>
                     </el-form-item>
@@ -81,12 +80,28 @@
                         <el-input v-model="form.sellDiscount"></el-input>
                     </el-form-item>
                     <el-form-item label="商品类型">
-                        <el-checkbox  v-for="(value,index) in GiftTypeArr" v-model="value.checked" :key="index" >{{value.name}}</el-checkbox>
+                      <el-checkbox  v-for="(value,index) in GiftTypeArr" v-model="value.checked" :key="index" v-show="(index%2)!=0">{{value.name}}</el-checkbox>
+                    </el-form-item>
+                    <el-form-item label="报单类型">
+                      <el-radio-group v-model="form.reconsumeType">
+                        <el-radio v-for="(value,index) in GiftTypeArr" :label="index" :key="index" v-show="(index%2)==0">{{value.name}}</el-radio>
+                        <el-radio :label="null">无</el-radio>
+                      </el-radio-group>
                     </el-form-item>
                     <!-- <el-form-item label="复消购买方式">
                          <el-checkbox  v-for="(value,index) in sell_type" v-model="value.checked" :key="index" >{{value.name}}</el-checkbox>
                     </el-form-item> -->
-
+                    <el-form-item label="PV分期">
+<!--                      <el-checkbox v-model="form.pvSplit" :checked="form.pvSplit">Yes</el-checkbox>-->
+            <el-select v-model="form.pvSplit" placeholder="">
+              <el-option
+                v-for="item in pvSplitOptions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value">
+              </el-option>
+            </el-select>
+                    </el-form-item>
                     <el-form-item label="商品编号">
                         <el-input v-model="form.goodsNo"></el-input>
                     </el-form-item>
@@ -99,7 +114,7 @@
                     <el-form-item label="销售价格" >
                         <el-input v-model="form.sellPrice"></el-input>
                     </el-form-item>
-                    <el-form-item label="价格PV	">
+                    <el-form-item label="价格PV">
                         <el-input v-model="form.pricePv"></el-input>
                     </el-form-item>
                     <el-form-item label="兑换积分" v-show="false">
@@ -132,8 +147,6 @@
                         </div>
                     </el-form-item>
 
-
-
             </el-form>
             <div slot="footer" class="dialog-footer">
                 <el-button @click="dialogEditFormVisible = false">取 消</el-button>
@@ -144,7 +157,6 @@
         <el-dialog title="商品限时" :visible.sync="dialogEditFormVisibleGoodsTimes">
             <el-form :model="form" label-width="250px" class="form-dialog" v-loading="dialogEditLoadingGoodsTimes">
 
-
                     <el-form-item label="是否限时">
                           <el-switch
                             v-model="form.statusdate"
@@ -162,8 +174,6 @@
                               popper-class='goodsdate'>
                             </el-date-picker>
 
-
-
                     </el-form-item>
                     </transition>
                     <transition name="el-zoom-in-top">
@@ -174,7 +184,6 @@
                     </el-form-item>
                     </transition>
 
-
             </el-form>
             <div slot="footer" class="dialog-footer">
                 <el-button @click="dialogEditFormVisibleGoodsTimes = false">取 消</el-button>
@@ -185,355 +194,374 @@
 </template>
 
 <script>
-    import network from '@/utils/network'
-    import tool from '@/utils/tool'
-    import baseInfo from '@/utils/baseInfo'
-    import FilterUser from '../../components/FilterUser'
-    import permission from '@/utils/permission'
-    import Pagination from '@/components/Pagination'
-    import filterHelper from '@/utils/filterHelper'
-    import {FRONTEND_SERVER} from '@/utils/config'
-    import store from './../../utils/vuexStore'
-     import LeoUploader from '@/components/Uploader';
-    export default {
-        name: 'index',
-        components: {FilterUser,Pagination,LeoUploader},
-        mounted () {
-            this.getData();
-            // this.$refs.up_load.successImageUrl='';
+import network from '@/utils/network'
+import tool from '@/utils/tool'
+import baseInfo from '@/utils/baseInfo'
+import FilterUser from '../../components/FilterUser'
+import permission from '@/utils/permission'
+import Pagination from '@/components/Pagination'
+import filterHelper from '@/utils/filterHelper'
+import {FRONTEND_SERVER} from '@/utils/config'
+import store from './../../utils/vuexStore'
+import LeoUploader from '@/components/Uploader'
+export default {
+  name: 'index',
+  components: {FilterUser,Pagination,LeoUploader},
+  mounted () {
+    this.getData()
+    // this.$refs.up_load.successImageUrl='';
+  },
+
+  data () {
+    return {
+      tableHeaders: null,
+      tableData: null,
+      loading: true,
+      currentPage: 1,
+      totalPages: 1,
+      totalCount: 1,
+      pageSize: 20,
+      multipleSelection: [],
+      tool: tool,
+      permission: permission,
+      baseDecLevels: baseInfo.decLevels(),
+      baseEmpLevels: baseInfo.empLevels(),
+      filterTypes: null,
+      dialogVisible: false,
+      dialogLoading: false,
+      filterModel: {},
+      value: [],
+      selectedIds: '',
+      dialogEditFormVisible: false,
+      dialogEditLoading: false,
+      dialogEditFormVisibleGoodsTimes: false,
+      dialogEditLoadingGoodsTimes: false,
+      pvSplitOptions: [
+        {
+          value: '0',
+          label: 'No'
         },
-
-        data () {
-            return {
-                tableHeaders: null,
-                tableData: null,
-                loading: true,
-                currentPage: 1,
-                totalPages: 1,
-                totalCount: 1,
-                pageSize: 20,
-                multipleSelection: [],
-                tool: tool,
-                permission: permission,
-                baseDecLevels: baseInfo.decLevels(),
-                baseEmpLevels: baseInfo.empLevels(),
-                filterTypes: null,
-                dialogVisible: false,
-                dialogLoading: false,
-                filterModel: {},
-                value:[],
-                selectedIds:'',
-                dialogEditFormVisible: false,
-                dialogEditLoading: false,
-                dialogEditFormVisibleGoodsTimes: false,
-                dialogEditLoadingGoodsTimes: false,
-                form:{
-                    sellType:[],
-                    goodsName:'',
-                    type:'',
-                    giftType:[],
-                    goodsNo:'',
-                    unit:'',
-                    marketPrice:'',
-                    sellPrice:'',
-                    pricePv:'',
-                    point:'',
-                    storeNums:'',
-                    content:'',
-                    sort:'',
-                    discount:'',
-                    cover:'',
-                    textarea:'',
-                    sellDiscount:'',
-                    statusdate:'',
-                    goodsstatusdate:'',
-                    goodsdate:'',
-                },
-                submitButtonStat: false,
-                goodsType:[],
-                GiftTypeArr:[],
-                sell_type:[],
-                img_show:true
+        {
+          value: '1',
+          label: 'Yes'
+        }],
+      form: {
+        sellType: [],
+        goodsName: '',
+        type: '',
+        giftType: [],
+        goodsNo: '',
+        unit: '',
+        marketPrice: '',
+        sellPrice: '',
+        pricePv: '',
+        point: '',
+        storeNums: '',
+        content: '',
+        sort: '',
+        discount: '',
+        cover: '',
+        textarea: '',
+        sellDiscount: '',
+        pvSplit: '',
+        statusdate: '',
+        goodsstatusdate: '',
+        goodsdate: '',
+        reconsumeType: null
+      },
+      submitButtonStat: false,
+      goodsType: [],
+      GiftTypeArr: [],
+      sell_type: [],
+      img_show: true
+    }
+  },
+  methods: {
+    handleSelectionChange (val) {
+      this.multipleSelection = val
+    },
+    handleCurrentChange (page) {
+      this.getData(page, this.pageSize)
+    },
+    handleSizeChange (pageSize) {
+      this.getData(this.currentPage, pageSize)
+    },
+    handleFilterUser (filterData) {
+      filterHelper.handleFilterUser(this, filterData)
+    },
+    checkSelectable (row) {
+      return row.DONT_DEL !== '1'
+    },
+    handleFilter () {
+      this.getData()
+    },
+    handlestate () {
+      this.$router.push({path: `/shop/goods-add`})
+    },
+    upLoadSuccess (file) {
+      this.form.cover = tool.getLocaleLink(file, '/files/')
+      this.form.coverOrigin = file
+      this.img_show = false
+    },
+    handleEditShow (row) {
+      this.dialogEditLoading = true
+      this.auditId = row.ID
+      this.dialogEditFormVisible = true
+      let vueObj = this
+      network.getData('shop/goods-edit', {id: this.auditId}).then(response => {
+        vueObj.dialogEditLoading = false
+        vueObj.goodsType = response.goodsType
+
+        let gift = response.goodsInfo.GIFT_TYPE
+        let gift_type = response.giftType
+
+        let giftType = []
+        if (gift.length > 0) {
+          for (let i in gift_type) {
+            giftType.push({key: i, name: gift_type[i].name, checked: false})
+            gift.map((v, k) => {
+              if (v == i) {
+                giftType[i - 1].checked = true
+              }
+            })
+          }
+          for (let j in gift) {
+            if (gift[j] % 2 != 0) {
+              vueObj.form.reconsumeType = gift[j] - 1
+            } else {
+              vueObj.form.reconsumeType = null
             }
-        },
-        methods: {
-
-            handleSelectionChange(val) {
-                this.multipleSelection = val
-            },
-            handleCurrentChange (page) {
-                this.getData(page, this.pageSize)
-            },
-            handleSizeChange (pageSize) {
-                this.getData(this.currentPage, pageSize)
-            },
-            handleFilterUser(filterData){
-                filterHelper.handleFilterUser(this, filterData)
-            },
-            checkSelectable(row) {
-                return row.DONT_DEL !== '1'
-            },
-            handleFilter() {
-                this.getData()
-            },
-            handlestate(){
-                this.$router.push({path: `/shop/goods-add`})
-            },
-            upLoadSuccess(file){
-                this.form.cover = tool.getLocaleLink(file, '/files/');
-                this.form.coverOrigin = file
-                this.img_show=false;
-            },
-            handleEditShow(row) {
-                this.dialogEditLoading = true
-                this.auditId = row.ID
-                this.dialogEditFormVisible = true
-                let vueObj = this
-                network.getData('shop/goods-edit', {id: this.auditId}).then(response => {
-                    vueObj.dialogEditLoading = false
-                    vueObj.goodsType=response.goodsType
-
-                    let gift=response.goodsInfo.GIFT_TYPE;
-                    let gift_type=response.giftType;
-
-                    let giftType=[];
-                    if(gift.length>0){
-                        for(let i in gift_type){
-                            giftType.push({key:i,name:gift_type[i].name,checked:false})
-                            gift.map((v,k)=>{
-                                if(v==i){
-                                    giftType[i-1].checked=true;
-                                }
-                            })
-                        }
-                    }
-                    vueObj.GiftTypeArr=giftType
-
-                    let sell=response.goodsInfo.SELL_TYPE;
-                    let sell_type=response.sellType;
-                    let sellType=[];
-                    if(sell.length>0){
-                        for(let i in sell_type){
-                            sellType.push({key:i,name:sell_type[i].name,checked:false})
-                            sell.map((item,index)=>{
-                                if(item==i){
-                                    sellType[i-1].checked=true;
-                                }
-                            })
-                        }
-                    }
-                    vueObj.sell_type=sellType;
-
-                    vueObj.form.goodsName=response.goodsInfo.GOODS_NAME
-                    vueObj.form.sellDiscount=response.goodsInfo.SELL_DISCOUNT
-                    vueObj.form.goodsNo=response.goodsInfo.GOODS_NO
-                    vueObj.form.type=response.goodsInfo.TYPE
-                    vueObj.form.unit=response.goodsInfo.UNIT
-                    vueObj.form.marketPrice=response.goodsInfo.MARKET_PRICE
-                    vueObj.form.sellPrice=response.goodsInfo.SELL_PRICE
-                    vueObj.form.pricePv=response.goodsInfo.PRICE_PV
-                    vueObj.form.point=response.goodsInfo.POINT
-                    vueObj.form.storeNums=response.goodsInfo.STORE_NUMS
-                    vueObj.form.content=response.goodsInfo.CONTENT
-                    vueObj.form.sort=response.goodsInfo.SORT
-                    vueObj.form.id=response.goodsInfo.ID
-                    vueObj.form.statusdate=response.goodsInfo.STATUS_DATE
-                    vueObj.form.goodsstatusdate=response.goodsInfo.GOODS_STATUS_DATE
-                    vueObj.form.goodsdate=response.goodsInfo.GOODS_DATE * 1000
-                    // vueObj.form.sellType=vueObj.form.sellType.map((item,index)=>{
-                    //   return response.goodsInfo.SELL_TYPE.some(val=>(index+1).toString()==val)
-                    //   })
-
-                    vueObj.form.coverOrigin = response.goodsInfo.COVER
-                    vueObj.form.cover = tool.getLocaleLink(response.goodsInfo.COVER, '/files/')
-
-                    this.$forceUpdate()
-
-                })
-            },
-            /**
-             * 2022-05-09
-             * York
-             * 限时商品
-             */
-            handleEditShowGoodsTimes(row) {
-                this.dialogEditLoadingGoodsTimes = true
-                this.auditId = row.ID
-                this.dialogEditFormVisibleGoodsTimes = true
-                let vueObj = this
-                network.getData('shop/goods-edit', {id: this.auditId}).then(response => {
-                    vueObj.dialogEditLoadingGoodsTimes = false
-                    vueObj.goodsType=response.goodsType
-
-                    let gift=response.goodsInfo.GIFT_TYPE;
-                    let gift_type=response.giftType;
-
-                    let giftType=[];
-                    if(gift.length>0){
-                        for(let i in gift_type){
-                            giftType.push({key:i,name:gift_type[i].name,checked:false})
-                            gift.map((v,k)=>{
-                                if(v==i){
-                                    giftType[i-1].checked=true;
-                                }
-                            })
-                        }
-                    }
-                    vueObj.GiftTypeArr=giftType
-
-                    let sell=response.goodsInfo.SELL_TYPE;
-                    let sell_type=response.sellType;
-                    let sellType=[];
-                    if(sell.length>0){
-                        for(let i in sell_type){
-                            sellType.push({key:i,name:sell_type[i].name,checked:false})
-                            sell.map((item,index)=>{
-                                if(item==i){
-                                    sellType[i-1].checked=true;
-                                }
-                            })
-                        }
-                    }
-                    vueObj.sell_type=sellType;
-
-                    vueObj.form.goodsName=response.goodsInfo.GOODS_NAME
-                    vueObj.form.sellDiscount=response.goodsInfo.SELL_DISCOUNT
-                    vueObj.form.goodsNo=response.goodsInfo.GOODS_NO
-                    vueObj.form.type=response.goodsInfo.TYPE
-                    vueObj.form.unit=response.goodsInfo.UNIT
-                    vueObj.form.marketPrice=response.goodsInfo.MARKET_PRICE
-                    vueObj.form.sellPrice=response.goodsInfo.SELL_PRICE
-                    vueObj.form.pricePv=response.goodsInfo.PRICE_PV
-                    vueObj.form.point=response.goodsInfo.POINT
-                    vueObj.form.storeNums=response.goodsInfo.STORE_NUMS
-                    vueObj.form.content=response.goodsInfo.CONTENT
-                    vueObj.form.sort=response.goodsInfo.SORT
-                    vueObj.form.id=response.goodsInfo.ID
-                    vueObj.form.statusdate=response.goodsInfo.STATUS_DATE
-                    vueObj.form.goodsstatusdate=response.goodsInfo.GOODS_STATUS_DATE
-                    vueObj.form.goodsdate=response.goodsInfo.GOODS_DATE * 1000
-                    vueObj.form.coverOrigin = response.goodsInfo.COVER
-                    vueObj.form.cover = tool.getLocaleLink(response.goodsInfo.COVER, '/files/')
-
-                    this.$forceUpdate()
-
-                })
-            },
-
-            handleEdit() {
-                this.dialogEditFormVisible = false
-                this.dialogEditFormVisibleGoodsTimes = false
-                this.$message({
-                    message: '正在修改数据',
-                    type: 'info'
-                })
-                let path = 'shop/goods-edit'
-
-                let sen_sell=[];
-                this.sell_type.map((item,index)=>{
-                    if(item.checked){
-                        sen_sell.push(item.key);
-                    }
-                })
-                this.form.sellType=sen_sell;
-
-                let sen_gift=[];
-                this.GiftTypeArr.map((item,index)=>{
-                    if(item.checked){
-                        sen_gift.push(item.key);
-                    }
-                })
-                this.form.giftType=sen_gift;
-                this.form.cover = this.form.coverOrigin;
-                delete this.form.coverOrigin;
-                network.postData(path, {...this.form}).then(response => {
-                    this.$message({
-                        message: response,
-                        type: 'success'
-                    })
-                    this.getData(this.currentPage, this.pageSize)
-                }).catch(response => {
-                })
-            },
-
-            handleDel(id = null) {
-                let obj = this
-                this.$confirm('确定删除选定的数据?', '提示', {
-                    confirmButtonText: '确定',
-                    cancelButtonText: '取消',
-                    type: 'warning'
-                }).then(() => {
-                    let selectedIds = []
-                    if (id === null) {
-                        for (let val of obj.multipleSelection) {
-                            selectedIds.push(val.ID)
-                        }
-                    } else {
-                        selectedIds.push(id)
-                    }
-                    return network.postData(`shop/goods-delete`, {
-                        selected: selectedIds
-                    })
-                }).then(response => {
-                    this.$message({
-                        message: response,
-                        type: 'success'
-                    })
-                    obj.getData(obj.currentPage, obj.pageSize)
-                }).catch(response => {
-
-                })
-            },
-            getData (page, pageSize) {
-                let filterData = this.filterModel
-                /*this.allData = response*/
-                network.getPageData(this, 'shop/index', page, pageSize, this.filterModel, response=>{
-                    console.log(response)
-                    this.filterTypes = response.filterTypes
-
-                })
-            },
-            handleGoodUp(id){
-                console.log(id);
-                network.postData('shop/goods-status',{selectedIds:id,status:1})
-                .then(response=>{
-                    this.$message({
-                        message: response,
-                        type: 'success'
-                    })
-                    this.getData(this.currentPage, this.pageSize)
-                })
-            },
-            handleGoodDown(id){
-                network.postData('shop/goods-status',{selectedIds:id,status:0})
-                .then(response=>{
-                    this.$message({
-                        message: response,
-                        type: 'success'
-                    })
-                    this.getData(this.currentPage, this.pageSize)
-                })
-            },
-
-            handleExport(){
-                this.$confirm(`确定要导出当前数据吗?`, '提示', {
-                    confirmButtonText: '确定',
-                    cancelButtonText: '取消',
-                    type: 'warning'
-                }).then(() => {
-                    return network.getData(`shop/goods-list-export`, this.filterModel)
-                }).then(response => {
-                    this.$message({
-                        message: response,
-                        type: 'success'
-                    })
-                }).catch(response => {
-
-                })
-            },
-        },
-
+          }
+        }
+        vueObj.GiftTypeArr = giftType
+
+        let sell = response.goodsInfo.SELL_TYPE
+        let sell_type = response.sellType
+        let sellType = []
+        if (sell.length > 0) {
+          for (let i in sell_type) {
+            sellType.push({key: i, name: sell_type[i].name, checked: false})
+            sell.map((item, index) => {
+              if (item == i) {
+                sellType[i - 1].checked = true
+              }
+            })
+          }
+        }
+        vueObj.sell_type = sellType
+
+        vueObj.form.goodsName = response.goodsInfo.GOODS_NAME
+        vueObj.form.sellDiscount = response.goodsInfo.SELL_DISCOUNT
+        vueObj.form.goodsNo = response.goodsInfo.GOODS_NO
+        vueObj.form.type = response.goodsInfo.TYPE
+        vueObj.form.unit = response.goodsInfo.UNIT
+        vueObj.form.marketPrice = response.goodsInfo.MARKET_PRICE
+        vueObj.form.sellPrice = response.goodsInfo.SELL_PRICE
+        vueObj.form.pricePv = response.goodsInfo.PRICE_PV
+        vueObj.form.point = response.goodsInfo.POINT
+        vueObj.form.storeNums = response.goodsInfo.STORE_NUMS
+        vueObj.form.content = response.goodsInfo.CONTENT
+        vueObj.form.sort = response.goodsInfo.SORT
+        vueObj.form.id = response.goodsInfo.ID
+        vueObj.form.statusdate = response.goodsInfo.STATUS_DATE
+        vueObj.form.pvSplit = response.goodsInfo.PV_SPLIT
+        vueObj.form.goodsstatusdate = response.goodsInfo.GOODS_STATUS_DATE
+        vueObj.form.goodsdate = response.goodsInfo.GOODS_DATE * 1000
+        // vueObj.form.sellType=vueObj.form.sellType.map((item,index)=>{
+        //   return response.goodsInfo.SELL_TYPE.some(val=>(index+1).toString()==val)
+        //   })
+
+        vueObj.form.coverOrigin = response.goodsInfo.COVER
+        vueObj.form.cover = tool.getLocaleLink(response.goodsInfo.COVER, '/files/')
+
+        this.$forceUpdate()
+      })
+    },
+    /**
+     * 2022-05-09
+     * York
+     * 限时商品
+     */
+    handleEditShowGoodsTimes (row) {
+      this.dialogEditLoadingGoodsTimes = true
+      this.auditId = row.ID
+      this.dialogEditFormVisibleGoodsTimes = true
+      let vueObj = this
+      network.getData('shop/goods-edit', {id: this.auditId}).then(response => {
+        vueObj.dialogEditLoadingGoodsTimes = false
+        vueObj.goodsType = response.goodsType
+
+        let gift = response.goodsInfo.GIFT_TYPE
+        let gift_type = response.giftType
+
+        let giftType = []
+        if (gift.length > 0) {
+          for (let i in gift_type) {
+            giftType.push({key: i, name: gift_type[i].name, checked: false})
+            gift.map((v, k) => {
+              if (v == i) {
+                giftType[i - 1].checked = true
+              }
+            })
+          }
+        }
+        vueObj.GiftTypeArr = giftType
+
+        let sell = response.goodsInfo.SELL_TYPE
+        let sell_type = response.sellType
+        let sellType = []
+        if (sell.length > 0) {
+          for (let i in sell_type) {
+            sellType.push({key: i, name: sell_type[i].name, checked: false})
+            sell.map((item, index) => {
+              if (item == i) {
+                sellType[i - 1].checked = true
+              }
+            })
+          }
+        }
+        vueObj.sell_type = sellType
+
+        vueObj.form.goodsName = response.goodsInfo.GOODS_NAME
+        vueObj.form.sellDiscount = response.goodsInfo.SELL_DISCOUNT
+        vueObj.form.goodsNo = response.goodsInfo.GOODS_NO
+        vueObj.form.type = response.goodsInfo.TYPE
+        vueObj.form.unit = response.goodsInfo.UNIT
+        vueObj.form.marketPrice = response.goodsInfo.MARKET_PRICE
+        vueObj.form.sellPrice = response.goodsInfo.SELL_PRICE
+        vueObj.form.pricePv = response.goodsInfo.PRICE_PV
+        vueObj.form.point = response.goodsInfo.POINT
+        vueObj.form.storeNums = response.goodsInfo.STORE_NUMS
+        vueObj.form.content = response.goodsInfo.CONTENT
+        vueObj.form.sort = response.goodsInfo.SORT
+        vueObj.form.id = response.goodsInfo.ID
+        vueObj.form.statusdate = response.goodsInfo.STATUS_DATE
+        vueObj.form.goodsstatusdate = response.goodsInfo.GOODS_STATUS_DATE
+        vueObj.form.goodsdate = response.goodsInfo.GOODS_DATE * 1000
+        vueObj.form.coverOrigin = response.goodsInfo.COVER
+        vueObj.form.cover = tool.getLocaleLink(response.goodsInfo.COVER, '/files/')
+
+        this.$forceUpdate()
+      })
+    },
+
+    handleEdit () {
+      this.dialogEditFormVisible = false
+      this.dialogEditFormVisibleGoodsTimes = false
+      this.$message({
+        message: '正在修改数据',
+        type: 'info'
+      })
+      let path = 'shop/goods-edit'
+
+      let sen_sell = []
+      this.sell_type.map((item, index) => {
+        if (item.checked) {
+          sen_sell.push(item.key)
+        }
+      })
+      this.form.sellType = sen_sell
+
+      let sen_gift = []
+      this.GiftTypeArr.map((item, index) => {
+        if (item.checked && (index % 2 != 0)) {
+          sen_gift.push(item.key)
+        }
+      })
+
+      if (this.form.reconsumeType == 0 || this.form.reconsumeType == 2){ // 复消类型,单选
+        sen_gift.push((this.form.reconsumeType + 1).toString())
+      }
+      this.form.giftType = sen_gift
+      this.form.cover = this.form.coverOrigin
+      delete this.form.coverOrigin
+      network.postData(path, {...this.form}).then(response => {
+        this.$message({
+          message: response,
+          type: 'success'
+        })
+        this.getData(this.currentPage, this.pageSize)
+      }).catch(response => {
+      })
+    },
+
+    handleDel (id = null) {
+      let obj = this
+      this.$confirm('确定删除选定的数据?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        let selectedIds = []
+        if (id === null) {
+          for (let val of obj.multipleSelection) {
+            selectedIds.push(val.ID)
+          }
+        } else {
+          selectedIds.push(id)
+        }
+        return network.postData(`shop/goods-delete`, {
+          selected: selectedIds
+        })
+      }).then(response => {
+        this.$message({
+          message: response,
+          type: 'success'
+        })
+        obj.getData(obj.currentPage, obj.pageSize)
+      }).catch(response => {
+
+      })
+    },
+    getData (page, pageSize) {
+      let filterData = this.filterModel
+      /* this.allData = response */
+      network.getPageData(this, 'shop/index', page, pageSize, this.filterModel, response => {
+        // console.log(response)
+        this.filterTypes = response.filterTypes
+      })
+    },
+    handleGoodUp (id) {
+      // console.log(id)
+      network.postData('shop/goods-status', {selectedIds: id, status: 1})
+        .then(response => {
+          this.$message({
+            message: response,
+            type: 'success'
+          })
+          this.getData(this.currentPage, this.pageSize)
+        })
+    },
+    handleGoodDown (id) {
+      network.postData('shop/goods-status', {selectedIds: id, status: 0})
+        .then(response => {
+          this.$message({
+            message: response,
+            type: 'success'
+          })
+          this.getData(this.currentPage, this.pageSize)
+        })
+    },
+
+    handleExport () {
+      this.$confirm(`确定要导出当前数据吗?`, '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        return network.getData(`shop/goods-list-export`, this.filterModel)
+      }).then(response => {
+        this.$message({
+          message: response,
+          type: 'success'
+        })
+      }).catch(response => {
+
+      })
     }
+  }
+
+}
 
 </script>
 

+ 129 - 112
backendEle/src/views/shop/order-list.vue

@@ -4,7 +4,8 @@
       <div class="filter-box">
         <filter-user :filter-types="filterTypes" @select-value="handleFilterUser"></filter-user>
       </div>
-      <el-table class="table-box" ref="multipleTable" :data="tableData" stripe style="width: 100%;"
+      <el-table ref="multipleTable" :data="tableData" style="width: 100%;"
+                :row-class-name="rowClassName"
                 @selection-change="handleSelectionChange"
                 :height="tool.getTableHeight()">
         <el-table-column type="selection" width="70" v-if="tableHeaders"></el-table-column>
@@ -58,132 +59,148 @@
 </template>
 
 <script>
-  import network from '@/utils/network'
-  import tool from '@/utils/tool'
-  import baseInfo from '@/utils/baseInfo'
-  import FilterUser from '@/components/FilterUser'
-  import permission from '@/utils/permission'
-  import Pagination from '@/components/Pagination'
-  import filterHelper from '@/utils/filterHelper'
+import network from '@/utils/network'
+import tool from '@/utils/tool'
+import baseInfo from '@/utils/baseInfo'
+import FilterUser from '@/components/FilterUser'
+import permission from '@/utils/permission'
+import Pagination from '@/components/Pagination'
+import filterHelper from '@/utils/filterHelper'
 
-  export default {
-    name: 'shop_order-list',
-    components: {FilterUser, Pagination},
-    mounted() {
-      this.getData()
-    },
-    data() {
-      return {
-        tableHeaders: null,
-        tableData: null,
-        tableHeight: window.innerHeight - 310,
-        loading: true,
-        multipleSelection: [],
-        currentPage: 1,
-        totalPages: 1,
-        totalCount: 1,
-        pageSize: 20,
-        tool: tool,
-        permission: permission,
-        filterTypes: null,
-        filterModel: {},
-        dialogDeliveryVisible: false,
-        deliveryForm: {
-          sn: '',
-          expressCompany: '',
-          orderTrackNo: '',
-        },
+export default {
+  name: 'shop_order-list',
+  components: {FilterUser, Pagination},
+  mounted () {
+    this.getData()
+  },
+  data () {
+    return {
+      tableHeaders: null,
+      tableData: null,
+      tableHeight: window.innerHeight - 310,
+      loading: true,
+      multipleSelection: [],
+      currentPage: 1,
+      totalPages: 1,
+      totalCount: 1,
+      pageSize: 20,
+      tool: tool,
+      permission: permission,
+      filterTypes: null,
+      filterModel: {},
+      dialogDeliveryVisible: false,
+      deliveryForm: {
+        sn: '',
+        expressCompany: '',
+        orderTrackNo: '',
+      },
+    }
+  },
+  methods: {
+    rowClassName (val) {
+      if (val.row) {
+        let index = this.multipleSelection.findIndex(item => {
+          return item.ID == val.row.ID
+        })
+        if (index >= 0) {
+          return 'selected-row'
+        }
+      } else {
+        return ''
       }
     },
-    methods: {
-      handleSelectionChange(val) {
-        this.multipleSelection = val
-      },
-      handleCurrentChange(page) {
-        this.getData(page, this.pageSize)
-      },
-      handleSizeChange(pageSize) {
-        this.getData(this.currentPage, pageSize)
-      },
-      handleFilterUser(filterData) {
-        filterHelper.handleFilterUser(this, filterData)
-      },
-      getData(page, pageSize) {
-        let filterData = this.filterModel
-        network.getPageData(this, 'shop/order-list', page, pageSize, filterData, response => {
-          this.filterTypes = response.filterTypes
-          this.allData = response
+    handleSelectionChange (val) {
+      this.multipleSelection = val
+      this.rowClassName(val)
+    },
+    handleCurrentChange (page) {
+      this.getData(page, this.pageSize)
+    },
+    handleSizeChange (pageSize) {
+      this.getData(this.currentPage, pageSize)
+    },
+    handleFilterUser (filterData) {
+      filterHelper.handleFilterUser(this, filterData)
+    },
+    getData (page, pageSize) {
+      let filterData = this.filterModel
+      network.getPageData(this, 'shop/order-list', page, pageSize, filterData, response => {
+        this.filterTypes = response.filterTypes
+        this.allData = response
+      })
+    },
+    handleExport () {
+      this.$confirm(`确定要导出当前数据吗?`, '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        return network.getData(`shop/order-list-export`, this.filterModel)
+      }).then(response => {
+        this.$message({
+          message: response,
+          type: 'success'
         })
-      },
-      handleExport(){
-        this.$confirm(`确定要导出当前数据吗?`, '提示', {
-          confirmButtonText: '确定',
-          cancelButtonText: '取消',
-          type: 'warning'
-        }).then(() => {
-          return network.getData(`shop/order-list-export`, this.filterModel)
-        }).then(response => {
+      }).catch(response => {
+
+      })
+    },
+    handleEdit () {
+      // 进入修改订单页面
+    },
+    handleDel (row) {
+      let orderSn = row.SN.value // order订单表的编号
+      this.$confirm(`确定要删除订单:${orderSn}吗?`, '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        // 删除订单
+        let postData = {
+          orderSn
+        }
+        return network.postData('shop/delete-order', postData).then(response => {
           this.$message({
             message: response,
             type: 'success'
           })
-        }).catch(response => {
-
+          this.submitButtonStat = false
+          this.$router.go(-1)
+        }).catch(() => {
+          this.submitButtonStat = false
         })
-      },
-      handleEdit() {
-        // 进入修改订单页面
-      },
-      handleDel(row) {
-        let orderSn = row.SN.value // order订单表的编号
-        this.$confirm(`确定要删除订单:${orderSn}吗?`, '提示', {
-          confirmButtonText: '确定',
-          cancelButtonText: '取消',
-          type: 'warning'
-        }).then(() => {
-          // 删除订单
-          let postData = {
-            orderSn
-          }
-          return network.postData('shop/delete-order', postData).then(response => {
-              console.log(response);
-              this.$message({
-                  message: response,
-                  type: 'success'
-              })
-              this.submitButtonStat = false
-              this.$router.go(-1)
-          }).catch(() => {
-              this.submitButtonStat = false
-          })
-        }).then(response => {
-          
-        }).catch(response => {
+      }).then(response => {
 
+      }).catch(response => {
+
+      })
+    },
+    // 显示发货对话框
+    handleShowDeliveryDialog (row) {
+      this.dialogDeliveryVisible = true
+      this.deliveryForm.sn = row['SN'].value
+    },
+    // 发货
+    handleDelivery () {
+      network.postData('shop/order-delivery', this.deliveryForm).then(response => {
+        this.$message({
+          message: response,
+          type: 'success'
         })
-      },
-      // 显示发货对话框
-      handleShowDeliveryDialog(row) {
-        this.dialogDeliveryVisible = true
-        this.deliveryForm.sn = row['SN'].value
-      },
-      // 发货
-      handleDelivery() {
-        network.postData('shop/order-delivery', this.deliveryForm).then(response => {
-          this.$message({
-            message: response,
-            type: 'success'
-          })
-          this.dialogDeliveryVisible = false
-          this.getData(this.currentPage, this.pageSize)
-        }).catch(response => {
-          this.dialogDeliveryVisible = false
-        })
-      }
+        this.dialogDeliveryVisible = false
+        this.getData(this.currentPage, this.pageSize)
+      }).catch(response => {
+        this.dialogDeliveryVisible = false
+      })
     }
   }
+}
 
 </script>
 
 <style scoped>
+/deep/.el-table .selected-row {
+  background: #bce5ef;
+  /*color: white;*/
+}
 </style>

+ 101 - 102
backendEle/src/views/shop/package-add.vue

@@ -1,113 +1,112 @@
 <template>
-    <div v-loading="loading">
-        <div class="white-box">
-            <el-form ref="form"  label-width="250px" class="form-page">
-
-                <el-form-item label="套餐名称">
-                    <el-input v-model="form.packageName"></el-input>
-                </el-form-item>
-                <el-form-item label="套餐编号">
-                    <el-input v-model="form.packageNo"></el-input>
-                </el-form-item>
-                <el-form-item label="套餐金额">
-                    <el-input v-model="form.amount"></el-input>
-                </el-form-item>
-                <el-form-item label="套餐PV">
-                    <el-input v-model="form.amountPv"></el-input>
-                </el-form-item>
-                <el-form-item label="报单级别ID">
-                    <el-select v-model="form.levelId" placeholder="请选择报单级别">
-                        <el-option v-for="(item,index) in allDecLevel" :key="index" :label="item.LEVEL_NAME"
-                                   :value="item.ID"></el-option>
-                    </el-select>
-                </el-form-item>
-                <el-form-item label="套餐内容">
-                    <el-input v-model="form.packageContent"></el-input>
-                </el-form-item>
-                <el-form-item label="套餐库存">
-                    <el-input oninput="value=value.replace(/[^\d]/g,'')" v-model="form.storenums"></el-input>
-                </el-form-item>
-
-
-                <el-form-item>
-                    <el-button type="primary" @click="addSubmit" :loading="submitButtonStat">添加</el-button>
-                </el-form-item>
-            </el-form>
-        </div>
+  <div v-loading="loading">
+    <div class="white-box">
+      <el-form ref="form"  label-width="250px" class="form-page">
+        <el-form-item label="套餐名称">
+          <el-input v-model="form.packageName"></el-input>
+        </el-form-item>
+        <el-form-item label="套餐编号">
+          <el-input v-model="form.packageNo"></el-input>
+        </el-form-item>
+        <el-form-item label="套餐金额">
+          <el-input v-model="form.amount"></el-input>
+        </el-form-item>
+        <el-form-item label="套餐PV">
+          <el-input v-model="form.amountPv"></el-input>
+        </el-form-item>
+        <el-form-item label="报单级别ID">
+          <el-select v-model="form.levelId" placeholder="请选择报单级别">
+            <el-option v-for="(item,index) in allDecLevel" :key="index" :label="item.LEVEL_NAME" :value="item.ID"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="套餐内容">
+          <el-input v-model="form.packageContent"></el-input>
+        </el-form-item>
+        <el-form-item label="套餐库存">
+          <el-input oninput="value=value.replace(/[^\d]/g,'')" v-model="form.storenums"></el-input>
+        </el-form-item>
+        <el-form-item label="排序">
+          <el-input oninput="value=value.replace(/[^\d]/g,'')" v-model="form.sort"></el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="addSubmit" :loading="submitButtonStat">添加</el-button>
+        </el-form-item>
+      </el-form>
     </div>
+  </div>
 </template>
 
 <script>
-    import store from '@/utils/vuexStore'
-    import network from '@/utils/network'
-    import tool from '@/utils/tool'
-    import baseInfo from '../../utils/baseInfo'
-    export default {
-        name: "package-add",
+import store from '@/utils/vuexStore'
+import network from '@/utils/network'
+import tool from '@/utils/tool'
+import baseInfo from '../../utils/baseInfo'
+export default {
+  name: 'package-add',
 
-        data(){
-            return{
-                loading: false,
-                form:{
-                    packageName:'',
-                    packageNo:'',
-                    id:'',
-                    amount:'',
-                    amountPv:'',
-                    levelId:'',
-                    packageContent:'',
-                    storenums:''
-                },
-                submitButtonStat: false,
-                allDecLevel: baseInfo.decLevels(),
-            }
-        },
-        methods: {
-            addSubmit() {
-                this.submitButtonStat = true
-                let path = 'shop/package-add';
-                let postData = {
-                    id: this.form.id,
-                    packageName: this.form.packageName,
-                    packageNo: this.form.packageNo,
-                    amount: this.form.amount,
-                    amountPv: this.form.amountPv,
-                    levelId: this.form.levelId,
-                    packageContent: this.form.packageContent,
-                    storenums:this.form.storenums,
-
-                }
+  data () {
+    return {
+      loading: false,
+      form: {
+        packageName: '',
+        packageNo: '',
+        id: '',
+        amount: '',
+        amountPv: '',
+        levelId: '',
+        packageContent: '',
+        storenums: '',
+        sort: ''
+      },
+      submitButtonStat: false,
+      allDecLevel: baseInfo.decLevels()
+    }
+  },
+  methods: {
+    addSubmit () {
+      this.submitButtonStat = true
+      let path = 'shop/package-add'
+      let postData = {
+        id: this.form.id,
+        packageName: this.form.packageName,
+        packageNo: this.form.packageNo,
+        amount: this.form.amount,
+        amountPv: this.form.amountPv,
+        levelId: this.form.levelId,
+        packageContent: this.form.packageContent,
+        storenums: this.form.storenums,
+        sort: this.form.sort
+      }
 
-                return network.postData(path, postData).then(response => {
-                    console.log(response);
-                    this.$message({
-                        message: response,
-                        type: 'success'
-                    })
-                    this.submitButtonStat = false
-                    this.$router.go(-1)
-                }).catch(() => {
-                    this.submitButtonStat = false
-                })
-            },
-            handleEdit() {
-                this.dialogEditFormVisible = false
-                this.$message({
-                    message: '正在修改数据',
-                    type: 'info'
-                })
-                let path = 'finance/deal-type-edit'
-                network.postData(path, this.form).then(response => {
-                    this.$message({
-                        message: response,
-                        type: 'success'
-                    })
-                    this.getData(this.currentPage, this.pageSize)
-                }).catch(response => {
-                })
-            },
-        }
+      return network.postData(path, postData).then(response => {
+        this.$message({
+          message: response,
+          type: 'success'
+        })
+        this.submitButtonStat = false
+        this.$router.go(-1)
+      }).catch(() => {
+        this.submitButtonStat = false
+      })
+    },
+    handleEdit () {
+      this.dialogEditFormVisible = false
+      this.$message({
+        message: '正在修改数据',
+        type: 'info'
+      })
+      let path = 'finance/deal-type-edit'
+      network.postData(path, this.form).then(response => {
+        this.$message({
+          message: response,
+          type: 'success'
+        })
+        this.getData(this.currentPage, this.pageSize)
+      }).catch(response => {
+      })
     }
+  }
+}
 </script>
 
 <style scoped>

+ 271 - 284
backendEle/src/views/shop/package.vue

@@ -1,300 +1,287 @@
 <template>
-    <div v-loading="loading">
-        <div class="white-box">
-            <div class="filter-box">
-                <filter-user :filter-types="filterTypes" @select-value="handleFilterUser"></filter-user>
-            </div>
-            <el-table class="table-box" ref="multipleTable" :data="tableData" stripe style="width: 100%;"
-                      @selection-change="handleSelectionChange"
-                      :height="tool.getTableHeight()">
-              <!--  <el-table-column type="selection" width="70" v-if="tableHeaders"></el-table-column>-->
-                <el-table-column v-for="(tableHeader, key) in tableHeaders" :key="key" :label="tableHeader.header" :width="tableHeader.other.width ? tableHeader.other.width : ''" :prop="tableHeader.other.prop ? tableHeader.other.prop : null">
-                    <template slot-scope="scope">
-                        <template v-if="scope.row[tableHeader.index].other.tag" >
-                            <el-tag :type="scope.row[tableHeader.index].other.tag.type ? scope.row[tableHeader.index].other.tag.type : null" :size="scope.row[tableHeader.index].other.tag.size ? scope.row[tableHeader.index].other.tag.size : null" :class="scope.row[tableHeader.index].other.tag.class ? scope.row[tableHeader.index].other.tag.class : null" >{{scope.row[tableHeader.index].value}}</el-tag>
-                        </template>
-                        <template v-else>
-                            <div v-html="scope.row[tableHeader.index].value"></div>
-                        </template>
-                    </template>
-                </el-table-column>
-                <el-table-column fixed="right" label="操作" width="180">
-                    <template slot-scope="scope">
-                        <el-dropdown size="small" trigger="click" v-if="permission.hasPermission(`shop/package-get`)">
-                            <el-button type="primary" size="small" @click.stop="">
-                                操作该数据<i class="el-icon-arrow-down el-icon--right"></i>
-                            </el-button>
-                            <el-dropdown-menu slot="dropdown">
-                                <el-dropdown-item command="package-get" @click.native="handleEditShow(scope.row)">修改数据
-                                </el-dropdown-item>
-                                <el-dropdown-item command="del" @click.native="handleDel(scope.row.ID)"
-                                                  v-show="permission.hasPermission(`shop/goods-delete`)">删除数据
-                                </el-dropdown-item>
-                                <el-dropdown-item command="goods-edit" @click.native="handleGoodUp(scope.row.ID)">商品上架 </el-dropdown-item>
-                                <el-dropdown-item command="goods-edit" @click.native="handleGoodDown(scope.row.ID)">商品下架 </el-dropdown-item>
-                                <el-dropdown-item command="package-get" @click.native="handleEditShowGoodsTimes(scope.row)">套餐限时
-                                </el-dropdown-item>
-                            </el-dropdown-menu>
-                        </el-dropdown>
-                    </template>
-                </el-table-column>
-            </el-table>
+  <div v-loading="loading">
+    <div class="white-box">
+      <div class="filter-box">
+        <filter-user :filter-types="filterTypes" @select-value="handleFilterUser"></filter-user>
+      </div>
+      <el-table class="table-box" ref="multipleTable" :data="tableData" stripe style="width: 100%;"
+                @selection-change="handleSelectionChange"
+                :height="tool.getTableHeight()">
+        <!--  <el-table-column type="selection" width="70" v-if="tableHeaders"></el-table-column>-->
+        <el-table-column v-for="(tableHeader, key) in tableHeaders" :key="key" :label="tableHeader.header" :width="tableHeader.other.width ? tableHeader.other.width : ''" :prop="tableHeader.other.prop ? tableHeader.other.prop : null">
+          <template slot-scope="scope">
+            <template v-if="scope.row[tableHeader.index].other.tag" >
+              <el-tag :type="scope.row[tableHeader.index].other.tag.type ? scope.row[tableHeader.index].other.tag.type : null" :size="scope.row[tableHeader.index].other.tag.size ? scope.row[tableHeader.index].other.tag.size : null" :class="scope.row[tableHeader.index].other.tag.class ? scope.row[tableHeader.index].other.tag.class : null" >{{scope.row[tableHeader.index].value}}</el-tag>
+            </template>
+            <template v-else>
+              <div v-html="scope.row[tableHeader.index].value"></div>
+            </template>
+          </template>
+        </el-table-column>
+        <el-table-column fixed="right" label="操作" width="180">
+          <template slot-scope="scope">
+            <el-dropdown size="small" trigger="click" v-if="permission.hasPermission(`shop/package`)">
+              <el-button type="primary" size="small" @click.stop="">
+                  操作该数据<i class="el-icon-arrow-down el-icon--right"></i>
+              </el-button>
+              <el-dropdown-menu slot="dropdown">
+                <el-dropdown-item command="package-get" @click.native="handleEditShow(scope.row)">修改数据</el-dropdown-item>
+                <el-dropdown-item command="del" @click.native="handleDel(scope.row.ID)"
+                                  v-show="permission.hasPermission(`shop/goods-delete`)">删除数据
+                </el-dropdown-item>
+                <el-dropdown-item command="goods-edit" @click.native="handleGoodUp(scope.row.ID)">商品上架 </el-dropdown-item>
+                <el-dropdown-item command="goods-edit" @click.native="handleGoodDown(scope.row.ID)">商品下架 </el-dropdown-item>
+                <el-dropdown-item command="package-get" @click.native="handleEditShowGoodsTimes(scope.row)">套餐限时</el-dropdown-item>
+              </el-dropdown-menu>
+            </el-dropdown>
+          </template>
+        </el-table-column>
+      </el-table>
 
-            <div class="white-box-footer">
-                <el-button type="primary" size="small" @click="handlestate" icon="el-icon-plus"
-                           v-if="permission.hasPermission(`shop/package-add`)">新增套餐
-                </el-button>
-                <pagination :total="totalCount" :page_size="pageSize" @size-change="handleSizeChange"
-                            @current-change="handleCurrentChange"></pagination>
-            </div>
-        </div>
-        <el-dialog title="修改套餐" :visible.sync="dialogEditFormVisible">
-            <el-form :model="form" label-width="250px" class="form-dialog" v-loading="dialogEditLoading">
-
-                <el-form-item label="套餐名称">
-                    <el-input v-model="form.packageName"></el-input>
-                </el-form-item>
-                <el-form-item label="套餐编号">
-                    <el-input v-model="form.packageNo"></el-input>
-                </el-form-item>
-                <el-form-item label="套餐金额">
-                    <el-input v-model="form.amount"></el-input>
-                </el-form-item>
-                <el-form-item label="套餐PV">
-                    <el-input v-model="form.amountPv"></el-input>
-                </el-form-item>
-                <el-form-item label="报单级别ID">
-                    <el-select v-model="form.levelId" placeholder="请选择报单级别">
-                        <el-option v-for="(item,index) in allDecLevel" :key="index" :label="item.LEVEL_NAME"
-                                   :value="item.ID"></el-option>
-                    </el-select>
-                </el-form-item>
-                <el-form-item label="套餐内容">
-                    <el-input v-model="form.packageContent"></el-input>
-                </el-form-item>
-                <el-form-item label="套餐库存">
-                    <el-input oninput="value=value.replace(/[^\d]/g,'')" v-model="form.storenums"></el-input>
-                </el-form-item>
-            </el-form>
-            <div slot="footer" class="dialog-footer">
-                <el-button @click="dialogEditFormVisible = false">取 消</el-button>
-                <el-button type="primary" @click.native="handleEdit">修 改</el-button>
-            </div>
-        </el-dialog>
-
-        <el-dialog title="限时套餐" :visible.sync="dialogEditFormVisibleGoodsTimes">
-            <el-form :model="form" label-width="250px" class="form-dialog" v-loading="dialogEditLoadingGoodsTimes">
-
-               <el-form-item label="是否限时">
-                     <el-switch
-                       v-model="form.statusdate"
-                       active-value="1"
-                       inactive-value="0">
-                     </el-switch>
-               </el-form-item>
-               <transition name="el-zoom-in-top">
-               <el-form-item label="限时时间" v-show='form.statusdate==1?true:false'>
-                       <el-date-picker
-                         v-model="form.packagedate"
-                         type="datetime"
-                         placeholder="选择日期时间"
-                         value-format="timestamp"
-                         popper-class='goodsdate'>
-                       </el-date-picker>
-               </el-form-item>
-               </transition>
-               <transition name="el-zoom-in-top">
-               <el-form-item label="限时类型" v-show='form.statusdate==1?true:false'>
-
-                    <el-radio v-model="form.packagestatusdate" label="0" border>下架</el-radio>
-                    <el-radio v-model="form.packagestatusdate" label="1" border>上架</el-radio>
-               </el-form-item>
-               </transition>
+      <div class="white-box-footer">
+        <el-button type="primary" size="small" @click="handlestate" icon="el-icon-plus"
+                   v-if="permission.hasPermission(`shop/package-add`)">新增套餐
+        </el-button>
+        <pagination :total="totalCount" :page_size="pageSize" @size-change="handleSizeChange"
+                    @current-change="handleCurrentChange"></pagination>
+      </div>
+    </div>
+    <el-dialog title="修改套餐" :visible.sync="dialogEditFormVisible">
+      <el-form :model="form" label-width="250px" class="form-dialog" v-loading="dialogEditLoading">
+        <el-form-item label="套餐名称">
+          <el-input v-model="form.packageName"></el-input>
+        </el-form-item>
+        <el-form-item label="套餐编号">
+          <el-input v-model="form.packageNo"></el-input>
+        </el-form-item>
+        <el-form-item label="套餐金额">
+          <el-input v-model="form.amount"></el-input>
+        </el-form-item>
+        <el-form-item label="套餐PV">
+          <el-input v-model="form.amountPv"></el-input>
+        </el-form-item>
+        <el-form-item label="报单级别ID">
+          <el-select v-model="form.levelId" placeholder="请选择报单级别">
+            <el-option v-for="(item,index) in allDecLevel" :key="index" :label="item.LEVEL_NAME"
+                       :value="item.ID"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="套餐内容">
+          <el-input v-model="form.packageContent"></el-input>
+        </el-form-item>
+        <el-form-item label="套餐库存">
+          <el-input oninput="value=value.replace(/[^\d]/g,'')" v-model="form.storenums"></el-input>
+        </el-form-item>
+        <el-form-item label="排序">
+          <el-input oninput="value=value.replace(/[^\d]/g,'')" v-model="form.sort"></el-input>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="dialogEditFormVisible = false">取 消</el-button>
+        <el-button type="primary" @click.native="handleEdit">修 改</el-button>
+      </div>
+    </el-dialog>
 
+    <el-dialog title="限时套餐" :visible.sync="dialogEditFormVisibleGoodsTimes">
+      <el-form :model="form" label-width="250px" class="form-dialog" v-loading="dialogEditLoadingGoodsTimes">
+        <el-form-item label="是否限时">
+          <el-switch
+           v-model="form.statusdate"
+           active-value="1"
+           inactive-value="0">
+          </el-switch>
+        </el-form-item>
+        <transition name="el-zoom-in-top">
+          <el-form-item label="限时时间" v-show='form.statusdate==1?true:false'>
+            <el-date-picker
+             v-model="form.packagedate"
+             type="datetime"
+             placeholder="选择日期时间"
+             value-format="timestamp"
+             popper-class='goodsdate'>
+            </el-date-picker>
+          </el-form-item>
+        </transition>
+        <transition name="el-zoom-in-top">
+          <el-form-item label="限时类型" v-show='form.statusdate==1?true:false'>
+            <el-radio v-model="form.packagestatusdate" label="0" border>下架</el-radio>
+            <el-radio v-model="form.packagestatusdate" label="1" border>上架</el-radio>
+          </el-form-item>
+        </transition>
 
-            </el-form>
-            <div slot="footer" class="dialog-footer">
-                <el-button @click="dialogEditFormVisibleGoodsTimes = false">取 消</el-button>
-                <el-button type="primary" @click.native="handleEdit">修 改</el-button>
-            </div>
-        </el-dialog>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="dialogEditFormVisibleGoodsTimes = false">取 消</el-button>
+        <el-button type="primary" @click.native="handleEdit">修 改</el-button>
+      </div>
+    </el-dialog>
 
-    </div>
+  </div>
 </template>
 
 <script>
-    import network from '@/utils/network'
-    import tool from '@/utils/tool'
-    import baseInfo from '@/utils/baseInfo'
-    import FilterUser from '@/components/FilterUser'
-    import permission from '@/utils/permission'
-    import Pagination from '@/components/Pagination'
-    import filterHelper from '@/utils/filterHelper'
-
-    export default {
-        name: 'package',
-        components: {FilterUser, Pagination},
-        mounted() {
-            this.getData()
-        },
-        data() {
-            return {
-                tableHeaders: null,
-                tableData: null,
-                tableHeight: window.innerHeight - 310,
-                loading: true,
-                multipleSelection: [],
-                currentPage: 1,
-                totalPages: 1,
-                totalCount: 1,
-                pageSize: 20,
-                tool: tool,
-                permission: permission,
-                baseDecLevels: baseInfo.decLevels(),
-                baseEmpLevels: baseInfo.empLevels(),
-                filterTypes: null,
-                filterModel: {},
-                dialogVisible: false,
-                dialogLoading: false,
-                statuses: null,
-                filterData: null,
-                dialogEditFormVisible: false,
-                dialogEditLoading: false,
-                dialogEditFormVisibleGoodsTimes: false,
-                dialogEditLoadingGoodsTimes: false,
-                allDecLevel: baseInfo.decLevels(),
-                form: {
-                    selectedIds: [],
-                    statusValue: [],
-                    sendType: null,
-                    remark: null,
+import network from '@/utils/network'
+import tool from '@/utils/tool'
+import baseInfo from '@/utils/baseInfo'
+import FilterUser from '@/components/FilterUser'
+import permission from '@/utils/permission'
+import Pagination from '@/components/Pagination'
+import filterHelper from '@/utils/filterHelper'
 
-                },
-            }
-        },
-        methods: {
-            handleSelectionChange(val) {
-                this.multipleSelection = val
-            },
-            handleCurrentChange(page) {
-                this.getData(page, this.pageSize)
-            },
-            handleSizeChange(pageSize) {
-                this.getData(this.currentPage, pageSize)
-            },
-            handleFilterUser(filterData) {
-                filterHelper.handleFilterUser(this, filterData)
-            },
-
-
-            handlestate(){
-                this.$router.push({path: `/shop/package-add`})
-            },
-            handleEditShow(row) {
-                this.dialogEditLoading = true
-                this.auditId = row.ID
-                this.dialogEditFormVisible = true
-                let vueObj = this
-                network.getData('shop/package-get', {id: this.auditId}).then(response => {
-                    console.log(response)
-                    vueObj.dialogEditLoading = false
-                    vueObj.form = response
-					vueObj.form.packagedate = response.packagedate*1000
-                })
-            },
-            handleEditShowGoodsTimes(row) {
-                this.dialogEditLoadingGoodsTimes = true
-                this.auditId = row.ID
-                this.dialogEditFormVisibleGoodsTimes = true
-                let vueObj = this
-                network.getData('shop/package-get', {id: this.auditId}).then(response => {
-                    console.log(response.packagedate*1000)
-                    vueObj.dialogEditLoadingGoodsTimes = false
-                    vueObj.form = response
-					vueObj.form.packagedate = response.packagedate*1000
-                })
-            },
-            handleEdit() {
-                this.dialogEditFormVisible = false
-                this.dialogEditFormVisibleGoodsTimes = false
-                this.$message({
-                    message: '正在修改数据',
-                    type: 'info'
-                })
-                let path = 'shop/package-get'
-                network.postData(path, this.form).then(response => {
-
-                    this.$message({
-                        message: response,
-                        type: 'success'
-                    })
-                    this.getData(this.currentPage, this.pageSize)
-                }).catch(response => {
-                })
-            },
-
-            handleDel(id = null) {
-                let obj = this
-                this.$confirm('确定删除选定的数据?', '提示', {
-                    confirmButtonText: '确定',
-                    cancelButtonText: '取消',
-                    type: 'warning'
-                }).then(() => {
-                    let selectedIds = []
-                    if (id === null) {
-                        for (let val of obj.multipleSelection) {
-                            selectedIds.push(val.ID)
-                        }
-                    } else {
-                        selectedIds.push(id)
-                    }
-                    return network.postData(`shop/package-delete`, {
-                        selected: selectedIds
-                    })
-                }).then(response => {
-                    this.$message({
-                        message: response,
-                        type: 'success'
-                    })
-                    obj.getData(obj.currentPage, obj.pageSize)
-                }).catch(response => {
+export default {
+  name: 'package',
+  components: {FilterUser, Pagination},
+  mounted () {
+    this.getData()
+  },
+  data () {
+    return {
+      tableHeaders: null,
+      tableData: null,
+      tableHeight: window.innerHeight - 310,
+      loading: true,
+      multipleSelection: [],
+      currentPage: 1,
+      totalPages: 1,
+      totalCount: 1,
+      pageSize: 20,
+      tool: tool,
+      permission: permission,
+      baseDecLevels: baseInfo.decLevels(),
+      baseEmpLevels: baseInfo.empLevels(),
+      filterTypes: null,
+      filterModel: {},
+      dialogVisible: false,
+      dialogLoading: false,
+      statuses: null,
+      filterData: null,
+      dialogEditFormVisible: false,
+      dialogEditLoading: false,
+      dialogEditFormVisibleGoodsTimes: false,
+      dialogEditLoadingGoodsTimes: false,
+      allDecLevel: baseInfo.decLevels(),
+      form: {
+        selectedIds: [],
+        statusValue: [],
+        sendType: null,
+        remark: null
+      }
+    }
+  },
+  methods: {
+    handleSelectionChange (val) {
+      this.multipleSelection = val
+    },
+    handleCurrentChange (page) {
+      this.getData(page, this.pageSize)
+    },
+    handleSizeChange (pageSize) {
+      this.getData(this.currentPage, pageSize)
+    },
+    handleFilterUser (filterData) {
+      filterHelper.handleFilterUser(this, filterData)
+    },
 
-                })
-            },
-            getData(page, pageSize) {
-                let filterData = this.filterModel
-                network.getPageData(this, 'shop/package', page, pageSize, filterData, response => {
-                    console.log('response')
-                    console.log(response);
-                    this.filterTypes = response.filterTypes
-                    this.allData = response
-                })
-            },
-            handleGoodUp(id){
-                console.log(id);
-                network.postData('shop/package-status',{selectedIds:id,status:1})
-                    .then(response=>{
-                        this.$message({
-                            message: response,
-                            type: 'success'
-                        })
-                        this.getData(this.currentPage, this.pageSize)
-                    })
-            },
-            handleGoodDown(id){
-                network.postData('shop/package-status',{selectedIds:id,status:0})
-                    .then(response=>{
-                        this.$message({
-                            message: response,
-                            type: 'success'
-                        })
-                        this.getData(this.currentPage, this.pageSize)
-                    })
-            }
+    handlestate () {
+      this.$router.push({path: `/shop/package-add`})
+    },
+    handleEditShow (row) {
+      this.dialogEditLoading = true
+      this.auditId = row.ID
+      this.dialogEditFormVisible = true
+      let vueObj = this
+      network.getData('shop/package-get', {id: this.auditId}).then(response => {
+        vueObj.dialogEditLoading = false
+        vueObj.form = response
+        vueObj.form.packagedate = response.packagedate * 1000
+      })
+    },
+    handleEditShowGoodsTimes (row) {
+      this.dialogEditLoadingGoodsTimes = true
+      this.auditId = row.ID
+      this.dialogEditFormVisibleGoodsTimes = true
+      let vueObj = this
+      network.getData('shop/package-get', {id: this.auditId}).then(response => {
+        vueObj.dialogEditLoadingGoodsTimes = false
+        vueObj.form = response
+        vueObj.form.packagedate = response.packagedate * 1000
+      })
+    },
+    handleEdit () {
+      this.dialogEditFormVisible = false
+      this.dialogEditFormVisibleGoodsTimes = false
+      this.$message({
+        message: '正在修改数据',
+        type: 'info'
+      })
+      let path = 'shop/package-get'
+      network.postData(path, this.form).then(response => {
+        this.$message({
+          message: response,
+          type: 'success'
+        })
+        this.getData(this.currentPage, this.pageSize)
+      }).catch(response => {
+      })
+    },
 
+    handleDel (id = null) {
+      let obj = this
+      this.$confirm('确定删除选定的数据?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        let selectedIds = []
+        if (id === null) {
+          for (let val of obj.multipleSelection) {
+            selectedIds.push(val.ID)
+          }
+        } else {
+          selectedIds.push(id)
         }
-    }
+        return network.postData(`shop/package-delete`, {
+          selected: selectedIds
+        })
+      }).then(response => {
+        this.$message({
+          message: response,
+          type: 'success'
+        })
+        obj.getData(obj.currentPage, obj.pageSize)
+      }).catch(response => {
 
+      })
+    },
+    getData (page, pageSize) {
+      let filterData = this.filterModel
+      network.getPageData(this, 'shop/package', page, pageSize, filterData, response => {
+        this.filterTypes = response.filterTypes
+        this.allData = response
+      })
+    },
+    handleGoodUp (id) {
+      network.postData('shop/package-status', {selectedIds: id, status: 1})
+        .then(response => {
+          this.$message({
+            message: response,
+            type: 'success'
+          })
+          this.getData(this.currentPage, this.pageSize)
+        })
+    },
+    handleGoodDown (id) {
+      network.postData('shop/package-status', {selectedIds: id, status: 0})
+        .then(response => {
+          this.$message({
+            message: response,
+            type: 'success'
+          })
+          this.getData(this.currentPage, this.pageSize)
+        })
+    }
+  }
+}
 </script>
 
 <style scoped>

+ 90 - 0
backendEle/src/views/shop/remain-pv.vue

@@ -0,0 +1,90 @@
+<template>
+  <div v-loading="loading">
+    <div class="white-box">
+      <div class="filter-box">
+        <filter-user :filter-types="filterTypes" @select-value="handleFilterUser"></filter-user>
+      </div>
+      <el-table class="table-box" ref="multipleTable" :data="tableData" stripe style="width: 100%;" :height="tool.getTableHeight()">
+        <el-table-column v-for="(tableHeader, key) in tableHeaders" :key="key" :label="tableHeader.header" :width="tableHeader.other.width ? tableHeader.other.width : ''" :prop="tableHeader.other.prop ? tableHeader.other.prop : null">
+          <template slot-scope="scope">
+            <template v-if="scope.row[tableHeader.index].other.tag" >
+              <el-tag :type="scope.row[tableHeader.index].other.tag.type ? scope.row[tableHeader.index].other.tag.type : null" :size="scope.row[tableHeader.index].other.tag.size ? scope.row[tableHeader.index].other.tag.size : null" :class="scope.row[tableHeader.index].other.tag.class ? scope.row[tableHeader.index].other.tag.class : null" >{{scope.row[tableHeader.index].value}}</el-tag>
+            </template>
+            <template v-else>
+              <div v-html="scope.row[tableHeader.index].value"></div>
+            </template>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="white-box-footer">
+        <pagination :total="totalCount" :page_size="pageSize" @size-change="handleSizeChange" @current-change="handleCurrentChange"></pagination>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import network from '@/utils/network'
+import tool from '@/utils/tool'
+import baseInfo from '@/utils/baseInfo'
+import FilterUser from '../../components/FilterUser'
+import permission from '@/utils/permission'
+import Pagination from '@/components/Pagination'
+import filterHelper from '@/utils/filterHelper'
+
+export default {
+  name: 'shop_remain-pv',
+  components: {FilterUser, Pagination},
+  mounted () {
+    this.getData()
+  },
+  data () {
+    return {
+      tableHeaders: null,
+      tableData: null,
+      loading: true,
+      multipleSelection: [],
+      currentPage: 1,
+      totalPages: 1,
+      totalCount: 1,
+      pageSize: 20,
+      tool: tool,
+      permission: permission,
+      baseDecLevels: baseInfo.decLevels(),
+      baseEmpLevels: baseInfo.empLevels(),
+      filterTypes: null,
+      filterModel: {}
+    }
+  },
+  methods: {
+    handleCurrentChange (page) {
+      this.getData(page, this.pageSize)
+    },
+    handleSizeChange (pageSize) {
+      this.getData(this.currentPage, pageSize)
+    },
+    handleFilterUser (filterData) {
+      filterHelper.handleFilterUser(this, filterData)
+    },
+    getData (page, pageSize) {
+      network.getPageData(this, 'shop/remain-pv', page, pageSize, this.filterModel, response => {
+        this.filterTypes = response.filterTypes
+      })
+    }
+  }
+}
+
+</script>
+
+<style scoped>
+  .table-box .el-form-item__label {
+    width: 100px;
+    color: #99a9bf;
+  }
+
+  .table-box .el-form-item {
+    width: 30%;
+    margin-right: 0;
+    margin-bottom: 0;
+  }
+</style>

+ 5 - 1
common/components/SwooleAsyncTimer.php

@@ -70,7 +70,11 @@ class SwooleAsyncTimer extends SwooleAsyncTimerComponent implements SocketInterf
             // 初始化任务队列
             Queue::instance()->initRedis();
             // 初始化备份历史奖金数据表
-            TaskFunc::initAutoBakBalance();
+//            TaskFunc::initAutoBakBalance();
+            // 初始化自动发送钉钉推送消息
+//            if (YII_ENV == YII_ENV_PROD) {
+//                TaskFunc::initAutoSendDingTalk();
+//            }
         }
     }
 

+ 8 - 1
common/config/params.php

@@ -44,7 +44,7 @@ return [
     'shopWalletType' => [
         'cash' =>[
             'value'=>'cash',
-            'title'=>'现金钱包',
+            'title'=>'充值账户',
         ],
     ],
     'shopFlowType' => [
@@ -325,4 +325,11 @@ return [
         'dataCenterId' => 2,//
         'workerId' => 2,
     ],
+    // 钉钉消息
+    'DingTalk' => [
+        'accessToken' => 'f6b61da1e4cef364298cbac4cad0af23f19a0b34a113ee4d39986d1f796c51b0',
+        'atMobiles'   => [],
+        'atUserIds'   => ['rob9muw'],
+        'isAtAll'     => false,
+    ],
 ];

+ 54 - 0
common/helpers/DingTalk.php

@@ -0,0 +1,54 @@
+<?php
+
+namespace common\helpers;
+
+class DingTalk
+{
+    private static $webhook = 'https://oapi.dingtalk.com/robot/send?access_token=';
+
+    private static function request_by_curl($post_string)
+    {
+        $ch = curl_init();
+        curl_setopt($ch, CURLOPT_URL, self::$webhook . \Yii::$app->params['DingTalk']['accessToken']);
+        curl_setopt($ch, CURLOPT_POST, 1);
+        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
+        curl_setopt($ch, CURLOPT_HTTPHEADER, array ('Content-Type: application/json;charset=utf-8'));
+        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+        // 线下环境不用开启curl证书验证, 未调通情况可尝试添加该代码
+         curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
+         curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
+        $data = curl_exec($ch);
+        curl_close($ch);
+
+        return json_decode($data, true);
+    }
+
+    public static function sendNotice($message)
+    {
+        $message['serverIP'] = $_SERVER['HTTP_HOST'];
+        $data = [
+            'msgtype' => 'text',
+            'text' => ['content' => $message],
+            "at" => [
+                'atMobiles' => \Yii::$app->params['DingTalk']['atMobiles'],
+                'atUserIds' => \Yii::$app->params['DingTalk']['atUserIds'],
+                'isAtAll'   => false,
+            ]
+        ];
+
+        // 正式环境才发送
+        if (in_array($_SERVER['HTTP_HOST'], ['fapi.ekhkad.com', 'bapi.ekhkad.com'])) {
+            $data['serverAddr'] = $_SERVER['SERVER_ADDR'];
+            $data['serverName'] = $_SERVER['SERVER_NAME'];
+            $result = self::request_by_curl(json_encode($data));
+            if ($result['errcode'] > 0) {
+                // 重新推送一次,如果失败,写错误日志
+                $result = self::request_by_curl(json_encode($data));
+                if (!$result['errcode']) {
+                    LoggerTool::error([$result, $message]);
+                }
+            }
+        }
+    }
+}

+ 16 - 0
common/helpers/Excel.php

@@ -25,6 +25,7 @@ use common\models\forms\RegInfoAuditForm;
 use common\models\forms\WithdrawForm;
 use common\models\Uploads;
 use common\models\UserNetwork;
+use common\models\User;
 use yii\base\BaseObject;
 use yii\base\Exception;
 use yii\base\StaticInstanceTrait;
@@ -829,6 +830,21 @@ class Excel extends BaseObject {
                 'storeFile' => $tempFileName,
                 'dropKeysRow' => $startRow == 1 ? false : true,
             ]);
+            $errUserArray = [];
+            foreach ($data as $u){ // 记录了导入中不存在的会员
+                $u['USER_NAME'] = trim($u['会员编号']);
+                if(!$u['USER_NAME']){
+                    continue;
+                }
+                $userInfo = User::checkUser($u['USER_NAME']);
+                if(!$userInfo){
+                    $errUserArray[] = $u['USER_NAME'];
+                }
+            }
+            if(count($errUserArray)>0){
+                $errUserStr = implode(', ', $errUserArray);
+                throw new Exception(count($errUserArray).'个用户不存在:'.substr($errUserStr,0, 600).'...');
+            }
         } catch (\Exception $e) {
             throw new Exception($e->getMessage());
         }

+ 56 - 0
common/helpers/LoggerTool.php

@@ -0,0 +1,56 @@
+<?php
+
+namespace common\helpers;
+
+
+use Monolog\Handler\FirePHPHandler;
+use Monolog\Handler\StreamHandler;
+use Monolog\Logger;
+
+class LoggerTool
+{
+    public static function info($message)
+    {
+        $logger = new Logger('info');
+        // 添加一些处理器
+        $logger->pushHandler(new StreamHandler(__DIR__ . "/../runtime/logs/info.log", Logger::DEBUG));
+        $logger->pushHandler(new FirePHPHandler());
+        $logger->info(json_encode($message));
+    }
+
+    public static function error($message)
+    {
+        $logger = new Logger('error');
+        // 添加一些处理器
+        $logger->pushHandler(new StreamHandler(__DIR__ . "/../runtime/logs/error.log", Logger::DEBUG));
+        $logger->pushHandler(new FirePHPHandler());
+        $logger->error(json_encode($message));
+    }
+
+    public static function warning($message)
+    {
+        $logger = new Logger('warning');
+        // 添加一些处理器
+        $logger->pushHandler(new StreamHandler(__DIR__ . "/../runtime/logs/warning.log", Logger::DEBUG));
+        $logger->pushHandler(new FirePHPHandler());
+        $logger->warning(json_encode($message));
+    }
+
+    public static function notice($message)
+    {
+        $logger = new Logger('notice');
+        // 添加一些处理器
+        $logger->pushHandler(new StreamHandler(__DIR__ . "/../runtime/logs/notice.log", Logger::DEBUG));
+        $logger->pushHandler(new FirePHPHandler());
+        $logger->notice(json_encode($message));
+    }
+
+    public static function debug($message)
+    {
+        $logger = new Logger('debug');
+        // 添加一些处理器
+        $logger->pushHandler(new StreamHandler(__DIR__ . "/../runtime/logs/debug.log", Logger::DEBUG));
+        $logger->pushHandler(new FirePHPHandler());
+        $logger->debug(json_encode($message));
+    }
+}

+ 13 - 122
common/helpers/bonus/BonusCalc.php

@@ -60,7 +60,7 @@ use yii\helpers\Json;
 class BonusCalc extends BaseObject {
     use StaticInstanceTrait;
 
-    private $_limit = 1000;
+    private $_limit = 10000;
     private $_gxLimit = 500;
     private $_handleUserId;
     private $_companyMonthPerf = 0;
@@ -198,33 +198,7 @@ class BonusCalc extends BaseObject {
             echo('计算推广奖'.($this->_sysConfig['openTG']['VALUE']?'完成':'关闭').',耗时:' . round($t5 - $t4, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
             $this->_updatePercent(20);
 
-            if($this->_sysConfig['openXF']['VALUE']) {
-                if( $this->_sysConfig['consumeRecPercent']['VALUE'] > 0 ) {
-                    $this->calcBonusXFToRec();
-                }
-                if( $this->_sysConfig['consumeSelfPercent']['VALUE'] > 0 ) {
-                    $this->calcBonusXFToSelf();
-                }
-            }
-            $t6 = microtime(true);
-            echo('计算消费奖'.($this->_sysConfig['openXF']['VALUE']?'完成':'关闭').',耗时:' . round($t6 - $t5, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
-            $this->_updatePercent(25);
-
-            if($this->_sysConfig['openYJ']['VALUE']) {
-                $this->calcBonusBdYJ();
-            }
-            $t7 = microtime(true);
-            echo('计算报单业绩奖'.($this->_sysConfig['openYJ']['VALUE']?'完成':'关闭').',耗时:' . round($t7 - $t6, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
-            $this->_updatePercent(30);
-
-            if($this->_sysConfig['fxOpenYJ']['VALUE']) {
-                $this->calcBonusFxYJ();
-            }
             $t8 = microtime(true);
-            echo('计算复消业绩奖'.($this->_sysConfig['fxOpenYJ']['VALUE']?'完成':'关闭').',耗时:' . round($t8 - $t7, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
-            $this->_updatePercent(35);
-
-
             if($this->_sysConfig['openQY']['VALUE']) {
                 $this->calcBonusQY();
                 $this->calcBonusBdQY();
@@ -249,19 +223,6 @@ class BonusCalc extends BaseObject {
             echo('计算报单管理奖'.($this->_sysConfig['openGL']['VALUE']?'完成':'关闭').',耗时:' . round($t13 - $t11, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
             $this->_updatePercent(50);
 
-//            if($this->_sysConfig['fxOpenGL']['VALUE']) {
-//                $this->calcBonusFxGL();
-//            }
-//            $t14 = microtime(true);
-//            echo('计算复消管理奖'.($this->_sysConfig['fxOpenGL']['VALUE']?'完成':'关闭').',耗时:' . round($t14 - $t13, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
-//            $this->_updatePercent(70);
-          
-
-            // if($this->_sysConfig['openYC']['VALUE']) {
-            //     $this->calcBonusYCStepOne();
-            //     $this->calcBonusYCStepTwo();
-            // }
-
             // 计算店服务奖 月奖
             if($this->_sysConfig['openStore']['VALUE']) {
                 if ($this->_sysConfig['openStoreReduce']['VALUE']) {
@@ -276,20 +237,7 @@ class BonusCalc extends BaseObject {
             echo('计算店服务奖金'.($this->_sysConfig['openStore']['VALUE']?'完成':'关闭').',耗时:' . round($t16 - $t13, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
             $this->_updatePercent(55);
 
-            if($this->_sysConfig['openVIP']['VALUE']) {
-                $this->calcBonusVIP();
-            }
             $t17 = microtime(true);
-            echo('计算VIP奖'.($this->_sysConfig['openVIP']['VALUE']?'完成':'关闭').',耗时:' . round($t17 - $t16, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
-            $this->_updatePercent(60);
-
-            if($this->_sysConfig['openJXS']['VALUE']) {
-                $this->calcBonusStandard();
-            }
-            $t18 = microtime(true);
-            echo('计算达标奖'.($this->_sysConfig['openJXS']['VALUE']?'完成':'关闭').',耗时:' . round($t18 - $t17, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
-            $this->_updatePercent(65);
-
             // 蓝星奖入库,实际上是插入有奖金会员数据缓存中.
             // 调用存储过程,计算蓝星管理奖金
             $this->calcBsProcedure();
@@ -297,8 +245,8 @@ class BonusCalc extends BaseObject {
             $this->calcBonusBsGL();
             $this->calcBonusBsGLCF();
             $this->calcBonusBsYJCF();
-            $t18temp = microtime(true);
-            echo('计算蓝星管理奖'.($this->_sysConfig['openGL']['VALUE']?'完成':'关闭').',耗时:' . round($t18temp - $t18, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
+            $t18 = microtime(true);
+            echo('计算蓝星管理奖'.($this->_sysConfig['openGL']['VALUE']?'完成':'关闭').',耗时:' . round($t18 - $t17, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
             $this->_updatePercent(65);
 
             //把奖金会员写入缓存
@@ -311,7 +259,7 @@ class BonusCalc extends BaseObject {
             $this->loopBonusUsers();
             // 入库完成,将各个奖金计算流水会员聘级,更新成蓝星奖当时计算的聘级
             $this->loopCalcBlueEmpLv();
-            $this->_updatePercent(75);
+            $this->_updatePercent(85);
             unset($calcWrite);
             $t20 = microtime(true);
             echo('奖金写库操作完成,耗时:' . round($t20 - $t19, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
@@ -320,21 +268,7 @@ class BonusCalc extends BaseObject {
             $this->loopMonthBonusUserToDb();
             $t21 = microtime(true);
             echo('奖金会员入库完成,耗时:' . round($t21 - $t20, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
-            $this->_updatePercent(80);
-
-            // 计算基础积分,不可以奖金入库之前计算这样可能会丢掉只有本期的奖金的会员
-            $this->calcBaseScore();
-            $this->_updatePercent(90);
-            $t22 = microtime(true);
-            echo('计算基础积分,耗时:' . round($t22 - $t21, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
-
-            //积分入库
-            $this->loopWriteScore();
             $this->_updatePercent(100);
-            $t23 = microtime(true);
-            echo('积分写库操作完成,耗时:' . round($t23 - $t22, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
-
-            //@todo 计算房产奖
 
             $t30 = microtime(true);
             echo('结算全部完成,共耗时:' . round($t30 - $t1, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
@@ -509,11 +443,6 @@ class BonusCalc extends BaseObject {
                         'decPercentConfig' => $this->_sysConfig['decPercent']['VALUE'],
                         'recNum' => $bonusUserInfo['REC_NUM'],
                         'decAmount' => $bonusUserInfo['ZC_AMOUNT'],
-                        'bonusTotalLimit' => [
-                            $this->_sysConfig['bonusTotalZeroLimit']['VALUE'],
-                            $this->_sysConfig['bonusTotalOneLimit']['VALUE'],
-                            $this->_sysConfig['bonusTotalTwoLimit']['VALUE'],
-                        ],
                     ]),
                 ];
 
@@ -597,11 +526,6 @@ class BonusCalc extends BaseObject {
                         'recNum' => $userBaseInfo['REC_NUM'],
                         'decAmount' => $userBaseInfo['ZC_AMOUNT'],
                         'decLevel' => $userBaseInfo['DEC_LV'],
-                        'bonusTotalLimit' => [
-                            $this->_sysConfig['bonusTotalZeroLimit']['VALUE'],
-                            $this->_sysConfig['bonusTotalOneLimit']['VALUE'],
-                            $this->_sysConfig['bonusTotalTwoLimit']['VALUE'],
-                        ],
                     ]),
                 ];
 
@@ -685,11 +609,6 @@ class BonusCalc extends BaseObject {
                         'recNum' => $userBaseInfo['REC_NUM'],
                         'decAmount' => $userBaseInfo['ZC_AMOUNT'],
                         'decLevel' => $userBaseInfo['DEC_LV'],
-                        'bonusTotalLimit' => [
-                            $this->_sysConfig['bonusTotalZeroLimit']['VALUE'],
-                            $this->_sysConfig['bonusTotalOneLimit']['VALUE'],
-                            $this->_sysConfig['bonusTotalTwoLimit']['VALUE'],
-                        ],
                     ]),
                 ];
 
@@ -773,11 +692,6 @@ class BonusCalc extends BaseObject {
                         'recNum' => $userBaseInfo['REC_NUM'],
                         'decAmount' => $userBaseInfo['ZC_AMOUNT'],
                         'decLevel' => $userBaseInfo['DEC_LV'],
-                        'bonusTotalLimit' => [
-                            $this->_sysConfig['bonusTotalZeroLimit']['VALUE'],
-                            $this->_sysConfig['bonusTotalOneLimit']['VALUE'],
-                            $this->_sysConfig['bonusTotalTwoLimit']['VALUE'],
-                        ],
                     ]),
                 ];
 
@@ -1189,11 +1103,6 @@ class BonusCalc extends BaseObject {
                             'recNum' => $bonusUserBaseInfo['REC_NUM'],
                             'decAmount' => $bonusUserBaseInfo['ZC_AMOUNT'],
                             'decLevel' => $bonusUserBaseInfo['DEC_LV'],
-                            'bonusTotalLimit' => [
-                                $this->_sysConfig['bonusTotalZeroLimit']['VALUE'],
-                                $this->_sysConfig['bonusTotalOneLimit']['VALUE'],
-                                $this->_sysConfig['bonusTotalTwoLimit']['VALUE'],
-                            ],
                         ]),
                     ];
 
@@ -1307,11 +1216,6 @@ class BonusCalc extends BaseObject {
                             'recNum' => $bonusUserBaseInfo['REC_NUM'],
                             'decAmount' => $bonusUserBaseInfo['ZC_AMOUNT'],
                             'decLevel' => $bonusUserBaseInfo['DEC_LV'],
-                            'bonusTotalLimit' => [
-                                $this->_sysConfig['bonusTotalZeroLimit']['VALUE'],
-                                $this->_sysConfig['bonusTotalOneLimit']['VALUE'],
-                                $this->_sysConfig['bonusTotalTwoLimit']['VALUE'],
-                            ],
                         ]),
                     ];
 
@@ -1768,11 +1672,6 @@ class BonusCalc extends BaseObject {
                             'incomeBonus' => $incomeBonus,
                             'recNum' => $userBaseInfo['REC_NUM'],
                             'decAmount' => $userBaseInfo['ZC_AMOUNT'],
-                            'bonusTotalLimit' => [
-                                $this->_sysConfig['bonusTotalZeroLimit']['VALUE'],
-                                $this->_sysConfig['bonusTotalOneLimit']['VALUE'],
-                                $this->_sysConfig['bonusTotalTwoLimit']['VALUE'],
-                            ],
                         ]),
                     ];
 
@@ -2073,11 +1972,6 @@ class BonusCalc extends BaseObject {
                             'decAmount' => $bonusUserBaseInfo['ZC_AMOUNT'],
                             'fromUserId' => $userId,
                             'decLevel' => $bonusUserBaseInfo['DEC_LV'],
-                            'bonusTotalLimit' => [
-                                $this->_sysConfig['bonusTotalZeroLimit']['VALUE'],
-                                $this->_sysConfig['bonusTotalOneLimit']['VALUE'],
-                                $this->_sysConfig['bonusTotalTwoLimit']['VALUE'],
-                            ],
                         ]),
                     ];
 
@@ -2208,11 +2102,6 @@ class BonusCalc extends BaseObject {
                             'decAmount' => $bonusUserBaseInfo['ZC_AMOUNT'],
                             'fromUserId' => $userId,
                             'decLevel' => $bonusUserBaseInfo['DEC_LV'],
-                            'bonusTotalLimit' => [
-                                $this->_sysConfig['bonusTotalZeroLimit']['VALUE'],
-                                $this->_sysConfig['bonusTotalOneLimit']['VALUE'],
-                                $this->_sysConfig['bonusTotalTwoLimit']['VALUE'],
-                            ],
                         ]),
                     ];
 
@@ -3457,13 +3346,13 @@ class BonusCalc extends BaseObject {
                         ':PERIOD_NUM' => $this->_periodNum
                     ]
                 );
-                // 奖金流水
-                FlowBonus::updateAll(['LAST_EMP_LV' => $nowBsEmpLv], 'USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', 
-                    [
-                        ':USER_ID' => $data['USER_ID'],
-                        ':PERIOD_NUM' => $this->_periodNum
-                    ]
-                );
+//                // 奖金流水
+//                FlowBonus::updateAll(['LAST_EMP_LV' => $nowBsEmpLv], 'USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM',
+//                    [
+//                        ':USER_ID' => $data['USER_ID'],
+//                        ':PERIOD_NUM' => $this->_periodNum
+//                    ]
+//                );
                 // 共享奖流水
                 CalcBonusGX::updateAll(['LAST_EMP_LV' => $nowBsEmpLv], 'USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', 
                     [
@@ -3618,6 +3507,7 @@ class BonusCalc extends BaseObject {
                 $bonus['BONUS_TOTAL'] = $bonus['BONUS_TOTAL'] - $blueBonusGL - $blueBonusYJ;
                 // 共享奖最后一起算,所以总原奖金中,需要加上整个月的数据
                 $bonus['BONUS_TOTAL'] = $bonus['BONUS_TOTAL'] + $oriGxMonthBonus;
+                $empLv = $userBS['LEVEL_ID'] ?? $empLv;
             } else {
                 // 蓝星奖原奖金在扣管理费的时候被加入到了BONUS_TOTAL,需要再减去原奖金
                 $oriBonusBs = isset($bonus['ORI_BONUS_BS']) && $bonus['ORI_BONUS_BS'] > 0 ? $bonus['ORI_BONUS_BS'] : 0;
@@ -3625,6 +3515,7 @@ class BonusCalc extends BaseObject {
                 $oriBonusBsYJCF = isset($bonus['ORI_BONUS_ABBR']) && $bonus['ORI_BONUS_ABBR'] > 0 ? $bonus['ORI_BONUS_ABBR'] : 0;
                 $oriBonusBsGLCF = isset($bonus['ORI_BONUS_MNT']) && $bonus['ORI_BONUS_MNT'] > 0 ? $bonus['ORI_BONUS_MNT'] : 0;
                 $bonus['BONUS_TOTAL'] = $bonus['BONUS_TOTAL'] - $oriBonusBs - $oriBonusBsYJCF - $oriBonusBsGLCF;
+                $empLv = EmployLevel::getDefaultLevelId();
             }
         }
         

+ 172 - 22
common/helpers/bonus/BonusSend.php

@@ -19,6 +19,7 @@ use common\helpers\user\Status;
 use common\libs\api\sms\SmsApi;
 use common\libs\swoole\Process;
 use common\models\DealType;
+use common\models\FlowRemainPv;
 use common\models\PerfPeriod;
 use common\models\DecOrder;
 use common\models\EmployLevel;
@@ -31,6 +32,8 @@ use common\models\UserPerf;
 use common\models\UserPerfUpdate;
 use common\models\UserTeamwork;
 use common\models\YearHighestEmpLv;
+use common\models\Order;
+use common\models\RemainPv;
 use yii\base\BaseObject;
 use yii\base\StaticInstanceTrait;
 use common\helpers\Cache;
@@ -121,6 +124,70 @@ class BonusSend extends BaseObject {
         return $this->_errors;
     }
 
+    /**
+     * 挂网时处理虚假订单
+     *
+     */
+    public function putFakeOrder() {
+        echo('开始处理-假订单' . PHP_EOL);
+        $sysConfig = Cache::getSystemConfig();
+        $mesureUpCondition =  $sysConfig['monthPcsPvFxCondition']['VALUE']; // 月达标条件 NC默认300
+        $fakeOrder= Order::find()->where(['PERIOD_NUM'=>$this->_periodNum, 'IS_AUTO'=>'1'])->asArray()->all();
+//        print_r($fakeOrder);exit;
+        foreach($fakeOrder as $fOrder){
+            $oRemainPv=RemainPv::findOne(["USER_ID"=>$fOrder['USER_ID']]);
+            $transactionRemain = \Yii::$app->db->beginTransaction();
+            try{
+                $fakeOrderPv = $oRemainPv->REMAIN_PV>=$mesureUpCondition?$mesureUpCondition:$oRemainPv->REMAIN_PV;
+                $flowRemainPvModel = new FlowRemainPv();
+                $flowRemainPvModel->ID = $this->_generateSn();
+                $flowRemainPvModel->USER_ID = $fOrder['USER_ID'];
+                $flowRemainPvModel->REMAIN_PV_FLOW = 0 - $fakeOrderPv;
+                $flowRemainPvModel->REMAIN_PV_TOTAL = $oRemainPv->REMAIN_PV - $fakeOrderPv;
+                $flowRemainPvModel->PERIOD_NUM = $this->_periodNum;
+                $flowRemainPvModel->UPDATED_AT = Date::nowTime();
+                $flowRemainPvModel->ORDER_SN = $fOrder['SN'];
+                if(!$flowRemainPvModel->save()){
+                    $this->addErrors($flowRemainPvModel->getErrors());
+                    return false;
+                }
+                $oRemainPv->updateCounters(['REMAIN_PV'=>0-$fakeOrderPv]);
+                $transactionRemain->commit();
+            } catch (Exception $e) {
+                $transactionRemain->rollBack();
+                $this->addError('add', $e->getMessage());
+                return null;
+            }
+        }
+        echo('假订单处理完' . PHP_EOL);
+        return true; // $flowRemainPvModel;
+    }
+    /**
+     * 生成流水号
+     * @return string
+     */
+    private function _generateSn() {
+        return Date::today('Ymd') . $this->_random(10, 1);
+    }
+
+    /**
+     * 生成随机数
+     * @param $length
+     * @param int $numeric
+     * @return string
+     */
+    private function _random($length, $numeric = 0) {
+        $seed = base_convert(md5(microtime() . $_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);
+        $seed = $numeric ? (str_replace('0', '', $seed) . '012340567890') : ($seed . 'zZ' . strtoupper($seed));
+        $hash = '';
+        $max = strlen($seed) - 1;
+        for ($i = 0; $i < $length; $i++) {
+            $hash .= $seed[mt_rand(0, $max)];
+        }
+        return $hash;
+    }
+
+
     /**
      * 进行奖金发放步骤
      * @return bool
@@ -130,6 +197,11 @@ class BonusSend extends BaseObject {
             $t1 = microtime(true);
             // 初始化
             $this->initTask();
+            echo('挂网开始');
+            $this->putFakeOrder();
+            // 先把有remainPv的订单处理一下,将remainPv加入到remain_pv及流水表
+            echo('处理当期REMAIN PV ' . date('Y-m-d  H:i:s', time()) . PHP_EOL);
+            $this->_calcRemainPv();
             $t2 = microtime(true);
             echo('初始化完成,当前期数【' . $this->_periodNum . '】,耗时:' . round($t2 - $t1, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
             // 改变状态
@@ -170,7 +242,7 @@ class BonusSend extends BaseObject {
             // $this->_updatePercent(95);
             // $t9 = microtime(true);
             // echo('更新会员累计月业绩完成,耗时:' . round($t9 - $t8, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
-            
+
             // 开启子进程去完成下面的循环发放和循环改聘级和循环更新累计业绩
             /*$process = new Process('sendBonus', 3);
             $process->run(function($workId, $pmid){
@@ -195,6 +267,58 @@ class BonusSend extends BaseObject {
         return true;
     }
 
+    /**
+     * 处理order表中有remain_pv的订单
+     * 将结果写入到remainPv相关表中
+     *
+     */
+    private function _calcRemainPv(){
+        $sysConfig = Cache::getSystemConfig();
+        $mesureUpCondition =  $sysConfig['monthPcsPvFxCondition']['VALUE']; // 月达标条件 NC默认300
+        $orders = Order::find()->where('PERIOD_NUM=:PERIOD_NUM AND REMAIN_PV>0 AND IS_DELETE=0',[':PERIOD_NUM'=>$this->_periodNum])->asArray()->all();
+        foreach($orders as $order){
+            $oRemainPv = RemainPv::find()->where(['USER_ID' => $order['USER_ID']])->one();
+            $myRemainPv = $oRemainPv?$oRemainPv['REMAIN_PV']:0;
+            $transactionRemain = \Yii::$app->db->beginTransaction();
+            try{
+                $flowRemainPvModel = new FlowRemainPv();
+                $flowRemainPvModel->ID = $this->_generateSn();
+                $flowRemainPvModel->USER_ID = $order['USER_ID'];
+                $flowRemainPvModel->REMAIN_PV_FLOW = $order['REMAIN_PV'];
+                $flowRemainPvModel->REMAIN_PV_TOTAL = $oRemainPv?$oRemainPv['REMAIN_PV']:0 + $order['REMAIN_PV'];
+                $flowRemainPvModel->PERIOD_NUM = $this->_periodNum;
+                $flowRemainPvModel->UPDATED_AT = Date::nowTime();
+                $flowRemainPvModel->ORDER_SN = $order['SN'];
+                if(!$flowRemainPvModel->save()){
+                    $this->addErrors($flowRemainPvModel->getErrors());
+                    return false;
+                }
+
+                $oRemainPv = RemainPv::find()->where(['USER_ID' => $order['USER_ID']])->one();
+                if($oRemainPv){
+                    $oRemainPv->updateCounters(['REMAIN_PV'=>$order['REMAIN_PV']]);
+                }else{
+                    $remainPvModel = new RemainPv();
+                    $remainPvModel->ID = $this->_generateSn();
+                    $remainPvModel->USER_ID = $order['USER_ID'];
+                    $remainPvModel->UPDATED_AT = Date::nowTime();
+                    $remainPvModel->REMAIN_PV = $order['REMAIN_PV'];
+                    $remainPvModel->STATUS = 1;
+                    if(!$remainPvModel->save()){
+                        $this->addErrors($remainPvModel->getErrors());
+                        return false;
+                    }
+                }
+                $transactionRemain->commit();
+            } catch (Exception $e) {
+                $transactionRemain->rollBack();
+                $this->addError('add', $e->getMessage());
+                return null;
+            }
+        }
+        return null;
+    }
+
     /**
      * 需要多进程执行的任务
      * @param $workId
@@ -289,7 +413,7 @@ class BonusSend extends BaseObject {
         $allData = CalcBonus::findUseDbCalc()
         ->yearMonth($this->_calcYearMonth)
         ->where(
-            '(IS_SENT=0 OR IS_SENT=2) AND CALC_MONTH=:CALC_MONTH AND PERIOD_NUM=:PERIOD_NUM', 
+            '(IS_SENT=0 OR IS_SENT=2) AND CALC_MONTH=:CALC_MONTH AND PERIOD_NUM=:PERIOD_NUM',
             [':CALC_MONTH' => $this->_calcYearMonth, ':PERIOD_NUM' => $periodNum]
         )
         ->limit($this->_limit)
@@ -358,12 +482,12 @@ class BonusSend extends BaseObject {
                         ]);
                         // 2022/05/17 复消积分,直接发放到余额账户
                         // Cash::changeUserCash(
-                        //     $data['USER_ID'], 
-                        //     'CASH', 
-                        //     abs($data['RECONSUME_POINTS']), 
+                        //     $data['USER_ID'],
+                        //     'CASH',
+                        //     abs($data['RECONSUME_POINTS']),
                         //     [
                         //     'TRANSFER_SN' => Transfer::generateSN(),
-                        //     'DEAL_TYPE_ID' => DealType::BONUS_SEND, 
+                        //     'DEAL_TYPE_ID' => DealType::BONUS_SEND,
                         //     'REMARK' => '复销点数发放'
                         //     ]
                         // );
@@ -412,7 +536,7 @@ class BonusSend extends BaseObject {
             $allData = CalcBonusBS::findUseDbCalc()
             ->yearMonth($this->_calcYearMonth)
             ->where(
-                'CALC_MONTH=:CALC_MONTH AND PERIOD_NUM=:PERIOD_NUM', 
+                'CALC_MONTH=:CALC_MONTH AND PERIOD_NUM=:PERIOD_NUM',
                 [
                     ':CALC_MONTH' => $this->_calcYearMonth,
                     ':PERIOD_NUM' =>$this->_periodNum
@@ -429,21 +553,29 @@ class BonusSend extends BaseObject {
                 $transaction = Yii::$app->db->beginTransaction();
                 try {
                     foreach ($allData as $data) {
-                        //@todo 用户级别不变则不更新
-                        if( $data['LEVEL_ID'] === $defaultEmpLv ) continue;
-                        $nowBsEmpLv = $data['LEVEL_ID']; // 当前蓝星奖计算(即管理奖) 的等级
+                        // 蓝星奖计算的最新聘级
+                        $latestEmpLv = $data['LEVEL_ID'];    // 本期计算最新管理级别
+                        $latestEmpLvSort = $empLv[$latestEmpLv]; // 当前蓝星计算的聘级 级别值
+                        if ($defaultEmpLv == $latestEmpLv) {
+                            continue;
+                        }
+                        // 用户存储的最高聘级
                         $user = CalcCache::getUserInfo($data['USER_ID'], $this->_periodNum);
-                        $userEmpLv = $user['EMP_LV']; // 用户的历史最高聘级
-                        $userEmpLvSort = $empLv[$userEmpLv]; // 历史最高聘级的 级别值
-                        $nowBsEmpLvSort = $empLv[$nowBsEmpLv]; // 当前蓝星计算的聘级 级别值
-                        if ($nowBsEmpLvSort > $userEmpLvSort) {
-                            // 如果当前期的级别值大于历史最高级别,则更新用户表里的最高聘级
-                            User::updateAll(['EMP_LV' => $data['LEVEL_ID']], 'ID=:USER_ID', [':USER_ID' => $data['USER_ID']]);
+                        $highestEmpLv = $user['EMP_LV']; // 用户的历史最高聘级
+                        $highestEmpLvSort = $empLv[$highestEmpLv]; // 历史最高聘级的 级别值
+                        // 如果当前期的聘级高于用户表的最高聘级,则进行更新
+                        if ($latestEmpLvSort > $highestEmpLvSort) {
+                            User::updateAll(['EMP_LV' => $latestEmpLv], 'ID=:USER_ID', [':USER_ID' => $data['USER_ID']]);
                             User::deleteBaseInfoFromRedis($data['USER_ID']);
-                            unset($data);
-                        } else {
-                            continue;
                         }
+                        // 更新最新用户表级别
+                        User::updateAll([
+                            'LAST_EMP_LV' => $latestEmpLv,
+                            'LAST_EMP_LV_UPDATED_AT' => time(),
+                            'LAST_EMP_LV_UPDATED_PERIOD' => $this->_periodNum
+                        ], 'ID=:USER_ID', [':USER_ID' => $data['USER_ID']]);
+                        User::deleteBaseInfoFromRedis($data['USER_ID']);
+                        unset($data);
                     }
                     $transaction->commit();
                 } catch (Exception $e) {
@@ -454,8 +586,26 @@ class BonusSend extends BaseObject {
                 unset($transaction, $allData, $defaultEmpLv);
                 return $this->updateEmpLevel($offset + $this->_limit);
             }
+
+            // 刷新会员EmpLv为0
+            User::updateAll([
+                'LAST_EMP_LV' => '',
+                'LAST_EMP_LV_UPDATED_AT' => time(),
+                'LAST_EMP_LV_UPDATED_PERIOD' => $this->_periodNum,
+            ], 'LAST_EMP_LV_UPDATED_PERIOD < :PERIOD_NUM AND LAST_EMP_LV <> ""', [':PERIOD_NUM' => $this->_periodNum]);
+            User::deleteAllBaseInfoFromRedis();
+
             unset($allData);
         }
+
+        // 刷新会员EmpLv为0
+        User::updateAll([
+            'LAST_EMP_LV' => '',
+            'LAST_EMP_LV_UPDATED_AT' => time(),
+            'LAST_EMP_LV_UPDATED_PERIOD' => $this->_periodNum,
+        ], 'LAST_EMP_LV_UPDATED_PERIOD < :PERIOD_NUM AND LAST_EMP_LV <> ""', [':PERIOD_NUM' => $this->_periodNum]);
+        User::deleteAllBaseInfoFromRedis();
+
         return true;
     }
 
@@ -499,8 +649,8 @@ class BonusSend extends BaseObject {
     public function updateActiveUser() {
         try {
             $ret = PerfActiveUser::updateAll(
-                ['IS_SENT' => 1], 
-                'PERIOD_NUM=:PERIOD_NUM AND IS_SENT=:IS_SENT', 
+                ['IS_SENT' => 1],
+                'PERIOD_NUM=:PERIOD_NUM AND IS_SENT=:IS_SENT',
                 ['IS_SENT'=>0, 'PERIOD_NUM'=>$this->_periodNum]
             );
 
@@ -930,4 +1080,4 @@ class BonusSend extends BaseObject {
         unset($allData);
         return true;
     }
-}
+}

+ 2 - 1
common/helpers/bonus/CalcCache.php

@@ -24,12 +24,13 @@ use common\models\UserBonus;
 use common\models\UserNetwork;
 use common\models\UserPerf;
 use common\models\UserRelation;
+use common\models\RemainPv;
 use Yii;
 use common\models\UserInfo;
 use yii\helpers\Json;
 
 class CalcCache {
-    const LIMIT = 1000;
+    const LIMIT = 10000;
 
     const REDIS_KEY_PREFIX_USER = 'calc:user_';
     const REDIS_KEY_PREFIX_USER_ACTIVE = 'calc:userActive_';

+ 118 - 20
common/helpers/bonus/PerfCalc.php

@@ -19,6 +19,7 @@ use common\helpers\user\Reconsume;
 use common\models\CalcBonus;
 use common\models\DeclarationLevel;
 use common\models\forms\DeclarationForm;
+use common\models\forms\OrderForm;
 use common\models\Order;
 use common\models\OrderDec;
 use common\models\OrderShop;
@@ -34,13 +35,15 @@ use common\models\EmployLevel;
 use common\models\PerfActiveUser;
 use common\models\StorePerfLog;
 use common\models\UserRelation;
+use common\models\RemainPv;
+use common\models\FlowRemainPv;
 use yii\base\Exception;
 use yii\base\StaticInstanceTrait;
 
 class PerfCalc {
     use StaticInstanceTrait;
 
-    private $_limit = 1000;
+    private $_limit = 10000;
     private $_handleUserId;
     private $_companyMonthPerf = 0;
     private $_cfTotalPercent = 0;
@@ -106,6 +109,112 @@ class PerfCalc {
         return $this->_errors;
     }
 
+    /**
+     * 生成流水号
+     * @return string
+     */
+    private function _generateSn() {
+        return Date::today('Ymd') . $this->_random(10, 1);
+    }
+
+    /**
+     * 生成随机数
+     * @param $length
+     * @param int $numeric
+     * @return string
+     */
+    private function _random($length, $numeric = 0) {
+        $seed = base_convert(md5(microtime() . $_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);
+        $seed = $numeric ? (str_replace('0', '', $seed) . '012340567890') : ($seed . 'zZ' . strtoupper($seed));
+        $hash = '';
+        $max = strlen($seed) - 1;
+        for ($i = 0; $i < $length; $i++) {
+            $hash .= $seed[mt_rand(0, $max)];
+        }
+        return $hash;
+    }
+
+    /**
+     * 处理order表中有remain_pv的订单
+     * 将结果写入到remainPv相关表中
+     *
+     */
+    private function _calcRemainPv(){
+        $orders = Order::find()->where('PERIOD_NUM=:PERIOD_NUM AND REMAIN_PV>0',[':PERIOD_NUM'=>$this->_periodNum])->asArray()->all();
+        foreach($orders as $order){
+            $oRemainPv = RemainPv::find()->where(['USER_ID' => $order['USER_ID']])->one();
+
+            $transactionRemain = \Yii::$app->db->beginTransaction();
+            try{
+                $flowRemainPvModel = new FlowRemainPv();
+                $flowRemainPvModel->ID = $this->_generateSn();
+                $flowRemainPvModel->USER_ID = $order['USER_ID'];
+                $flowRemainPvModel->REMAIN_PV_FLOW = $order['REMAIN_PV'];
+                $flowRemainPvModel->REMAIN_PV_TOTAL = $oRemainPv['REMAIN_PV'] + $order['REMAIN_PV'];
+                $flowRemainPvModel->PERIOD_NUM = $this->_periodNum;
+                $flowRemainPvModel->UPDATED_AT = Date::nowTime();
+                $flowRemainPvModel->ORDER_SN = $order['SN'];
+                if(!$flowRemainPvModel->save()){
+                    $this->addErrors($flowRemainPvModel->getErrors());
+                    return false;
+                }
+
+                $oRemainPv = RemainPv::find()->where(['USER_ID' => $order['USER_ID']])->one();
+                if($oRemainPv){
+                    $oRemainPv->updateCounters(['REMAIN_PV'=>$order['REMAIN_PV']]);
+                }else{
+                    $remainPvModel = new RemainPv();
+                    $remainPvModel->ID = $this->_generateSn();
+                    $remainPvModel->USER_ID = $order['USER_ID'];
+                    $remainPvModel->UPDATED_AT = Date::nowTime();
+                    $remainPvModel->REMAIN_PV = $order['REMAIN_PV'];
+                    $remainPvModel->STATUS = 1;
+                    if(!$remainPvModel->save()){
+                        $this->addErrors($remainPvModel->getErrors());
+                        return false;
+                    }
+                }
+                $transactionRemain->commit();
+            } catch (Exception $e) {
+                $transactionRemain->rollBack();
+                $this->addError('add', $e->getMessage());
+                return null;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 生成假订单
+     *
+     */
+    public static function _createFakeOrder($periodNum){
+        echo('假假假'.$periodNum. PHP_EOL);
+        $sysConfig = Cache::getSystemConfig();
+        $mesureUpCondition =  $sysConfig['monthPcsPvFxCondition']['VALUE']; // 月达标条件 NC默认300
+        $userHaveRemain = RemainPv::findAllAsArray('REMAIN_PV >=:MESURE_UP',[':MESURE_UP'=>$mesureUpCondition]);
+        $currentPeriod = Period::getInfoByPeriodNum($periodNum);
+        $sysConfig = Cache::getSystemConfig();
+        $mesureUpCondition =  $sysConfig['monthPcsPvFxCondition']['VALUE']; // 月达标条件 NC默认300
+        if($currentPeriod['IS_MONTH']){
+            print_r('是月结点'.PHP_EOL);
+            $periods = Period::getCurrentMonthPeriodByPeriodNum($periodNum);
+            //先清除本期的假订单
+            echo('首先,清除上次尝试生成业绩单时所创建的虚假订单'. date('Y-m-d  H:i:s', time()) . PHP_EOL);
+            $delFOrder = Order::deleteAll(['IS_AUTO'=>'1','PERIOD_NUM'=>$periodNum]);
+            echo('检查有结余PV的用户,如果他当月PV不足'.$mesureUpCondition.',则为其创建假订单'. PHP_EOL);
+            foreach($userHaveRemain as $uR){
+                $myPv = Order::find()->where(['PERIOD_NUM'=>$periods, 'USER_ID'=>$uR['USER_ID']])->SUM('PV');
+                if($myPv < $mesureUpCondition){
+                    //制造虚拟订单
+                    echo('不足'.$mesureUpCondition.'了,生成假订单' . PHP_EOL);
+                    $newOrderForm = new OrderForm();
+                    $newOrderForm->addFakeOrder($uR['USER_ID'],$periodNum);
+                }
+            }
+        }
+    }
+
     /**
      * 计算步骤
      * @param $periodNum
@@ -129,9 +238,14 @@ class PerfCalc {
             // 清空相关表数据
             $this->clearTableData();
             $t2 = microtime(true);
+            echo(PHP_EOL . $periodNum. '期,生成业绩单,开始' . PHP_EOL);
             echo('初始化、清空缓存及相关数据表完成,耗时:' . round($t2 - $t1, 3) . ',内存使用:' . (round(memory_get_usage() / 1024 / 1024, 3)) . 'MB' . PHP_EOL);
             $this->_updatePercent(10);
             // 计算月奖,才需要向缓存中加入按推荐深度的所有用户
+            echo('向缓存中加入用户开始 ' . date('Y-m-d  H:i:s', time()) . PHP_EOL);
+            echo('若需要,生成假订单' . date('Y-m-d  H:i:s', time()) . PHP_EOL);
+            $this->_createFakeOrder($periodNum);
+            echo('生成假订单完成,开始缓存用户'. date('Y-m-d  H:i:s', time()) . PHP_EOL);
             //修改每一期都缓存所有用户
             CalcCache::addUsers($this->_periodNum);
             $t3 = microtime(true);
@@ -963,16 +1077,7 @@ class PerfCalc {
                 $periodPerf = CalcCache::nowPeriodPerf($userId, $this->_periodNum);
 
                 $userBaseInfo = CalcCache::getUserInfo($userId, $this->_periodNum);
-                //级别必须为VIP
-                $isVip = false;
-                if( $userBaseInfo['DEC_LV'] === DeclarationLevel::VIP_LEVEL_ID ) {
-                    $isVip= true;
-                }
-                if( $this->_sysConfig['vipBonusGoldDecLevel']['VALUE'] && $userBaseInfo['DEC_LV'] === DeclarationLevel::JIN_ZUAN_LEVEL_ID ) {
-                    $isVip = true;
-                }
-
-
+                
                 $nowMonthPerf = [
                     'USER_ID' => $userId,
                     'FX_AMOUNT_CASH' => $everyData['FX_AMOUNT_CASH_SUM'],
@@ -985,13 +1090,6 @@ class PerfCalc {
                     'PV_4L' => $everyData['PV_4L_SUM'],
                     'PV_5L' => $everyData['PV_5L_SUM'],
 
-                    //VIP统计相关业绩
-                    'VIP_PV_1L_ZC' => $isVip ? $everyData['PV_1L_ZC_SUM'] : 0,
-                    'VIP_PV_2L_ZC' => $isVip ? $everyData['PV_2L_ZC_SUM'] : 0,
-                    'VIP_PV_3L_ZC' => $isVip ? $everyData['PV_3L_ZC_SUM'] : 0,
-                    'VIP_PV_4L_ZC' => $isVip ? $everyData['PV_4L_ZC_SUM'] : 0,
-                    'VIP_PV_5L_ZC' => $isVip ? $everyData['PV_5L_ZC_SUM'] : 0,
-
                     //总数据,历史+本期。不能用上月加本月,因为上月可能没业绩,上上个月有业绩。
                     'PV_1L_TOTAL' => $periodPerf['PV_1L'] + $userLastPerf['PV_1L'],
                     'PV_2L_TOTAL' => $periodPerf['PV_2L'] + $userLastPerf['PV_2L'],
@@ -1005,7 +1103,7 @@ class PerfCalc {
                 CalcCache::addHasMonthPerfUsers($userId, $this->_periodNum);
                 CalcCache::nowMonthPerf($userId, $this->_periodNum, $nowMonthPerf);
 
-                unset($userId, $everyData, $nowMonthPerf, $lastMonthData, $userBaseInfo, $isVip);
+                unset($userId, $everyData, $nowMonthPerf, $lastMonthData, $userBaseInfo);
             }
             unset($allData);
             $this->loopCalcMonthPerfTableData($offset + $this->_limit);
@@ -1678,4 +1776,4 @@ class PerfCalc {
         \Yii::$app->swooleAsyncTimer->pushAsyncPercentToAdmin($percent, ['MODEL' => 'PERIOD', 'ID' => $this->_periodId, 'FIELD' => 'PERF_PERCENT']);
     }
 
-}
+}

+ 3 - 32
common/helpers/bonus/PreparePerfCalc.php

@@ -844,14 +844,7 @@ class PreparePerfCalc {
                 $periodPerf = PrepareCalcCache::nowPeriodPerf($userId, $this->_periodNum);
 
                 $userBaseInfo = PrepareCalcCache::getUserInfo($userId, $this->_periodNum);
-                //级别必须为VIP
-                $isVip = false;
-                if( $userBaseInfo['DEC_LV'] === DeclarationLevel::VIP_LEVEL_ID ) {
-                    $isVip= true;
-                }
-                if( $this->_sysConfig['vipBonusGoldDecLevel']['VALUE'] && $userBaseInfo['DEC_LV'] === DeclarationLevel::JIN_ZUAN_LEVEL_ID ) {
-                    $isVip = true;
-                }
+
                 // 查询月节点此期业绩,是否包含此用户
                 // 查询perfperiodprepare表中数据,是否有此用户信息.因为是月提前结算,所以此结算期是只有一个数据
                 $monthPrepare = PerfPeriodPrepare::findUseDbCalc()
@@ -903,13 +896,6 @@ class PreparePerfCalc {
                     'PV_4L' => $everyData['PV_4L_SUM'],
                     'PV_5L' => $everyData['PV_5L_SUM'],
 
-                    //VIP统计相关业绩
-                    'VIP_PV_1L_ZC' => $isVip ? $everyData['PV_1L_ZC_SUM'] : 0,
-                    'VIP_PV_2L_ZC' => $isVip ? $everyData['PV_2L_ZC_SUM'] : 0,
-                    'VIP_PV_3L_ZC' => $isVip ? $everyData['PV_3L_ZC_SUM'] : 0,
-                    'VIP_PV_4L_ZC' => $isVip ? $everyData['PV_4L_ZC_SUM'] : 0,
-                    'VIP_PV_5L_ZC' => $isVip ? $everyData['PV_5L_ZC_SUM'] : 0,
-
                     //总数据,历史+本期。不能用上月加本月,因为上月可能没业绩,上上个月有业绩。
                     'PV_1L_TOTAL' => $periodPerf['PV_1L'] + $userLastPerf['PV_1L'],
                     'PV_2L_TOTAL' => $periodPerf['PV_2L'] + $userLastPerf['PV_2L'],
@@ -923,7 +909,7 @@ class PreparePerfCalc {
                 PrepareCalcCache::addHasMonthPerfUsers($userId, $this->_periodNum);
                 PrepareCalcCache::nowMonthPerf($userId, $this->_periodNum, $nowMonthPerf);
 
-                unset($userId, $everyData, $nowMonthPerf, $lastMonthData, $userBaseInfo, $isVip);
+                unset($userId, $everyData, $nowMonthPerf, $lastMonthData, $userBaseInfo);
             }
             unset($allData);
             return $this->loopCalcMonthPerfTableData($offset + $this->_limit);
@@ -977,14 +963,6 @@ class PreparePerfCalc {
                 $periodPerf = PrepareCalcCache::nowPeriodPerf($userId, $this->_periodNum);
 
                 $userBaseInfo = PrepareCalcCache::getUserInfo($userId, $this->_periodNum);
-                //级别必须为VIP
-                $isVip = false;
-                if( $userBaseInfo['DEC_LV'] === DeclarationLevel::VIP_LEVEL_ID ) {
-                    $isVip= true;
-                }
-                if( $this->_sysConfig['vipBonusGoldDecLevel']['VALUE'] && $userBaseInfo['DEC_LV'] === DeclarationLevel::JIN_ZUAN_LEVEL_ID ) {
-                    $isVip = true;
-                }
 
                 $nowMonthPerf = [
                     'USER_ID' => $userId,
@@ -998,13 +976,6 @@ class PreparePerfCalc {
                     'PV_4L' => $everyData['PV_4L_SUM'],
                     'PV_5L' => $everyData['PV_5L_SUM'],
 
-                    //VIP统计相关业绩
-                    'VIP_PV_1L_ZC' => $isVip ? $everyData['PV_1L_ZC_SUM'] : 0,
-                    'VIP_PV_2L_ZC' => $isVip ? $everyData['PV_2L_ZC_SUM'] : 0,
-                    'VIP_PV_3L_ZC' => $isVip ? $everyData['PV_3L_ZC_SUM'] : 0,
-                    'VIP_PV_4L_ZC' => $isVip ? $everyData['PV_4L_ZC_SUM'] : 0,
-                    'VIP_PV_5L_ZC' => $isVip ? $everyData['PV_5L_ZC_SUM'] : 0,
-
                     //总数据,历史+本期。不能用上月加本月,因为上月可能没业绩,上上个月有业绩。
                     'PV_1L_TOTAL' => $periodPerf['PV_1L'] + $userLastPerf['PV_1L'],
                     'PV_2L_TOTAL' => $periodPerf['PV_2L'] + $userLastPerf['PV_2L'],
@@ -1027,7 +998,7 @@ class PreparePerfCalc {
                 );
 
 
-                unset($userId, $everyData, $nowMonthPerf, $lastMonthData, $userBaseInfo, $isVip);
+                unset($userId, $everyData, $nowMonthPerf, $lastMonthData, $userBaseInfo);
             }
             unset($allData);
             return $this->loopCalcMonthPerfTableDataPrepare($offset + $this->_limit);

+ 1 - 1
common/helpers/user/Balance.php

@@ -458,7 +458,7 @@ class Balance {
             $flowInsertData = [
                 'USER_ID' => $userId,
                 'LAST_DEC_LV' => $userInfo['DEC_LV'],
-                'LAST_EMP_LV' => $userInfo['EMP_LV'],
+                'LAST_EMP_LV' => $userInfo['LAST_EMP_LV'],
                 'LAST_STATUS' => $userInfo['STATUS'],
                 'CALC_ID' => $params['CALC_ID'] ?? null,
                 'AMOUNT' => $amount,

+ 1 - 1
common/helpers/user/Info.php

@@ -604,7 +604,7 @@ class Info {
      * @return array|null
      */
     public static function getLastInfo($userId){
-        $data = User::findOneAsArray('ID=:ID', [':ID' => $userId], 'LAST_DEC_LV AS DEC_LV,EMP_LV,STATUS');
+        $data = User::findOneAsArray('ID=:ID', [':ID' => $userId], 'LAST_DEC_LV AS DEC_LV,EMP_LV,LAST_EMP_LV,STATUS');
         return $data;
     }
 

+ 38 - 0
common/libs/taskQueue/TaskFunc.php

@@ -6,6 +6,8 @@ namespace common\libs\taskQueue;
 
 use common\helpers\Cache;
 use common\helpers\Date;
+use common\helpers\DingTalk;
+use common\helpers\LoggerTool;
 use common\models\forms\HistoryBonusForm;
 use common\models\TaskQueue;
 use SebastianBergmann\CodeCoverage\Report\PHP;
@@ -42,4 +44,40 @@ class TaskFunc
     public static function testTaskQueue(){
         print_r('执行到测试任务'.PHP_EOL);
     }
+
+    /**
+     * 初始化自动发送钉钉提醒任务
+     */
+//    public static function initAutoSendDingTalk() {
+//        // 查看数据库中是否存在未开始的任务,如果没有就添加一个新任务
+//        if(!TaskQueue::find()->where('TYPE=:TYPE AND CONTENT=:CONTENT AND STARTED_AT>:STARTED_AT', [':TYPE'=>Queue::TYPE_FUNC, ':CONTENT'=>TaskFunc::class.'::autoSendDingTalkTable', ':STARTED_AT'=>Date::nowTime()])->asArray()->exists()){
+//            // 获取站点配置中的备份时间
+//            $config = Cache::getSystemConfig();
+//            $sendDingTalkTime = $config['sendDingTalkTime']['VALUE'];
+//            Queue::instance()->addTask(Queue::TYPE_FUNC, TaskFunc::class.'::autoSendDingTalkTable', [], Queue::LOOP_TYPE_DAY, $sendDingTalkTime, 0);
+//        }
+//    }
+
+    /**
+     * 自动送钉钉提醒
+     */
+//    public static function autoSendDingTalkTable() {
+//        $ip = 'https://fapi.ekhkad.com';
+////        $ip = 'http://16.163.228.151:8013';
+//        $curl = curl_init();
+//        curl_setopt($curl, CURLOPT_URL, $ip . '/v1/site/send-notice');
+//        curl_setopt($curl, CURLOPT_TIMEOUT, 5000);
+//        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
+//        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
+//        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+//        $res = curl_exec($curl);
+//        if ($res) {
+//            curl_close($curl);
+//            LoggerTool::info($res);
+//        } else {
+//            $error = curl_errno($curl);
+//            curl_close($curl);
+//            LoggerTool::error($error);
+//        }
+//    }
 }

+ 245 - 0
common/models/BaiduRegion.php

@@ -0,0 +1,245 @@
+<?php
+
+namespace common\models;
+
+use common\models\Region;
+use sunmoon\phpspreadsheet\Excel;
+
+class BaiduRegion extends \common\components\ActiveRecord
+{
+    /**
+     * {@inheritdoc}
+     */
+    public static function tableName()
+    {
+        return '{{%BAIDU_REGION}}';
+    }
+
+    public static function importXls($startRow, $limit, $offset=0){
+//        $offset = 0;
+        $inData = BaiduRegion::getXlsData($startRow, $limit);
+        if($inData){
+            $offset += $limit;
+//            print_r($inData);
+//            print_r("插入数据");
+            BaiduRegion::batchInsert($inData);
+            unset($inData);
+            self::importXls($startRow+$offset, $limit);
+        }
+    }
+
+    public static function getXlsData($startRow, $limit) {
+        $filePath = \Yii::getAlias('@common/runtime/uploads/area.xlsx');
+        $tempFileName = \Yii::getAlias('@common/runtime/uploads/' . 'importTemp.txt');
+        $xlsData = Excel::import($filePath, [
+            'setFirstRecordAsKeys' => true,
+            'readStartRow' => $startRow + 1,
+            'readEndRow' => $startRow + $limit,
+            'storeFile' => $tempFileName,
+            'dropKeysRow' => $startRow == 1 ? false : true,
+        ]);
+        $dataArray = [];
+        foreach ($xlsData as $dl) {
+            if ($dl['乡镇代码']) {
+                $dataArray[] = [
+                    'PROV_NAME' => $dl['省份名称'],
+                    'PROV_CODE' => $dl['省份代码'],
+                    'CITY_NAME' => $dl['城市名称'],
+                    'CITY_CODE' => $dl['城市代码'],
+                    'COUNTY_NAME' => $dl['区县名称'],
+                    'COUNTY_CODE' => $dl['区县代码'],
+                    'TOWN_NAME' => $dl['乡镇名称'],
+                    'TOWN_CODE' => $dl['乡镇代码'],
+                ];
+            }else{
+                break;
+            }
+        }
+        return $dataArray;
+    }
+
+    public static function _getAllNcRegion() {
+        $ncRegion = Region::find()->select("REGION_CODE, REGION_NAME, PID, DEEP")
+            ->where("STATUS = 1 AND DEEP <= 5")
+            ->orderBy("REGION_CODE")
+            ->asArray()->all();
+        return $ncRegion;
+    }
+
+    public static function _getBdProv() {
+        $bdProv = self::find()->select('PROV_CODE,PROV_NAME')
+//            ->where("CITY_CODE like :CITY_CODE", [':CITY_CODE'=>'%00'])
+//            ->andWhere("PROV_CODE !=:PROV_CODE", [':PROV_CODE'=>'710000'])
+            ->groupBy('PROV_CODE')
+            ->asArray()->all();
+        return $bdProv;
+    }
+
+    public static function _getBdCity() {
+        $bdCity = self::find()->select('CITY_CODE,CITY_NAME,PROV_CODE')
+            ->where("PROV_CODE <=:PROV_CODE", [':PROV_CODE'=>800000])
+            ->groupBy('CITY_CODE')
+            ->asArray()->all();
+        return $bdCity;
+    }
+
+    public static function _getBdCounty() {
+        $bdCounty = self::find()->select('COUNTY_CODE,COUNTY_NAME,CITY_CODE')
+            ->where("PROV_CODE <=:PROV_CODE", [':PROV_CODE'=>800000])
+            ->groupBy('COUNTY_CODE')
+            ->asArray()->all();
+        return $bdCounty;
+    }
+
+    public static function _getBdTown() {
+        $bdTown = self::find()->select('TOWN_CODE,TOWN_NAME,COUNTY_CODE')
+            ->where(["in","CITY_CODE",[
+                '419001', '429004', '429005', '429006', '429021', // 济源、仙天潜神
+                '441900', '442000', '460400', '469001', '620200', // 东莞、中山、儋州、嘉峪关
+                '469001','469002','469005','469006','469007','469021','469022','469023','469024','469025','469026','469027','469028','469029','469030', // 海南
+                '659001', '659002', '659003', '659004', '659005', '659006', '659007', '659008', '659009', // 石河子、阿拉尔、图木舒克、五家渠、北屯、铁门关、双河、可克达拉、昆玉
+                '659010', '659011', // 胡杨河、新星市
+            ]])
+            ->asArray()->all();
+        return $bdTown;
+    }
+
+    public static function _checkInNc($region_code){
+        $p = Region::find()->select('REGION_CODE, REGION_NAME')
+            ->where('STATUS = 1 AND REGION_CODE = :REGION_CODE', [':REGION_CODE'=>$region_code])
+            ->asArray()->one();
+        return $p;
+    }
+
+    public static function addNcRegion($region_code, $region_name, $pid, $deep){
+        $newRegion = new Region();
+        $newRegion->REGION_CODE = $region_code;
+        $newRegion->REGION_NAME = $region_name;
+        $newRegion->PID = $pid;
+        $newRegion->DEEP = $deep;
+        $newRegion->STATUS = 1;
+        return $newRegion->save();
+    }
+
+    public static function _checkInBd($region_code, $region_name, $pid, $deep) {
+        $ncOtherRegion = [
+            '419001', '429004', '429005', '429006', '429021', // 济源,仙天潜神
+//            '441900', '442000', '460400', '469001', '620200', // 东莞、中山、儋州、嘉峪关
+            '469001','469002','469005','469006','469007','469021','469022','469023','469024','469025','469026','469027','469028','469029','469030', // 海南
+            '659001', '659002', '659003', '659004', '659005', '659006', '659007', '659008', '659009', // 石河子、阿拉尔、图木舒克、五家渠、北屯、铁门关、双河、可克达拉、昆玉
+            '659010', '659011', // 胡杨河、新星市
+        ];
+        $ret = [];
+        if ($deep==2){ // 省级
+            $t = BaiduRegion::find()->select('PROV_CODE, PROV_NAME')
+                ->where("PROV_CODE = :PROV_CODE", [':PROV_CODE'=>$region_code])
+//                ->orderBy('PROV_CODE')->groupBy('PROV_CODE')
+                ->asArray()->one();
+            if($t){
+                $ret = [
+                    'REGION_CODE' => $region_code
+                ];
+                $ret['REGION_NAME'] = $t['PROV_NAME'];
+                $ret['PID'] = '1';
+            }
+
+        }else if($deep==3){ // 地级
+            $t = BaiduRegion::find()->select('CITY_CODE, CITY_NAME, PROV_CODE')
+                ->where("CITY_CODE = :CITY_CODE", [':CITY_CODE'=>$region_code])
+//                ->orderBy('CITY_CODE')->groupBy('CITY_CODE')
+                ->asArray()->one();
+            if($t){
+                $ret = [
+                    'REGION_CODE' => $region_code
+                ];
+                $ret['REGION_NAME'] = $t['CITY_NAME'];
+                $ret['PID'] = $t['PROV_CODE'];
+            }
+
+        }else if($deep==4){ // 县级
+            $t = BaiduRegion::find()->select('COUNTY_CODE, COUNTY_NAME, CITY_CODE, PROV_CODE')
+                ->where("COUNTY_CODE = :COUNTY_CODE", [':COUNTY_CODE'=>$region_code])
+//                ->orderBy('COUNTY_CODE')->groupBy('COUNTY_CODE')
+                ->asArray()->one();
+            if($t){
+                $ret = [
+                    'REGION_CODE' => $region_code
+                ];
+                $ret['REGION_NAME'] = $t['COUNTY_NAME'];
+                $ret['PID'] = $t['CITY_CODE'];
+                if(in_array($region_code, $ncOtherRegion)){
+                    $ret['PID'] = $t['PROV_CODE'];
+                }
+            }
+
+        }else if($deep==5){ // 乡镇
+            $t = BaiduRegion::find()->select('TOWN_CODE, TOWN_NAME, COUNTY_CODE')
+                ->where("TOWN_CODE = :TOWN_CODE", [':TOWN_CODE'=>$region_code])
+//                ->orderBy('COUNTY_CODE')->groupBy('COUNTY_CODE')
+                ->asArray()->one();
+            if($t){
+                $ret = [
+                    'REGION_CODE' => $region_code
+                ];
+                $ret['REGION_NAME'] = $t['TOWN_NAME'];
+                $ret['PID'] = $t['COUNTY_CODE'];
+            }
+
+        }
+        if(!$t){
+            $ret = null;
+        }
+        return $ret;
+    }
+
+    // 构建js用到:
+
+    public static function _getAllNcProv() {
+        $ncRegion = Region::find()->select("REGION_CODE, REGION_NAME, PID, DEEP")
+            ->where("STATUS = 1 AND DEEP = 2")
+            ->orderBy("REGION_CODE")
+            ->asArray()->all();
+        return $ncRegion;
+    }
+
+    public static function _getAllNcCity() {
+        $ncRegion = Region::find()->select("REGION_CODE, REGION_NAME, PID, DEEP")
+            ->where("STATUS = 1 AND DEEP = 3 AND REGION_CODE!='999900'")
+            ->orderBy("REGION_CODE")
+            ->asArray()->all();
+        return $ncRegion;
+    }
+
+    public static function _getAllNcCounty() {
+        $ncRegion = Region::find()->select("REGION_CODE, REGION_NAME, PID, DEEP")
+            ->where(['in', 'REGION_CODE', [
+                '419001', '429004', '429005', '429006', '429021', // 济源、仙天潜神
+//                '441900', '442000', '460400', '469001', '620200', // 东莞、中山、儋州、嘉峪关
+                '469001','469002','469005','469006','469007','469021','469022','469023','469024','469025','469026','469027','469028','469029','469030', // 海南
+                '659001', '659002', '659003', '659004', '659005', '659006', '659007', '659008', '659009', // 石河子、阿拉尔、图木舒克、五家渠、北屯、铁门关、双河、可克达拉、昆玉
+                '659010', '659011', // 胡杨河、新星市
+            ]])
+            ->andWhere("STATUS = 1 AND DEEP = 4")
+            ->orderBy("REGION_CODE")
+            ->asArray()->all();
+        return $ncRegion;
+    }
+
+    public static function _getAllNcCountyByCity($pid) {
+        $ncRegion = Region::find()->select("REGION_CODE, REGION_NAME, PID, DEEP")
+            ->where("STATUS = 1 AND PID = :PID", [':PID'=>$pid])
+            ->orderBy("REGION_CODE")
+            ->asArray()->all();
+        return $ncRegion;
+    }
+
+    public static function _getAllNcTownByCity($pid) {
+        $ncRegion = Region::find()->select("REGION_CODE, REGION_NAME, PID, DEEP")
+            ->where("STATUS = 1 AND DEEP = 5 AND PID = :PID", [':PID'=>$pid])
+            ->orderBy("REGION_CODE")
+            ->asArray()->all();
+        return $ncRegion;
+    }
+
+
+}

+ 3 - 3
common/models/BalanceAudit.php

@@ -32,11 +32,11 @@ class BalanceAudit extends \common\components\ActiveRecord
     const TYPE = [
         'bonus' => [
             'name' => 'bonus',
-            'label' => '会员账户奖金',
+            'label' => '奖金账户',
         ],
         'reconsume_points' => [
             'name' => 'reconsume_points',
-            'label' => '复销点数',
+            'label' => '复消积分',
         ],
         'exchange_points' => [
             'name' => 'exchange_points',
@@ -44,7 +44,7 @@ class BalanceAudit extends \common\components\ActiveRecord
         ],
         'cash' => [
             'name' => 'cash',
-            'label' => '会员账户余额',
+            'label' => '充值账户',
         ],
 //        'cf' => [
 //            'name' => 'cf',

+ 1 - 0
common/models/Config.php

@@ -83,6 +83,7 @@ class Config extends \common\components\ActiveRecord
      * @return array|mixed|\yii\db\ActiveRecord[]
      */
     public static function getFromCache(){
+//        Yii::$app->cache->delete(Cache::SYSTEM_CONFIG_KEY);
         $config = Yii::$app->cache->get(Cache::SYSTEM_CONFIG_KEY);
         if(!$config){
             // 获取配置

+ 1 - 1
common/models/DeclarationPackage.php

@@ -110,7 +110,7 @@ class DeclarationPackage extends \common\components\ActiveRecord
      * @return array|\yii\db\ActiveRecord[]
      */
     public static function getAllData(){
-        return static::find()->where('IS_DEL=0 AND STATUS=1')->indexBy('ID')->orderBy('ID ASC')->asArray()->all();
+        return static::find()->where('IS_DEL=0 AND STATUS=1')->indexBy('ID')->orderBy('SORT ASC')->asArray()->all();
     }
 
     /**

+ 25 - 0
common/models/FlowRemainPv.php

@@ -0,0 +1,25 @@
+<?php
+namespace common\models;
+
+use Yii;
+
+/**
+ * This is the model class for table "{{%FLOW_REMAIN_PV}}".
+ *
+ * @property string $ID
+ * @property string $USER_ID 会员ID
+ * @property int $REMAIN_PV_FLOW 剩余BV FLOW
+ * @property int $UPDATED_AT 更新时间
+ * @property varchar $ORDER_SN 订单SN号
+ */
+class FlowRemainPv extends \common\components\ActiveRecord
+{
+    /**
+     * @inheritdoc
+     */
+    public static function tableName()
+    {
+        return '{{%FLOW_REMAIN_PV}}';
+    }
+
+}

+ 26 - 0
common/models/Order.php

@@ -126,4 +126,30 @@ class Order extends \common\components\ActiveRecord
             'WAREHOUSE' => '发货仓',
         ];
     }
+    /*
+     * 通过 期数和用户ID
+     * 查询当月订单
+     */
+    public static function fetchOrderCurrentMonth($periodNum, $userId){
+        $currentPeriod = Period::findOneAsArray("PERIOD_NUM = :PERIOD_NUM", [':PERIOD_NUM' => $periodNum]);
+
+        switch ($currentPeriod['WEEK_NUMBER']){
+            case 1:
+                $periods = [$periodNum];
+                break;
+            case 2:
+                $periods = [$periodNum-1, $periodNum];
+                break;
+            case 3:
+                $periods = [$periodNum-2, $periodNum-1, $periodNum];
+                break;
+            case 4:
+                $periods = [$periodNum-3, $periodNum-2, $periodNum-1, $periodNum];
+                break;
+        }
+
+        $periodsStr = implode(",", $periods);
+        $orders = Order::find()->where("USER_ID = :USER_ID AND PERIOD_NUM IN ($periodsStr)", [':USER_ID' => $userId]);
+        return $orders;
+    }
 }

+ 27 - 2
common/models/Period.php

@@ -580,8 +580,16 @@ class Period extends \common\components\ActiveRecord
         if($period){
             $year = $period['CALC_YEAR'];
             $month = $period['CALC_MONTH'];
-            $lastYear = Date::lastMonth($year.'-'.$month, 'Y');
-            $lastMonth = Date::lastMonth($year.'-'.$month, 'm');
+            if($month=='13'){
+                $lastYear = $year;
+                $lastMonth = '12';
+            } else if($month=='1'){
+                $lastYear = Date::lastMonth($year.'-'.$month,'Y');
+                $lastMonth = '13';
+            } else {
+                $lastYear = Date::lastMonth($year.'-'.$month, 'Y');
+                $lastMonth = Date::lastMonth($year.'-'.$month, 'm');
+            }
             return [
                 'year' => $lastYear,
                 'month' => intval($lastMonth),
@@ -831,4 +839,21 @@ class Period extends \common\components\ActiveRecord
     public static function getMonthNum($startPeriodNum,$endPeriodNum){
         return self::find()->select('CALC_MONTH')->groupBy('CALC_MONTH')->where('PERIOD_NUM>=:START_PERIOD AND PERIOD_NUM<=:END_PERIOD',[':START_PERIOD'=>$startPeriodNum,':END_PERIOD'=>$endPeriodNum])->count();
     }
+
+    /**
+     * 从期数获取当前月的所有期
+     *
+     */
+    public static function getCurrentMonthPeriodByPeriodNum($periodNum){
+        $currentPeriod = self::getInfoByPeriodNum($periodNum);
+        $currentYear = $currentPeriod['CALC_YEAR'];
+        $currentMonth = $currentPeriod['CALC_MONTH'];
+        $periodsArray = self::findAllAsArray(['CALC_YEAR'=>$currentYear,'CALC_MONTH'=>$currentMonth]);
+        $periods = [];
+        foreach ($periodsArray as $p){
+            $periods[] = $p['PERIOD_NUM'];
+        }
+
+        return $periods;
+    }
 }

+ 22 - 0
common/models/RemainPv.php

@@ -0,0 +1,22 @@
+<?php
+namespace common\models;
+
+use Yii;
+
+/**
+ * This is the model class for table "{{%REMAIN_PV}}".
+ *
+ * @property string $USER_ID 会员ID
+ * @property int $REMAIN_PV 剩余BV
+ * @property int $UPDATED_AT 更新时间
+ */
+class RemainPv extends \common\components\ActiveRecord
+{
+    /**
+     * @inheritdoc
+     */
+    public static function tableName()
+    {
+        return '{{%REMAIN_PV}}';
+    }
+}

+ 70 - 10
common/models/User.php

@@ -6,6 +6,7 @@ use common\helpers\Cache;
 use common\helpers\Tool;
 use common\helpers\user\Info;
 use Yii;
+use yii\data\Pagination;
 use yii\helpers\Json;
 use common\libs\logging\operate\valueType\Config as ValueTypeConfig;
 
@@ -224,6 +225,10 @@ class User extends \common\components\ActiveRecord
         return $this->hasOne(UserInfo::class, ['USER_ID' => 'ID']);
     }
 
+    public static function checkUser($userName){
+        return self::find()->select('ID')->where('USER_NAME=:USER_NAME', [':USER_NAME'=>$userName])->asArray()->one();
+    }
+
     /**
      * 获取会员基本信息
      * @param $userId
@@ -267,6 +272,14 @@ class User extends \common\components\ActiveRecord
         Yii::$app->redis->hdel(Cache::USER_INFO_KEY, $userId);
     }
 
+    /**
+     * 批量删除用户
+     * @return void
+     */
+    public static function deleteAllBaseInfoFromRedis() {
+        Yii::$app->redis->del(Cache::USER_INFO_KEY);
+    }
+
     /**
      * 获取会员的部分信息并对敏感信息加密
      * @param $userId
@@ -391,7 +404,7 @@ class User extends \common\components\ActiveRecord
         }
     }
 
-    
+
     /**
      *  判断用户是否是观察期
      *  观望期:自加入算起2个月
@@ -416,10 +429,10 @@ class User extends \common\components\ActiveRecord
     public static function sumDevPvByUserId($userId) {
         $decOrderPv = DecOrder::find()
         ->select('SUM(DEC_PV) AS PV_SUM')
-        ->where('TO_USER_ID=:TO_USER_ID AND IS_DEL=0', 
+        ->where('TO_USER_ID=:TO_USER_ID AND IS_DEL=0',
             [
-                'TO_USER_ID'=>$userId, 
-                
+                'TO_USER_ID'=>$userId,
+
             ]
         )
         ->asArray()
@@ -427,10 +440,10 @@ class User extends \common\components\ActiveRecord
         $decOrderPv = isset($decOrderPv['PV_SUM']) ? $decOrderPv['PV_SUM'] : 0;
         $orderDecPv = OrderDec::find()
         ->select('SUM(PAY_PV) AS PV_SUM')
-        ->where('USER_ID=:USER_ID AND IS_DELETE=0', 
+        ->where('USER_ID=:USER_ID AND IS_DELETE=0',
             [
-                'USER_ID'=>$userId, 
-                
+                'USER_ID'=>$userId,
+
             ]
         )
         ->asArray()
@@ -439,10 +452,10 @@ class User extends \common\components\ActiveRecord
         // 还得加上用户在老系统中的所有报单PV之和
         $originPv = OriginDecPv::find()
         ->select('SUM(DEC_PV) AS PV_SUM')
-        ->where('USER_ID=:USER_ID', 
+        ->where('USER_ID=:USER_ID',
             [
-                'USER_ID'=>$userId, 
-                
+                'USER_ID'=>$userId,
+
             ]
         )
         ->asArray()
@@ -560,4 +573,51 @@ class User extends \common\components\ActiveRecord
             'SEX' => '性别',
         ];
     }
+
+    /**
+     * 获取列表
+     * @param string $condition
+     * @param array $params
+     * @param array $argv
+     * @return array
+     */
+    public static function lists($condition = '', $params = [], $argv = []) {
+        self::prepare($condition, $params, $argv, true);
+        unset($condition, $params, $argv);
+
+        $countQuery = clone self::$query;
+        $simpleQuery = clone self::$query;
+
+        if(!$simpleQuery->params){
+            $simpleQuery->join = [];
+            $count = $simpleQuery->count(self::$argv['count']);
+        } else {
+            $count = $countQuery->count(self::$argv['count']); // 得到总数
+        }
+//        $count = $countQuery->count(self::$argv['count']); // 得到总数
+        $pagination = new Pagination(['totalCount' => $count]);
+        $pagination->setPageSize(self::$argv['pageSize']);
+        if(self::$argv['page'] !== null){
+            $pagination->setPage(self::$argv['page']);
+        }
+        self::$query->offset($pagination->offset)->limit($pagination->limit);
+        if(self::$argv['asArray']){
+            self::$query->asArray();
+        }
+        $lists = self::$query->all();
+
+        self::$query = null;
+        unset($countQuery);
+        $startNum = $pagination->page * $pagination->pageSize + 1;
+        return [
+            'list' => $lists ? $lists : [],
+            'pagination' => $pagination,
+            // 'sql'=self::$rawSql,
+            'currentPage'=>$pagination->page,
+            'totalPages'=>$pagination->pageCount,
+            'startNum' => $startNum,
+            'totalCount' => $pagination->totalCount,
+            'pageSize' => $pagination->pageSize,
+        ];
+    }
 }

+ 10 - 0
common/models/UserInfo.php

@@ -248,4 +248,14 @@ class UserInfo extends \common\components\ActiveRecord
             ],
         ];
     }
+
+        /**
+     * 查询安置网的会员
+     * @param $userId
+     * @return array|null
+     */
+    public static function getPlacementChildren($userId): ?array
+    {
+        return static::findAllAsArray('REC_UID=:REC_UID', [':REC_UID' => $userId], 'USER_ID,USER_NAME');
+    }
 }

+ 7 - 3
common/models/UserNetwork.php

@@ -256,7 +256,7 @@ class UserNetwork extends \common\components\ActiveRecord
      * @throws \yii\base\Exception
      * @throws \yii\db\Exception
      */
-    public static function getChildrenWithDeepAndLayer($userId, $deep, $loopedDeep = 1, $periodNum=null){
+    public static function getChildrenWithDeepAndLayer($userId, $deep, $loopedDeep = 1, $periodNum=null, $hiddenUser=[]){
         $allData = self::getChildrenFromPeriod($userId, $periodNum);
         if($allData){
             $decLevelConfig = Cache::getDecLevelConfig();
@@ -273,10 +273,14 @@ class UserNetwork extends \common\components\ActiveRecord
 //                    'MOBILE' => $baseInfo['MOBILE'],
                     'PERIOD_AT' => $baseInfo['PERIOD_AT'],
                 ]);
+                if(in_array($data['USER_ID'], $hiddenUser)){
+                    unset($allData[$key]);
+                    continue;
+                }
                 // 获取字节点数量
                 $childNum = self::firstFloorChildNumFromPeriod($data['USER_ID'], $periodNum);
                 if($childNum > 0 && $loopedDeep < $deep){
-                    $child = self::getChildrenWithDeepAndLayer($data['USER_ID'], $deep, $loopedDeep + 1, $periodNum);
+                    $child = self::getChildrenWithDeepAndLayer($data['USER_ID'], $deep, $loopedDeep + 1, $periodNum, $hiddenUser);
                     $leaf = false;
                     $icon = 'el-icon-user-solid';
                 }
@@ -297,7 +301,7 @@ class UserNetwork extends \common\components\ActiveRecord
                 $allData[$key]['displayNone'] = 'display-none';
             }
         }
-        return $allData;
+        return array_values($allData);
     }
 
     /**

+ 57 - 0
common/models/UserNetworkHidden.php

@@ -0,0 +1,57 @@
+<?php
+
+namespace common\models;
+
+use common\components\ActiveRecord;
+
+/**
+ * This is the model class for table "{{%USER_NETWORK}}".
+ *
+ * @property string $USER_ID 会员ID
+ * @property string $HIDDEN_USER_ID 隐藏会员ID
+ */
+class UserNetworkHidden extends \common\components\ActiveRecord
+{
+    /**
+     * @inheritdoc
+     */
+    public static function tableName()
+    {
+        return '{{%USER_NETWORK_HIDDEN}}';
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function rules()
+    {
+        return [
+        ];
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function attributeLabels()
+    {
+        return [
+            'USER_ID' => '会员ID',
+            'HIDDEN_USER_ID' => '隐藏会员ID',
+        ];
+    }
+
+    /**
+     * 获取隐藏会员列表
+     * @param $userId
+     * @return array
+     */
+    public static function fetchHiddenUser($userId)
+    {
+        $hiddenUsers = static::find()->select(['HIDDEN_USER_ID'])->where('USER_ID=:USER_ID', ['USER_ID'=>$userId])->asArray()->all();
+        $hiddenUser = [];
+        foreach($hiddenUsers as $hu){
+            $hiddenUser[] = $hu['HIDDEN_USER_ID'];
+        }
+        return $hiddenUser;
+    }
+}

+ 19 - 0
common/models/UserPerf.php

@@ -171,6 +171,15 @@ class UserPerf extends \common\components\ActiveRecord
             'PV_4L' => '四市场累计业绩',
             'PV_5L' => '五市场累计业绩',
             'PV_PSS' => '推荐团队累计业绩',
+            'SURPLUS_1L'    => '一市场综合结余业绩',
+            'SURPLUS_1L_ZC' => '一市场综合报单业绩',
+            'SURPLUS_1L_FX' => '一市场复消结余业绩',
+            'SURPLUS_2L'    => '二市场综合结余业绩',
+            'SURPLUS_2L_ZC' => '二市场综合报单业绩',
+            'SURPLUS_2L_FX' => '二市场复消结余业绩',
+            'SURPLUS_3L'    => '三市场综合结余业绩',
+            'SURPLUS_3L_ZC' => '三市场综合报单业绩',
+            'SURPLUS_3L_FX' => '三市场复消结余业绩',
         ];
     }
 
@@ -217,4 +226,14 @@ class UserPerf extends \common\components\ActiveRecord
 
         return $result;
     }
+
+        /**
+     * 查询会员结余业绩
+     * @param $userId
+     * @return array|null
+     */
+    public static function getPerfMarket($userId): ?array
+    {
+        return self::findOneAsArray('USER_ID=:USER_ID', [':USER_ID' => $userId], 'USER_ID,SURPLUS_1L,SURPLUS_1L_ZC,SURPLUS_1L_FX,SURPLUS_2L,SURPLUS_2L_ZC,SURPLUS_2L_FX,SURPLUS_3L,SURPLUS_3L_ZC,SURPLUS_3L_FX');
+    }
 }

+ 33 - 24
common/models/Withdraw.php

@@ -59,7 +59,7 @@ class Withdraw extends \common\components\ActiveRecord {
     const STATUS_APPLIED = 0;       // 已申请
 //    const STATUS_INVOICED = 1;      // 已传票
     const STATUS_AUDITED = 2;       // 已审核
-    const STATUS_WAIT_PAID = 3;     // 待付款
+    const STATUS_WAIT_PAID = 3;     // 待复核
     const STATUS_PAID_FALSE = 4;    // 付款失败
     const STATUS_REFUSED = 5;       // 已拒绝
     const STATUS_PAID = 6;          // 已付款
@@ -69,7 +69,7 @@ class Withdraw extends \common\components\ActiveRecord {
         self::STATUS_APPLIED => '提现待审核',
 //        self::STATUS_INVOICED => '提现待审核',
         self::STATUS_AUDITED => '提现已审核',
-        self::STATUS_WAIT_PAID => '提现待付款',
+        self::STATUS_WAIT_PAID => '提现待复核',
         self::STATUS_PAID_FALSE => '付款失败',
         self::STATUS_REFUSED => '已拒绝',
         self::STATUS_PAID => '提现已付款',
@@ -157,13 +157,16 @@ class Withdraw extends \common\components\ActiveRecord {
      */
     public static function getPeriod($nowTime) {
         $period = Period::instance();
+        $nowPeriodNum = $period->getNowPeriodNum();
         $year = $period->getNowYear();
         $month = $period->getNowMonth();
         $yearMonth = $period->getNowYearMonth();
-        $thisMonth = Period::getPeriodNumRangeFromMonth($year, $month);
-        $period->setPeriodNum($thisMonth['min']);
+//        $thisMonth = Period::getPeriodNumRangeFromMonth($year, $month);
+//        $period->setPeriodNum($thisMonth['min']);
+        $period->setPeriodNum($nowPeriodNum);
         $endTime = $period->getNowPeriodEnd();
-        return ['nowPeriodNum' => $thisMonth['min'], 'nowYear' => $year, 'nowMonth' => $month, 'yearMonth'=>$yearMonth, 'endTime' => $endTime];
+//        return ['nowPeriodNum' => $thisMonth['min'], 'nowYear' => $year, 'nowMonth' => $month, 'yearMonth'=>$yearMonth, 'endTime' => $endTime];
+        return ['nowPeriodNum' => $nowPeriodNum, 'nowYear' => $year, 'nowMonth' => $month, 'yearMonth'=>$yearMonth, 'endTime' => $endTime];
     }
 
     /**
@@ -337,42 +340,48 @@ class Withdraw extends \common\components\ActiveRecord {
         $statusName = self::STATUS_NAME;
         $msg = '提现单' . $sn . '当前状态为【' . $statusName[$nowStatus] . '】,无法设置为【' . $statusName[$toStatus] . '】';
         switch ($toStatus) {
-            //审核
-            case Withdraw::STATUS_AUDITED:
-                if ($nowStatus == Withdraw::STATUS_APPLIED) {
+            // 取消审核
+            case Withdraw::STATUS_APPLIED; // 0 待审核 取消审核
+                if ($nowStatus == Withdraw::STATUS_WAIT_PAID) {
                     $msg = '';
                 }
                 break;
-            //待付款
-            case Withdraw::STATUS_WAIT_PAID:
-                if ($nowStatus == Withdraw::STATUS_AUDITED || $nowStatus == Withdraw::STATUS_PAID_FALSE) {
+            //已审核
+//            case Withdraw::STATUS_AUDITED: // 2 已审核
+//                if ($nowStatus == Withdraw::STATUS_APPLIED) {
+//                    $msg = '';
+//                }
+//                break;
+            //待复核
+            case Withdraw::STATUS_WAIT_PAID: // 3 待复核
+                if ($nowStatus == Withdraw::STATUS_APPLIED) {
                     $msg = '';
                 }
                 break;
             //已付款
-            case Withdraw::STATUS_PAID:
+            case Withdraw::STATUS_PAID: // 6 已付款
                 if ($nowStatus == Withdraw::STATUS_WAIT_PAID) {
                     $msg = '';
                 }
                 break;
             //付款失败
-            case Withdraw::STATUS_PAID_FALSE:
-                if ($nowStatus == Withdraw::STATUS_PAID) {
-                    $msg = '';
-                }
-                break;
+//            case Withdraw::STATUS_PAID_FALSE:
+//                if ($nowStatus == Withdraw::STATUS_PAID) {
+//                    $msg = '';
+//                }
+//                break;
             //提现退回
-            case Withdraw::STATUS_RETURN:
-                if ($nowStatus == Withdraw::STATUS_APPLIED  || $nowStatus == Withdraw::STATUS_AUDITED || Withdraw::STATUS_WAIT_PAID) {
-                    $msg = '';
-                }
-                break;
-            //审核拒绝
-            case Withdraw::STATUS_REFUSED:
+            case Withdraw::STATUS_RETURN: // 7 已退回
                 if ($nowStatus == Withdraw::STATUS_APPLIED) {
                     $msg = '';
                 }
                 break;
+            //审核拒绝
+//            case Withdraw::STATUS_REFUSED:
+//                if ($nowStatus == Withdraw::STATUS_APPLIED) {
+//                    $msg = '';
+//                }
+//                break;
             default:
         }
         return $msg;

+ 8 - 5
common/models/forms/DecPackageForm.php

@@ -25,6 +25,7 @@ class DecPackageForm extends Model
     public $statusdate;
     public $packagedate;
     public $packagestatusdate;
+    public $sort;
 
     /**
      * @inheritdoc
@@ -55,6 +56,7 @@ class DecPackageForm extends Model
             'levelId' => '所属报单级别',
             'packageContent' => '套餐详情',
             'storenums' => '套餐库存',
+            'sort' => '排序',
         ];
     }
 
@@ -66,8 +68,8 @@ class DecPackageForm extends Model
     {
         $parentScenarios =  parent::scenarios();
         $customScenarios = [
-            'add' => ['packageName','packageNo','amount','amountPv','levelId', 'packageContent','storenums'],
-            'edit' => ['id','packageName','packageNo','amount','amountPv', 'levelId', 'packageContent','storenums','statusdate','packagedate','packagestatusdate'],
+            'add' => ['packageName','packageNo','amount','amountPv','levelId', 'packageContent','storenums','sort'],
+            'edit' => ['id','packageName','packageNo','amount','amountPv', 'levelId', 'packageContent','storenums','statusdate','packagedate','packagestatusdate','sort'],
             'changeStatus' => ['selectedIds', 'status'],
         ];
         return array_merge($parentScenarios, $customScenarios);
@@ -101,9 +103,9 @@ class DecPackageForm extends Model
         } elseif($this->scenario == 'edit') {
             $model = DeclarationPackage::findOne(['ID'=>$this->id]);
             $model->UPDATE_ADMIN = Admin::getAdminNameById(\Yii::$app->user->id);
-            $model->UPDATED_AT = Date::nowTime();
-			$model->STATUS_DATE = $this->statusdate;
-			$model->PACKAGE_STATUS_DATE = $this->packagestatusdate;
+            $model->UPDATED_AT = Date::nowTime();
+			$model->STATUS_DATE = $this->statusdate;
+			$model->PACKAGE_STATUS_DATE = $this->packagestatusdate;
 			$model->PACKAGE_DATE = $this->packagedate / 1000;
         } else {
             $this->addError('id', '提交场景不存在');
@@ -116,6 +118,7 @@ class DecPackageForm extends Model
         $model->LEVEL_ID = $this->levelId;
         $model->PACKAGE_CONTENT = $this->packageContent;
         $model->STORE_NUMS = $this->storenums;
+        $model->SORT = $this->sort;
         if($model->save()){
             return $model;
         } else {

+ 7 - 3
common/models/forms/DeclarationForm.php

@@ -641,6 +641,10 @@ class DeclarationForm extends Model
                 foreach ($this->goodsNum as $k => $v) {
                     if ($v) {
                         $goods = ShopGoods::findOneAsArray('ID=:ID AND STATUS=1',[':ID'=> $ids[$k]]);
+                        if (!$goods) {
+                            throw new Exception('商品已下架');
+                            return;
+                        }
                         if($goods['STORE_NUMS']>0){
                             $totalAmount += $goods['SELL_PRICE'] * intval($v);
                             $totalPv += $goods['PRICE_PV'] * intval($v);
@@ -722,7 +726,7 @@ class DeclarationForm extends Model
                 $userPayPasswd = '111111';
             }
         }
-        
+
         // 增加会员
         $user = new User();
         $user->USER_NAME = $this->insertUserName;
@@ -744,8 +748,8 @@ class DeclarationForm extends Model
         $user->DEC_LV = $this->decLv;
         $user->LAST_DEC_LV = $this->decLv;
         $user->EMP_LV = EmployLevel::getDefaultLevelId();
-        $user->PROVINCE = $this->province ?? 0;
-        $user->CITY = $this->city ?? 0;
+        $user->PROVINCE = intval($this->province) ?? 0;
+        $user->CITY = intval($this->city) ?? 0;
         $user->COUNTY = intval($this->county) ?? 0;
         $user->AVATAR = 'avatar/1.png';
         $user->IS_DEC = 0;

+ 7 - 0
common/models/forms/DeclarationLoopForm.php

@@ -123,6 +123,9 @@ class DeclarationLoopForm extends Model
                  */
                 if (isset($value['packageId']) && $value['packageId']){
                     $packagedata = DeclarationPackage::findOneAsArray('ID=:ID', [':ID' => $value['packageId']]);
+                    if (!$packagedata) {
+                        throw new Exception('商品不存在');
+                    }
                     //var_dump($packagedata['ID']);
                     if($packagedata['STORE_NUMS']<=0){
                         throw new Exception($packagedata['PACKAGE_NAME'].'库存不足');
@@ -132,6 +135,10 @@ class DeclarationLoopForm extends Model
                 if (count($value['goodsId']) > 0 && (count($value['goodsId']) == count($value['goodsNum']))){
                     for ($i=0;$i<count($value['goodsId']);$i++){
                         $goods = ShopGoods::findOneAsArray('ID=:ID',[':ID'=> $value['goodsId'][$i]]);
+                        if (!$goods) {
+                            throw new Exception('商品已下架');
+                            return;
+                        }
                         if ($goods['STATUS'] == 1 ){
                             if($goods['STORE_NUMS'] < $value['goodsNum'][$i]){
                                 throw new Exception($goods['GOODS_NAME'].'商品库存不足');

+ 6 - 1
common/models/forms/DeclarationUpgradeForm.php

@@ -148,6 +148,9 @@ class DeclarationUpgradeForm extends Model
                 foreach ($this->goodsNum as $k => $v) {
                     if ($v) {
                         $goods = ShopGoods::findOneAsArray('ID=:ID AND STATUS=1',[':ID'=> $ids[$k]]);
+                        if (!$goods) {
+                            throw new Exception('商品不存在');
+                        }
                         if($goods['STORE_NUMS']>0){
                             $totalAmount += $goods['SELL_PRICE'] * intval($v);
                             $totalPv += $goods['PRICE_PV'] * intval($v);
@@ -281,7 +284,9 @@ class DeclarationUpgradeForm extends Model
             foreach ($this->goodsNum as $k => $v) {
                 if ($v) {
                     $goods = ShopGoods::findOneAsArray('ID=:ID',[':ID'=> $this->goodsId[$k]]);
-
+                    if (!$goods) {
+                        throw new Exception('商品不存在');
+                    }
                     $storenums = $goods['STORE_NUMS'] - $this->goodsNum[$k];
                     if($goods['STATUS']==1){
                         if($goods['STORE_NUMS'] >=$this->goodsNum[$k]){

+ 5 - 5
common/models/forms/ExcelOrderShopForm.php

@@ -80,13 +80,13 @@ class ExcelOrderShopForm extends \common\components\ActiveRecord
 
             $formatOrderData = [];
             $formatOrderGoodsData = [];
-            foreach ($everyData as $key => $value) {
+            foreach ($everyData as $key => $value) { // 读取excel内容
                 if(isset(self::EXCEL_ORDER_SHOP_FIELD[$key])) {
-                    $formatOrderData[self::EXCEL_ORDER_SHOP_FIELD[$key]] = $value;
+                    $formatOrderData[self::EXCEL_ORDER_SHOP_FIELD[$key]] = trim($value);
                 }
 
                 if(isset(self::EXCEL_ORDER_SHOP_GOODS_FIELD[$key])) {
-                    $formatOrderGoodsData[self::EXCEL_ORDER_SHOP_GOODS_FIELD[$key]] = $value;
+                    $formatOrderGoodsData[self::EXCEL_ORDER_SHOP_GOODS_FIELD[$key]] = trim($value);
                 }
             }
 
@@ -103,10 +103,10 @@ class ExcelOrderShopForm extends \common\components\ActiveRecord
             }
 
             //判断商城订单是表中是否已经存在该订单
-            $one = OrderShop::find()->select(["USER_ID", "PERIOD_NUM", "SN", "ORDER_AMOUNT", "PV", "PAY_AMOUNT", "PAY_PV"])->where('SN=:SN', ['SN' => $formatOrderGoodsData['ORDER_SN']])->asArray()->one();
+            $one = OrderShop::find()->select(["USER_ID", "PERIOD_NUM", "ORDER_DAY", "SN", "ORDER_AMOUNT", "PV", "PAY_AMOUNT", "PAY_PV"])->where('SN=:SN', ['SN' => $formatOrderGoodsData['ORDER_SN']])->asArray()->one();
             if ($one) {
 
-                if ( $one['PERIOD_NUM'] != $formatOrderData['PERIOD_NUM'] ) {
+                if ( $one['PERIOD_NUM'] != $formatOrderData['PERIOD_NUM'] || $one['ORDER_DAY'] != $orderDay) {
                     throw new \Exception(sprintf('订单号【%s】重复不可以导入', $formatOrderGoodsData['ORDER_SN']));
                 }
 

+ 93 - 10
common/models/forms/OrderForm.php

@@ -18,6 +18,8 @@ use common\models\Region;
 use common\models\ShopGoods;
 use common\models\User;
 use common\models\UserNetwork;
+use common\models\RemainPv;
+use common\models\FlowRemainPv;
 use yii\base\Exception;
 
 /**
@@ -52,6 +54,8 @@ class OrderForm extends Model
     private $_freight;
     private $_payAmount;
     private $_orderGoods;
+    private $_remainPv;
+    private $_realPv;
 
     /**
      * @var Order
@@ -270,6 +274,27 @@ class OrderForm extends Model
         return $this->_model;
     }
 
+    /**
+     * BV分期
+     *
+     *
+     */
+    private function _pvSplit($oPv){
+        $sysConfig = Cache::getSystemConfig();
+        $mesureUpCondition =  $sysConfig['monthPcsPvFxCondition']['VALUE'];
+        if($oPv>$mesureUpCondition){
+            $currentPv = $oPv % $mesureUpCondition + $mesureUpCondition;
+            $remainPv = $oPv - $currentPv;
+        }else{
+            $currentPv = $oPv;
+            $remainPv = 0;
+        }
+        return [
+            'current' => $currentPv,
+            'remain' => $remainPv
+        ];
+    }
+
     /**
      * 复销
      * @return bool|null
@@ -283,22 +308,40 @@ class OrderForm extends Model
         $ids = $this->goodsId;
         $totalAmount = 0;
         $totalPv = 0;
+        $totalRealPv = 0;
+        $this->_remainPv = 0;
         foreach ($this->goodsNum as $k => $v) {
             if ($v) {
                 $goods = ShopGoods::findOneAsArray('ID=:ID AND STATUS=1',[':ID'=> $ids[$k]]);
+                if (!$goods) {
+                    throw new Exception('商品不存在');
+                }
                 if($goods['STORE_NUMS']>0){
                     $discount = $goods['SELL_DISCOUNT'];
                     $realPrice = $goods['SELL_PRICE'] * $discount;
                     $realPv = $goods['PRICE_PV'] * $discount;
+                    if($goods['PV_SPLIT']==1){ // 当商品为PV分期时
+                        $pvSplit = $this->_pvSplit($realPv);
+                        $currentPv = $pvSplit['current'];
+                        $remainPv = $pvSplit['remain'];
+                        $totalPv += $currentPv * intval($v);
+                        $totalRealPv += $realPv * intval($v);
+                        $this->_remainPv += $remainPv * intval($v);
+                    }else{
+                        $currentPv = $goods['PRICE_PV'];
+                        $totalPv += $realPv * intval($v);
+                        $totalRealPv += $realPv * intval($v);
+                        $remainPv = 0;
+                        $this->_remainPv += 0;
+                    }
                     $totalAmount += $realPrice * intval($v);
-                    $totalPv += $realPv * intval($v);
-
                     $this->_orderGoods[] = [
                         'GOODS_ID' => $goods['ID'],
                         'PRICE' => $goods['SELL_PRICE'],
-                        'PV' => $goods['PRICE_PV'],
+                        'PV' => $currentPv, // $goods['PRICE_PV'],
                         'REAL_PRICE' => $realPrice,
                         'REAL_PV' => $realPv,
+                        'REMAIN_PV' => $remainPv,
                         'POINT' => $goods['POINT'],
                         'BUY_NUMS' => intval($v),
                         'SKU_CODE' => $goods['GOODS_NO'],
@@ -309,6 +352,7 @@ class OrderForm extends Model
         }
         $this->_decAmount = $totalAmount;
         $this->_decPv = $totalPv;
+        $this->_realPv = $totalRealPv;
         $this->_freight = ($totalAmount>=300) ? 0 : 15;
         $this->_payAmount = $this->_decAmount + $this->_freight;
 
@@ -340,6 +384,10 @@ class OrderForm extends Model
             foreach ($this->goodsNum as $k => $v){
                 if ($v){
                     $goods = ShopGoods::findOneAsArray('ID=:ID AND STATUS=1',[':ID'=> $ids[$k]]);
+                    if (!$goods) {
+                        throw new Exception('商品不存在');
+                        return;
+                    }
                     if ($goods['STORE_NUMS'] >= $this->goodsNum[$k]){
                         $data = ShopGoods::find()->where(['ID' => $ids[$k]])->one();
                         $goods_store_nums = $data->STORE_NUMS - $this->goodsNum[$k];
@@ -401,6 +449,7 @@ class OrderForm extends Model
         $orderModel->PV = $this->payType =='exchange' ? 0 : $this->_decPv;
         $orderModel->PAY_AMOUNT = $this->_payAmount;
         $orderModel->PAY_PV = $this->payType =='exchange' ? 0 : $this->_decPv; // 兑换积分不能算业绩
+        $orderModel->REMAIN_PV = $this->_remainPv;
         $orderModel->PAY_AT = Date::nowTime();
         $orderModel->PAY_TYPE = $this->payType;
         $orderModel->PERIOD_NUM = $nowPeriodNum;
@@ -446,9 +495,8 @@ class OrderForm extends Model
 
     /**
      * 帮会员复销
-     * @return bool|null
      * @throws Exception
-     * @throws \yii\db\Exception
+     * @throws \yii\db\Exception|\Throwable
      */
     public function reconsumeAdd(){
         if(!$this->validate()){
@@ -460,6 +508,10 @@ class OrderForm extends Model
         foreach ($this->goodsNum as $k => $v) {
             if ($v) {
                 $goods = ShopGoods::findOneAsArray('ID=:ID AND STATUS=1',[':ID'=> $ids[$k]]);
+                if (!$goods) {
+                    throw new Exception('商品已下架');
+                    return;
+                }
                 if($goods['STORE_NUMS']>0){
                     $discount = $goods['SELL_DISCOUNT'];
                     $realPrice = $goods['SELL_PRICE'] * $discount;
@@ -519,6 +571,10 @@ class OrderForm extends Model
             foreach ($this->goodsNum as $k => $v){
                 if ($v){
                     $goods = ShopGoods::findOneAsArray('ID=:ID AND STATUS=1',[':ID'=> $ids[$k]]);
+                    if (!$goods) {
+                        throw new Exception('商品已下架');
+                        return;
+                    }
                     if ($goods['STORE_NUMS'] >= $this->goodsNum[$k]){
                         $data = ShopGoods::find()->where(['ID' => $ids[$k]])->one();
                         $goods_store_nums = $data->STORE_NUMS - $this->goodsNum[$k];
@@ -533,10 +589,7 @@ class OrderForm extends Model
                         }
                     }else{
                         throw new Exception($goods['GOODS_NAME'].'库存不足,无法购买商品');
-
                     }
-
-
                 }
             }
 //                exit();
@@ -556,6 +609,7 @@ class OrderForm extends Model
 
     /**
      * 帮会员复消的订单
+     * @throws Exception
      */
     public function addUserOrder(){
         $periodObj = Period::instance();
@@ -577,6 +631,7 @@ class OrderForm extends Model
         $orderModel->SN = 'OS'.$ordNo;
         $orderModel->DEC_SN = 'DS'.$ordNo;
         $orderModel->ORDER_TYPE = $this->type;
+        $orderModel->ORDER_CATEGORY = 'STUDIO';
         $orderModel->USER_ID = $userId;
         $orderModel->USER_NAME = $this->userName;
         $orderModel->ORDER_AMOUNT = $this->_decAmount;
@@ -601,8 +656,9 @@ class OrderForm extends Model
         $orderModel->CREATED_AT = Date::nowTime();
         $orderModel->CREATE_USER = $loginUserName;
         if(!$orderModel->save()){
-            $this->addErrors($orderModel->getErrors());
-            return false;
+//            $this->addErrors($orderModel->getErrors());
+            throw new Exception($orderModel->getErrors());
+//            return false;
         }
         // 加入商品到订单商品表
         foreach($this->_orderGoods as $key=>$value){
@@ -644,4 +700,31 @@ class OrderForm extends Model
         }
         return $hash;
     }
+
+    public function addFakeOrder($userId, $periodNum){
+        $userName = Info::getUserNameByUserId($userId);
+        $sysConfig = Cache::getSystemConfig();
+        $mesureUpCondition =  $sysConfig['monthPcsPvFxCondition']['VALUE']; // 月达标条件 NC默认300
+        $ordNo = $this->_generateSn();
+        $orderModel = new Order();
+        $orderModel->SN = 'OS'.$ordNo;
+        $orderModel->DEC_SN = 'DS'.$ordNo;
+        $orderModel->USER_ID = $userId;
+        $orderModel->USER_NAME = $userName;
+        $orderModel->PERIOD_NUM = $periodNum;
+        $orderModel->CREATE_USER = 'AUTO';
+        $orderModel->ORDER_TYPE = 'FX';
+        $orderModel->STATUS = 1;
+        $orderModel->PV = $mesureUpCondition;
+        $orderModel->PAY_PV = $mesureUpCondition;
+        $orderModel->P_CALC_MONTH = '1970-01-01';
+        $orderModel->CREATED_AT = Date::nowTime();
+        $orderModel->EXPRESS_TYPE = 1;
+        $orderModel->IS_AUTO = 1;
+        if(!$orderModel->save()){
+            $this->addErrors($orderModel->getErrors());
+            return false;
+        }
+        return $orderModel;
+    }
 }

+ 136 - 0
common/models/forms/PerfAdjustmentForm.php

@@ -0,0 +1,136 @@
+<?php
+namespace common\models\forms;
+
+use common\components\Model;
+use common\helpers\Form;
+use common\libs\logging\operate\AdminOperate;
+use common\models\Period;
+use common\models\UserPerf;
+use yii\base\Exception;
+
+class PerfAdjustmentForm extends Model
+{
+    public $USER_ID;
+    public $USER_NAME;
+
+    public $SURPLUS_1L;
+    public $SURPLUS_1L_ZC;
+    public $SURPLUS_1L_FX;
+
+    public $SURPLUS_2L;
+    public $SURPLUS_2L_ZC;
+    public $SURPLUS_2L_FX;
+
+    public $SURPLUS_3L;
+    public $SURPLUS_3L_ZC;
+    public $SURPLUS_3L_FX;
+
+    public function init()
+    {
+        parent::init();
+        $this->adminOperateLogger = new AdminOperate([
+            'fetchClass' => UserPerf::class,
+        ]);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function rules()
+    {
+        return [
+            [['USER_ID', 'SURPLUS_1L', 'SURPLUS_1L_ZC', 'SURPLUS_1L_FX', 'SURPLUS_2L', 'SURPLUS_2L_ZC', 'SURPLUS_2L_FX', 'SURPLUS_3L', 'SURPLUS_3L_ZC', 'SURPLUS_3L_FX'], 'required'],
+        ];
+    }
+
+    /**
+     * 指定场景
+     * @return array
+     */
+    public function scenarios() {
+        $parentScenarios = parent::scenarios();
+        $customScenarios = [
+            'perfAdjustment' => ['USER_ID', 'USER_NAME', 'SURPLUS_1L', 'SURPLUS_1L_ZC', 'SURPLUS_1L_FX', 'SURPLUS_2L', 'SURPLUS_2L_ZC', 'SURPLUS_2L_FX', 'SURPLUS_3L', 'SURPLUS_3L_ZC', 'SURPLUS_3L_FX']
+        ];
+        return array_merge($parentScenarios, $customScenarios);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function attributeLabels()
+    {
+        return [
+            'USER_ID'       => '会员ID',
+            'SURPLUS_1L'    => '一市场综合结余业绩',
+            'SURPLUS_1L_ZC' => '一市场综合报单业绩',
+            'SURPLUS_1L_FX' => '一市场复消结余业绩',
+            'SURPLUS_2L'    => '二市场综合结余业绩',
+            'SURPLUS_2L_ZC' => '二市场综合报单业绩',
+            'SURPLUS_2L_FX' => '二市场复消结余业绩',
+            'SURPLUS_3L'    => '三市场综合结余业绩',
+            'SURPLUS_3L_ZC' => '三市场综合报单业绩',
+            'SURPLUS_3L_FX' => '三市场复消结余业绩',
+        ];
+    }
+
+    /**
+     * 调整会员业绩
+     * @return bool|null
+     */
+    public function perfAdjustment(): ?bool
+    {
+        if (!$this->validate()) {
+            return false;
+        }
+
+        $transaction = \Yii::$app->db->beginTransaction();
+        try {
+            // 修改前业绩
+            $userPerf = UserPerf::find()
+                ->where('USER_ID=:USER_ID', [':USER_ID' => $this->USER_ID])
+                ->select('USER_ID,SURPLUS_1L,SURPLUS_1L_ZC,SURPLUS_1L_FX,SURPLUS_2L,SURPLUS_2L_ZC,SURPLUS_2L_FX,SURPLUS_3L,SURPLUS_3L_ZC,SURPLUS_3L_FX')
+                ->one();
+            if (!$userPerf->toArray()) {
+                throw new Exception('Member performance does not exist'); // 会员业绩不存在
+            }
+
+            $this->adminOperateLogger->beforeUpdate($userPerf);
+
+            $modernPerf = [
+                'SURPLUS_1L'    => $this->SURPLUS_1L,
+                'SURPLUS_1L_ZC' => $this->SURPLUS_1L_ZC,
+                'SURPLUS_1L_FX' => $this->SURPLUS_1L_FX,
+                'SURPLUS_2L'    => $this->SURPLUS_2L,
+                'SURPLUS_2L_ZC' => $this->SURPLUS_2L_ZC,
+                'SURPLUS_2L_FX' => $this->SURPLUS_2L_FX,
+                'SURPLUS_3L'    => $this->SURPLUS_3L,
+                'SURPLUS_3L_ZC' => $this->SURPLUS_3L_ZC,
+                'SURPLUS_3L_FX' => $this->SURPLUS_3L_FX,
+            ];
+            if (!UserPerf::updateAll($modernPerf, 'USER_ID=:USER_ID', [':USER_ID' => $this->USER_ID])) {
+                throw new Exception(Form::formatErrorsForApi($userPerf->getErrors()));
+            }
+
+            $transaction->commit();
+
+            $afterUpdate = UserPerf::find()
+                ->where('USER_ID=:USER_ID', [':USER_ID' => $this->USER_ID])
+                ->select('USER_ID,SURPLUS_1L,SURPLUS_1L_ZC,SURPLUS_1L_FX,SURPLUS_2L,SURPLUS_2L_ZC,SURPLUS_2L_FX,SURPLUS_3L,SURPLUS_3L_ZC,SURPLUS_3L_FX')
+                ->one();
+            $this->adminOperateLogger->afterUpdate($afterUpdate)->clean()->save([
+                'optType' => '调整业绩',
+                'userId' => $this->USER_ID,
+                'userName' => $this->USER_NAME,
+                'periodNum' => Period::instance()->getNowPeriodNum(),
+            ]);
+        } catch (Exception $e) {
+            $transaction->rollBack();
+            $this->addError('perfAdjustment', $e->getMessage());
+            return false;
+        }
+
+        return true;
+    }
+
+}

+ 19 - 10
common/models/forms/TransferForm.php

@@ -6,6 +6,7 @@ use common\helpers\Cache;
 use common\helpers\Date;
 use common\components\Model;
 use common\helpers\Form;
+use common\helpers\LoggerTool;
 use common\helpers\snowflake\SnowFake;
 use common\helpers\Tool;
 use common\helpers\user\Balance;
@@ -262,7 +263,13 @@ class TransferForm extends Model {
      * @param $params
      */
     public function validatePassword($attribute, $params) {
-        if (!User::validatePayPassword($this->_fromUserInfo['ID'], $this->payPassword)) {
+        $uid = \Yii::$app->user->id;
+        if(!$this->toUserName || !$this->toRealName || $this->amount == 0){
+            $this->addError($attribute, '转账失败');
+        }else if(!$this->_fromUserInfo){
+            LoggerTool::info('transfer error, '.$uid.' '. $this->amount.' '. $this->toUserName);
+            $this->addError($attribute, '转账时发生错误');
+        }else if (!User::validatePayPassword($this->_fromUserInfo['ID'], $this->payPassword)) {
             $this->addError($attribute, '支付密码不正确');
         }
     }
@@ -301,9 +308,11 @@ class TransferForm extends Model {
         if (!$this->validate()) {
             return null;
         }
-
         $fromData = Balance::getLogData($this->_fromUserInfo['ID']);
         $toData = Balance::getLogData($this->_toUserInfo['ID']);
+        if ($this->_fromUserInfo['ID']==$this->_toUserInfo['ID'] && $this->_transferConfig['out']==$this->_transferConfig['in']){
+            throw new \Exception('不能给同一账户转账');
+        }
         $this->userOperateLogger->saveBeforeContent=array_merge($fromData,$toData);
 
         $db = \Yii::$app->db;
@@ -354,22 +363,22 @@ class TransferForm extends Model {
                 // 复消积分转余额
                 // 减少复消积分
                 Balance::changeUserBonus(
-                    $this->_fromUserInfo['ID'], 
-                    'reconsume_points', 
-                    -abs($this->amount), 
+                    $this->_fromUserInfo['ID'],
+                    'reconsume_points',
+                    -abs($this->amount),
                     [
-                        'TRANSFER_SN' => $model->TRANSFER_SN, 
-                        'DEAL_TYPE_ID' => DealType::TRANSFER_OUT, 
+                        'TRANSFER_SN' => $model->TRANSFER_SN,
+                        'DEAL_TYPE_ID' => DealType::TRANSFER_OUT,
                         'REMARK' => 'To:' . $this->_toUserInfo['USER_NAME'] . ',' . $this->remark
                     ]
                 );
                 // 增加余额
                 Cash::changeUserCash(
-                    $this->_toUserInfo['ID'], 
-                    'CASH', abs($amount), 
+                    $this->_toUserInfo['ID'],
+                    'CASH', abs($amount),
                     [
                         'TRANSFER_SN' => $model->TRANSFER_SN,
-                        'DEAL_TYPE_ID' => DealType::TRANSFER_IN, 
+                        'DEAL_TYPE_ID' => DealType::TRANSFER_IN,
                         'REMARK' => 'From:' . $this->_fromUserInfo['USER_NAME'] . ',' . $this->remark
                     ]
                 );

+ 3 - 3
common/models/forms/WithdrawForm.php

@@ -381,7 +381,7 @@ class WithdrawForm extends Model {
             $this->addError('add', '完善身份信息后才可以提现');
             return -1;
         }
-        return 0; 
+        return 0;
         // 暂时不进行身份证号接口校验了,先直接返回正常
         $response = LingYunGongApi::hasIdCardInfo($user['ID_CARD']);
         if( !$response ) {
@@ -556,13 +556,13 @@ class WithdrawForm extends Model {
                         }
                     }
                     $oneWithdraw->REMARK = $this->createRemark ?? '';
-                } //已审核->待付款
+                } //已审核->待复核
                 elseif ($this->auditStatus == Withdraw::STATUS_WAIT_PAID) {
                     $oneWithdraw->PAID_FAIL_REMARK = '';
                     $oneWithdraw->PAID_FAIL_AT = 0;
                     $oneWithdraw->REMARK = $this->createRemark ?? '';
                     $oneWithdraw->PLAN_PAID_AT = Date::utcToTime($this->planPaidAt);
-                } //待付款->已付款
+                } //待复核->已付款
                 elseif ($this->auditStatus == Withdraw::STATUS_PAID) {
                     $oneWithdraw->PAID_AT = Date::utcToTime($this->paidAt);
                     //记录付款信息

+ 3 - 0
composer.json

@@ -36,6 +36,9 @@
         "process-timeout": 1800,
         "fxp-asset": {
             "enabled": false
+        },
+        "allow-plugins": {
+            "yiisoft/yii2-composer": true
         }
     },
     "repositories": {

+ 51 - 0
console/controllers/ToolController.php

@@ -12,6 +12,7 @@ use common\helpers\Cache;
 use common\helpers\DataBak;
 use common\helpers\Date;
 use common\helpers\Form;
+use common\helpers\LoggerTool;
 use common\helpers\ocr\OcrApi;
 use common\helpers\Tool;
 use common\libs\api\sms\SmsApi;
@@ -125,6 +126,13 @@ class ToolController extends BaseController
         echo '清空成功'.PHP_EOL;
     }
 
+    /**
+     * 清空缓存
+     */
+    public function actionClearConfigCache() {
+        \Yii::$app->cache->delete(Cache::SYSTEM_CONFIG_KEY);
+        echo '清空成功: ' . Cache::SYSTEM_CONFIG_KEY . PHP_EOL;
+    }
 
     /**
      * 重置接点和推荐数量
@@ -167,4 +175,47 @@ class ToolController extends BaseController
         \Yii::$app->redis->del(Cache::USER_RELATION_PARENTS);
     }
 
+    /**
+     * 自动送钉钉提醒
+     */
+    public function actionAutoSendDingTalkFrontend() {
+        $ip = 'https://fapi.ekhkad.com';
+        $curl = curl_init();
+        curl_setopt($curl, CURLOPT_URL, $ip . '/v1/site/send-notice');
+        curl_setopt($curl, CURLOPT_TIMEOUT, 5000);
+        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
+        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+        $res = curl_exec($curl);
+        if ($res) {
+            curl_close($curl);
+            LoggerTool::info($res);
+        } else {
+            $error = curl_errno($curl);
+            curl_close($curl);
+            LoggerTool::error($error);
+        }
+    }
+
+    /**
+     * 自动送钉钉提醒
+     */
+    public function actionAutoSendDingTalkBackend() {
+        $ip = 'https://bapi.ekhkad.com';
+        $curl = curl_init();
+        curl_setopt($curl, CURLOPT_URL, $ip . '/v1/site/send-notice');
+        curl_setopt($curl, CURLOPT_TIMEOUT, 5000);
+        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
+        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+        $res = curl_exec($curl);
+        if ($res) {
+            curl_close($curl);
+            LoggerTool::info($res);
+        } else {
+            $error = curl_errno($curl);
+            curl_close($curl);
+            LoggerTool::error($error);
+        }
+    }
 }

+ 1 - 1
frontendApi/config/params.php

@@ -1,6 +1,6 @@
 <?php
 return [
     'adminEmail' => 'admin@example.com',
-    'noCheckTokenActions' => ['v1/oauth/login', 'v1/oauth/refresh-access-token', 'v1/oauth/refresh-refresh-token', 'v1/oauth/refresh-token', 'v1/site/days-diff', 'v1/site/page-data', 'v1/site/captcha', 'v1/oauth/is-login-verify','v1/oauth/login-by-backend', 'v1/oauth/no-login-modify-password', 'v1/site/doc', 'v1/site/config'],
+    'noCheckTokenActions' => ['v1/oauth/login', 'v1/oauth/refresh-access-token', 'v1/oauth/refresh-refresh-token', 'v1/oauth/refresh-token', 'v1/site/days-diff', 'v1/site/page-data', 'v1/site/captcha', 'v1/oauth/is-login-verify','v1/oauth/login-by-backend', 'v1/oauth/no-login-modify-password', 'v1/site/doc', 'v1/site/config', 'v1/site/send-notice',],
     'noCheckPermissionActions' => [],
 ];

+ 1 - 0
frontendApi/config/urlManagerRules.php

@@ -19,6 +19,7 @@ return [
             'GET config' => 'config',
             'GET page-data' => 'page-data',
             'GET captcha' => 'captcha',
+            'GET send-notice' => 'send-notice',
         ],
     ],
     [

+ 5 - 2
frontendApi/modules/v1/controllers/AtlasController.php

@@ -12,6 +12,7 @@ use common\helpers\Cache;
 use common\helpers\user\Info;
 use common\models\Period;
 use common\models\UserNetwork;
+use common\models\UserNetworkHidden;
 use Yii;
 use common\models\User;
 
@@ -81,10 +82,12 @@ class AtlasController extends BaseController {
         $userId = Yii::$app->request->get('id', \Yii::$app->user->id);
         $periodNum = Yii::$app->request->get('periodNum', null);
         $deep = Yii::$app->request->get('deep', 5);
+        $myUserId = \Yii::$app->user->id;
+        $hiddenUser = UserNetworkHidden::fetchHiddenUser($myUserId);
         if ($deep > 20) {
             return static::notice('最多查看会员的前20层子会员', 400);
         }
-        $allData = UserNetwork::getChildrenWithDeepAndLayer($userId, $deep, 1, $periodNum);
+        $allData = UserNetwork::getChildrenWithDeepAndLayer($userId, $deep, 1, $periodNum, $hiddenUser);
         return static::notice(['allData' => $allData, 'periodNum' => $periodNum]);
     }
 
@@ -147,4 +150,4 @@ class AtlasController extends BaseController {
         ]);
     }
 
-}
+}

+ 1037 - 1029
frontendApi/modules/v1/controllers/BonusController.php

@@ -1,1029 +1,1037 @@
-<?php
-/**
- * Created by PhpStorm.
- * User: leo
- * Date: 2018/2/24
- * Time: 下午12:48
- */
-
-namespace frontendApi\modules\v1\controllers;
-
-
-
-use common\helpers\Cache;
-use common\helpers\Date;
-use common\helpers\Tool;
-use common\helpers\user\Info;
-use common\helpers\user\Perf;
-use common\models\CalcBonus;
-use common\models\CalcBonusBsDetail;
-use common\models\CalcBonusBT;
-use common\models\CalcBonusFL;
-use common\models\DealType;
-use common\models\FlowBonus;
-use common\models\FlowCF;
-use common\models\FlowLX;
-use common\models\FlowReconsumePoints;
-use common\models\FlowWallet;
-use common\models\PerfMonth;
-use common\models\Period;
-use common\models\DecRole;
-use common\models\EmployLevel;
-use common\models\FlowExchangePoints;
-use common\models\PerfMonthPrepare;
-use common\models\PeriodPrepare;
-use common\models\ScoreMonth;
-use common\models\UserBonus;
-use common\models\UserRelation;
-use common\models\UserWallet;
-use frontendApi\modules\v1\models\User;
-use Yii;
-
-class BonusController extends BaseController {
-    public $modelClass = CalcBonus::class;
-
-    /**
-     * 我的账户
-     * @return mixed
-     * @throws \yii\web\HttpException
-     */
-    public function actionIndex() {
-        $userId = \Yii::$app->user->id;
-        $data = UserBonus::findUseSlaves()->select('BONUS,RECONSUME_POINTS,EXCHANGE_POINTS')->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
-        if (!$data) {
-            $data = [
-                'BONUS' => 0,
-                'RECONSUME_POINTS' => 0,
-                'EXCHANGE_POINTS' => 0,
-            ];
-        }
-        $data['CASH'] = 0;
-        $cashWallet = UserWallet::findOneAsArray('USER_ID=:USER_ID', [':USER_ID'=>$userId], 'CASH');
-        if($cashWallet){
-            $data['CASH'] = $cashWallet['CASH'];
-        }
-        //是否显示车房领袖
-//        $showCFLX = true;
-//        if ($data['CF'] <= 0 && $data['LX'] <= 0) {
-//            $showCFLX = false;
-//            //查看历史最高聘级是否到过五钻
-//            if (EmployLevel::getSortById(Info::getHighEmpLv($userId)) >= 7) {
-//                $showCFLX = true;
-//            }
-//        }
-        // 会员奖金->增值点数      会员余额->消费点数
-        $wallet[] = ['walletType' => 'bonus', 'walletName' => '增值点数', 'amount' => Tool::formatPrice($data['BONUS'])];
-        $wallet[] = ['walletType' => 'cash', 'walletName' => '消费点数', 'amount' => Tool::formatPrice($data['CASH'])];
-        $wallet[] = ['walletType' => 'point', 'walletName' => '复销点数', 'amount' => Tool::formatPrice($data['RECONSUME_POINTS'])];
-        $wallet[] = ['walletType' => 'exchange', 'walletName' => '兑换点数', 'amount' => Tool::formatPrice($data['EXCHANGE_POINTS'])];
-//        if ($showCFLX) {
-//            $wallet[] = ['walletType' => 'cf', 'walletName' => '福利积分一', 'amount' => Tool::formatPrice($data['CF'])];
-//            $wallet[] = ['walletType' => 'lx', 'walletName' => '福利积分二', 'amount' => Tool::formatPrice($data['LX'])];
-//        }
-        //是否显示报单中心
-//        $showBt = true;
-//        $showFl = true;
-//        $userInfo = User::getEnCodeInfo(\Yii::$app->user->id);
-//        if ($userInfo['IS_DEC'] != 1) {
-//            $showBt = false;
-//            $showFl = false;
-//        }else{
-//            $sysConfig = Cache::getSystemConfig();
-//            if(!$sysConfig['openBT']['VALUE']&&!$sysConfig['openPROD']['VALUE']) $showBt = false;
-//            if(!$sysConfig['openFL']['VALUE']) $showFl = false;
-//            $decRole = DecRole::find()->where('1=1')->indexBy('ID')->asArray()->all()[$userInfo['DEC_ROLE_ID']];
-//            if ($decRole['GOODS_SUBSIDY'] <= 0) $showFl = false;
-//        }
-
-        $dealSwitch = isset(Cache::getSystemConfig()['dealSwitch']) ? Cache::getSystemConfig()['dealSwitch']['VALUE'] : '';
-
-        return static::notice(['wallet' => $wallet,'dealSwitch'=>$dealSwitch]);
-    }
-
-    /**
-     * 团队查询
-     * @return mixed
-     * @throws \yii\web\HttpException
-     */
-    public function actionTeams() {
-        $userId = \Yii::$app->user->id;
-        $period = Period::instance();
-        $periodNum = $period->getNowPeriodNum();
-        $month = $period->getNowYearMonth();
-        // 判断是否是周日,并且是否是月结节点
-        // 特殊要求,测试环境要去掉是否是周日的判断,周一至周日都能看.正式环境只有周日能看
-        // 读取加入到忽略文件的common/config/config.php文件内容
-        $preparePerfLimit = isset(Yii::$app->params['preparePerfLimit']) ? Yii::$app->params['preparePerfLimit'] : false;
-        $isCalcMonth = $period->isCalcMonth($periodNum);
-        $w = date('w', time());
-        //特殊要求,测试环境要去掉是否是周日的判断,周一至周日都能看
-        if($preparePerfLimit === true && $isCalcMonth != 1) {
-            return static::notice(['user' => [],'team'=>[]]);
-        } else if ($preparePerfLimit !== true && ($w != '0' || $isCalcMonth != 1)) {
-            return static::notice(['user' => [],'team'=>[]]);
-        }
-        // 判断此业绩期是否已经完成生成了预计算业绩单,生成完毕才能看到
-        $isPerfed = PeriodPrepare::isPerfed($periodNum);
-        if (!$isPerfed) {
-            return static::notice(['user' => [],'team'=>[]]);
-        }
-        
-        // 获取最新的计算时间
-        $calcAt = PeriodPrepare::getInfo($periodNum);
-        $calcAt = date('Y-m-d H:i:s', $calcAt['PERF_STARTED_AT']);
-
-        // 达标规则,小组底下有一个大于等于一万.或者个人情况里的合计大于等于一万
-        $data = PerfMonthPrepare::getMonthPerfPrepare($userId, $month);
-        // PV_PCS 个人业绩  PV_PSS 月新增团队业绩  PV_PSS_TOTAL月累计团队业绩
-        // 其中页面使用的是月新增团队业绩
-        // 获取用信息
-        $userInfo = User::getEnCodeInfo($userId);
-        $user[0] = [
-            'number' => $userInfo['USER_NAME'],
-            'name' => $userInfo['REAL_NAME'],
-            'perf_status' => '0', // 0  未达标  1为已达标
-            'perf_status_name' => '不达标',
-            'user_perf' => 0, // 个人业绩
-            'team_perf' => 0, // 团队新增累计业绩
-            'total_perf' => 0 // 合计业绩
-        ];
-        if (!empty($data)) {
-            // 调整个人合格了,依旧不显示业绩
-            $userCheck = PerfMonthPrepare::checkPrepareStatus($data['PV_PCS']+$data['PV_PSS']);
-            $user[0]['user_perf'] = Tool::formatPreparePerf($data['PV_PCS']);
-            $user[0]['team_perf'] = $userCheck ? '' : Tool::formatPreparePerf($data['PV_PSS']);
-            $user[0]['total_perf'] = $userCheck ? '' : Tool::formatPreparePerf($data['PV_PCS']+$data['PV_PSS']);
-            $user[0]['perf_status'] = $userCheck ? '1' : $user[0]['perf_status'];
-            $user[0]['perf_status_name'] = $userCheck ? '达标' : $user[0]['perf_status_name'];
-        }
-        $teamInfo = [];
-        // 查询此用户的推荐(开拓)团队一级信息
-        $relation = UserRelation::getChildrenWithDeepAndLayer($userId, 1, 1, $periodNum);
-        $userStatusFlag = false;
-        if ($relation) {
-            // 循环一级开拓用户
-            foreach($relation as $k=>$v) {
-                // 获取此用户预计算月业绩
-                $relationPerf = PerfMonthPrepare::getMonthPerfPrepare($v['USER_ID'], $month);
-                if (empty($relationPerf)) {
-                    $relationPerf['PV_PCS'] = 0;
-                    $relationPerf['PV_PSS'] = 0;
-                }
-                $relationCheck = PerfMonthPrepare::checkPrepareStatus($relationPerf['PV_PCS']+$relationPerf['PV_PSS']);
-                $teamInfo[]['perf_status'] = $relationCheck ? '1' : '0';
-                if ($relationCheck) {
-                    $userStatusFlag = true; // 只要有一个达标,则个人就达标
-                    $teamInfo[$k]['number'] = '';
-                    $teamInfo[$k]['name'] = '';
-                    $teamInfo[$k]['user_perf'] = '';
-                    $teamInfo[$k]['team_perf'] = '';
-                    $teamInfo[$k]['total_perf'] = '';
-                    $teamInfo[$k]['perf_status'] = '1';
-                    $teamInfo[$k]['perf_status_name'] = '达标';
-                } else {
-                    $teamInfo[$k]['number'] = $v['USER_NAME'];
-                    $teamInfo[$k]['name'] = $v['REAL_NAME'];
-                    $teamInfo[$k]['user_perf'] = Tool::formatPreparePerf($relationPerf['PV_PCS']);
-                    $teamInfo[$k]['team_perf'] = Tool::formatPreparePerf($relationPerf['PV_PSS']);
-                    $teamInfo[$k]['total_perf'] = Tool::formatPreparePerf($relationPerf['PV_PCS']+$relationPerf['PV_PSS']);
-                    $teamInfo[$k]['perf_status'] = '0';
-                    $teamInfo[$k]['perf_status_name'] = '不达标';
-                } 
-            }
-        }
-        if ($userStatusFlag === true) {
-            $user[0]['perf_status'] = '1';
-            $user[0]['perf_status_name'] = '达标';
-        }
-        
-        return static::notice(['user' => $user,'team'=>$teamInfo,'calcAt' => $calcAt]);
-    }
-
-    /**
-     * 交易记录
-     * @return mixed
-     * @throws \yii\web\HttpException
-     */
-    public function actionWalletFlow(){
-        $walletType = \Yii::$app->request->get('walletType');
-        if(!in_array($walletType,['bonus','point','cash','exchange'])) return static::notice('错误的账户类型',400);
-        $dealType = \Yii::$app->request->get('dealType');
-        $createAt = \Yii::$app->request->get('createAt');
-        $remark = \Yii::$app->request->get('remark');
-
-        //获取可以查看几期流水
-        $showFlowPeriodNum = Cache::getSystemConfig()['showFlowPeriodNum']['VALUE'];
-        $periodArr = Period::getNearlyPeriodNum($showFlowPeriodNum);
-        $condition = ' AND USER_ID=:USER_ID AND PERIOD_NUM>=:PERIOD_NUM_MIN AND PERIOD_NUM<=:PERIOD_NUM_MAX';
-        $params = [':USER_ID' => \Yii::$app->user->id,':PERIOD_NUM_MIN' => min($periodArr), ':PERIOD_NUM_MAX'=> max($periodArr)];
-        if($dealType){
-            if($dealType==1){//增加
-                $condition.=' AND IS_INCR=1 AND DEAL_TYPE_IS_PRESET=0';
-            }elseif ($dealType==2){//扣除
-                $condition.=' AND IS_INCR=0 AND DEAL_TYPE_IS_PRESET=0';
-            }else{
-                $condition.=' AND DEAL_TYPE_ID=:DEAL_TYPE';
-                $params[':DEAL_TYPE'] = $dealType;
-            }
-        }
-        if ($createAt) {
-            $condition .= " AND CREATED_AT>:CREATED_START AND CREATED_AT<:CREATED_END";
-            $params[':CREATED_START'] = Date::utcToTime($createAt[0]);
-            $params[':CREATED_END'] = Date::utcToTime($createAt[1])+86399;
-        }
-        if($remark){
-            $condition .= " AND REMARK LIKE :REMARK";
-            $params[':REMARK'] = '%'.$remark.'%';
-        }
-        $data = [];
-        $dealLists=[];
-        $dealTypes=[];
-        if($walletType == 'bonus') {
-            $dealLists = FlowBonus::find()->groupBy('DEAL_TYPE_ID')->select('DEAL_TYPE_ID')->where('USER_ID=:USER_ID',[':USER_ID'=>\Yii::$app->user->id])->asArray()->all();
-            $data = FlowBonus::lists($condition, $params, [
-                'useSlaves' => true,
-                'select' => 'AMOUNT,TOTAL,IS_INCR,REMARK,REMARK_IS_SHOW,PERIOD_NUM,CALC_MONTH,CREATED_AT,DEAL_TYPE_ID,DEAL_TYPE_IS_PRESET',
-                'orderBy' => 'CREATED_AT DESC,SORT DESC',
-            ]);
-        }elseif ($walletType == 'point'){
-            $dealLists = FlowReconsumePoints::find()->groupBy('DEAL_TYPE_ID')->select('DEAL_TYPE_ID')->where('USER_ID=:USER_ID',[':USER_ID'=>\Yii::$app->user->id])->asArray()->all();
-            $data = FlowReconsumePoints::lists($condition, $params, [
-                'useSlaves' => true,
-                'select' => 'AMOUNT,TOTAL,IS_INCR,REMARK,REMARK_IS_SHOW,PERIOD_NUM,CALC_MONTH,CREATED_AT,DEAL_TYPE_ID,DEAL_TYPE_IS_PRESET',
-                'orderBy' => 'CREATED_AT DESC',
-            ]);
-        }elseif ($walletType == 'cash'){
-            $data = FlowWallet::lists($condition, $params, [
-                'select' => 'AMOUNT,TOTAL,IS_INCR,REMARK,PERIOD_NUM,CALC_MONTH,CREATED_AT',
-                'orderBy' => 'CREATED_AT DESC',
-            ]);
-        }else if ($walletType == 'exchange') {
-            $dealLists = FlowExchangePoints::find()->groupBy('DEAL_TYPE_ID')->select('DEAL_TYPE_ID')->where('USER_ID=:USER_ID',[':USER_ID'=>\Yii::$app->user->id])->asArray()->all();
-            $data = FlowExchangePoints::lists($condition, $params, [
-                'useSlaves' => true,
-                'select' => 'AMOUNT,TOTAL,IS_INCR,REMARK,REMARK_IS_SHOW,PERIOD_NUM,CALC_MONTH,CREATED_AT,DEAL_TYPE_ID,DEAL_TYPE_IS_PRESET',
-                'orderBy' => 'CREATED_AT DESC',
-            ]);
-        }
-        if($data) {
-            if($walletType != 'cash') {
-                foreach ($data['list'] as $key => $value) {
-                    if ($value['DEAL_TYPE_IS_PRESET'] == 0) {
-                        $data['list'][$key]['DEAL_TYPE_NAME'] = $value['AMOUNT'] > 0 ? '增加' : '减少';
-                    } else {
-                        $data['list'][$key]['DEAL_TYPE_NAME'] = DealType::getAllTypesForShow()[$value['DEAL_TYPE_ID']]['TYPE_NAME'] ?? '';
-                    }
-                    if ($value['REMARK_IS_SHOW'] == 0) $data['list'][$key]['REMARK'] = '';
-                    $data['list'][$key]['REMARK'] = str_replace("车房养老奖", "福利积分一", $data['list'][$key]['REMARK']);
-                    $data['list'][$key]['REMARK'] = str_replace("领袖分红奖", "福利积分二", $data['list'][$key]['REMARK']);
-                    $data['list'][$key]['REMARK'] = str_replace("车房养老", "福利积分一", $data['list'][$key]['REMARK']);
-                    $data['list'][$key]['REMARK'] = str_replace("领袖分红", "福利积分二", $data['list'][$key]['REMARK']);
-                }
-            }
-        }
-        if($dealLists){
-            foreach ($dealLists as $key=>$value){
-                if(!$value['DEAL_TYPE_ID']) continue;
-                $dealType = DealType::getAllTypesForShow()[$value['DEAL_TYPE_ID']];
-                if($dealType['IS_PRESET']==0){
-                    $dealTypes['1'] = '增加';
-                    $dealTypes['2'] = '扣除';
-                }else{
-                    $dealLists[$key]['DEAL_TYPE_NAME'] = $dealType['TYPE_NAME']??'';
-                    $dealTypes[$value['DEAL_TYPE_ID']] = $dealLists[$key]['DEAL_TYPE_NAME'];
-                }
-            }
-        }
-        $data['dealTypes'] = $dealTypes;
-        unset($dealTypes);
-        return static::notice($data);
-    }
-
-    /**
-     * 最新奖金
-     * @return mixed
-     * @throws \yii\db\Exception
-     * @throws \yii\web\HttpException
-     */
-    public function actionNew(){
-        if(!$periodNum = \Yii::$app->request->get('periodNum')) {
-            $periodNum = Period::sentMaxPeriodNum();
-        }
-        //是否近期期数
-        $showFlowPeriodNum = Cache::getSystemConfig()['showFlowPeriodNum']['VALUE'];
-        $periodArr = Period::getNearlySendPeriodNum($showFlowPeriodNum);
-        if(!in_array($periodNum,$periodArr)) return static::notice('该期不能查看',400);
-        //增加明细开关控制(0 只显示总奖金 1 全部显示)
-        $flowBonusSwitch = Cache::getSystemConfig()['flowBonusSwitch']['VALUE'];
-        $data = $this->_periodBonus($periodNum,$flowBonusSwitch);
-        if(!$data) return static::notice('当期无奖金记录',400);
-        return static::notice($data);
-    }
-
-    /**
-     * 期数对应的奖金-已挂网
-     * @param $periodNum
-     * @param $detailSwitch
-     * @return array
-     * @throws \yii\db\Exception
-     */
-    private function _periodBonus($periodNum,$detailSwitch=1) {
-        $period = Period::instance();
-        $yearMonth = $period->getYearMonth($periodNum);
-        if(!$calcBonus = CalcBonus::find()
-        ->yearMonth($yearMonth)
-        ->where('USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM',[':USER_ID'=>\Yii::$app->user->id,':PERIOD_NUM'=>$periodNum])
-        ->asArray()
-        ->one()){
-            return [];
-        }
-        $sysConfig = Cache::getSystemConfig();
-        if($detailSwitch) {
-            $data[] = ['name' => '期数', 'value' => $periodNum];
-            $data[] = ['name' => '级别', 'value' => Cache::getDecLevelConfig()[$calcBonus['LAST_DEC_LV']]['LEVEL_NAME']];
-            $isCalcMonth = $period->isCalcMonth($periodNum);
-            // 判断如果是月节点,如果用户是无聘级,则判断是否是同享专员
-            if ($isCalcMonth == 1 && $calcBonus['LAST_EMP_LV'] == EmployLevel::NO_LEVEL_ID) {
-                // 如果ORI_BONUS值大于0,则是同享专员
-                $bsDetail = CalcBonusBsDetail::isCommonShare(\Yii::$app->user->id,$periodNum,EmployLevel::NO_LEVEL_ID);
-                if ($bsDetail) {
-                    $tempEmpName = Cache::getEmpLevelConfig()[$calcBonus['LAST_EMP_LV']]['LEVEL_NAME'];
-                    $data[] = ['name' => '最新聘级', 'value' => $tempEmpName.'(同享专员)'];
-                } else {
-                    $data[] = ['name' => '最新聘级', 'value' => Cache::getEmpLevelConfig()[$calcBonus['LAST_EMP_LV']]['LEVEL_NAME']];
-                }
-            } else {
-                $data[] = ['name' => '最新聘级', 'value' => Cache::getEmpLevelConfig()[$calcBonus['LAST_EMP_LV']]['LEVEL_NAME']];
-            }
-            if ($sysConfig['openTG']['VALUE']) {
-                // 销售奖金 就是 原来的推广奖
-                $data[] = ['name' => '销售奖金', 'value' => Tool::formatPrice($calcBonus['ORI_BONUS_TG'])];
-            }
-            // 2022/06/28 特殊需求,如果user_id为670B84FD7C216D4EE055736AECE8644D齐长青,则将服务奖加到团队奖里面去,然后服务奖显示为0
-            if ($sysConfig['openQY']['VALUE']) {
-                // 业绩奖金  就是原来的团队奖 并将业绩奖金改成绩效奖金
-                // $data[] = ['name' => '团队奖', 'value' => Tool::formatPrice($calcBonus['ORI_BONUS_QY'])];
-                if (\Yii::$app->user->id == '670B84FD7C216D4EE055736AECE8644D') {
-                    $data[] = ['name' => '绩效奖金', 'value' => Tool::formatPrice($calcBonus['ORI_BONUS_QY']+$calcBonus['ORI_BONUS_BD'])];
-                } else {
-                    $data[] = ['name' => '绩效奖金', 'value' => Tool::formatPrice($calcBonus['ORI_BONUS_QY'])];
-                }
-            }
-            // 管理奖金 就是新的蓝星奖
-            $data[] = ['name' => '管理奖金', 'value' => Tool::formatPrice($calcBonus['ORI_BONUS_BS'])];
-
-            if ($sysConfig['openGX']['VALUE']) {
-                $data[] = ['name' => '周共享奖金', 'value' => Tool::formatPrice($calcBonus['ORI_BONUS_GX'])];
-                $data[] = ['name' => '月共享奖金', 'value' => Tool::formatPrice($calcBonus['ORI_MONTH_GX_BONUS'])];
-            }
-            if ($sysConfig['openStore']['VALUE']) {
-                // 店服务奖
-                $data[] = ['name' => '店服务奖金', 'value' => Tool::formatPrice($calcBonus['ORI_BONUS_ST'])];
-            }
-            if ($sysConfig['openFW']['VALUE']) {
-                if (\Yii::$app->user->id == '670B84FD7C216D4EE055736AECE8644D') {
-                    $data[] = ['name' => '服务奖金', 'value' => '0.00'];
-                } else {
-                    $data[] = ['name' => '服务奖金', 'value' => Tool::formatPrice($calcBonus['ORI_BONUS_BD'])];
-                }
-            }
-
-            $data[] = ['name' => '总奖金', 'value' => Tool::formatPrice($calcBonus['BONUS_TOTAL'])];
-            $data[] = ['name' => '管理费', 'value' => Tool::formatPrice($calcBonus['MANAGE_TAX'])];
-            $data[] = ['name' => '实发奖金', 'value' => Tool::formatPrice($calcBonus['BONUS_REAL'])];
-            $data[] = ['name' => '复销点数', 'value' => Tool::formatPrice($calcBonus['RECONSUME_POINTS'])];
-            $data[] = ['name' => '兑换点数', 'value' => Tool::formatPrice($calcBonus['EXCHANGE_POINTS'])];
-            $data[] = ['name' => '一市场新增业绩', 'value' => Tool::formatFrontPerf($calcBonus['PV_1L'])];
-            $data[] = ['name' => '二市场新增业绩', 'value' => Tool::formatFrontPerf($calcBonus['PV_2L'])];
-            $data[] = ['name' => '三市场新增业绩', 'value' => Tool::formatFrontPerf($calcBonus['PV_3L'])];
-            $data[] = ['name' => '一市场结余业绩', 'value' => Tool::formatFrontPerf($calcBonus['SURPLUS_1L'])];
-            $data[] = ['name' => '二市场结余业绩', 'value' => Tool::formatFrontPerf($calcBonus['SURPLUS_2L'])];
-            $data[] = ['name' => '三市场结余业绩', 'value' => Tool::formatFrontPerf($calcBonus['SURPLUS_3L'])];
-        }else{
-            $data[] = ['name' => '总奖金', 'value' => Tool::formatPrice($calcBonus['BONUS_TOTAL'])];
-        }
-        return $data;
-    }
-
-    /**
-     * 往期奖金
-     * @return mixed
-     * @throws \yii\web\HttpException
-     */
-    public function actionOther(){
-        //获取可以查看几期奖金
-        $showBonusPeriodNum = Cache::getSystemConfig()['showBonusPeriodNum']['VALUE'];
-        $calcBonus = CalcBonus::find()->where('USER_ID=:USER_ID AND IS_SENT=1', [':USER_ID' => \Yii::$app->user->id])
-        ->select('ORI_BONUS_ST,USER_ID,PERIOD_NUM,ORI_BONUS_QY,ORI_BONUS_YC,ORI_BONUS_VIP,ORI_BONUS_STANDARD,ORI_BONUS_BD,ORI_BONUS_TG,
-        ORI_BONUS_XF,BONUS_TOTAL,MANAGE_TAX,BONUS_REAL,BONUS_INCOME,ORI_BONUS_YJ,ORI_BONUS_GX,ORI_MONTH_GX_BONUS,ORI_BONUS_GL,RECONSUME_POINTS,
-        LAST_DEC_LV,LAST_EMP_LV,EXCHANGE_POINTS,ORI_BONUS_BS,ORI_BONUS_MNT,ORI_BONUS_ABBR')
-        ->limit($showBonusPeriodNum)
-        ->orderBy('PERIOD_NUM DESC')
-        ->asArray()
-        ->all();
-        $sysConfig = Cache::getSystemConfig();
-
-        //增加明细开关控制(0 只显示总奖金 1 全部显示)
-        $flowBonusSwitch = Cache::getSystemConfig()['flowBonusSwitch']['VALUE'];
-
-        foreach ($calcBonus as $key => $data) {
-            if($flowBonusSwitch) {
-                $calcBonus[$key]['PERIOD_NUM'] = ['name' => '期数', 'value' => $calcBonus[$key]['PERIOD_NUM']];
-                $calcBonus[$key]['LAST_DEC_NAME'] = ['name' => '级别', 'value' => Cache::getDecLevelConfig()[$calcBonus[$key]['LAST_DEC_LV']]['LEVEL_NAME']];
-                $calcBonus[$key]['LAST_EMP_NAME'] = ['name' => '聘级', 'value' => Cache::getEmpLevelConfig()[$calcBonus[$key]['LAST_EMP_LV']]['LEVEL_NAME']];
-
-                // 销售奖金,就是原来的推广奖金
-                if ($sysConfig['openTG']['VALUE']) {
-                    $calcBonus[$key]['BONUS_TG'] = ['name' => '销售奖金', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_TG'])];
-                }
-                // 业绩奖金,就是原来的团队奖  并将业绩奖金改成绩效奖金
-                if ($sysConfig['openQY']['VALUE']) {
-                    $calcBonus[$key]['BONUS_QY'] = ['name' => '绩效奖金', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_QY'])];
-                }
-                // 管理奖金 就是新的蓝星奖金
-                $calcBonus[$key]['BONUS_BS'] = ['name' => '管理奖金', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_BS'])];
-
-                //共享奖
-                if ($sysConfig['openGX']['VALUE']) {
-                    $calcBonus[$key]['BONUS_GX'] = ['name' => '周共享奖金', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_GX'])];
-                    $calcBonus[$key]['ORI_MONTH_GX_BONUS'] = ['name' => '月共享奖金', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_MONTH_GX_BONUS'])];
-                }
-                //店服务奖
-                if ($sysConfig['openStore']['VALUE']) {
-                    $calcBonus[$key]['BONUS_ST'] = ['name' => '店服务奖金', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_ST'])];
-                }
-                //服务奖
-                if ($sysConfig['openFW']['VALUE']) {
-                    $calcBonus[$key]['BONUS_BD'] = ['name' => '服务奖金', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_BD'])];
-                }
-
-                // 2022/06/28 特殊需求,如果user_id为670B84FD7C216D4EE055736AECE8644D齐长青,则将服务奖加到团队奖里面去,然后服务奖显示为0
-                if ($data['USER_ID'] == '670B84FD7C216D4EE055736AECE8644D') {
-                    $calcBonus[$key]['BONUS_BD'] = ['name' => '服务奖金', 'value' => '0.00'];
-                    $calcBonus[$key]['BONUS_QY'] = [
-                        'name' => '绩效奖金', 
-                        'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_QY']+$calcBonus[$key]['ORI_BONUS_BD'])
-                    ];
-                }
-                // 总奖金
-                $calcBonus[$key]['BONUS_TOTAL'] = ['name' => '总奖金', 'value' => Tool::formatPrice($calcBonus[$key]['BONUS_TOTAL'])];
-                $calcBonus[$key]['RECONSUME_POINTS'] = ['name' => '复销点数', 'value' => Tool::formatPrice($calcBonus[$key]['RECONSUME_POINTS'])];
-                $calcBonus[$key]['EXCHANGE_POINTS'] = ['name' => '兑换点数', 'value' => Tool::formatPrice($calcBonus[$key]['EXCHANGE_POINTS'])];
-                $calcBonus[$key]['MANAGE_TAX'] = ['name' => '管理费', 'value' => Tool::formatPrice($calcBonus[$key]['MANAGE_TAX'])];
-                $calcBonus[$key]['BONUS_REAL'] = ['name' => '实发奖金', 'value' => Tool::formatPrice($calcBonus[$key]['BONUS_REAL'])];
-                // if ($sysConfig['openYC']['VALUE']) {
-                //     $calcBonus[$key]['BONUS_YC'] = ['name' => '荣衔奖', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_YC'])];
-                // }
-                // if ($sysConfig['openVIP']['VALUE']) {
-                //     $calcBonus[$key]['BONUS_VIP'] = ['name' => 'VIP奖', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_VIP'])];
-                // }
-                // if ($sysConfig['openXF']['VALUE']) {
-                //     $calcBonus[$key]['BONUS_XF'] = ['name' => '消费奖', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_XF'])];
-                // }
-                // if ($sysConfig['openYJ']['VALUE']) {
-                //     $calcBonus[$key]['BONUS_YJ'] = ['name' => '业绩奖', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_YJ'])];
-                // }
-                // if ($sysConfig['openGL']['VALUE']) {
-                //     $calcBonus[$key]['BONUS_GL'] = ['name' => '管理奖', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_GL'])];
-                // }
-                // if ($sysConfig['openJXS']['VALUE']) {
-                //     $calcBonus[$key]['BONUS_STANDARD'] = ['name' => '团队成长奖', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_STANDARD'])];
-                // }
-            }else{
-
-                $calcBonus[$key]['BONUS_TOTAL'] = ['name' => '总奖金', 'value' => Tool::formatPrice($calcBonus[$key]['BONUS_TOTAL'])];
-
-            }
-        }
-
-        if($flowBonusSwitch) {
-            $tableKey[] = 'PERIOD_NUM';
-            if ($sysConfig['openTG']['VALUE']) {
-                $tableKey[] = 'BONUS_TG';
-            }
-            if ($sysConfig['openQY']['VALUE']) {
-                $tableKey[] = 'BONUS_QY';
-            }
-            $tableKey[] = 'BONUS_BS';
-
-            if ($sysConfig['openGX']['VALUE']) {
-                $tableKey[] = 'BONUS_GX';
-                $tableKey[] = 'ORI_MONTH_GX_BONUS';
-            }
-            if ($sysConfig['openStore']['VALUE']) {
-                $tableKey[] = 'BONUS_ST';
-            }
-            if ($sysConfig['openFW']['VALUE']) {
-                $tableKey[] = 'BONUS_BD';
-            }
-            
-            
-            // if ($sysConfig['openXF']['VALUE']) {
-            //     $tableKey[] = 'BONUS_XF';
-            // }
-            // if ($sysConfig['openYJ']['VALUE']) {
-            //     $tableKey[] = 'BONUS_YJ';
-            // }
-            
-            // if ($sysConfig['openGL']['VALUE']) {
-            //     $tableKey[] = 'BONUS_GL';
-            // }
-            // if ($sysConfig['openJXS']['VALUE']) {
-            //     $tableKey[] = 'BONUS_STANDARD';
-            // }
-           
-            $tableKey[] = 'BONUS_TOTAL';
-            $tableKey[] = 'RECONSUME_POINTS';
-            $tableKey[] = 'EXCHANGE_POINTS';
-            $tableKey[] = 'MANAGE_TAX';
-            $tableKey[] = 'BONUS_REAL';
-        }else{
-            $tableKey[] = 'BONUS_TOTAL';
-        }
-
-        return static::notice(['tableData' => $calcBonus, 'tableKey' => $tableKey]);
-    }
-
-    /**
-     * 实时业绩
-     * @return mixed
-     * @throws \yii\web\HttpException
-     */
-    public function actionRealTimePerf() {
-        $userId = \Yii::$app->user->id;
-        $period = Period::instance();
-        $newPerf = Perf::getPeriodNewPerf($userId);
-        $weekData = [['PV_1L' => Tool::formatFrontPerf($newPerf['PV_1L']), 'PV_2L' => Tool::formatFrontPerf($newPerf['PV_2L']), 'PV_3L' => Tool::formatFrontPerf($newPerf['PV_3L'])]];
-        $monthPerf = Perf::getMonthPerf($userId);
-        $monthData = [['PV_1L' => Tool::formatFrontPerf($monthPerf['PV_1L']), 'PV_2L' => Tool::formatFrontPerf($monthPerf['PV_2L']), 'PV_3L' => Tool::formatFrontPerf($monthPerf['PV_3L'])]];
-        $lastMonth = PerfMonth::getMonthPerf($period->getLastMonth()['yearMonth'], $userId);
-        $lastData = [['PV_1L' => Tool::formatFrontPerf($lastMonth['PV_1L_TOTAL']), 'PV_2L' => Tool::formatFrontPerf($lastMonth['PV_2L_TOTAL']), 'PV_3L' => Tool::formatFrontPerf($lastMonth['PV_3L_TOTAL'])]];
-        //是否合格
-//        $lastChkStatus = '';
-//        $lastMonthPerfChk = Cache::getSystemConfig()['lastMonthPerfChk']['VALUE'];
-//        $lastArr = [$lastMonth['PV_1L_TOTAL'], $lastMonth['PV_2L_TOTAL'], $lastMonth['PV_3L_TOTAL'], $lastMonth['PV_4L_TOTAL'], $lastMonth['PV_5L_TOTAL']];
-//        if (array_sum($lastArr) >= $lastMonthPerfChk) {
-//            $lastChkStatus = '已合格';
-//        }
-        //判断大区
-//        $bigLocation = array_search(max($lastArr), $lastArr) + 1;
-        return static::notice(['weekData' => $weekData, 'monthData' => $monthData, 'lastData' => $lastData]);
-    }
-
-    /**
-     * 近十期已挂网的期数
-     * @return mixed
-     * @throws \yii\web\HttpException
-     */
-    public function actionDecPeriod() {
-        $showDecPeriodNum = Cache::getSystemConfig()['showDecPeriodNum']['VALUE'];
-        $data = Period::find()->where('IS_SENT=:IS_SENT',[':IS_SENT' => Period::SEND_FINISH])->select('PERIOD_NUM,END_TIME')->limit($showDecPeriodNum)->orderBy('PERIOD_NUM DESC')->asArray()->all();
-        return static::notice($data);
-    }
-
-    /**
-     * 报单中心补助明细
-     * @return mixed
-     * @throws \yii\web\HttpException
-     */
-    public function actionFlowBt() {
-        $periodNum = \Yii::$app->request->get('periodNum');
-        $condition = '';
-        $params = [];
-        if (!$periodNum) {
-            return static::notice('请选择期数',400);
-        }
-        if ($periodNum) {
-            $showDecPeriodNum = Cache::getSystemConfig()['showDecPeriodNum']['VALUE'];
-            $periodNums = Period::find()->where('IS_SENT=:IS_SENT',[':IS_SENT' => Period::SEND_FINISH])->select('PERIOD_NUM')->limit($showDecPeriodNum)->orderBy('PERIOD_NUM DESC')->asArray()->all();
-            if(!in_array($periodNum,array_column($periodNums,'PERIOD_NUM'))){
-                return static::notice('该期无法查看',400);
-            }
-            $condition .= ' AND PERIOD_NUM=:PERIOD_NUM';
-            $params[':PERIOD_NUM'] = $periodNum;
-        }
-        $condition .= ' AND USER_ID=:USER_ID';
-        $params[':USER_ID'] = \Yii::$app->user->id;
-        $data = CalcBonusBT::lists($condition, $params, [
-            'select' => 'BT_TYPE,FROM_ORDER_SN,ORDER_TIME,PAY_PV,DELIVERY_AT,TRANSFER_AMOUNT,TRANSFER_AT,AMOUNT',
-            'from' => CalcBonusBT::tableName(),
-            'orderBy' => 'CREATED_AT DESC',
-        ]);
-        if ($data['list']) {
-            foreach ($data['list'] as $key => $value) {
-                $data['list'][$key]['BT_TYPE_NAME'] = CalcBonusBT::TYPE_NAME[$value['BT_TYPE']];
-                foreach ($value as $k=>$item){
-                    if($item==0) $data['list'][$key][$k] ='';
-                }
-            }
-        }
-
-        return static::notice($data);
-    }
-
-    /**
-     * 报单中心货补追溯
-     * @return mixed
-     * @throws \yii\web\HttpException
-     */
-    public function actionTraceFl() {
-        $periodNum = \Yii::$app->request->get('periodNum');
-        $condition = '';
-        $params = [];
-        if (!$periodNum) {
-            return static::notice('请选择期数',400);
-        }
-        if ($periodNum) {
-            $showDecPeriodNum = Cache::getSystemConfig()['showDecPeriodNum']['VALUE'];
-            $periodNums = Period::find()->where('IS_SENT=:IS_SENT',[':IS_SENT' => Period::SEND_FINISH])->select('PERIOD_NUM')->limit($showDecPeriodNum)->orderBy('PERIOD_NUM DESC')->asArray()->all();
-            if(!in_array($periodNum,array_column($periodNums,'PERIOD_NUM'))){
-                return static::notice('该期无法查看',400);
-            }
-            $condition .= ' AND PERIOD_NUM=:PERIOD_NUM';
-            $params[':PERIOD_NUM'] = $periodNum;
-        }
-        $condition .= ' AND USER_ID=:USER_ID';
-        $params[':USER_ID'] = \Yii::$app->user->id;
-        $data = CalcBonusFL::lists($condition, $params, [
-            'select' => 'DEC_SN,DEC_AT,DEC_PV,AMOUNT',
-            'from' => CalcBonusFL::tableName(),
-            'orderBy' => 'CREATED_AT DESC',
-        ]);
-
-        return static::notice($data);
-    }
-
-
-
-
-    /**
-     * 查看所传期数的各项奖金
-     * @return mixed
-     * @throws \yii\db\Exception
-     * @throws \yii\web\HttpException
-     */
-    public function actionBonusDetail() {
-        $periodNum = \Yii::$app->request->get('periodNum');
-        $period = Period::instance();
-        $periodInfo = $period->setPeriodNum($periodNum);
-        $yearMonth = $period->getYearMonth($periodNum);
-        if (!$period->isSent($periodNum)) {
-            return static::notice('该期不能查看',400);
-        }
-        $data = CalcBonus::findUseSlaves()->yearMonth($yearMonth)->select('BONUS_QY,BONUS_YC,BONUS_FX,BONUS_LS,BONUS_CF,BONUS_LX,BONUS_FL')->where('PERIOD_NUM=:PERIOD_NUM AND USER_ID=:USER_ID', [':PERIOD_NUM' => $periodNum, ':USER_ID' => \Yii::$app->user->id])->asArray()->one();
-        return static::notice(['period' => $periodInfo, 'bonus' => $data]);
-    }
-
-    /**
-     * 奖金流水
-     * @return mixed
-     * @throws \yii\web\HttpException
-     */
-    public function actionFlowBonus() {
-        $yearMonth = \Yii::$app->request->get('yearMonth');
-        if ($yearMonth) {
-            if (!Date::isYearMonth($yearMonth)) {
-                return static::notice('无效参数', 400);
-            }
-        } else {
-            $period = Period::instance();
-            $yearMonth = $period->getNowYearMonth();
-        }
-        $data = FlowBonus::lists(' AND USER_ID=:USER_ID', [':USER_ID' => \Yii::$app->user->id], [
-            'useSlaves' => true,
-            'select' => 'AMOUNT,TOTAL,IS_INCR,REMARK,REMARK_IS_SHOW,PERIOD_NUM,CALC_MONTH,CREATED_AT',
-            'yearMonth' => $yearMonth,
-            'orderBy' => 'CREATED_AT DESC',
-        ]);
-        foreach ($data['list'] as $key => $value) {
-            if($value['REMARK_IS_SHOW']==0) $data['list'][$key]['REMARK'] = '';
-        }
-        return static::notice($data);
-    }
-
-    /**
-     * 提现列表
-     * @return mixed
-     * @throws \yii\base\Exception
-     * @throws \yii\web\HttpException
-     */
-    public function actionWithdraw() {
-        $yearMonth = \Yii::$app->request->get('yearMonth');
-        if ($yearMonth) {
-            if (!Date::isYearMonth($yearMonth)) {
-                return static::notice('无效参数', 400);
-            }
-        } else {
-            $period = Period::instance();
-            $yearMonth = $period->getNowYearMonth();
-        }
-        $data = Withdraw::lists('AND W.USER_ID=:USER_ID', [':USER_ID' => \Yii::$app->user->id], [
-            'useSlaves' => true,
-            'select' => 'W.ID,W.USER_ID,W.IS_AUTO_WITHDRAW,W.AMOUNT,W.AUDIT_STATUS,W.CREATED_AT,W.PAID_AT,W.PAY_TYPE,W.PAID_FAIL_REMARK,W.INVOICE_ID,IA.AMOUNT INVOICE_AMOUNT,IA.AUDIT_STATUS INVOICE_AUDIT_STATUS,IA.UPLOAD_ID',
-            'from' => Withdraw::tableName() . ' AS W',
-            'join' => [
-                ['LEFT JOIN', InvoiceAudit::tableName() . ' AS IA', 'W.ID=IA.WITHDRAW_ID'],
-            ],
-            'yearMonth' => $yearMonth,
-            'orderBy' => 'W.CREATED_AT DESC',
-            //'with' => 'openBank',
-        ]);
-        $auditStatus = array_column(\Yii::$app->params['auditStatus'], null, 'value');
-        foreach ($data['list'] as $key => $value) {
-            $baseInfo = Info::baseInfo($value['USER_ID']);
-            $data['list'][$key]['USER_NAME'] = $baseInfo['USER_NAME'];
-            $data['list'][$key]['REAL_NAME'] = $baseInfo['REAL_NAME'];
-            $data['list'][$key]['STATUS_NAME'] = Withdraw::STATUS_NAME[$value['AUDIT_STATUS']];
-            $data['list'][$key]['INVOICE_STATUS_NAME'] = isset($value['INVOICE_AUDIT_STATUS'])?$auditStatus[$value['INVOICE_AUDIT_STATUS']]['label']:'未传发票';
-        }
-        return static::notice($data);
-    }
-
-    /**
-     * 提交提现申请
-     * @return mixed
-     * @throws \yii\db\Exception
-     * @throws \yii\web\HttpException
-     */
-    public function actionWithdrawAdd() {
-        if (\Yii::$app->request->isPost) {
-            $formModel = new WithdrawForm();
-            $formModel->scenario = 'addByUser';
-            if ($formModel->load(\Yii::$app->request->post(), '') && $formModel->add()) {
-                return static::notice('提现申请已提交,请等待审核');
-            } else {
-                return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
-            }
-        } else {
-            return static::notice('非法请求', 400);
-        }
-    }
-
-    /**
-     * 提现退回
-     * @return mixed
-     * @throws \yii\db\Exception
-     * @throws \yii\web\HttpException
-     */
-    public function actionWithdrawBack() {
-        if (\Yii::$app->request->isPost) {
-            $formModel = new WithdrawForm();
-            $formModel->scenario = 'backByUser';
-            if ($formModel->load(\Yii::$app->request->post(), '') && $formModel->backByUser()) {
-                return static::notice('提现已退回');
-            } else {
-                return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
-            }
-        } else {
-            return static::notice('非法请求', 400);
-        }
-    }
-
-    /**
-     * 判断并获取提现的会员信息
-     * @return mixed
-     * @throws \yii\web\HttpException
-     */
-    public function actionChkWithdrawUser() {
-        $uid = \Yii::$app->user->id;
-        if (!Info::isVerified($uid)) {
-            return static::notice('未实名验证无法提现', 400);
-        }
-        $userInfo = UserInfo::findOneAsArray('USER_ID=:USER_ID', [':USER_ID' => $uid], 'IS_BIND,IS_BIND_MAIN,IS_AUTO_WITHDRAW,REG_TYPE,TRANSFER_PROP');
-        if ($userInfo['IS_BIND'] == 1 && $userInfo['IS_BIND_MAIN'] == 0) {
-            return static::notice('附属会员无法提现', 400);
-        }
-        if ($userInfo['IS_AUTO_WITHDRAW'] == 1) {
-            return static::notice('已开启自动提现,如需手动提现请关闭自动提现', 400);
-        }
-        if (!Withdraw::allowWithdraw()) {
-            return static::notice('未到提现日期,请在每月挂网后第一周申请提现', 400);
-        }
-        if (Withdraw::hasThisMonthWithdraw($uid)) {
-            return static::notice('提现失败,每月只可以提现一次', 400);
-        }
-        if (Withdraw::existWaitAudit($uid)) {
-            return static::notice('提现失败,您存在未审核的提现记录', 400);
-        }
-        //是否显示服务协议
-        $regType = RegType::findOneAsArray('ID=:ID', [':ID' => $userInfo['REG_TYPE']], 'IS_PACT');
-        $path = \Yii::getAlias('@common/runtime/datas/pact.php');
-        if (!file_exists($path)) {
-            $oneData = '';
-        } else {
-            $oneData = include $path;
-        }
-        $isCanTransferProp = Cache::getSystemConfig()['isCanTransferProp']['VALUE'];
-        if ($isCanTransferProp == 0) {
-            $userInfo['WITHDRAW_PROP'] = 100;
-        } else {
-            $userInfo['WITHDRAW_PROP'] = 100 - $userInfo['TRANSFER_PROP'];
-        }
-        return static::notice(['userInfo' => $userInfo, 'isPact' => $regType['IS_PACT'], 'content' => $oneData['CONTENT']]);
-    }
-
-    /**
-     * 归集附属会员奖金
-     * @return mixed
-     * @throws \yii\db\Exception
-     * @throws \yii\web\HttpException
-     */
-    public function actionCollectBind() {
-        $transferBonusForm = new TransferBonusForm();
-        if ($totals=$transferBonusForm->collectBind(\Yii::$app->user->id)) {
-            return static::notice('归集完成,归集金额'.$totals);
-        } else {
-            if($totals==0){
-                return static::notice('归集完成,归集金额'.$totals);
-            }else{
-                return static::notice(Form::formatErrorsForApi($transferBonusForm->getErrors()), 400);
-            }
-        }
-    }
-
-    /**
-     * 上传发票之前
-     * @return mixed
-     * @throws \yii\web\HttpException
-     */
-    public function actionInvoiceBeforeAdd() {
-        $id = \Yii::$app->request->get('id');
-        $withdraw = Withdraw::findOneAsArray('ID=:ID', [':ID' => $id]);
-        if (!$withdraw) {
-            return static::notice('数据不存在', 400);
-        }
-        $uploadInvoiceTip = Cache::getSystemConfig()['uploadInvoiceTip']['VALUE'];
-        if ($withdraw['AUDIT_STATUS'] == Withdraw::STATUS_APPLIED) {
-            return static::notice(['addInvoiceTips' => $uploadInvoiceTip]);
-        } else {
-            return static::notice('该提现记录无法上传发票', 400);
-        }
-    }
-
-    /**
-     * 上传发票
-     * @return mixed
-     * @throws \yii\db\Exception
-     * @throws \yii\web\HttpException
-     */
-    public function actionInvoiceAdd() {
-        $id = \Yii::$app->request->get('id');
-        $withdraw = Withdraw::findOneAsArray('ID=:ID', [':ID' => $id]);
-        if (!$withdraw) {
-            return static::notice('数据不存在', 400);
-        }
-        if (\Yii::$app->request->isPost) {
-            $formModel = new UploadForm();
-            $formModel->scenario = 'invoiceFront';
-            $formModel->file = UploadedFile::getInstanceByName('file');
-            $formModel->withdrawId = $withdraw['ID'];
-            $formModel->remark = '提现'.$withdraw['SN'].'发票';
-            //$formModel->token = \Yii::$app->request->post('uploadToken');
-            $formModel->token = \Yii::$app->request->request('uploadToken');
-            if ($formModel->file && $formModel->upload()) {
-                return static::notice('上传成功');
-            } else {
-                return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
-            }
-        }
-    }
-
-    /**
-     * 显示上传的发票
-     * @return mixed
-     * @throws \yii\web\HttpException
-     */
-    public function actionInvoiceShow() {
-        $id = \Yii::$app->request->get('id');
-        $uploads = Uploads::findOneAsArray('ID=:ID', [':ID' => $id],'URL');
-        if (!$uploads) {
-            return static::notice('数据不存在', 400);
-        }
-        return static::notice($uploads['URL']);
-    }
-
-    /**
-     * 获取可用余额
-     * @return mixed
-     * @throws \yii\web\HttpException
-     */
-    public function actionAvailableBalance() {
-        return static::notice(Balance::getAvailableBalance(\Yii::$app->user->id));
-    }
-
-    /**
-     * 查看业绩
-     * @return mixed
-     * @throws \yii\web\HttpException
-     */
-    public function actionPerf() {
-        $yearMonth = \Yii::$app->request->get('yearMonth');
-        if ($yearMonth) {
-            if (!Date::isYearMonth($yearMonth)) {
-                return static::notice('无效参数', 400);
-            }
-        } else {
-            $period = Period::instance();
-            $yearMonth = $period->getNowYearMonth();
-        }
-        $data = PerfPeriod::lists('AND P.USER_ID=:USER_ID AND PN.IS_SENT=1', [':USER_ID' => \Yii::$app->user->id], [
-            'select' => 'P.*',
-            'yearMonth' => $yearMonth,
-            'from' => PerfPeriod::tableName() . ' AS P',
-            'join' => [
-                ['LEFT JOIN', Period::tableName() . ' AS PN', 'P.PERIOD_NUM=PN.PERIOD_NUM']
-            ],
-            'orderBy' => 'P.PERIOD_NUM DESC',
-        ]);
-        $data['request']['yearMonth'] = $yearMonth;
-        return static::notice($data);
-    }
-
-    /**
-     * 转账列表
-     * @return mixed
-     * @throws \yii\web\HttpException
-     */
-    public function actionTransferList() {
-        $type = \Yii::$app->request->get('type', 'out');
-        if ($type == 'out') {
-            $condition = ' AND T.FROM_UID=:USER_ID';
-        } else {
-            $condition = ' AND T.TO_UID=:USER_ID';
-        }
-        $params = [
-            ':USER_ID' => \Yii::$app->user->id,
-        ];
-        $data = Transfer::lists($condition, $params, [
-            'select' => 'FUI.USER_NAME AS FROM_USER_NAME, TUI.USER_NAME AS TO_USER_NAME, T.AMOUNT, T.PERIOD_NUM, T.CREATED_AT',
-            'from' => Transfer::tableName() . ' AS T',
-            'join' => [
-                ['LEFT JOIN', UserInfo::tableName() . ' AS FUI', 'FUI.USER_ID=T.FROM_UID'],
-                ['LEFT JOIN', UserInfo::tableName() . ' AS TUI', 'TUI.USER_ID=T.TO_UID'],
-            ],
-        ]);
-        return static::notice($data);
-    }
-
-    /**
-     * 转账
-     * @throws \yii\db\Exception
-     * @throws \yii\web\HttpException
-     */
-    public function actionTransferAdd() {
-        if (\Yii::$app->request->isPost) {
-            $formModel = new TransferForm();
-            if ($formModel->load(\Yii::$app->request->post(), '') && $formModel->transfer()) {
-                return static::notice('转账成功');
-            } else {
-                return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
-            }
-        }
-    }
-
-    /**
-     * 检查转账资格
-     * @return mixed
-     * @throws \yii\web\HttpException
-     */
-    public function actionChkTransferUser() {
-        $uid = \Yii::$app->user->id;
-        if (!Info::isVerified($uid)) {
-            return static::notice('未实名验证无法转账', 400);
-        }
-        $userInfo = UserInfo::findOneAsArray('USER_ID=:USER_ID', [':USER_ID' => $uid], 'ALLOW_TRANSFER,TRANSFER_PROP');
-        if($userInfo['ALLOW_TRANSFER']==0){
-            return static::notice('您不允许转账', 400);
-        }
-        $isCanTransferProp = Cache::getSystemConfig()['isCanTransferProp']['VALUE'];
-        if($isCanTransferProp==0){
-            $userInfo['TRANSFER_PROP']=100;
-        }
-        return static::notice(['userInfo' => $userInfo]);
-    }
-
-    /**
-     * 房产积分列表
-     * @return mixed
-     * @throws \yii\web\HttpException
-     */
-    public function actionFcPoint() {
-        $condition = ' AND USER_ID=:USER_ID';
-        $params = [':USER_ID' => \Yii::$app->user->id];
-
-        $yearMonth = \Yii::$app->request->get('yearMonth');
-        if ($yearMonth) {
-            if (!Date::isYearMonth($yearMonth)) {
-                return static::notice('无效参数', 400);
-            }
-            $condition .= ' AND CALC_MONTH=:CALC_MONTH';
-            $params['CALC_MONTH'] = $yearMonth;
-        }
-
-        $data = ScoreMonth::lists($condition, $params, [
-            'from' => ScoreMonth::tableName(),
-            'orderBy' => 'ID DESC',
-        ]);
-        return static::notice($data);
-    }
-}
+<?php
+/**
+ * Created by PhpStorm.
+ * User: leo
+ * Date: 2018/2/24
+ * Time: 下午12:48
+ */
+
+namespace frontendApi\modules\v1\controllers;
+
+use common\helpers\Cache;
+use common\helpers\Date;
+use common\helpers\Tool;
+use common\helpers\user\Info;
+use common\helpers\user\Perf;
+use common\models\CalcBonus;
+use common\models\CalcBonusBsDetail;
+use common\models\CalcBonusBT;
+use common\models\CalcBonusFL;
+use common\models\DealType;
+use common\models\FlowBonus;
+use common\models\FlowCF;
+use common\models\FlowLX;
+use common\models\FlowReconsumePoints;
+use common\models\FlowWallet;
+use common\models\PerfMonth;
+use common\models\Period;
+use common\models\DecRole;
+use common\models\EmployLevel;
+use common\models\FlowExchangePoints;
+use common\models\PerfMonthPrepare;
+use common\models\PeriodPrepare;
+use common\models\ScoreMonth;
+use common\models\UserBonus;
+use common\models\UserRelation;
+use common\models\UserWallet;
+use frontendApi\modules\v1\models\User;
+use Yii;
+
+class BonusController extends BaseController {
+    public $modelClass = CalcBonus::class;
+
+    /**
+     * 我的账户
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionIndex() {
+        $userId = \Yii::$app->user->id;
+        $data = UserBonus::findUseSlaves()->select('BONUS,RECONSUME_POINTS,EXCHANGE_POINTS')->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
+        if (!$data) {
+            $data = [
+                'BONUS' => 0,
+                'RECONSUME_POINTS' => 0,
+                'EXCHANGE_POINTS' => 0,
+            ];
+        }
+        $data['CASH'] = 0;
+        $cashWallet = UserWallet::findOneAsArray('USER_ID=:USER_ID', [':USER_ID'=>$userId], 'CASH');
+        if($cashWallet){
+            $data['CASH'] = $cashWallet['CASH'];
+        }
+        //是否显示车房领袖
+//        $showCFLX = true;
+//        if ($data['CF'] <= 0 && $data['LX'] <= 0) {
+//            $showCFLX = false;
+//            //查看历史最高聘级是否到过五钻
+//            if (EmployLevel::getSortById(Info::getHighEmpLv($userId)) >= 7) {
+//                $showCFLX = true;
+//            }
+//        }
+        // 会员奖金->增值点数      会员余额->消费点数
+        $wallet[] = ['walletType' => 'bonus', 'walletName' => '增值点数', 'amount' => Tool::formatPrice($data['BONUS'])];
+        $wallet[] = ['walletType' => 'cash', 'walletName' => '消费点数', 'amount' => Tool::formatPrice($data['CASH'])];
+        $wallet[] = ['walletType' => 'point', 'walletName' => '复销点数', 'amount' => Tool::formatPrice($data['RECONSUME_POINTS'])];
+        $wallet[] = ['walletType' => 'exchange', 'walletName' => '兑换点数', 'amount' => Tool::formatPrice($data['EXCHANGE_POINTS'])];
+//        if ($showCFLX) {
+//            $wallet[] = ['walletType' => 'cf', 'walletName' => '福利积分一', 'amount' => Tool::formatPrice($data['CF'])];
+//            $wallet[] = ['walletType' => 'lx', 'walletName' => '福利积分二', 'amount' => Tool::formatPrice($data['LX'])];
+//        }
+        //是否显示报单中心
+//        $showBt = true;
+//        $showFl = true;
+//        $userInfo = User::getEnCodeInfo(\Yii::$app->user->id);
+//        if ($userInfo['IS_DEC'] != 1) {
+//            $showBt = false;
+//            $showFl = false;
+//        }else{
+//            $sysConfig = Cache::getSystemConfig();
+//            if(!$sysConfig['openBT']['VALUE']&&!$sysConfig['openPROD']['VALUE']) $showBt = false;
+//            if(!$sysConfig['openFL']['VALUE']) $showFl = false;
+//            $decRole = DecRole::find()->where('1=1')->indexBy('ID')->asArray()->all()[$userInfo['DEC_ROLE_ID']];
+//            if ($decRole['GOODS_SUBSIDY'] <= 0) $showFl = false;
+//        }
+
+        $dealSwitch = isset(Cache::getSystemConfig()['dealSwitch']) ? Cache::getSystemConfig()['dealSwitch']['VALUE'] : '';
+
+        return static::notice(['wallet' => $wallet,'dealSwitch'=>$dealSwitch]);
+    }
+
+    /**
+     * 团队查询
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionTeams() {
+        $userId = \Yii::$app->user->id;
+        $period = Period::instance();
+        $periodNum = $period->getNowPeriodNum();
+        $month = $period->getNowYearMonth();
+        $newMonth = 0;
+        if($period->periodArr['WEEK_NUMBER']==1){
+            $periodNum = $periodNum - 1;
+            $month = $period->getLastMonth()['yearMonth'];
+            $newMonth = 1;
+        }
+        // 判断是否是周日,并且是否是月结节点
+        // 特殊要求,测试环境要去掉是否是周日的判断,周一至周日都能看.正式环境只有周日能看
+        // 读取加入到忽略文件的common/config/config.php文件内容
+        $preparePerfLimit = isset(Yii::$app->params['preparePerfLimit']) ? Yii::$app->params['preparePerfLimit'] : false;
+        $isCalcMonth = $period->isCalcMonth($periodNum);
+        $w = date('w', time());
+        //特殊要求,测试环境要去掉是否是周日的判断,周一至周日都能看
+        if($preparePerfLimit === true && $isCalcMonth != 1) {
+            return static::notice(['user' => [],'team'=>[]]);
+        } else if ($preparePerfLimit !== true && (($w != '0' && $w != '1') || $isCalcMonth != 1)) {
+            return static::notice(['user' => [],'team'=>[]]);
+        } else if ($preparePerfLimit !== true && (($w == '0' || $w == '1') || $isCalcMonth != 1)) {
+            if ($newMonth && $w != '1'){
+                return static::notice(['user' => [],'team'=>[]]);
+            }
+        }
+        // 判断此业绩期是否已经完成生成了预计算业绩单,生成完毕才能看到
+        $isPerfed = PeriodPrepare::isPerfed($periodNum);
+        if (!$isPerfed) {
+            return static::notice(['user' => [],'team'=>[]]);
+        }
+
+        // 获取最新的计算时间
+        $calcAt = PeriodPrepare::getInfo($periodNum);
+        $calcAt = date('Y-m-d H:i:s', $calcAt['PERF_STARTED_AT']);
+
+        // 达标规则,小组底下有一个大于等于一万.或者个人情况里的合计大于等于一万
+        $data = PerfMonthPrepare::getMonthPerfPrepare($userId, $month);
+        // PV_PCS 个人业绩  PV_PSS 月新增团队业绩  PV_PSS_TOTAL月累计团队业绩
+        // 其中页面使用的是月新增团队业绩
+        // 获取用信息
+        $userInfo = User::getEnCodeInfo($userId);
+        $user[0] = [
+            'number' => $userInfo['USER_NAME'],
+            'name' => $userInfo['REAL_NAME'],
+            'perf_status' => '0', // 0  未达标  1为已达标
+            'perf_status_name' => '不达标',
+            'user_perf' => 0, // 个人业绩
+            'team_perf' => 0, // 团队新增累计业绩
+            'total_perf' => 0 // 合计业绩
+        ];
+        if (!empty($data)) {
+            // 调整个人合格了,依旧不显示业绩
+            $userCheck = PerfMonthPrepare::checkPrepareStatus($data['PV_PCS']+$data['PV_PSS']);
+            $user[0]['user_perf'] = Tool::formatPreparePerf($data['PV_PCS']);
+            $user[0]['team_perf'] = $userCheck ? '' : Tool::formatPreparePerf($data['PV_PSS']);
+            $user[0]['total_perf'] = $userCheck ? '' : Tool::formatPreparePerf($data['PV_PCS']+$data['PV_PSS']);
+            $user[0]['perf_status'] = $userCheck ? '1' : $user[0]['perf_status'];
+            $user[0]['perf_status_name'] = $userCheck ? '达标' : $user[0]['perf_status_name'];
+        }
+        $teamInfo = [];
+        // 查询此用户的推荐(开拓)团队一级信息
+        $relation = UserRelation::getChildrenWithDeepAndLayer($userId, 1, 1, $periodNum);
+        $userStatusFlag = false;
+        if ($relation) {
+            // 循环一级开拓用户
+            foreach($relation as $k=>$v) {
+                // 获取此用户预计算月业绩
+                $relationPerf = PerfMonthPrepare::getMonthPerfPrepare($v['USER_ID'], $month);
+                if (empty($relationPerf)) {
+                    $relationPerf['PV_PCS'] = 0;
+                    $relationPerf['PV_PSS'] = 0;
+                }
+                $relationCheck = PerfMonthPrepare::checkPrepareStatus($relationPerf['PV_PCS']+$relationPerf['PV_PSS']);
+                $teamInfo[]['perf_status'] = $relationCheck ? '1' : '0';
+                if ($relationCheck) {
+                    $userStatusFlag = true; // 只要有一个达标,则个人就达标
+                    $teamInfo[$k]['number'] = $v['USER_NAME'];
+                    $teamInfo[$k]['name'] = $v['REAL_NAME'];
+                    $teamInfo[$k]['user_perf'] = '';
+                    $teamInfo[$k]['team_perf'] = '';
+                    $teamInfo[$k]['total_perf'] = '';
+                    $teamInfo[$k]['perf_status'] = '1';
+                    $teamInfo[$k]['perf_status_name'] = '达标';
+                } else {
+                    $teamInfo[$k]['number'] = $v['USER_NAME'];
+                    $teamInfo[$k]['name'] = $v['REAL_NAME'];
+                    $teamInfo[$k]['user_perf'] = Tool::formatPreparePerf($relationPerf['PV_PCS']);
+                    $teamInfo[$k]['team_perf'] = Tool::formatPreparePerf($relationPerf['PV_PSS']);
+                    $teamInfo[$k]['total_perf'] = Tool::formatPreparePerf($relationPerf['PV_PCS']+$relationPerf['PV_PSS']);
+                    $teamInfo[$k]['perf_status'] = '0';
+                    $teamInfo[$k]['perf_status_name'] = '不达标';
+                }
+            }
+        }
+        if ($userStatusFlag === true) {
+            $user[0]['perf_status'] = '1';
+            $user[0]['perf_status_name'] = '达标';
+        }
+
+        return static::notice(['user' => $user,'team'=>$teamInfo,'calcAt' => $calcAt]);
+    }
+
+    /**
+     * 交易记录
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionWalletFlow(){
+        $walletType = \Yii::$app->request->get('walletType');
+        if(!in_array($walletType,['bonus','point','cash','exchange'])) return static::notice('错误的账户类型',400);
+        $dealType = \Yii::$app->request->get('dealType');
+        $createAt = \Yii::$app->request->get('createAt');
+        $remark = \Yii::$app->request->get('remark');
+
+        //获取可以查看几期流水
+        $showFlowPeriodNum = Cache::getSystemConfig()['showFlowPeriodNum']['VALUE'];
+        $periodArr = Period::getNearlyPeriodNum($showFlowPeriodNum);
+        $condition = ' AND USER_ID=:USER_ID AND PERIOD_NUM>=:PERIOD_NUM_MIN AND PERIOD_NUM<=:PERIOD_NUM_MAX';
+        $params = [':USER_ID' => \Yii::$app->user->id,':PERIOD_NUM_MIN' => min($periodArr), ':PERIOD_NUM_MAX'=> max($periodArr)];
+        if($dealType){
+            if($dealType==1){//增加
+                $condition.=' AND IS_INCR=1 AND DEAL_TYPE_IS_PRESET=0';
+            }elseif ($dealType==2){//扣除
+                $condition.=' AND IS_INCR=0 AND DEAL_TYPE_IS_PRESET=0';
+            }else{
+                $condition.=' AND DEAL_TYPE_ID=:DEAL_TYPE';
+                $params[':DEAL_TYPE'] = $dealType;
+            }
+        }
+        if ($createAt) {
+            $condition .= " AND CREATED_AT>:CREATED_START AND CREATED_AT<:CREATED_END";
+            $params[':CREATED_START'] = Date::utcToTime($createAt[0]);
+            $params[':CREATED_END'] = Date::utcToTime($createAt[1])+86399;
+        }
+        if($remark){
+            $condition .= " AND REMARK LIKE :REMARK";
+            $params[':REMARK'] = '%'.$remark.'%';
+        }
+        $data = [];
+        $dealLists=[];
+        $dealTypes=[];
+        if($walletType == 'bonus') {
+            $dealLists = FlowBonus::find()->groupBy('DEAL_TYPE_ID')->select('DEAL_TYPE_ID')->where('USER_ID=:USER_ID',[':USER_ID'=>\Yii::$app->user->id])->asArray()->all();
+            $data = FlowBonus::lists($condition, $params, [
+                'useSlaves' => true,
+                'select' => 'AMOUNT,TOTAL,IS_INCR,REMARK,REMARK_IS_SHOW,PERIOD_NUM,CALC_MONTH,CREATED_AT,DEAL_TYPE_ID,DEAL_TYPE_IS_PRESET',
+                'orderBy' => 'CREATED_AT DESC,SORT DESC',
+            ]);
+        }elseif ($walletType == 'point'){
+            $dealLists = FlowReconsumePoints::find()->groupBy('DEAL_TYPE_ID')->select('DEAL_TYPE_ID')->where('USER_ID=:USER_ID',[':USER_ID'=>\Yii::$app->user->id])->asArray()->all();
+            $data = FlowReconsumePoints::lists($condition, $params, [
+                'useSlaves' => true,
+                'select' => 'AMOUNT,TOTAL,IS_INCR,REMARK,REMARK_IS_SHOW,PERIOD_NUM,CALC_MONTH,CREATED_AT,DEAL_TYPE_ID,DEAL_TYPE_IS_PRESET',
+                'orderBy' => 'CREATED_AT DESC',
+            ]);
+        }elseif ($walletType == 'cash'){
+            $data = FlowWallet::lists($condition, $params, [
+                'select' => 'AMOUNT,TOTAL,IS_INCR,REMARK,PERIOD_NUM,CALC_MONTH,CREATED_AT',
+                'orderBy' => 'CREATED_AT DESC',
+            ]);
+        }else if ($walletType == 'exchange') {
+            $dealLists = FlowExchangePoints::find()->groupBy('DEAL_TYPE_ID')->select('DEAL_TYPE_ID')->where('USER_ID=:USER_ID',[':USER_ID'=>\Yii::$app->user->id])->asArray()->all();
+            $data = FlowExchangePoints::lists($condition, $params, [
+                'useSlaves' => true,
+                'select' => 'AMOUNT,TOTAL,IS_INCR,REMARK,REMARK_IS_SHOW,PERIOD_NUM,CALC_MONTH,CREATED_AT,DEAL_TYPE_ID,DEAL_TYPE_IS_PRESET',
+                'orderBy' => 'CREATED_AT DESC',
+            ]);
+        }
+        if($data) {
+            if($walletType != 'cash') {
+                foreach ($data['list'] as $key => $value) {
+                    if ($value['DEAL_TYPE_IS_PRESET'] == 0) {
+                        $data['list'][$key]['DEAL_TYPE_NAME'] = $value['AMOUNT'] > 0 ? '增加' : '减少';
+                    } else {
+                        $data['list'][$key]['DEAL_TYPE_NAME'] = DealType::getAllTypesForShow()[$value['DEAL_TYPE_ID']]['TYPE_NAME'] ?? '';
+                    }
+                    if ($value['REMARK_IS_SHOW'] == 0) $data['list'][$key]['REMARK'] = '';
+                    $data['list'][$key]['REMARK'] = str_replace("车房养老奖", "福利积分一", $data['list'][$key]['REMARK']);
+                    $data['list'][$key]['REMARK'] = str_replace("领袖分红奖", "福利积分二", $data['list'][$key]['REMARK']);
+                    $data['list'][$key]['REMARK'] = str_replace("车房养老", "福利积分一", $data['list'][$key]['REMARK']);
+                    $data['list'][$key]['REMARK'] = str_replace("领袖分红", "福利积分二", $data['list'][$key]['REMARK']);
+                }
+            }
+        }
+        if($dealLists){
+            foreach ($dealLists as $key=>$value){
+                if(!$value['DEAL_TYPE_ID']) continue;
+                $dealType = DealType::getAllTypesForShow()[$value['DEAL_TYPE_ID']];
+                if($dealType['IS_PRESET']==0){
+                    $dealTypes['1'] = '增加';
+                    $dealTypes['2'] = '扣除';
+                }else{
+                    $dealLists[$key]['DEAL_TYPE_NAME'] = $dealType['TYPE_NAME']??'';
+                    $dealTypes[$value['DEAL_TYPE_ID']] = $dealLists[$key]['DEAL_TYPE_NAME'];
+                }
+            }
+        }
+        $data['dealTypes'] = $dealTypes;
+        unset($dealTypes);
+        return static::notice($data);
+    }
+
+    /**
+     * 最新奖金
+     * @return mixed
+     * @throws \yii\db\Exception
+     * @throws \yii\web\HttpException
+     */
+    public function actionNew(){
+        if(!$periodNum = \Yii::$app->request->get('periodNum')) {
+            $periodNum = Period::sentMaxPeriodNum();
+        }
+        //是否近期期数
+        $showFlowPeriodNum = Cache::getSystemConfig()['showFlowPeriodNum']['VALUE'];
+        $periodArr = Period::getNearlySendPeriodNum($showFlowPeriodNum);
+        if(!in_array($periodNum,$periodArr)) return static::notice('该期不能查看',400);
+        //增加明细开关控制(0 只显示总奖金 1 全部显示)
+        $flowBonusSwitch = Cache::getSystemConfig()['flowBonusSwitch']['VALUE'];
+        $data = $this->_periodBonus($periodNum,$flowBonusSwitch);
+        if(!$data) return static::notice('当期无奖金记录',400);
+        return static::notice($data);
+    }
+
+    /**
+     * 期数对应的奖金-已挂网
+     * @param $periodNum
+     * @param $detailSwitch
+     * @return array
+     * @throws \yii\db\Exception
+     */
+    private function _periodBonus($periodNum,$detailSwitch=1) {
+        $period = Period::instance();
+        $yearMonth = $period->getYearMonth($periodNum);
+        if(!$calcBonus = CalcBonus::find()
+        ->yearMonth($yearMonth)
+        ->where('USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM',[':USER_ID'=>\Yii::$app->user->id,':PERIOD_NUM'=>$periodNum])
+        ->asArray()
+        ->one()){
+            return [];
+        }
+        $sysConfig = Cache::getSystemConfig();
+        if($detailSwitch) {
+            $data[] = ['name' => '期数', 'value' => $periodNum];
+            $data[] = ['name' => '级别', 'value' => Cache::getDecLevelConfig()[$calcBonus['LAST_DEC_LV']]['LEVEL_NAME']];
+            $isCalcMonth = $period->isCalcMonth($periodNum);
+            // 判断如果是月节点,如果用户是无聘级,则判断是否是同享专员
+            if ($isCalcMonth == 1 && $calcBonus['LAST_EMP_LV'] == EmployLevel::NO_LEVEL_ID) {
+                // 如果ORI_BONUS值大于0,则是同享专员
+                $bsDetail = CalcBonusBsDetail::isCommonShare(\Yii::$app->user->id,$periodNum,EmployLevel::NO_LEVEL_ID);
+                if ($bsDetail) {
+                    $tempEmpName = Cache::getEmpLevelConfig()[$calcBonus['LAST_EMP_LV']]['LEVEL_NAME'];
+                    $data[] = ['name' => '最新聘级', 'value' => $tempEmpName.'(同享专员)'];
+                } else {
+                    $data[] = ['name' => '最新聘级', 'value' => Cache::getEmpLevelConfig()[$calcBonus['LAST_EMP_LV']]['LEVEL_NAME']];
+                }
+            } else {
+                $data[] = ['name' => '最新聘级', 'value' => Cache::getEmpLevelConfig()[$calcBonus['LAST_EMP_LV']]['LEVEL_NAME']];
+            }
+            if ($sysConfig['openTG']['VALUE']) {
+                // 销售奖金 就是 原来的推广奖
+                $data[] = ['name' => '销售奖金', 'value' => Tool::formatPrice($calcBonus['ORI_BONUS_TG'])];
+            }
+            // 2022/06/28 特殊需求,如果user_id为670B84FD7C216D4EE055736AECE8644D齐长青,则将服务奖加到团队奖里面去,然后服务奖显示为0
+            if ($sysConfig['openQY']['VALUE']) {
+                // 业绩奖金  就是原来的团队奖 并将业绩奖金改成绩效奖金
+                // $data[] = ['name' => '团队奖', 'value' => Tool::formatPrice($calcBonus['ORI_BONUS_QY'])];
+                if (\Yii::$app->user->id == '670B84FD7C216D4EE055736AECE8644D') {
+                    $data[] = ['name' => '绩效奖金', 'value' => Tool::formatPrice($calcBonus['ORI_BONUS_QY']+$calcBonus['ORI_BONUS_BD'])];
+                } else {
+                    $data[] = ['name' => '绩效奖金', 'value' => Tool::formatPrice($calcBonus['ORI_BONUS_QY'])];
+                }
+            }
+            // 管理奖金 就是新的蓝星奖
+            $data[] = ['name' => '管理奖金', 'value' => Tool::formatPrice($calcBonus['ORI_BONUS_BS'])];
+
+            if ($sysConfig['openGX']['VALUE']) {
+                $data[] = ['name' => '周共享奖金', 'value' => Tool::formatPrice($calcBonus['ORI_BONUS_GX'])];
+                $data[] = ['name' => '月共享奖金', 'value' => Tool::formatPrice($calcBonus['ORI_MONTH_GX_BONUS'])];
+            }
+            if ($sysConfig['openStore']['VALUE']) {
+                // 店服务奖
+                $data[] = ['name' => '店服务奖金', 'value' => Tool::formatPrice($calcBonus['ORI_BONUS_ST'])];
+            }
+            if ($sysConfig['openFW']['VALUE']) {
+                if (\Yii::$app->user->id == '670B84FD7C216D4EE055736AECE8644D') {
+                    $data[] = ['name' => '服务奖金', 'value' => '0.00'];
+                } else {
+                    $data[] = ['name' => '服务奖金', 'value' => Tool::formatPrice($calcBonus['ORI_BONUS_BD'])];
+                }
+            }
+
+            $data[] = ['name' => '总奖金', 'value' => Tool::formatPrice($calcBonus['BONUS_TOTAL'])];
+            $data[] = ['name' => '管理费', 'value' => Tool::formatPrice($calcBonus['MANAGE_TAX'])];
+            $data[] = ['name' => '实发奖金', 'value' => Tool::formatPrice($calcBonus['BONUS_REAL'])];
+            $data[] = ['name' => '复销点数', 'value' => Tool::formatPrice($calcBonus['RECONSUME_POINTS'])];
+            $data[] = ['name' => '兑换点数', 'value' => Tool::formatPrice($calcBonus['EXCHANGE_POINTS'])];
+            $data[] = ['name' => '一市场新增业绩', 'value' => Tool::formatFrontPerf($calcBonus['PV_1L'])];
+            $data[] = ['name' => '二市场新增业绩', 'value' => Tool::formatFrontPerf($calcBonus['PV_2L'])];
+            $data[] = ['name' => '三市场新增业绩', 'value' => Tool::formatFrontPerf($calcBonus['PV_3L'])];
+            $data[] = ['name' => '一市场结余业绩', 'value' => Tool::formatFrontPerf($calcBonus['SURPLUS_1L'])];
+            $data[] = ['name' => '二市场结余业绩', 'value' => Tool::formatFrontPerf($calcBonus['SURPLUS_2L'])];
+            $data[] = ['name' => '三市场结余业绩', 'value' => Tool::formatFrontPerf($calcBonus['SURPLUS_3L'])];
+        }else{
+            $data[] = ['name' => '总奖金', 'value' => Tool::formatPrice($calcBonus['BONUS_TOTAL'])];
+        }
+        return $data;
+    }
+
+    /**
+     * 往期奖金
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionOther(){
+        //获取可以查看几期奖金
+        $showBonusPeriodNum = Cache::getSystemConfig()['showBonusPeriodNum']['VALUE'];
+        $calcBonus = CalcBonus::find()->where('USER_ID=:USER_ID AND IS_SENT=1', [':USER_ID' => \Yii::$app->user->id])
+        ->select('ORI_BONUS_ST,USER_ID,PERIOD_NUM,ORI_BONUS_QY,ORI_BONUS_YC,ORI_BONUS_VIP,ORI_BONUS_STANDARD,ORI_BONUS_BD,ORI_BONUS_TG,
+        ORI_BONUS_XF,BONUS_TOTAL,MANAGE_TAX,BONUS_REAL,BONUS_INCOME,ORI_BONUS_YJ,ORI_BONUS_GX,ORI_MONTH_GX_BONUS,ORI_BONUS_GL,RECONSUME_POINTS,
+        LAST_DEC_LV,LAST_EMP_LV,EXCHANGE_POINTS,ORI_BONUS_BS,ORI_BONUS_MNT,ORI_BONUS_ABBR')
+        ->limit($showBonusPeriodNum)
+        ->orderBy('PERIOD_NUM DESC')
+        ->asArray()
+        ->all();
+        $sysConfig = Cache::getSystemConfig();
+
+        //增加明细开关控制(0 只显示总奖金 1 全部显示)
+        $flowBonusSwitch = Cache::getSystemConfig()['flowBonusSwitch']['VALUE'];
+
+        foreach ($calcBonus as $key => $data) {
+            if($flowBonusSwitch) {
+                $calcBonus[$key]['PERIOD_NUM'] = ['name' => '期数', 'value' => $calcBonus[$key]['PERIOD_NUM']];
+                $calcBonus[$key]['LAST_DEC_NAME'] = ['name' => '级别', 'value' => Cache::getDecLevelConfig()[$calcBonus[$key]['LAST_DEC_LV']]['LEVEL_NAME']];
+                $calcBonus[$key]['LAST_EMP_NAME'] = ['name' => '最新聘级', 'value' => Cache::getEmpLevelConfig()[$calcBonus[$key]['LAST_EMP_LV']]['LEVEL_NAME']];
+
+                // 销售奖金,就是原来的推广奖金
+                if ($sysConfig['openTG']['VALUE']) {
+                    $calcBonus[$key]['BONUS_TG'] = ['name' => '销售奖金', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_TG'])];
+                }
+                // 业绩奖金,就是原来的团队奖  并将业绩奖金改成绩效奖金
+                if ($sysConfig['openQY']['VALUE']) {
+                    $calcBonus[$key]['BONUS_QY'] = ['name' => '绩效奖金', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_QY'])];
+                }
+                // 管理奖金 就是新的蓝星奖金
+                $calcBonus[$key]['BONUS_BS'] = ['name' => '管理奖金', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_BS'])];
+
+                //共享奖
+                if ($sysConfig['openGX']['VALUE']) {
+                    $calcBonus[$key]['BONUS_GX'] = ['name' => '周共享奖金', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_GX'])];
+                    $calcBonus[$key]['ORI_MONTH_GX_BONUS'] = ['name' => '月共享奖金', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_MONTH_GX_BONUS'])];
+                }
+                //店服务奖
+                if ($sysConfig['openStore']['VALUE']) {
+                    $calcBonus[$key]['BONUS_ST'] = ['name' => '店服务奖金', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_ST'])];
+                }
+                //服务奖
+                if ($sysConfig['openFW']['VALUE']) {
+                    $calcBonus[$key]['BONUS_BD'] = ['name' => '服务奖金', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_BD'])];
+                }
+
+                // 2022/06/28 特殊需求,如果user_id为670B84FD7C216D4EE055736AECE8644D齐长青,则将服务奖加到团队奖里面去,然后服务奖显示为0
+                if ($data['USER_ID'] == '670B84FD7C216D4EE055736AECE8644D') {
+                    $calcBonus[$key]['BONUS_BD'] = ['name' => '服务奖金', 'value' => '0.00'];
+                    $calcBonus[$key]['BONUS_QY'] = [
+                        'name' => '绩效奖金',
+                        'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_QY']+$calcBonus[$key]['ORI_BONUS_BD'])
+                    ];
+                }
+                // 总奖金
+                $calcBonus[$key]['BONUS_TOTAL'] = ['name' => '总奖金', 'value' => Tool::formatPrice($calcBonus[$key]['BONUS_TOTAL'])];
+                $calcBonus[$key]['RECONSUME_POINTS'] = ['name' => '复销点数', 'value' => Tool::formatPrice($calcBonus[$key]['RECONSUME_POINTS'])];
+                $calcBonus[$key]['EXCHANGE_POINTS'] = ['name' => '兑换点数', 'value' => Tool::formatPrice($calcBonus[$key]['EXCHANGE_POINTS'])];
+                $calcBonus[$key]['MANAGE_TAX'] = ['name' => '管理费', 'value' => Tool::formatPrice($calcBonus[$key]['MANAGE_TAX'])];
+                $calcBonus[$key]['BONUS_REAL'] = ['name' => '实发奖金', 'value' => Tool::formatPrice($calcBonus[$key]['BONUS_REAL'])];
+                // if ($sysConfig['openYC']['VALUE']) {
+                //     $calcBonus[$key]['BONUS_YC'] = ['name' => '荣衔奖', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_YC'])];
+                // }
+                // if ($sysConfig['openVIP']['VALUE']) {
+                //     $calcBonus[$key]['BONUS_VIP'] = ['name' => 'VIP奖', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_VIP'])];
+                // }
+                // if ($sysConfig['openXF']['VALUE']) {
+                //     $calcBonus[$key]['BONUS_XF'] = ['name' => '消费奖', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_XF'])];
+                // }
+                // if ($sysConfig['openYJ']['VALUE']) {
+                //     $calcBonus[$key]['BONUS_YJ'] = ['name' => '业绩奖', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_YJ'])];
+                // }
+                // if ($sysConfig['openGL']['VALUE']) {
+                //     $calcBonus[$key]['BONUS_GL'] = ['name' => '管理奖', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_GL'])];
+                // }
+                // if ($sysConfig['openJXS']['VALUE']) {
+                //     $calcBonus[$key]['BONUS_STANDARD'] = ['name' => '团队成长奖', 'value' => Tool::formatPrice($calcBonus[$key]['ORI_BONUS_STANDARD'])];
+                // }
+            }else{
+
+                $calcBonus[$key]['BONUS_TOTAL'] = ['name' => '总奖金', 'value' => Tool::formatPrice($calcBonus[$key]['BONUS_TOTAL'])];
+
+            }
+        }
+
+        if($flowBonusSwitch) {
+            $tableKey[] = 'PERIOD_NUM';
+            if ($sysConfig['openTG']['VALUE']) {
+                $tableKey[] = 'BONUS_TG';
+            }
+            if ($sysConfig['openQY']['VALUE']) {
+                $tableKey[] = 'BONUS_QY';
+            }
+            $tableKey[] = 'BONUS_BS';
+
+            if ($sysConfig['openGX']['VALUE']) {
+                $tableKey[] = 'BONUS_GX';
+                $tableKey[] = 'ORI_MONTH_GX_BONUS';
+            }
+            if ($sysConfig['openStore']['VALUE']) {
+                $tableKey[] = 'BONUS_ST';
+            }
+            if ($sysConfig['openFW']['VALUE']) {
+                $tableKey[] = 'BONUS_BD';
+            }
+
+
+            // if ($sysConfig['openXF']['VALUE']) {
+            //     $tableKey[] = 'BONUS_XF';
+            // }
+            // if ($sysConfig['openYJ']['VALUE']) {
+            //     $tableKey[] = 'BONUS_YJ';
+            // }
+
+            // if ($sysConfig['openGL']['VALUE']) {
+            //     $tableKey[] = 'BONUS_GL';
+            // }
+            // if ($sysConfig['openJXS']['VALUE']) {
+            //     $tableKey[] = 'BONUS_STANDARD';
+            // }
+
+            $tableKey[] = 'BONUS_TOTAL';
+            $tableKey[] = 'RECONSUME_POINTS';
+            $tableKey[] = 'EXCHANGE_POINTS';
+            $tableKey[] = 'MANAGE_TAX';
+            $tableKey[] = 'BONUS_REAL';
+        }else{
+            $tableKey[] = 'BONUS_TOTAL';
+        }
+
+        return static::notice(['tableData' => $calcBonus, 'tableKey' => $tableKey]);
+    }
+
+    /**
+     * 实时业绩
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionRealTimePerf() {
+        $userId = \Yii::$app->user->id;
+        $period = Period::instance();
+        $newPerf = Perf::getPeriodNewPerf($userId);
+        $weekData = [['PV_1L' => Tool::formatFrontPerf($newPerf['PV_1L']), 'PV_2L' => Tool::formatFrontPerf($newPerf['PV_2L']), 'PV_3L' => Tool::formatFrontPerf($newPerf['PV_3L'])]];
+        $monthPerf = Perf::getMonthPerf($userId);
+        $monthData = [['PV_1L' => Tool::formatFrontPerf($monthPerf['PV_1L']), 'PV_2L' => Tool::formatFrontPerf($monthPerf['PV_2L']), 'PV_3L' => Tool::formatFrontPerf($monthPerf['PV_3L'])]];
+        $lastMonth = PerfMonth::getMonthPerf($period->getLastMonth()['yearMonth'], $userId);
+        $lastData = [['PV_1L' => Tool::formatFrontPerf($lastMonth['PV_1L_TOTAL']), 'PV_2L' => Tool::formatFrontPerf($lastMonth['PV_2L_TOTAL']), 'PV_3L' => Tool::formatFrontPerf($lastMonth['PV_3L_TOTAL'])]];
+        //是否合格
+//        $lastChkStatus = '';
+//        $lastMonthPerfChk = Cache::getSystemConfig()['lastMonthPerfChk']['VALUE'];
+//        $lastArr = [$lastMonth['PV_1L_TOTAL'], $lastMonth['PV_2L_TOTAL'], $lastMonth['PV_3L_TOTAL'], $lastMonth['PV_4L_TOTAL'], $lastMonth['PV_5L_TOTAL']];
+//        if (array_sum($lastArr) >= $lastMonthPerfChk) {
+//            $lastChkStatus = '已合格';
+//        }
+        //判断大区
+//        $bigLocation = array_search(max($lastArr), $lastArr) + 1;
+        return static::notice(['weekData' => $weekData, 'monthData' => $monthData, 'lastData' => $lastData]);
+    }
+
+    /**
+     * 近十期已挂网的期数
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionDecPeriod() {
+        $showDecPeriodNum = Cache::getSystemConfig()['showDecPeriodNum']['VALUE'];
+        $data = Period::find()->where('IS_SENT=:IS_SENT',[':IS_SENT' => Period::SEND_FINISH])->select('PERIOD_NUM,END_TIME')->limit($showDecPeriodNum)->orderBy('PERIOD_NUM DESC')->asArray()->all();
+        return static::notice($data);
+    }
+
+    /**
+     * 报单中心补助明细
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionFlowBt() {
+        $periodNum = \Yii::$app->request->get('periodNum');
+        $condition = '';
+        $params = [];
+        if (!$periodNum) {
+            return static::notice('请选择期数',400);
+        }
+        if ($periodNum) {
+            $showDecPeriodNum = Cache::getSystemConfig()['showDecPeriodNum']['VALUE'];
+            $periodNums = Period::find()->where('IS_SENT=:IS_SENT',[':IS_SENT' => Period::SEND_FINISH])->select('PERIOD_NUM')->limit($showDecPeriodNum)->orderBy('PERIOD_NUM DESC')->asArray()->all();
+            if(!in_array($periodNum,array_column($periodNums,'PERIOD_NUM'))){
+                return static::notice('该期无法查看',400);
+            }
+            $condition .= ' AND PERIOD_NUM=:PERIOD_NUM';
+            $params[':PERIOD_NUM'] = $periodNum;
+        }
+        $condition .= ' AND USER_ID=:USER_ID';
+        $params[':USER_ID'] = \Yii::$app->user->id;
+        $data = CalcBonusBT::lists($condition, $params, [
+            'select' => 'BT_TYPE,FROM_ORDER_SN,ORDER_TIME,PAY_PV,DELIVERY_AT,TRANSFER_AMOUNT,TRANSFER_AT,AMOUNT',
+            'from' => CalcBonusBT::tableName(),
+            'orderBy' => 'CREATED_AT DESC',
+        ]);
+        if ($data['list']) {
+            foreach ($data['list'] as $key => $value) {
+                $data['list'][$key]['BT_TYPE_NAME'] = CalcBonusBT::TYPE_NAME[$value['BT_TYPE']];
+                foreach ($value as $k=>$item){
+                    if($item==0) $data['list'][$key][$k] ='';
+                }
+            }
+        }
+
+        return static::notice($data);
+    }
+
+    /**
+     * 报单中心货补追溯
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionTraceFl() {
+        $periodNum = \Yii::$app->request->get('periodNum');
+        $condition = '';
+        $params = [];
+        if (!$periodNum) {
+            return static::notice('请选择期数',400);
+        }
+        if ($periodNum) {
+            $showDecPeriodNum = Cache::getSystemConfig()['showDecPeriodNum']['VALUE'];
+            $periodNums = Period::find()->where('IS_SENT=:IS_SENT',[':IS_SENT' => Period::SEND_FINISH])->select('PERIOD_NUM')->limit($showDecPeriodNum)->orderBy('PERIOD_NUM DESC')->asArray()->all();
+            if(!in_array($periodNum,array_column($periodNums,'PERIOD_NUM'))){
+                return static::notice('该期无法查看',400);
+            }
+            $condition .= ' AND PERIOD_NUM=:PERIOD_NUM';
+            $params[':PERIOD_NUM'] = $periodNum;
+        }
+        $condition .= ' AND USER_ID=:USER_ID';
+        $params[':USER_ID'] = \Yii::$app->user->id;
+        $data = CalcBonusFL::lists($condition, $params, [
+            'select' => 'DEC_SN,DEC_AT,DEC_PV,AMOUNT',
+            'from' => CalcBonusFL::tableName(),
+            'orderBy' => 'CREATED_AT DESC',
+        ]);
+
+        return static::notice($data);
+    }
+
+
+
+
+    /**
+     * 查看所传期数的各项奖金
+     * @return mixed
+     * @throws \yii\db\Exception
+     * @throws \yii\web\HttpException
+     */
+    public function actionBonusDetail() {
+        $periodNum = \Yii::$app->request->get('periodNum');
+        $period = Period::instance();
+        $periodInfo = $period->setPeriodNum($periodNum);
+        $yearMonth = $period->getYearMonth($periodNum);
+        if (!$period->isSent($periodNum)) {
+            return static::notice('该期不能查看',400);
+        }
+        $data = CalcBonus::findUseSlaves()->yearMonth($yearMonth)->select('BONUS_QY,BONUS_YC,BONUS_FX,BONUS_LS,BONUS_CF,BONUS_LX,BONUS_FL')->where('PERIOD_NUM=:PERIOD_NUM AND USER_ID=:USER_ID', [':PERIOD_NUM' => $periodNum, ':USER_ID' => \Yii::$app->user->id])->asArray()->one();
+        return static::notice(['period' => $periodInfo, 'bonus' => $data]);
+    }
+
+    /**
+     * 奖金流水
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionFlowBonus() {
+        $yearMonth = \Yii::$app->request->get('yearMonth');
+        if ($yearMonth) {
+            if (!Date::isYearMonth($yearMonth)) {
+                return static::notice('无效参数', 400);
+            }
+        } else {
+            $period = Period::instance();
+            $yearMonth = $period->getNowYearMonth();
+        }
+        $data = FlowBonus::lists(' AND USER_ID=:USER_ID', [':USER_ID' => \Yii::$app->user->id], [
+            'useSlaves' => true,
+            'select' => 'AMOUNT,TOTAL,IS_INCR,REMARK,REMARK_IS_SHOW,PERIOD_NUM,CALC_MONTH,CREATED_AT',
+            'yearMonth' => $yearMonth,
+            'orderBy' => 'CREATED_AT DESC',
+        ]);
+        foreach ($data['list'] as $key => $value) {
+            if($value['REMARK_IS_SHOW']==0) $data['list'][$key]['REMARK'] = '';
+        }
+        return static::notice($data);
+    }
+
+    /**
+     * 提现列表
+     * @return mixed
+     * @throws \yii\base\Exception
+     * @throws \yii\web\HttpException
+     */
+    public function actionWithdraw() {
+        $yearMonth = \Yii::$app->request->get('yearMonth');
+        if ($yearMonth) {
+            if (!Date::isYearMonth($yearMonth)) {
+                return static::notice('无效参数', 400);
+            }
+        } else {
+            $period = Period::instance();
+            $yearMonth = $period->getNowYearMonth();
+        }
+        $data = Withdraw::lists('AND W.USER_ID=:USER_ID', [':USER_ID' => \Yii::$app->user->id], [
+            'useSlaves' => true,
+            'select' => 'W.ID,W.USER_ID,W.IS_AUTO_WITHDRAW,W.AMOUNT,W.AUDIT_STATUS,W.CREATED_AT,W.PAID_AT,W.PAY_TYPE,W.PAID_FAIL_REMARK,W.INVOICE_ID,IA.AMOUNT INVOICE_AMOUNT,IA.AUDIT_STATUS INVOICE_AUDIT_STATUS,IA.UPLOAD_ID',
+            'from' => Withdraw::tableName() . ' AS W',
+            'join' => [
+                ['LEFT JOIN', InvoiceAudit::tableName() . ' AS IA', 'W.ID=IA.WITHDRAW_ID'],
+            ],
+            'yearMonth' => $yearMonth,
+            'orderBy' => 'W.CREATED_AT DESC',
+            //'with' => 'openBank',
+        ]);
+        $auditStatus = array_column(\Yii::$app->params['auditStatus'], null, 'value');
+        foreach ($data['list'] as $key => $value) {
+            $baseInfo = Info::baseInfo($value['USER_ID']);
+            $data['list'][$key]['USER_NAME'] = $baseInfo['USER_NAME'];
+            $data['list'][$key]['REAL_NAME'] = $baseInfo['REAL_NAME'];
+            $data['list'][$key]['STATUS_NAME'] = Withdraw::STATUS_NAME[$value['AUDIT_STATUS']];
+            $data['list'][$key]['INVOICE_STATUS_NAME'] = isset($value['INVOICE_AUDIT_STATUS'])?$auditStatus[$value['INVOICE_AUDIT_STATUS']]['label']:'未传发票';
+        }
+        return static::notice($data);
+    }
+
+    /**
+     * 提交提现申请
+     * @return mixed
+     * @throws \yii\db\Exception
+     * @throws \yii\web\HttpException
+     */
+    public function actionWithdrawAdd() {
+        if (\Yii::$app->request->isPost) {
+            $formModel = new WithdrawForm();
+            $formModel->scenario = 'addByUser';
+            if ($formModel->load(\Yii::$app->request->post(), '') && $formModel->add()) {
+                return static::notice('提现申请已提交,请等待审核');
+            } else {
+                return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
+            }
+        } else {
+            return static::notice('非法请求', 400);
+        }
+    }
+
+    /**
+     * 提现退回
+     * @return mixed
+     * @throws \yii\db\Exception
+     * @throws \yii\web\HttpException
+     */
+    public function actionWithdrawBack() {
+        if (\Yii::$app->request->isPost) {
+            $formModel = new WithdrawForm();
+            $formModel->scenario = 'backByUser';
+            if ($formModel->load(\Yii::$app->request->post(), '') && $formModel->backByUser()) {
+                return static::notice('提现已退回');
+            } else {
+                return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
+            }
+        } else {
+            return static::notice('非法请求', 400);
+        }
+    }
+
+    /**
+     * 判断并获取提现的会员信息
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionChkWithdrawUser() {
+        $uid = \Yii::$app->user->id;
+        if (!Info::isVerified($uid)) {
+            return static::notice('未实名验证无法提现', 400);
+        }
+        $userInfo = UserInfo::findOneAsArray('USER_ID=:USER_ID', [':USER_ID' => $uid], 'IS_BIND,IS_BIND_MAIN,IS_AUTO_WITHDRAW,REG_TYPE,TRANSFER_PROP');
+        if ($userInfo['IS_BIND'] == 1 && $userInfo['IS_BIND_MAIN'] == 0) {
+            return static::notice('附属会员无法提现', 400);
+        }
+        if ($userInfo['IS_AUTO_WITHDRAW'] == 1) {
+            return static::notice('已开启自动提现,如需手动提现请关闭自动提现', 400);
+        }
+        if (!Withdraw::allowWithdraw()) {
+            return static::notice('未到提现日期,请在每月挂网后第一周申请提现', 400);
+        }
+        if (Withdraw::hasThisMonthWithdraw($uid)) {
+            return static::notice('提现失败,每月只可以提现一次', 400);
+        }
+        if (Withdraw::existWaitAudit($uid)) {
+            return static::notice('提现失败,您存在未审核的提现记录', 400);
+        }
+        //是否显示服务协议
+        $regType = RegType::findOneAsArray('ID=:ID', [':ID' => $userInfo['REG_TYPE']], 'IS_PACT');
+        $path = \Yii::getAlias('@common/runtime/datas/pact.php');
+        if (!file_exists($path)) {
+            $oneData = '';
+        } else {
+            $oneData = include $path;
+        }
+        $isCanTransferProp = Cache::getSystemConfig()['isCanTransferProp']['VALUE'];
+        if ($isCanTransferProp == 0) {
+            $userInfo['WITHDRAW_PROP'] = 100;
+        } else {
+            $userInfo['WITHDRAW_PROP'] = 100 - $userInfo['TRANSFER_PROP'];
+        }
+        return static::notice(['userInfo' => $userInfo, 'isPact' => $regType['IS_PACT'], 'content' => $oneData['CONTENT']]);
+    }
+
+    /**
+     * 归集附属会员奖金
+     * @return mixed
+     * @throws \yii\db\Exception
+     * @throws \yii\web\HttpException
+     */
+    public function actionCollectBind() {
+        $transferBonusForm = new TransferBonusForm();
+        if ($totals=$transferBonusForm->collectBind(\Yii::$app->user->id)) {
+            return static::notice('归集完成,归集金额'.$totals);
+        } else {
+            if($totals==0){
+                return static::notice('归集完成,归集金额'.$totals);
+            }else{
+                return static::notice(Form::formatErrorsForApi($transferBonusForm->getErrors()), 400);
+            }
+        }
+    }
+
+    /**
+     * 上传发票之前
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionInvoiceBeforeAdd() {
+        $id = \Yii::$app->request->get('id');
+        $withdraw = Withdraw::findOneAsArray('ID=:ID', [':ID' => $id]);
+        if (!$withdraw) {
+            return static::notice('数据不存在', 400);
+        }
+        $uploadInvoiceTip = Cache::getSystemConfig()['uploadInvoiceTip']['VALUE'];
+        if ($withdraw['AUDIT_STATUS'] == Withdraw::STATUS_APPLIED) {
+            return static::notice(['addInvoiceTips' => $uploadInvoiceTip]);
+        } else {
+            return static::notice('该提现记录无法上传发票', 400);
+        }
+    }
+
+    /**
+     * 上传发票
+     * @return mixed
+     * @throws \yii\db\Exception
+     * @throws \yii\web\HttpException
+     */
+    public function actionInvoiceAdd() {
+        $id = \Yii::$app->request->get('id');
+        $withdraw = Withdraw::findOneAsArray('ID=:ID', [':ID' => $id]);
+        if (!$withdraw) {
+            return static::notice('数据不存在', 400);
+        }
+        if (\Yii::$app->request->isPost) {
+            $formModel = new UploadForm();
+            $formModel->scenario = 'invoiceFront';
+            $formModel->file = UploadedFile::getInstanceByName('file');
+            $formModel->withdrawId = $withdraw['ID'];
+            $formModel->remark = '提现'.$withdraw['SN'].'发票';
+            //$formModel->token = \Yii::$app->request->post('uploadToken');
+            $formModel->token = \Yii::$app->request->request('uploadToken');
+            if ($formModel->file && $formModel->upload()) {
+                return static::notice('上传成功');
+            } else {
+                return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
+            }
+        }
+    }
+
+    /**
+     * 显示上传的发票
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionInvoiceShow() {
+        $id = \Yii::$app->request->get('id');
+        $uploads = Uploads::findOneAsArray('ID=:ID', [':ID' => $id],'URL');
+        if (!$uploads) {
+            return static::notice('数据不存在', 400);
+        }
+        return static::notice($uploads['URL']);
+    }
+
+    /**
+     * 获取可用余额
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionAvailableBalance() {
+        return static::notice(Balance::getAvailableBalance(\Yii::$app->user->id));
+    }
+
+    /**
+     * 查看业绩
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionPerf() {
+        $yearMonth = \Yii::$app->request->get('yearMonth');
+        if ($yearMonth) {
+            if (!Date::isYearMonth($yearMonth)) {
+                return static::notice('无效参数', 400);
+            }
+        } else {
+            $period = Period::instance();
+            $yearMonth = $period->getNowYearMonth();
+        }
+        $data = PerfPeriod::lists('AND P.USER_ID=:USER_ID AND PN.IS_SENT=1', [':USER_ID' => \Yii::$app->user->id], [
+            'select' => 'P.*',
+            'yearMonth' => $yearMonth,
+            'from' => PerfPeriod::tableName() . ' AS P',
+            'join' => [
+                ['LEFT JOIN', Period::tableName() . ' AS PN', 'P.PERIOD_NUM=PN.PERIOD_NUM']
+            ],
+            'orderBy' => 'P.PERIOD_NUM DESC',
+        ]);
+        $data['request']['yearMonth'] = $yearMonth;
+        return static::notice($data);
+    }
+
+    /**
+     * 转账列表
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionTransferList() {
+        $type = \Yii::$app->request->get('type', 'out');
+        if ($type == 'out') {
+            $condition = ' AND T.FROM_UID=:USER_ID';
+        } else {
+            $condition = ' AND T.TO_UID=:USER_ID';
+        }
+        $params = [
+            ':USER_ID' => \Yii::$app->user->id,
+        ];
+        $data = Transfer::lists($condition, $params, [
+            'select' => 'FUI.USER_NAME AS FROM_USER_NAME, TUI.USER_NAME AS TO_USER_NAME, T.AMOUNT, T.PERIOD_NUM, T.CREATED_AT',
+            'from' => Transfer::tableName() . ' AS T',
+            'join' => [
+                ['LEFT JOIN', UserInfo::tableName() . ' AS FUI', 'FUI.USER_ID=T.FROM_UID'],
+                ['LEFT JOIN', UserInfo::tableName() . ' AS TUI', 'TUI.USER_ID=T.TO_UID'],
+            ],
+        ]);
+        return static::notice($data);
+    }
+
+    /**
+     * 转账
+     * @throws \yii\db\Exception
+     * @throws \yii\web\HttpException
+     */
+    public function actionTransferAdd() {
+        if (\Yii::$app->request->isPost) {
+            $formModel = new TransferForm();
+            if ($formModel->load(\Yii::$app->request->post(), '') && $formModel->transfer()) {
+                return static::notice('转账成功');
+            } else {
+                return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
+            }
+        }
+    }
+
+    /**
+     * 检查转账资格
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionChkTransferUser() {
+        $uid = \Yii::$app->user->id;
+        if (!Info::isVerified($uid)) {
+            return static::notice('未实名验证无法转账', 400);
+        }
+        $userInfo = UserInfo::findOneAsArray('USER_ID=:USER_ID', [':USER_ID' => $uid], 'ALLOW_TRANSFER,TRANSFER_PROP');
+        if($userInfo['ALLOW_TRANSFER']==0){
+            return static::notice('您不允许转账', 400);
+        }
+        $isCanTransferProp = Cache::getSystemConfig()['isCanTransferProp']['VALUE'];
+        if($isCanTransferProp==0){
+            $userInfo['TRANSFER_PROP']=100;
+        }
+        return static::notice(['userInfo' => $userInfo]);
+    }
+
+    /**
+     * 房产积分列表
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionFcPoint() {
+        $condition = ' AND USER_ID=:USER_ID';
+        $params = [':USER_ID' => \Yii::$app->user->id];
+
+        $yearMonth = \Yii::$app->request->get('yearMonth');
+        if ($yearMonth) {
+            if (!Date::isYearMonth($yearMonth)) {
+                return static::notice('无效参数', 400);
+            }
+            $condition .= ' AND CALC_MONTH=:CALC_MONTH';
+            $params['CALC_MONTH'] = $yearMonth;
+        }
+
+        $data = ScoreMonth::lists($condition, $params, [
+            'from' => ScoreMonth::tableName(),
+            'orderBy' => 'ID DESC',
+        ]);
+        return static::notice($data);
+    }
+}

+ 27 - 0
frontendApi/modules/v1/controllers/DashboardController.php

@@ -19,6 +19,8 @@ use common\models\CalcBonus;
 use common\models\FlowBonus;
 use common\models\Period;
 use common\models\ReconsumePool;
+use common\models\RemainPv;
+use common\models\Order;
 
 class DashboardController extends BaseController
 {
@@ -72,6 +74,29 @@ class DashboardController extends BaseController
                 $wkrd =$k+1;break;
             }
         }
+        //剩余分期PV显示
+        $myRemainPv = RemainPv::findOne(['USER_ID'=>$baseInfo['ID']])->REMAIN_PV ?? 0;
+        // 找到当月的所有订单,计算总PV及总REMAIN_PV
+        $myOrders = Order::fetchOrderCurrentMonth($periodNum, $baseInfo['ID']);
+
+        $currentPv = $myOrders->SUM('PV');
+        $currentRemainPv = $myOrders->SUM('REMAIN_PV');
+
+        $totalRemainPv = $myRemainPv + $currentRemainPv;
+
+        $sysConfig = Cache::getSystemConfig();
+        $mesureUpCondition =  $sysConfig['monthPcsPvFxCondition']['VALUE']; // 月达标条件 NC默认300
+
+        $remainMonth = round($totalRemainPv / $mesureUpCondition);
+
+        if($currentPv >= $mesureUpCondition){ // 如果当月合格,则活跃资格延后一个月
+            $activeEndStr = date("Y-m", strtotime('next month'));
+        }else{
+            $activeEndStr = date("Y-m");
+        }
+
+        $activeEndStr = $activeEndStr. " + $remainMonth months";
+        $activeEnd = date("Y-m-d H:i:s", strtotime($activeEndStr));
 
         return static::notice([
             'nowTime' => $nowTime,
@@ -82,6 +107,8 @@ class DashboardController extends BaseController
             'slides'=>Ad::findUseSlaves()->select('ID,IMAGE,LID,TITLE,CONTENT,TYPE')->where('LID=:LID AND STATUS=1', [':LID'=>'7EFF6260A16C3CC7E053693418AC03E4'])->orderBy('SORT ASC')->asArray()->all(),
             'news'=>$news,
             'periodNum'=>$periodNum.'期,'.$curYM['CALC_MONTH'].'月第'.$wkrd.'周,共'.$weeks.'周',
+            'myRemainPv'=>$totalRemainPv,
+            'activeEnd'=>$activeEnd
         ]);
     }
 

+ 6 - 4
frontendApi/modules/v1/controllers/OauthController.php

@@ -57,7 +57,7 @@ class OauthController extends BaseController
         if($isDec==1 && $item['allow']=='declarer'){
             return true;
         }
-        
+
         return false;
     }
 
@@ -95,7 +95,9 @@ class OauthController extends BaseController
      * @throws \yii\base\Exception
      */
     public function actionLogin() {
-        $userName = Yii::$app->request->post('userName');
+        $userName = preg_replace("/[^A-Z0-9]/", "", Yii::$app->request->post('userName'));
+        $posts = Yii::$app->request->post();
+        $posts['userName'] = $userName;
         $model = new LoginForm(
             [
                 'userName' =>$userName
@@ -106,7 +108,7 @@ class OauthController extends BaseController
         }else {
             $model->scenario = 'login';
         }
-        if ($model->load(Yii::$app->request->post(), '') && $model->login()) {
+        if ($model->load($posts, '') && $model->login()) {
             $token = Yii::$app->getUser()->getToken();
             return static::notice($token);
         } else {
@@ -201,4 +203,4 @@ class OauthController extends BaseController
         return static::notice('非法访问', 400);
     }
 
-}
+}

+ 17 - 9
frontendApi/modules/v1/controllers/ShopController.php

@@ -33,10 +33,10 @@ class ShopController extends BaseController {
      */
     public function actionIndex() {
         $condition = ' AND STATUS=1 AND (FIND_IN_SET(2,GIFT_TYPE)>0';
-        $isStudio = User::getEnCodeInfo(\Yii::$app->user->id)['IS_STUDIO'];
-        if($isStudio==1){
-            $condition.= " OR FIND_IN_SET(4,GIFT_TYPE)>0";
-        }
+//        $isStudio = User::getEnCodeInfo(\Yii::$app->user->id)['IS_STUDIO'];
+//        if($isStudio==1){
+//            $condition.= " OR FIND_IN_SET(4,GIFT_TYPE)>0";
+//        }
         $condition.=")";
 
         $data = ShopGoods::lists($condition, [], [
@@ -166,14 +166,16 @@ class ShopController extends BaseController {
         ]);
         foreach ($data['list'] as $key => $value) {
             if($value['ORDER_TYPE']=='ZC'){
-                $data['list'][$key]['ORDER_TYPE'] = '单';
+                $data['list'][$key]['ORDER_TYPE'] = '单';
             }else{
-                $data['list'][$key]['ORDER_TYPE'] = in_array($value['PAY_TYPE'], ['cash', 'paystack']) ? '复消': '积分';
+//                $data['list'][$key]['ORDER_TYPE'] = in_array($value['PAY_TYPE'], ['cash', 'paystack']) ? '复消': '积分';
+                $data['list'][$key]['ORDER_TYPE'] = '复消';
             }
             //$data['list'][$key]['PROVINCE_NAME'] = $value['PROVINCE'] ? Region::getCnName($value['PROVINCE']) : '';
            //$data['list'][$key]['CITY_NAME'] = $value['CITY'] ? Region::getCnName($value['CITY']) : '';
             //$data['list'][$key]['COUNTY_NAME'] = $value['COUNTY'] ? Region::getCnName($value['COUNTY']) : '';
             $data['list'][$key]['PAY_AT'] = Date::convert($value['PAY_AT'],'Y-m-d H:i:s');
+            $data['list'][$key]['PAY_TYPE'] = $value['PAY_TYPE'] == 'cash' ? '消费点数' : ($value['PAY_TYPE'] == 'exchange' ? '兑换点数' : '复消点数');
         }
         return static::notice($data);
     }
@@ -182,13 +184,19 @@ class ShopController extends BaseController {
      * 会员复消
      */
     public function actionReconsume() {
-        $condition = ' AND STATUS=1 AND (FIND_IN_SET(2,GIFT_TYPE)>0 OR FIND_IN_SET(4,GIFT_TYPE)>0)';
+        $isStudio = User::getEnCodeInfo(\Yii::$app->user->id)['IS_STUDIO'];
+        $condition = " AND STATUS=1";
+        if($isStudio==1){
+            $condition .= " AND  (FIND_IN_SET(4,GIFT_TYPE)>0)";
+        }
+//        $condition.= ")";
+
         $data = ShopGoods::lists($condition, [], [
             'orderBy' => 'SORT ASC,CREATED_AT DESC',
             'from' => ShopGoods::tableName(),
         ]);
         foreach ($data['list'] as $key => $value) {
-            $data['list'][$key]['DISCOUNT'] = $value['SELL_DISCOUNT']*100;  
+            $data['list'][$key]['DISCOUNT'] = $value['SELL_DISCOUNT']*100;
         }
         return static::notice($data);
     }
@@ -231,4 +239,4 @@ class ShopController extends BaseController {
         }
     }
 
-}
+}

+ 15 - 0
frontendApi/modules/v1/controllers/SiteController.php

@@ -271,4 +271,19 @@ class SiteController extends BaseController
         $siteTitle = $systemConfig['siteTitle']['VALUE'];
         return static::notice(['siteClose' => false, 'siteTitle' => $siteTitle]);
     }
+
+    /**
+     * 发送钉钉测试信息
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionSendNotice()
+    {
+        $data = [
+            'code' => 400,
+            'message' => 'autoSendDingTalk',
+        ];
+
+        return static::notice(['data' => $data['bug监控正常运行,没有发现异常,奥利给!']]);
+    }
 }

+ 11 - 10
frontendApi/modules/v1/controllers/UserController.php

@@ -313,12 +313,14 @@ class UserController extends BaseController {
         $isDec = User::getEnCodeInfo(\Yii::$app->user->id)['IS_DEC'];
         $isStudio = User::getEnCodeInfo(\Yii::$app->user->id)['IS_STUDIO'];
         $decUserName = User::getEnCodeInfo(\Yii::$app->user->id)['USER_NAME'];
-        $query_condition= " AND (1<>1";
-        if(!$isDecReg || ($isDecReg && $isDec==1)){
-            $query_condition = " AND (FIND_IN_SET(1,GIFT_TYPE)>0";
-        }
+//        $query_condition= " AND (1<>1";
+//        if(!$isDecReg || ($isDecReg && $isDec==1)){
+//            $query_condition = " AND (FIND_IN_SET(1,GIFT_TYPE)>0";
+//        }
         if($isStudio==1){
-            $query_condition.= " OR FIND_IN_SET(3,GIFT_TYPE)>0";
+            $query_condition = " AND ((FIND_IN_SET(1,GIFT_TYPE)>0) OR (FIND_IN_SET(3,GIFT_TYPE)>0)";
+        }else{
+            $query_condition = " AND (FIND_IN_SET(1,GIFT_TYPE)>0";
         }
         $query_condition.= ")";
 
@@ -370,12 +372,11 @@ class UserController extends BaseController {
         $isDecReg = Cache::getSystemConfig()['isDecReg']['VALUE'];
         $isDec = User::getEnCodeInfo(\Yii::$app->user->id)['IS_DEC'];
         $isStudio = User::getEnCodeInfo(\Yii::$app->user->id)['IS_STUDIO'];
-        $query_condition= " AND (1<>1";
-        if(!$isDecReg || ($isDecReg && $isDec==1)){
-            $query_condition = " AND (FIND_IN_SET(1,GIFT_TYPE)>0";
-        }
+
         if($isStudio==1){
-            $query_condition.= " OR FIND_IN_SET(3,GIFT_TYPE)>0";
+            $query_condition = " AND ((FIND_IN_SET(1,GIFT_TYPE)>0) OR (FIND_IN_SET(3,GIFT_TYPE)>0)";
+        }else{
+            $query_condition = " AND (FIND_IN_SET(1,GIFT_TYPE)>0";
         }
         $query_condition.= ")";
 

+ 10 - 3
frontendEle/src/views/dashboard/index.vue

@@ -17,6 +17,8 @@
               </el-col>
               <el-col :xs="24" :sm="24" :md="24" :lg="4" :xl="12">会员级别:{{decLvName}}</el-col>
               <el-col :xs="24" :sm="24" :md="24" :lg="8" :xl="12">当前业绩期:{{periodNum}}</el-col>
+<!--              <el-col :xs="24" :sm="24" :md="24" :lg="8" :xl="12">剩余PV:{{myRemainPv}}</el-col>&lt;!&ndash;剩余的PV&ndash;&gt;-->
+<!--              <el-col :xs="24" :sm="24" :md="24" :lg="8" :xl="12">活跃日期截止:{{activeEnd}}</el-col>&lt;!&ndash;活跃日期截止&ndash;&gt;-->
             </el-row>
           </el-col>
         </el-row>
@@ -86,6 +88,8 @@
         this.news = response.news
         this.periodNum = response.periodNum
         this.decLvName = response.decLvName
+        this.myRemainPv = response.myRemainPv
+        this.activeEnd = response.activeEnd
         this.loading = false
         this.imgLoad()
         return network.getData(`dashboard/bonus-num`)
@@ -117,6 +121,8 @@
         news: [],
         periodNum: '',
         decLvName: '',
+        myRemainPv: '',
+        activeEnd: '',
         bannerHeight: '',
       }
     },
@@ -126,11 +132,12 @@
       }
     },
     methods: {
-      getEmpIco(type) {
+      getEmpIco (type) {
         if (type) return require('@/assets/emp-ico-' + type + '.png')
       },
-      getEmpBg(type) {
-        if (type != 0) return 'backgroundImage:url(' + require('@/assets/emp-bg-' + type + '.png') + ')'
+      getEmpBg (type) {
+        let index = parseInt(type)
+        if (index) return 'backgroundImage:url(' + require('@/assets/emp-bg-' + index + '.png') + ')'
       },
       sub_str(str, len = 15) {
         if (str) return str.slice(0, len)

+ 64 - 66
frontendEle/src/views/finance/transfer-add.vue

@@ -66,22 +66,22 @@ export default {
   },
   data () {
     return {
-      allWallet:{'bonus':'会员账户','cash':'现金钱包','point':'复销点数'},
+      allWallet: {'bonus': '会员账户', 'cash': '现金钱包', 'point': '复销点数'},
       form: {
-        type:1,
+        type: 1,
         toUserName: '',
         toRealName: '',
         amount: 0,
         payPassword: '',
         remark: '',
-        transferCode: '',
+        transferCode: ''
       },
       userInfo: {
-        TRANSFER_PROP:100,
+        TRANSFER_PROP: 100
       },
       balance: 0,
       cash: 0,
-      point:0,
+      point: 0,
       maxAmount: 0,
       fee: '0',
       realAmount: 0,
@@ -91,32 +91,33 @@ export default {
       submitButtonStat: false,
       openBanks: null,
       tool: tool,
-      transferConfig: [],
+      transferConfig: []
     }
   },
   methods: {
-      handleChange() {
-          this.loading = true
-          network.getData('user/full-info', {userName: this.form.toUserName}).then(response => {
-              this.form.toRealName = response.REAL_NAME
-              this.loading = false
-          }).catch(response => {
-                  this.loading = false
-          })
-      },
-    chkReal(){
-      this.realAmount = tool.formatPrice(this.form.amount * (100-this.fee) * 0.01)
+    handleChange () {
+      this.loading = true
+      network.getData('user/full-info', {userName: this.form.toUserName}).then(response => {
+        this.form.toRealName = response.REAL_NAME
+        this.loading = false
+      }).catch(response => {
+        this.form.toRealName = ''
+        this.loading = false
+      })
+    },
+    chkReal () {
+      this.realAmount = tool.formatPrice(this.form.amount * (100 - this.fee) * 0.01)
     },
-    getWalletName(out,inw){
-      return this.allWallet[out]+'转'+this.allWallet[inw]
+    getWalletName (out, inw) {
+      return this.allWallet[out] + '转' + this.allWallet[inw]
     },
-    handleTypeChange(){
-      //奖金转现金
-      this.fee = this.transferConfig[this.form.type-1].fee
+    handleTypeChange () {
+      // 奖金转现金
+      this.fee = this.transferConfig[this.form.type - 1].fee
     },
-    chkTransferUserinfo(){
+    chkTransferUserinfo () {
       network.getData(`finance/chk-transfer-user`).then(response => {
-        console.log(response);
+        // console.log(response)
         this.loading = false
         this.userInfo = response.userInfo
         this.transferConfig = response.transferConfig
@@ -126,7 +127,7 @@ export default {
         this.$router.go(-1)
       })
     },
-    getBalance() {
+    getBalance () {
       this.$message({
         message: '正获取您的奖金...',
         type: 'info'
@@ -140,54 +141,51 @@ export default {
         this.loading = false
       })
     },
-    getMaxAmount(){
+    getMaxAmount () {
       this.maxAmount = Math.floor(tool.formatPrice(this.balance * this.userInfo.TRANSFER_PROP * 0.01))
       this.transferProp = this.userInfo.TRANSFER_PROP
     },
     onSubmit () {
-        this.submitButtonStat = true
-        let path = 'finance/transfer-add'
-
-        network.getData('finance/mult-point').then(response => {
-            this.form.transferCode = response.transferCode
+      this.submitButtonStat = true
+      let path = 'finance/transfer-add'
 
-            this.$prompt('请输入支付密码', '提示', {
-                confirmButtonText: '确定',
-                cancelButtonText: '取消',
-                inputType: 'password',
-                inputPattern: /\S+/,
-                inputErrorMessage: '请输入支付密码',
-                beforeClose:async (action, instance, done)=>{
-                    if (action === 'confirm') {
-                        instance.confirmButtonLoading = true;
-                        instance.confirmButtonText = '执行中...';
-                        console.log(instance.inputValue);
-                        this.form.payPassword = instance.inputValue;
-                        await network.postData(path, this.form).then(response => {
+      network.getData('finance/mult-point').then(response => {
+        this.form.transferCode = response.transferCode
 
-                            instance.confirmButtonLoading = false;
-                            done();
-                            this.$message({
-                                message: response,
-                                type: 'success'
-                            })
-                            this.submitButtonStat = false
-                            this.$router.go(-1)
-                        }).catch(error=>{
-                            instance.confirmButtonLoading = false;
-                            this.submitButtonStat = false
-                            done();
-                        })
-                    }else {
-                        this.submitButtonStat = false
-                        done();
-                    }
-                }
-            })
+        this.$prompt('请输入支付密码', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          inputType: 'password',
+          inputPattern: /\S+/,
+          inputErrorMessage: '请输入支付密码',
+          beforeClose: async (action, instance, done) => {
+            if (action === 'confirm') {
+              instance.confirmButtonLoading = true
+              instance.confirmButtonText = '执行中...'
+              console.log(instance.inputValue)
+              this.form.payPassword = instance.inputValue
+              await network.postData(path, this.form).then(response => {
+                instance.confirmButtonLoading = false
+                done()
+                this.$message({
+                  message: response,
+                  type: 'success'
+                })
+                this.submitButtonStat = false
+                this.$router.go(-1)
+              }).catch(error => {
+                instance.confirmButtonLoading = false
+                this.submitButtonStat = false
+                done()
+              })
+            } else {
+              this.submitButtonStat = false
+              done()
+            }
+          }
         })
-
-
-    },
+      })
+    }
   }
 }
 </script>

+ 144 - 146
frontendEle/src/views/finance/withdraw-add.vue

@@ -57,160 +57,158 @@
 </template>
 
 <script>
-  import Vue from 'vue'
-  import store from '@/utils/vuexStore'
-  import network from '@/utils/network'
-  import tool from '@/utils/tool'
-  import userInfo from '@/utils/userInfo'
-  import {CDN_IMG_URL} from '@/utils/config'
+import Vue from 'vue'
+import store from '@/utils/vuexStore'
+import network from '@/utils/network'
+import tool from '@/utils/tool'
+import userInfo from '@/utils/userInfo'
+import {CDN_IMG_URL} from '@/utils/config'
 
-  export default {
-    name: 'finance_withdraw-add',
-    mounted() {
-      this.init()
-      this.chkWithdrawUserinfo()
-    },
-    data() {
-      return {
-        form: {
-          applyAmount: 0,
-          payPassword: '',
-          withdrawCode: '',
-        },
-        balance: 0,
-        loading: true,
-        userInfo: {
-          WITHDRAW_PROP:100
-        },
-        submitButtonStat: false,
-        openBanks: null,
-        isPact: null,
-        checked: this.chkAgree(),
-        content: null,
-        dialogVisible: false,
-        idCardDialogVisible: false,
-        withdrawProp: 100,
-        maxAmount: 0,
-        minAmount: 0,
-        withdrawFee: 0,
-        idCardInfoQrCodeUrl:'',
-      }
-    },
-    methods: {
-      init() {
-        this.idCardInfoQrCodeUrl = CDN_IMG_URL + "img_data/idCardInfo.png"
+export default {
+  name: 'finance_withdraw-add',
+  mounted () {
+    this.init()
+    this.chkWithdrawUserinfo()
+  },
+  data () {
+    return {
+      form: {
+        applyAmount: 0,
+        payPassword: '',
+        withdrawCode: ''
       },
-      chkAgree() {
-        if (this.isPact === '0') return true
-        return tool.getStorage('withdrawAgree'+userInfo.userId()) === '1' ? true : false
+      balance: 0,
+      loading: true,
+      userInfo: {
+        WITHDRAW_PROP: 100
       },
-      chkWithdrawUserinfo() {
-        network.getData(`finance/chk-withdraw-user`).then(response => {
-          this.loading = false
-          this.userInfo = response.userInfo
-          this.isPact = response.isPact
-          this.checked=this.chkAgree()
-          this.content = response.content
-          this.minAmount = response.minAmount
-          this.withdrawFee = response.withdrawFee
-            this.getBalance()
-        }).catch(() => {
-          this.$router.go(-1)
-        })
-      },
-      getBalance() {
-        this.$message({
-          message: '正获取您的奖金...',
-          type: 'info'
-        })
-        network.getData('finance/available-balance').then(response => {
-          this.$message.closeAll()
-          this.balance = response.bonus
-          this.getMaxAmount()
-          this.loading = false
-        })
-      },
-      getMaxAmount(){
-          this.maxAmount = this.balance
-        // this.maxAmount = Math.floor(tool.formatPrice(this.balance * this.userInfo.WITHDRAW_PROP * 0.01))
-        // this.withdrawProp = this.userInfo.WITHDRAW_PROP
-      },
-      onSubmit() {
-        this.submitButtonStat = true
-        tool.setStorage('withdrawAgree'+userInfo.userId(), 1)
-        console.log(tool.getStorage('withdrawAgree'))
-        let path = 'finance/withdraw-add'
-
-          network.getData('finance/wd-mult-point').then(response => {
-              this.form.withdrawCode = response.withdrawCode
+      submitButtonStat: false,
+      openBanks: null,
+      isPact: null,
+      checked: this.chkAgree(),
+      content: null,
+      dialogVisible: false,
+      idCardDialogVisible: false,
+      withdrawProp: 100,
+      maxAmount: 0,
+      minAmount: 0,
+      withdrawFee: 0,
+      idCardInfoQrCodeUrl: ''
+    }
+  },
+  methods: {
+    init () {
+      this.idCardInfoQrCodeUrl = CDN_IMG_URL + 'img_data/idCardInfo.png'
+    },
+    chkAgree () {
+      if (this.isPact === '0') return true
+      return tool.getStorage('withdrawAgree' + userInfo.userId()) === '1' ? true : false
+    },
+    chkWithdrawUserinfo () {
+      network.getData(`finance/chk-withdraw-user`).then(response => {
+        this.loading = false
+        this.userInfo = response.userInfo
+        this.isPact = response.isPact
+        this.checked = this.chkAgree()
+        this.content = response.content
+        this.minAmount = response.minAmount
+        this.withdrawFee = response.withdrawFee
+        this.getBalance()
+      }).catch(() => {
+        this.$router.go(-1)
+      })
+    },
+    getBalance () {
+      this.$message({
+        message: '正获取您的奖金...',
+        type: 'info'
+      })
+      network.getData('finance/available-balance').then(response => {
+        this.$message.closeAll()
+        this.balance = response.bonus
+        this.getMaxAmount()
+        this.loading = false
+      })
+    },
+    getMaxAmount () {
+      this.maxAmount = this.balance
+      // this.maxAmount = Math.floor(tool.formatPrice(this.balance * this.userInfo.WITHDRAW_PROP * 0.01))
+      // this.withdrawProp = this.userInfo.WITHDRAW_PROP
+    },
+    onSubmit () {
+      this.submitButtonStat = true
+      tool.setStorage('withdrawAgree' + userInfo.userId(), 1)
+      console.log(tool.getStorage('withdrawAgree'))
+      let path = 'finance/withdraw-add'
 
-              this.$prompt('请输入支付密码', '提示', {
-                  confirmButtonText: '确定',
-                  cancelButtonText: '取消',
-                  inputType: 'password',
-                  inputPattern: /\S+/,
-                  inputErrorMessage: '请输入支付密码',
-                  beforeClose:async (action, instance, done)=>{
-                      if (action === 'confirm') {
-                          instance.confirmButtonLoading = true;
-                          instance.confirmButtonText = '执行中...';
-                          console.log(instance.inputValue);
-                          this.form.payPassword = instance.inputValue;
-                          await network.postData(path, this.form).then(response => {
+      network.getData('finance/wd-mult-point').then(response => {
+        this.form.withdrawCode = response.withdrawCode
 
-                              instance.confirmButtonLoading = false;
-                              done();
-                              this.$message({
-                                  message: response,
-                                  type: 'success'
-                              })
-                              tool.setStorage('withdrawAgree', 1)
-                              this.submitButtonStat = false
-                              this.$router.go(-1)
-                          }).catch(error=>{
-                              instance.confirmButtonLoading = false;
-                              this.submitButtonStat = false
-                              if( error.status === 424 ) {
-                                  this.idCardDialogVisible = true
-                              }
-                              done();
-                          })
-                      }else {
-                          this.submitButtonStat = false
-                          done();
-                      }
-                  }
+        this.$prompt('请输入支付密码', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          inputType: 'password',
+          inputPattern: /\S+/,
+          inputErrorMessage: '请输入支付密码',
+          beforeClose: async (action, instance, done) => {
+            if (action === 'confirm') {
+              instance.confirmButtonLoading = true
+              instance.confirmButtonText = '执行中...'
+              console.log(instance.inputValue)
+              this.form.payPassword = instance.inputValue
+              await network.postData(path, this.form).then(response => {
+                instance.confirmButtonLoading = false
+                done()
+                this.$message({
+                  message: response,
+                  type: 'success'
+                })
+                tool.setStorage('withdrawAgree', 1)
+                this.submitButtonStat = false
+                this.$router.go(-1)
+              }).catch(error => {
+                instance.confirmButtonLoading = false
+                this.submitButtonStat = false
+                if (error.status === 424) {
+                  this.idCardDialogVisible = true
+                }
+                done()
               })
-
-          })
-        // this.$prompt('请输入支付密码', '提示', {
-        //   confirmButtonText: '确定',
-        //   cancelButtonText: '取消',
-        //   inputType: 'password',
-        //   inputPattern: /\S+/,
-        //   inputErrorMessage: '请输入支付密码'
-        // }).then(({value}) => {
-        //   this.form.payPassword = value
-        //   return network.postData(path, this.form).then(response => {
-        //     this.$message({
-        //       message: response,
-        //       type: 'success'
-        //     })
-        //     tool.setStorage('withdrawAgree', 1)
-        //     this.submitButtonStat = false
-        //     this.$router.go(-1)
-        //   }).catch((error) => {
-        //     this.submitButtonStat = false
-        //     if( error.status === 424 ) {
-        //         this.idCardDialogVisible = true
-        //     }
-        //   })
-        // }).catch((response) => {
-        //   this.submitButtonStat = false
-        // })
-      },
+            } else {
+              this.submitButtonStat = false
+              done()
+            }
+          }
+        })
+      })
+      // this.$prompt('请输入支付密码', '提示', {
+      //   confirmButtonText: '确定',
+      //   cancelButtonText: '取消',
+      //   inputType: 'password',
+      //   inputPattern: /\S+/,
+      //   inputErrorMessage: '请输入支付密码'
+      // }).then(({value}) => {
+      //   this.form.payPassword = value
+      //   return network.postData(path, this.form).then(response => {
+      //     this.$message({
+      //       message: response,
+      //       type: 'success'
+      //     })
+      //     tool.setStorage('withdrawAgree', 1)
+      //     this.submitButtonStat = false
+      //     this.$router.go(-1)
+      //   }).catch((error) => {
+      //     this.submitButtonStat = false
+      //     if( error.status === 424 ) {
+      //         this.idCardDialogVisible = true
+      //     }
+      //   })
+      // }).catch((response) => {
+      //   this.submitButtonStat = false
+      // })
     }
   }
+}
 </script>
 
 <style scoped>

+ 2 - 9
frontendEle/src/views/shop/order-list.vue

@@ -22,6 +22,7 @@
         <el-table-column label="收货电话" prop="MOBILE"></el-table-column>
         <el-table-column label="支付时间" prop="PAY_AT"></el-table-column>
         <el-table-column label="订单类型" prop="ORDER_TYPE"></el-table-column>
+        <el-table-column label="支付类型" prop="PAY_TYPE"></el-table-column>
       </el-table>
       <div class="white-box-footer">
         <pagination :total="totalCount" :page_size="pageSize" @size-change="handleSizeChange" @current-change="handleCurrentChange"></pagination>
@@ -68,15 +69,7 @@
   //
       objectSpanMethod(obj) {
 
-        if (
-          obj.columnIndex === 5 ||
-          obj.columnIndex === 6 ||
-          obj.columnIndex === 7 ||
-          obj.columnIndex === 8 ||
-          obj.columnIndex === 9 ||
-          obj.columnIndex === 10 ||
-          obj.columnIndex === 11
-        ) {
+        if (obj.columnIndex >= 5) {
           // ⼆维数组存储的数据取出
           var _row = this.spanArr[obj.rowIndex];
           var _col = _row > 0 ? 1 : 0;

+ 259 - 260
frontendEle/src/views/user/dec.vue

@@ -233,268 +233,267 @@
 </template>
 
 <script>
-    import Vue from 'vue'
-    import network from '@/utils/network'
-    import baseInfo from '@/utils/baseInfo'
-    import userInfo from '@/utils/userInfo'
-    import store from '@/utils/vuexStore'
-    import tool from '@/utils/tool'
-
-    export default {
-        name: 'user_dec',
-        mounted() {
-            this.getData()
-        },
-        created() {
-            this.getDecName()
-        },
-        computed:{
-            _tableData(){
-                if(this.tableData==null){
-                    return [];
-                }
-                if(this.form.decLv==''){
-                    return this.tableData;
-                }
-                return this.tableData.filter(item=>{
-                    return item.LEVEL_ID == this.form.decLv
-                })
-            }
-        },
-
-        data() {
-            return {
-                currentRow:null,
-                decWay:'1',
-                regionData: store.state.regionInfo.regionData,
-                form: {
-
-                    realName:'',
-                    decLv: '',
-                    insertUserName:'',
-                    decUserName:'',
-                    recUserName:'',
-                    conUserName:'',
-                    insertUserIdCard:'',
-                    consignee:'',
-                    acceptMobile:'',
-                    areaSelected: [],
-                    address: '',
-                    openBank:'',
-                    bankAddress: '',
-                    bankProvince: '',
-                    bankCity: '',
-                    bankCounty: '',
-                    bankNo: '',
-                    bankAreaSelected: [],
-                    password:'',
-                    payPassword:'',
-                    mobile:'',
-                    packageId:'',
-                    goodsId:[],
-                    goodsNum:[],
-                    province:'',
-                    city:'',
-                    county:'',
-
-
-                },
-                conRealName: '-',
-                recRealName: '-',
-                num: 1,
-                tableData:null,
-                tableDatas:null,
-                allOpenBank: null,
-                allDecPackage:{},
-                allDecLevel: baseInfo.decLevels(),
-                loading: false,
-                submitButtonStat: false,
-                submitButton:false,
-                allGoods:[],
-                multipleSelection: [],
-                goodsNums:[],
-                numList: [],
-                sell_price_sum:0.00,
-                price_pv_sum:0.00
-            }
-        },
-        methods: {
-            getDecName() {
-                this.form.decUserName = userInfo.userName()
-            },
-            idcarChange() {
-                if (this.form.insertUserIdCard.length >= 6) {
-                    this.form.payPassword = this.form.password = this.form.insertUserIdCard.substring(this.form.insertUserIdCard.length-6,this.form.insertUserIdCard.length);
-                } else {
-                    this.form.payPassword = this.form.password = '111111'
-                }
-            },
-            getSum(){
-                let sell_price_sum=0,price_pv_sum=0;
-                this.multipleSelection.map((item,index)=>{
-                    console.log(item)
-                    sell_price_sum+=Number(item.SELL_PRICE)*item.goodsNum;
-                    price_pv_sum+=Number(item.PRICE_PV)*item.goodsNum;
-                })
-                this.sell_price_sum=tool.formatPrice(sell_price_sum);
-                this.price_pv_sum=tool.formatPrice(price_pv_sum);
-                console.log(this.sell_price_sum,this.price_pv_sum)
-            },
-            getData () {
-                network.getData(`user/dec`).then(response => {
-                    this.loading = false;
-                    this.form.insertUserName = response.userName;
-                    this.allOpenBank = response.allOpenBank;
-                    this.allDecPackage = response.allDecPackage;
-                    this.allGoods = response.allGoods;
-                    let settingObj=this.allDecPackage;
-                    let settingArr = Object.keys(settingObj).map(key => {
-                        //console.log(key); //为每个键名
-                        return settingObj[key];  //把每个对象返回出去生成一个新的数组中相当于0:{id:1}
-                    } );
-                    this.tableData=settingArr;
-                    let settingObj1=this.allGoods;
-                    for(let i in settingObj1){
-                        this.numList[i] = 1;
-                        settingObj1[i].goodsNum= 1 ;
-                    }
-                     this.tableDatas=settingObj1;
-                    // this.tableDatas=this.allGoods.map(item=>{return {...item,goodsNum:1}});
-                }).catch(() => {
-                });
-            },
-            handleCurrentChange(val) {
-                console.log(val)
-                if(!val){return}
-                this.currentRow = val;
-                this.form.packageId=this.currentRow.ID;
-
-                console.log(this.form.packageId)
-            },
-            // handleSelectionChange(val) {
-            //     this.multipleSelection = val;
-            //     this.form.goodsId = this.multipleSelection.map(item => item.ID)
-            //     this.form.goodsNum = this.multipleSelection.map(item=>{
-            //         return item.goodsNum
-            //     })
-            // },
-            handleSelectionChange(val) {
-                let idx = -1,num;
-                for(let i in this.tableDatas){
-                    for(let v in val){
-                        if(val[v].ID==this.tableDatas[i].ID){
-                            idx = i;
-                            num = this.numList[idx];
-                            val[v]["goodsNum"] = num;
-                            break;
-                        }
-                    }
-                }
-                console.log(val)
-                this.multipleSelection = val;
-                
-            },
-            handleChange(value,ID) {
-                for(let i in this.multipleSelection){
-                    if(this.multipleSelection[i]['ID']==ID) {
-                        this.multipleSelection[i]["goodsNum"] = value;
-                    }
-                }
-            },
-            getGoods(){
-                this.form.goodsId=[];
-                this.form.goodsNum=[];
-                this.multipleSelection.map((item,index)=>{
-                    console.log(item);
-                    console.log('==');
-                    this.form.goodsId.push(item.ID)
-                    this.form.goodsNum.push(item.goodsNum)
-            })
-            },
-            onSubmit() {
-                this.getGoods();
-                this.submitButtonStat = true
-                let path = 'user/dec'
-                let postData = {
-                    consignee: this.form.consignee,
-                    acceptMobile: this.form.acceptMobile,
-                    province: this.form.areaSelected[0] ? this.form.areaSelected[0] : '',
-                    city: this.form.areaSelected[1] ? this.form.areaSelected[1] : '',
-                    county: this.form.areaSelected[2] ? this.form.areaSelected[2] : '',
-                    address: this.form.address,
-                    insertUserName: this.form.insertUserName,
-                    decLv: this.form.decLv,
-                    realName: this.form.realName,
-                    decUserName: this.form.decUserName,
-                    conUserName: this.form.conUserName,
-                    recUserName: this.form.recUserName,
-                    insertUserIdCard: this.form.insertUserIdCard,
-                    openBank: this.form.openBank,
-                    bankAddress: this.form.bankAddress,
-                    mobile: this.form.mobile,
-
-                    bankProvince: this.form.bankAreaSelected[0] ? this.form.bankAreaSelected[0] : '',
-                    bankCity: this.form.bankAreaSelected[1] ? this.form.bankAreaSelected[1] : '',
-                    bankCounty: this.form.bankAreaSelected[2] ? this.form.bankAreaSelected[2] : '',
-
-
-                    bankNo: this.form.bankNo,
-                    password: this.form.password,
-                    payPassword: this.form.payPassword,
-                    packageId: this.form.packageId,
-                    goodsId: this.form.goodsId,
-                    goodsNum: this.form.goodsNum,
-                    location: this.form.location,
-                    decWay:this.decWay
-                }
-
-                return network.postData(path, postData).then(response => {
-                    console.log(response);
-                    this.$message({
-                        message: response,
-                        type: 'success'
-                    })
-                    this.submitButtonStat = false
-                    this.$router.go(-1)
-                }).catch(() => {
-                    this.submitButtonStat = false
-                })
-            },
-
-            selectOne(event, item) {
-                network.getData(`user/dec`).then(response => {
-
-                })
-
-            },
-
-            handleChkConUser() {
-                if (this.form.conUserName) {
-                    this.loading = true
-                    network.getData('user/full-info', {userName: this.form.conUserName}).then(response => {
-                        this.conRealName = response.REAL_NAME + response.isLocation
-                        this.loading = false
-                    }).catch(response => {
-                        this.conRealName = '-'
-                        this.loading = false
-                    })
-                }
-            },
-
-            handleChkRecUser() {
-                if (this.form.recUserName) {
-                    this.loading = true
-                    network.getData('user/full-info', {userName: this.form.recUserName}).then(response => {
-                        this.recRealName = response.REAL_NAME
-                        this.loading = false
-                    }).catch(response => {
-                        this.recRealName = '-'
-                        this.loading = false
-                    })
-                }
-            },
+import Vue from 'vue'
+import network from '@/utils/network'
+import baseInfo from '@/utils/baseInfo'
+import userInfo from '@/utils/userInfo'
+import store from '@/utils/vuexStore'
+import tool from '@/utils/tool'
+
+export default {
+  name: 'user_dec',
+  mounted () {
+    this.getData()
+  },
+  created () {
+    this.getDecName()
+  },
+  computed: {
+    _tableData () {
+      if (this.tableData == null) {
+        return []
+      }
+      if (this.form.decLv == '') {
+        return this.tableData
+      }
+      return this.tableData.filter(item => {
+        return item.LEVEL_ID == this.form.decLv
+      })
+    }
+  },
+
+  data () {
+    return {
+      currentRow: null,
+      decWay: '1',
+      regionData: store.state.regionInfo.regionData,
+      form: {
+        realName: '',
+        decLv: '',
+        insertUserName: '',
+        decUserName: '',
+        recUserName: '',
+        conUserName: '',
+        insertUserIdCard: '',
+        consignee: '',
+        acceptMobile: '',
+        areaSelected: [],
+        address: '',
+        openBank: '',
+        bankAddress: '',
+        bankProvince: '',
+        bankCity: '',
+        bankCounty: '',
+        bankNo: '',
+        bankAreaSelected: [],
+        password: '',
+        payPassword: '',
+        mobile: '',
+        packageId: '',
+        goodsId: [],
+        goodsNum: [],
+        province: '',
+        city: '',
+        county: ''
+      },
+      conRealName: '-',
+      recRealName: '-',
+      num: 1,
+      tableData: null,
+      tableDatas: null,
+      allOpenBank: null,
+      allDecPackage: {},
+      allDecLevel: baseInfo.decLevels(),
+      loading: false,
+      submitButtonStat: false,
+      submitButton: false,
+      allGoods: [],
+      multipleSelection: [],
+      goodsNums: [],
+      numList: [],
+      sell_price_sum: 0.00,
+      price_pv_sum: 0.00
+    }
+  },
+  methods: {
+    getDecName () {
+      this.form.decUserName = userInfo.userName()
+    },
+    idcarChange () {
+      if (this.form.insertUserIdCard.length >= 6) {
+        this.form.payPassword = this.form.password = this.form.insertUserIdCard.substring(this.form.insertUserIdCard.length - 6, this.form.insertUserIdCard.length)
+      } else {
+        this.form.payPassword = this.form.password = '111111'
+      }
+    },
+    getSum () {
+      let sell_price_sum = 0, price_pv_sum = 0
+      this.multipleSelection.map((item, index) => {
+        console.log(item)
+        sell_price_sum += Number(item.SELL_PRICE) * item.goodsNum
+        price_pv_sum += Number(item.PRICE_PV) * item.goodsNum
+      })
+      this.sell_price_sum = tool.formatPrice(sell_price_sum)
+      this.price_pv_sum = tool.formatPrice(price_pv_sum)
+      console.log(this.sell_price_sum, this.price_pv_sum)
+    },
+    getData () {
+      network.getData(`user/dec`).then(response => {
+        this.loading = false
+        this.form.insertUserName = response.userName
+        this.allOpenBank = response.allOpenBank
+        this.allDecPackage = response.allDecPackage
+        this.allGoods = response.allGoods
+        let settingObj = this.allDecPackage
+        let settingArr = Object.keys(settingObj).map(key => {
+          // console.log(key); //为每个键名
+          return settingObj[key] // 把每个对象返回出去生成一个新的数组中相当于0:{id:1}
+        })
+        this.tableData = settingArr
+        let settingObj1 = this.allGoods
+        for (let i in settingObj1) {
+          this.numList[i] = 1
+          settingObj1[i].goodsNum = 1
+        }
+        this.tableDatas = settingObj1
+        // this.tableDatas=this.allGoods.map(item=>{return {...item,goodsNum:1}});
+      }).catch(() => {
+      })
+    },
+    handleCurrentChange (val) {
+      console.log(val)
+      if (!val) { return }
+      this.currentRow = val
+      this.form.packageId = this.currentRow.ID
+
+      console.log(this.form.packageId)
+    },
+    // handleSelectionChange(val) {
+    //     this.multipleSelection = val;
+    //     this.form.goodsId = this.multipleSelection.map(item => item.ID)
+    //     this.form.goodsNum = this.multipleSelection.map(item=>{
+    //         return item.goodsNum
+    //     })
+    // },
+    handleSelectionChange (val) {
+      let idx = -1, num
+      for (let i in this.tableDatas) {
+        for (let v in val) {
+          if (val[v].ID == this.tableDatas[i].ID) {
+            idx = i
+            num = this.numList[idx]
+            val[v]['goodsNum'] = num
+            break
+          }
+        }
+      }
+      console.log(val)
+      this.multipleSelection = val
+    },
+    handleChange (value, ID) {
+      for (let i in this.multipleSelection) {
+        if (this.multipleSelection[i]['ID'] == ID) {
+          this.multipleSelection[i]['goodsNum'] = value
         }
+      }
+    },
+    getGoods () {
+      this.form.goodsId = []
+      this.form.goodsNum = []
+      this.multipleSelection.map((item, index) => {
+        console.log(item)
+        console.log('==')
+        this.form.goodsId.push(item.ID)
+        this.form.goodsNum.push(item.goodsNum)
+      })
+    },
+    onSubmit () {
+      this.getGoods()
+      this.submitButtonStat = true
+      let path = 'user/dec'
+      let postData = {
+        consignee: this.form.consignee,
+        acceptMobile: this.form.acceptMobile,
+        province: this.form.areaSelected[0] ? this.form.areaSelected[0] : '',
+        city: this.form.areaSelected[1] ? this.form.areaSelected[1] : '',
+        county: this.form.areaSelected[2] ? this.form.areaSelected[2] : '',
+        address: this.form.address,
+        insertUserName: this.form.insertUserName,
+        decLv: this.form.decLv,
+        realName: this.form.realName,
+        decUserName: this.form.decUserName,
+        conUserName: this.form.conUserName,
+        recUserName: this.form.recUserName,
+        insertUserIdCard: this.form.insertUserIdCard,
+        openBank: this.form.openBank,
+        bankAddress: this.form.bankAddress,
+        mobile: this.form.mobile,
+
+        bankProvince: this.form.bankAreaSelected[0] ? this.form.bankAreaSelected[0] : '',
+        bankCity: this.form.bankAreaSelected[1] ? this.form.bankAreaSelected[1] : '',
+        bankCounty: this.form.bankAreaSelected[2] ? this.form.bankAreaSelected[2] : '',
+
+        bankNo: this.form.bankNo,
+        password: this.form.password,
+        payPassword: this.form.payPassword,
+        packageId: this.form.packageId,
+        goodsId: this.form.goodsId,
+        goodsNum: this.form.goodsNum,
+        location: this.form.location,
+        decWay: this.decWay
+      }
+      if (this.form.goodsId.length === 0 && this.form.packageId.length === 0) {
+        this.$message({
+          message: '未选择商品或套餐',
+          type: 'warning'
+        })
+        this.submitButtonStat = false
+      }
+      return network.postData(path, postData).then(response => {
+        // console.log(response)
+        this.$message({
+          message: response,
+          type: 'success'
+        })
+        this.submitButtonStat = false
+        this.$router.go(-1)
+      }).catch(() => {
+        this.submitButtonStat = false
+      })
+    },
+
+    selectOne (event, item) {
+      network.getData(`user/dec`).then(response => {
+      })
+    },
+
+    handleChkConUser () {
+      if (this.form.conUserName) {
+        this.loading = true
+        network.getData('user/full-info', {userName: this.form.conUserName}).then(response => {
+          this.conRealName = response.REAL_NAME + response.isLocation
+          this.loading = false
+        }).catch(response => {
+          this.conRealName = '-'
+          this.loading = false
+        })
+      }
+    },
+
+    handleChkRecUser () {
+      if (this.form.recUserName) {
+        this.loading = true
+        network.getData('user/full-info', {userName: this.form.recUserName}).then(response => {
+          this.recRealName = response.REAL_NAME
+          this.loading = false
+        }).catch(response => {
+          this.recRealName = '-'
+          this.loading = false
+        })
+      }
     }
+  }
+}
 </script>
 
 <style>

+ 4 - 0
sql/2047.sql

@@ -0,0 +1,4 @@
+-- 会员表增加EMP_LV属性字段
+ALTER TABLE `AR_USER` ADD COLUMN `LAST_EMP_LV` varchar(32) COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '最新EMP级别';
+ALTER TABLE `AR_USER` ADD COLUMN `LAST_EMP_LV_UPDATED_AT` int(11) NOT NULL DEFAULT 0 COMMENT '最新EMP级别更新时间';
+ALTER TABLE `AR_USER` ADD COLUMN `LAST_EMP_LV_UPDATED_PERIOD` int(11) NOT NULL DEFAULT 0 COMMENT '最新EMP级别更新期数';

+ 4 - 0
sql/upgrade/1035.sql

@@ -0,0 +1,4 @@
+CREATE TABLE `AR_USER_NETWORK_HIDDEN`  (
+  `USER_ID` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
+  `HIDDEN_USER_ID` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

+ 5 - 0
vendor/autoload.php

@@ -2,6 +2,11 @@
 
 // autoload.php @generated by Composer
 
+if (PHP_VERSION_ID < 50600) {
+    echo 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
+    exit(1);
+}
+
 require_once __DIR__ . '/composer/autoload_real.php';
 
 return ComposerAutoloaderInitfefd691d76b71aadb785cf30e72d29ac::getLoader();

+ 141 - 14
vendor/composer/ClassLoader.php

@@ -37,26 +37,80 @@ namespace Composer\Autoload;
  *
  * @author Fabien Potencier <fabien@symfony.com>
  * @author Jordi Boggiano <j.boggiano@seld.be>
- * @see    http://www.php-fig.org/psr/psr-0/
- * @see    http://www.php-fig.org/psr/psr-4/
+ * @see    https://www.php-fig.org/psr/psr-0/
+ * @see    https://www.php-fig.org/psr/psr-4/
  */
 class ClassLoader
 {
+    /** @var ?string */
+    private $vendorDir;
+
     // PSR-4
+    /**
+     * @var array[]
+     * @psalm-var array<string, array<string, int>>
+     */
     private $prefixLengthsPsr4 = array();
+    /**
+     * @var array[]
+     * @psalm-var array<string, array<int, string>>
+     */
     private $prefixDirsPsr4 = array();
+    /**
+     * @var array[]
+     * @psalm-var array<string, string>
+     */
     private $fallbackDirsPsr4 = array();
 
     // PSR-0
+    /**
+     * @var array[]
+     * @psalm-var array<string, array<string, string[]>>
+     */
     private $prefixesPsr0 = array();
+    /**
+     * @var array[]
+     * @psalm-var array<string, string>
+     */
     private $fallbackDirsPsr0 = array();
 
+    /** @var bool */
     private $useIncludePath = false;
+
+    /**
+     * @var string[]
+     * @psalm-var array<string, string>
+     */
     private $classMap = array();
+
+    /** @var bool */
     private $classMapAuthoritative = false;
+
+    /**
+     * @var bool[]
+     * @psalm-var array<string, bool>
+     */
     private $missingClasses = array();
+
+    /** @var ?string */
     private $apcuPrefix;
 
+    /**
+     * @var self[]
+     */
+    private static $registeredLoaders = array();
+
+    /**
+     * @param ?string $vendorDir
+     */
+    public function __construct($vendorDir = null)
+    {
+        $this->vendorDir = $vendorDir;
+    }
+
+    /**
+     * @return string[]
+     */
     public function getPrefixes()
     {
         if (!empty($this->prefixesPsr0)) {
@@ -66,28 +120,47 @@ class ClassLoader
         return array();
     }
 
+    /**
+     * @return array[]
+     * @psalm-return array<string, array<int, string>>
+     */
     public function getPrefixesPsr4()
     {
         return $this->prefixDirsPsr4;
     }
 
+    /**
+     * @return array[]
+     * @psalm-return array<string, string>
+     */
     public function getFallbackDirs()
     {
         return $this->fallbackDirsPsr0;
     }
 
+    /**
+     * @return array[]
+     * @psalm-return array<string, string>
+     */
     public function getFallbackDirsPsr4()
     {
         return $this->fallbackDirsPsr4;
     }
 
+    /**
+     * @return string[] Array of classname => path
+     * @psalm-return array<string, string>
+     */
     public function getClassMap()
     {
         return $this->classMap;
     }
 
     /**
-     * @param array $classMap Class to filename map
+     * @param string[] $classMap Class to filename map
+     * @psalm-param array<string, string> $classMap
+     *
+     * @return void
      */
     public function addClassMap(array $classMap)
     {
@@ -102,9 +175,11 @@ class ClassLoader
      * Registers a set of PSR-0 directories for a given prefix, either
      * appending or prepending to the ones previously set for this prefix.
      *
-     * @param string       $prefix  The prefix
-     * @param array|string $paths   The PSR-0 root directories
-     * @param bool         $prepend Whether to prepend the directories
+     * @param string          $prefix  The prefix
+     * @param string[]|string $paths   The PSR-0 root directories
+     * @param bool            $prepend Whether to prepend the directories
+     *
+     * @return void
      */
     public function add($prefix, $paths, $prepend = false)
     {
@@ -147,11 +222,13 @@ class ClassLoader
      * Registers a set of PSR-4 directories for a given namespace, either
      * appending or prepending to the ones previously set for this namespace.
      *
-     * @param string       $prefix  The prefix/namespace, with trailing '\\'
-     * @param array|string $paths   The PSR-4 base directories
-     * @param bool         $prepend Whether to prepend the directories
+     * @param string          $prefix  The prefix/namespace, with trailing '\\'
+     * @param string[]|string $paths   The PSR-4 base directories
+     * @param bool            $prepend Whether to prepend the directories
      *
      * @throws \InvalidArgumentException
+     *
+     * @return void
      */
     public function addPsr4($prefix, $paths, $prepend = false)
     {
@@ -195,8 +272,10 @@ class ClassLoader
      * Registers a set of PSR-0 directories for a given prefix,
      * replacing any others previously set for this prefix.
      *
-     * @param string       $prefix The prefix
-     * @param array|string $paths  The PSR-0 base directories
+     * @param string          $prefix The prefix
+     * @param string[]|string $paths  The PSR-0 base directories
+     *
+     * @return void
      */
     public function set($prefix, $paths)
     {
@@ -211,10 +290,12 @@ class ClassLoader
      * Registers a set of PSR-4 directories for a given namespace,
      * replacing any others previously set for this namespace.
      *
-     * @param string       $prefix The prefix/namespace, with trailing '\\'
-     * @param array|string $paths  The PSR-4 base directories
+     * @param string          $prefix The prefix/namespace, with trailing '\\'
+     * @param string[]|string $paths  The PSR-4 base directories
      *
      * @throws \InvalidArgumentException
+     *
+     * @return void
      */
     public function setPsr4($prefix, $paths)
     {
@@ -234,6 +315,8 @@ class ClassLoader
      * Turns on searching the include path for class files.
      *
      * @param bool $useIncludePath
+     *
+     * @return void
      */
     public function setUseIncludePath($useIncludePath)
     {
@@ -256,6 +339,8 @@ class ClassLoader
      * that have not been registered with the class map.
      *
      * @param bool $classMapAuthoritative
+     *
+     * @return void
      */
     public function setClassMapAuthoritative($classMapAuthoritative)
     {
@@ -276,6 +361,8 @@ class ClassLoader
      * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
      *
      * @param string|null $apcuPrefix
+     *
+     * @return void
      */
     public function setApcuPrefix($apcuPrefix)
     {
@@ -296,25 +383,44 @@ class ClassLoader
      * Registers this instance as an autoloader.
      *
      * @param bool $prepend Whether to prepend the autoloader or not
+     *
+     * @return void
      */
     public function register($prepend = false)
     {
         spl_autoload_register(array($this, 'loadClass'), true, $prepend);
+
+        if (null === $this->vendorDir) {
+            return;
+        }
+
+        if ($prepend) {
+            self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
+        } else {
+            unset(self::$registeredLoaders[$this->vendorDir]);
+            self::$registeredLoaders[$this->vendorDir] = $this;
+        }
     }
 
     /**
      * Unregisters this instance as an autoloader.
+     *
+     * @return void
      */
     public function unregister()
     {
         spl_autoload_unregister(array($this, 'loadClass'));
+
+        if (null !== $this->vendorDir) {
+            unset(self::$registeredLoaders[$this->vendorDir]);
+        }
     }
 
     /**
      * Loads the given class or interface.
      *
      * @param  string    $class The name of the class
-     * @return bool|null True if loaded, null otherwise
+     * @return true|null True if loaded, null otherwise
      */
     public function loadClass($class)
     {
@@ -323,6 +429,8 @@ class ClassLoader
 
             return true;
         }
+
+        return null;
     }
 
     /**
@@ -367,6 +475,21 @@ class ClassLoader
         return $file;
     }
 
+    /**
+     * Returns the currently registered loaders indexed by their corresponding vendor directories.
+     *
+     * @return self[]
+     */
+    public static function getRegisteredLoaders()
+    {
+        return self::$registeredLoaders;
+    }
+
+    /**
+     * @param  string       $class
+     * @param  string       $ext
+     * @return string|false
+     */
     private function findFileWithExtension($class, $ext)
     {
         // PSR-4 lookup
@@ -438,6 +561,10 @@ class ClassLoader
  * Scope isolated include.
  *
  * Prevents access to $this/self from included files.
+ *
+ * @param  string $file
+ * @return void
+ * @private
  */
 function includeFile($file)
 {

+ 2 - 1
vendor/composer/autoload_classmap.php

@@ -2,11 +2,12 @@
 
 // autoload_classmap.php @generated by Composer
 
-$vendorDir = dirname(dirname(__FILE__));
+$vendorDir = dirname(__DIR__);
 $baseDir = dirname($vendorDir);
 
 return array(
     'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
+    'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
     'JsonException' => $vendorDir . '/symfony/polyfill-php73/Resources/stubs/JsonException.php',
     'Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php',
     'PHPUnit\\Exception' => $vendorDir . '/phpunit/phpunit/src/Exception.php',

+ 6 - 6
vendor/composer/autoload_files.php

@@ -2,23 +2,23 @@
 
 // autoload_files.php @generated by Composer
 
-$vendorDir = dirname(dirname(__FILE__));
+$vendorDir = dirname(__DIR__);
 $baseDir = dirname($vendorDir);
 
 return array(
-    'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
-    '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
     '2cffec82183ee1cea088009cef9a6fc3' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
-    '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
     '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
+    'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
+    '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
     'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php',
     '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
-    '0d59ee240a4cd96ddbb4ff164fccea4d' => $vendorDir . '/symfony/polyfill-php73/bootstrap.php',
+    '6124b4c8570aa390c21fafd04a26c69f' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
+    '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
     'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php',
     '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
     'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php',
+    '0d59ee240a4cd96ddbb4ff164fccea4d' => $vendorDir . '/symfony/polyfill-php73/bootstrap.php',
     'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',
-    '6124b4c8570aa390c21fafd04a26c69f' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
     '2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php',
     '180092cfc969a12e06f2132a203a3184' => $vendorDir . '/codeception/verify/src/Codeception/function.php',
 );

+ 1 - 1
vendor/composer/autoload_namespaces.php

@@ -2,7 +2,7 @@
 
 // autoload_namespaces.php @generated by Composer
 
-$vendorDir = dirname(dirname(__FILE__));
+$vendorDir = dirname(__DIR__);
 $baseDir = dirname($vendorDir);
 
 return array(

+ 3 - 1
vendor/composer/autoload_psr4.php

@@ -2,7 +2,7 @@
 
 // autoload_psr4.php @generated by Composer
 
-$vendorDir = dirname(dirname(__FILE__));
+$vendorDir = dirname(__DIR__);
 $baseDir = dirname($vendorDir);
 
 return array(
@@ -40,12 +40,14 @@ return array(
     'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
     'Symfony\\Component\\BrowserKit\\' => array($vendorDir . '/symfony/browser-kit'),
     'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'),
+    'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
     'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'),
     'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'),
     'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
     'Prophecy\\' => array($vendorDir . '/phpspec/prophecy/src/Prophecy'),
     'PhpOffice\\PhpSpreadsheet\\' => array($vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet'),
     'MyCLabs\\Enum\\' => array($vendorDir . '/myclabs/php-enum/src'),
+    'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
     'Matrix\\' => array($vendorDir . '/markbaker/matrix/classes/src'),
     'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
     'Godruoyi\\Snowflake\\' => array($vendorDir . '/godruoyi/php-snowflake/src'),

+ 13 - 29
vendor/composer/autoload_real.php

@@ -22,39 +22,18 @@ class ComposerAutoloaderInitfefd691d76b71aadb785cf30e72d29ac
             return self::$loader;
         }
 
+        require __DIR__ . '/platform_check.php';
+
         spl_autoload_register(array('ComposerAutoloaderInitfefd691d76b71aadb785cf30e72d29ac', 'loadClassLoader'), true, true);
-        self::$loader = $loader = new \Composer\Autoload\ClassLoader();
+        self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
         spl_autoload_unregister(array('ComposerAutoloaderInitfefd691d76b71aadb785cf30e72d29ac', 'loadClassLoader'));
 
-        $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
-        if ($useStaticLoader) {
-            require_once __DIR__ . '/autoload_static.php';
-
-            call_user_func(\Composer\Autoload\ComposerStaticInitfefd691d76b71aadb785cf30e72d29ac::getInitializer($loader));
-        } else {
-            $map = require __DIR__ . '/autoload_namespaces.php';
-            foreach ($map as $namespace => $path) {
-                $loader->set($namespace, $path);
-            }
-
-            $map = require __DIR__ . '/autoload_psr4.php';
-            foreach ($map as $namespace => $path) {
-                $loader->setPsr4($namespace, $path);
-            }
-
-            $classMap = require __DIR__ . '/autoload_classmap.php';
-            if ($classMap) {
-                $loader->addClassMap($classMap);
-            }
-        }
+        require __DIR__ . '/autoload_static.php';
+        call_user_func(\Composer\Autoload\ComposerStaticInitfefd691d76b71aadb785cf30e72d29ac::getInitializer($loader));
 
         $loader->register(true);
 
-        if ($useStaticLoader) {
-            $includeFiles = Composer\Autoload\ComposerStaticInitfefd691d76b71aadb785cf30e72d29ac::$files;
-        } else {
-            $includeFiles = require __DIR__ . '/autoload_files.php';
-        }
+        $includeFiles = \Composer\Autoload\ComposerStaticInitfefd691d76b71aadb785cf30e72d29ac::$files;
         foreach ($includeFiles as $fileIdentifier => $file) {
             composerRequirefefd691d76b71aadb785cf30e72d29ac($fileIdentifier, $file);
         }
@@ -63,11 +42,16 @@ class ComposerAutoloaderInitfefd691d76b71aadb785cf30e72d29ac
     }
 }
 
+/**
+ * @param string $fileIdentifier
+ * @param string $file
+ * @return void
+ */
 function composerRequirefefd691d76b71aadb785cf30e72d29ac($fileIdentifier, $file)
 {
     if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
-        require $file;
-
         $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
+
+        require $file;
     }
 }

+ 16 - 5
vendor/composer/autoload_static.php

@@ -7,19 +7,19 @@ namespace Composer\Autoload;
 class ComposerStaticInitfefd691d76b71aadb785cf30e72d29ac
 {
     public static $files = array (
-        'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
-        '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
         '2cffec82183ee1cea088009cef9a6fc3' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
-        '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
         '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
+        'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
+        '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
         'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php',
         '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
-        '0d59ee240a4cd96ddbb4ff164fccea4d' => __DIR__ . '/..' . '/symfony/polyfill-php73/bootstrap.php',
+        '6124b4c8570aa390c21fafd04a26c69f' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
+        '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
         'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php',
         '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
         'def43f6c87e4f8dfd0c9e1b1bab14fe8' => __DIR__ . '/..' . '/symfony/polyfill-iconv/bootstrap.php',
+        '0d59ee240a4cd96ddbb4ff164fccea4d' => __DIR__ . '/..' . '/symfony/polyfill-php73/bootstrap.php',
         'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php',
-        '6124b4c8570aa390c21fafd04a26c69f' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php',
         '2c102faa651ef8ea5874edb585946bce' => __DIR__ . '/..' . '/swiftmailer/swiftmailer/lib/swift_required.php',
         '180092cfc969a12e06f2132a203a3184' => __DIR__ . '/..' . '/codeception/verify/src/Codeception/function.php',
     );
@@ -85,6 +85,7 @@ class ComposerStaticInitfefd691d76b71aadb785cf30e72d29ac
         'P' => 
         array (
             'Psr\\SimpleCache\\' => 16,
+            'Psr\\Log\\' => 8,
             'Psr\\Http\\Message\\' => 17,
             'Psr\\Http\\Client\\' => 16,
             'Psr\\Container\\' => 14,
@@ -94,6 +95,7 @@ class ComposerStaticInitfefd691d76b71aadb785cf30e72d29ac
         'M' => 
         array (
             'MyCLabs\\Enum\\' => 13,
+            'Monolog\\' => 8,
             'Matrix\\' => 7,
         ),
         'G' => 
@@ -263,6 +265,10 @@ class ComposerStaticInitfefd691d76b71aadb785cf30e72d29ac
         array (
             0 => __DIR__ . '/..' . '/psr/simple-cache/src',
         ),
+        'Psr\\Log\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
+        ),
         'Psr\\Http\\Message\\' => 
         array (
             0 => __DIR__ . '/..' . '/psr/http-factory/src',
@@ -288,6 +294,10 @@ class ComposerStaticInitfefd691d76b71aadb785cf30e72d29ac
         array (
             0 => __DIR__ . '/..' . '/myclabs/php-enum/src',
         ),
+        'Monolog\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/monolog/monolog/src/Monolog',
+        ),
         'Matrix\\' => 
         array (
             0 => __DIR__ . '/..' . '/markbaker/matrix/classes/src',
@@ -365,6 +375,7 @@ class ComposerStaticInitfefd691d76b71aadb785cf30e72d29ac
 
     public static $classMap = array (
         'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
+        'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
         'JsonException' => __DIR__ . '/..' . '/symfony/polyfill-php73/Resources/stubs/JsonException.php',
         'Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php',
         'PHPUnit\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Exception.php',

+ 6097 - 5779
vendor/composer/installed.json

@@ -1,5917 +1,6235 @@
-[
-    {
-        "name": "anlity/yii2-swoole-async-timer",
-        "version": "0.9.2",
-        "version_normalized": "0.9.2.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/anlityli/yii2-swoole-async-timer.git",
-            "reference": "60bb70e0e34951d5aa46b89fa224f471f68e666d"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/anlityli/yii2-swoole-async-timer/zipball/60bb70e0e34951d5aa46b89fa224f471f68e666d",
-            "reference": "60bb70e0e34951d5aa46b89fa224f471f68e666d",
-            "shasum": "",
-            "mirrors": [
-                {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+{
+    "packages": [
+        {
+            "name": "anlity/yii2-swoole-async-timer",
+            "version": "0.9.2",
+            "version_normalized": "0.9.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/anlityli/yii2-swoole-async-timer.git",
+                "reference": "60bb70e0e34951d5aa46b89fa224f471f68e666d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/anlityli/yii2-swoole-async-timer/zipball/60bb70e0e34951d5aa46b89fa224f471f68e666d",
+                "reference": "60bb70e0e34951d5aa46b89fa224f471f68e666d",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "yiisoft/yii2": "~2.0.0"
+            },
+            "time": "2019-11-22T03:10:24+00:00",
+            "type": "yii2-extension",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "anlity\\swooleAsyncTimer\\": ""
                 }
-            ]
-        },
-        "require": {
-            "yiisoft/yii2": "~2.0.0"
-        },
-        "time": "2019-11-22T03:10:24+00:00",
-        "type": "yii2-extension",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "anlity\\swooleAsyncTimer\\": ""
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-4-Clause"
-        ],
-        "authors": [
-            {
-                "name": "anlity",
-                "email": "leo@leocode.net"
-            }
-        ],
-        "description": "用于异步处理任务和需要定时器完成的任务",
-        "homepage": "https://github.com/anlityli/yii2-swoole-async-timer",
-        "keywords": [
-            "extension",
-            "swoole",
-            "yii2"
-        ]
-    },
-    {
-        "name": "behat/gherkin",
-        "version": "v4.9.0",
-        "version_normalized": "4.9.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/Behat/Gherkin.git",
-            "reference": "0bc8d1e30e96183e4f36db9dc79caead300beff4"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/Behat/Gherkin/zipball/0bc8d1e30e96183e4f36db9dc79caead300beff4",
-            "reference": "0bc8d1e30e96183e4f36db9dc79caead300beff4",
-            "shasum": "",
-            "mirrors": [
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-4-Clause"
+            ],
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "anlity",
+                    "email": "leo@leocode.net"
                 }
-            ]
-        },
-        "require": {
-            "php": "~7.2|~8.0"
-        },
-        "require-dev": {
-            "cucumber/cucumber": "dev-gherkin-22.0.0",
-            "phpunit/phpunit": "~8|~9",
-            "symfony/yaml": "~3|~4|~5"
-        },
-        "suggest": {
-            "symfony/yaml": "If you want to parse features, represented in YAML files"
-        },
-        "time": "2021-10-12T13:05:09+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "4.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-0": {
-                "Behat\\Gherkin": "src/"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Konstantin Kudryashov",
-                "email": "ever.zet@gmail.com",
-                "homepage": "http://everzet.com"
-            }
-        ],
-        "description": "Gherkin DSL parser for PHP",
-        "homepage": "http://behat.org/",
-        "keywords": [
-            "BDD",
-            "Behat",
-            "Cucumber",
-            "DSL",
-            "gherkin",
-            "parser"
-        ]
-    },
-    {
-        "name": "bower-asset/bootstrap",
-        "version": "v3.3.7",
-        "version_normalized": "3.3.7.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/twbs/bootstrap.git",
-            "reference": "0b9c4a4007c44201dce9a6cc1a38407005c26c86"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/twbs/bootstrap/zipball/0b9c4a4007c44201dce9a6cc1a38407005c26c86",
-            "reference": "0b9c4a4007c44201dce9a6cc1a38407005c26c86"
-        },
-        "require": {
-            "bower-asset/jquery": ">=1.9.1,<4.0"
-        },
-        "type": "bower-asset",
-        "installation-source": "dist",
-        "license": [
-            "MIT"
-        ]
-    },
-    {
-        "name": "bower-asset/inputmask",
-        "version": "3.3.11",
-        "version_normalized": "3.3.11.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/RobinHerbots/Inputmask.git",
-            "reference": "5e670ad62f50c738388d4dcec78d2888505ad77b"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/RobinHerbots/Inputmask/zipball/5e670ad62f50c738388d4dcec78d2888505ad77b",
-            "reference": "5e670ad62f50c738388d4dcec78d2888505ad77b"
-        },
-        "require": {
-            "bower-asset/jquery": ">=1.7"
-        },
-        "type": "bower-asset",
-        "installation-source": "dist",
-        "license": [
-            "http://opensource.org/licenses/mit-license.php"
-        ]
-    },
-    {
-        "name": "bower-asset/jquery",
-        "version": "3.2.1",
-        "version_normalized": "3.2.1.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/jquery/jquery-dist.git",
-            "reference": "77d2a51d0520d2ee44173afdf4e40a9201f5964e"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/jquery/jquery-dist/zipball/77d2a51d0520d2ee44173afdf4e40a9201f5964e",
-            "reference": "77d2a51d0520d2ee44173afdf4e40a9201f5964e"
-        },
-        "type": "bower-asset",
-        "installation-source": "dist",
-        "license": [
-            "MIT"
-        ]
-    },
-    {
-        "name": "bower-asset/punycode",
-        "version": "v1.3.2",
-        "version_normalized": "1.3.2.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/bestiejs/punycode.js.git",
-            "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/bestiejs/punycode.js/zipball/38c8d3131a82567bfef18da09f7f4db68c84f8a3",
-            "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3"
-        },
-        "type": "bower-asset",
-        "installation-source": "dist"
-    },
-    {
-        "name": "bower-asset/typeahead.js",
-        "version": "v0.11.1",
-        "version_normalized": "0.11.1.0",
-        "source": {
-            "type": "git",
-            "url": "git@github.com:twitter/typeahead.js.git",
-            "reference": "588440f66559714280628a4f9799f0c4eb880a4a"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/twitter/typeahead.js/zipball/588440f66559714280628a4f9799f0c4eb880a4a",
-            "reference": "588440f66559714280628a4f9799f0c4eb880a4a"
-        },
-        "require": {
-            "bower-asset/jquery": ">=1.7"
-        },
-        "type": "bower-asset",
-        "installation-source": "dist"
-    },
-    {
-        "name": "bower-asset/yii2-pjax",
-        "version": "2.0.7.1",
-        "version_normalized": "2.0.7.1",
-        "source": {
-            "type": "git",
-            "url": "git@github.com:yiisoft/jquery-pjax.git",
-            "reference": "aef7b953107264f00234902a3880eb50dafc48be"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/yiisoft/jquery-pjax/zipball/aef7b953107264f00234902a3880eb50dafc48be",
-            "reference": "aef7b953107264f00234902a3880eb50dafc48be"
-        },
-        "require": {
-            "bower-asset/jquery": ">=1.8"
-        },
-        "type": "bower-asset",
-        "installation-source": "dist",
-        "license": [
-            "MIT"
-        ]
-    },
-    {
-        "name": "cebe/markdown",
-        "version": "1.2.1",
-        "version_normalized": "1.2.1.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/cebe/markdown.git",
-            "reference": "9bac5e971dd391e2802dca5400bbeacbaea9eb86"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/cebe/markdown/zipball/9bac5e971dd391e2802dca5400bbeacbaea9eb86",
-            "reference": "9bac5e971dd391e2802dca5400bbeacbaea9eb86",
-            "shasum": "",
-            "mirrors": [
-                {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+            ],
+            "description": "用于异步处理任务和需要定时器完成的任务",
+            "homepage": "https://github.com/anlityli/yii2-swoole-async-timer",
+            "keywords": [
+                "extension",
+                "swoole",
+                "yii2"
+            ],
+            "install-path": "../anlity/yii2-swoole-async-timer"
+        },
+        {
+            "name": "behat/gherkin",
+            "version": "v4.9.0",
+            "version_normalized": "4.9.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Behat/Gherkin.git",
+                "reference": "0bc8d1e30e96183e4f36db9dc79caead300beff4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Behat/Gherkin/zipball/0bc8d1e30e96183e4f36db9dc79caead300beff4",
+                "reference": "0bc8d1e30e96183e4f36db9dc79caead300beff4",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "~7.2|~8.0"
+            },
+            "require-dev": {
+                "cucumber/cucumber": "dev-gherkin-22.0.0",
+                "phpunit/phpunit": "~8|~9",
+                "symfony/yaml": "~3|~4|~5"
+            },
+            "suggest": {
+                "symfony/yaml": "If you want to parse features, represented in YAML files"
+            },
+            "time": "2021-10-12T13:05:09+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "4.x-dev"
                 }
-            ]
-        },
-        "require": {
-            "lib-pcre": "*",
-            "php": ">=5.4.0"
-        },
-        "require-dev": {
-            "cebe/indent": "*",
-            "facebook/xhprof": "*@dev",
-            "phpunit/phpunit": "4.1.*"
-        },
-        "time": "2018-03-26T11:24:36+00:00",
-        "bin": [
-            "bin/markdown"
-        ],
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "1.2.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "cebe\\markdown\\": ""
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Carsten Brandt",
-                "email": "mail@cebe.cc",
-                "homepage": "http://cebe.cc/",
-                "role": "Creator"
-            }
-        ],
-        "description": "A super fast, highly extensible markdown parser for PHP",
-        "homepage": "https://github.com/cebe/markdown#readme",
-        "keywords": [
-            "extensible",
-            "fast",
-            "gfm",
-            "markdown",
-            "markdown-extra"
-        ]
-    },
-    {
-        "name": "codeception/base",
-        "version": "2.5.6",
-        "version_normalized": "2.5.6.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/Codeception/base.git",
-            "reference": "aace5bab5593c93d8473b620f70754135a1eb4f0"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/Codeception/base/zipball/aace5bab5593c93d8473b620f70754135a1eb4f0",
-            "reference": "aace5bab5593c93d8473b620f70754135a1eb4f0",
-            "shasum": "",
-            "mirrors": [
-                {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-0": {
+                    "Behat\\Gherkin": "src/"
                 }
-            ]
-        },
-        "require": {
-            "behat/gherkin": "^4.4.0",
-            "codeception/phpunit-wrapper": "^6.0.9|^7.0.6",
-            "codeception/stub": "^2.0",
-            "ext-curl": "*",
-            "ext-json": "*",
-            "ext-mbstring": "*",
-            "guzzlehttp/psr7": "~1.0",
-            "php": ">=5.6.0 <8.0",
-            "symfony/browser-kit": ">=2.7 <5.0",
-            "symfony/console": ">=2.7 <5.0",
-            "symfony/css-selector": ">=2.7 <5.0",
-            "symfony/dom-crawler": ">=2.7 <5.0",
-            "symfony/event-dispatcher": ">=2.7 <5.0",
-            "symfony/finder": ">=2.7 <5.0",
-            "symfony/yaml": ">=2.7 <5.0"
-        },
-        "require-dev": {
-            "codeception/specify": "~0.3",
-            "facebook/graph-sdk": "~5.3",
-            "flow/jsonpath": "~0.2",
-            "monolog/monolog": "~1.8",
-            "pda/pheanstalk": "~3.0",
-            "php-amqplib/php-amqplib": "~2.4",
-            "predis/predis": "^1.0",
-            "squizlabs/php_codesniffer": "~2.0",
-            "symfony/process": ">=2.7 <5.0",
-            "vlucas/phpdotenv": "^3.0"
-        },
-        "suggest": {
-            "aws/aws-sdk-php": "For using AWS Auth in REST module and Queue module",
-            "codeception/phpbuiltinserver": "Start and stop PHP built-in web server for your tests",
-            "codeception/specify": "BDD-style code blocks",
-            "codeception/verify": "BDD-style assertions",
-            "flow/jsonpath": "For using JSONPath in REST module",
-            "league/factory-muffin": "For DataFactory module",
-            "league/factory-muffin-faker": "For Faker support in DataFactory module",
-            "phpseclib/phpseclib": "for SFTP option in FTP Module",
-            "stecman/symfony-console-completion": "For BASH autocompletion",
-            "symfony/phpunit-bridge": "For phpunit-bridge support"
-        },
-        "time": "2019-04-24T11:36:34+00:00",
-        "bin": [
-            "codecept"
-        ],
-        "type": "library",
-        "extra": {
-            "branch-alias": []
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Codeception\\": "src/Codeception",
-                "Codeception\\Extension\\": "ext"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Michael Bodnarchuk",
-                "email": "davert@mail.ua",
-                "homepage": "http://codegyre.com"
-            }
-        ],
-        "description": "BDD-style testing framework",
-        "homepage": "http://codeception.com/",
-        "keywords": [
-            "BDD",
-            "TDD",
-            "acceptance testing",
-            "functional testing",
-            "unit testing"
-        ],
-        "abandoned": true
-    },
-    {
-        "name": "codeception/phpunit-wrapper",
-        "version": "7.8.2",
-        "version_normalized": "7.8.2.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/Codeception/phpunit-wrapper.git",
-            "reference": "cafed18048826790c527843f9b85e8cc79b866f1"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/Codeception/phpunit-wrapper/zipball/cafed18048826790c527843f9b85e8cc79b866f1",
-            "reference": "cafed18048826790c527843f9b85e8cc79b866f1",
-            "shasum": "",
-            "mirrors": [
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Konstantin Kudryashov",
+                    "email": "ever.zet@gmail.com",
+                    "homepage": "http://everzet.com"
                 }
-            ]
-        },
-        "require": {
-            "phpunit/php-code-coverage": "^6.0",
-            "phpunit/phpunit": "7.5.*",
-            "sebastian/comparator": "^3.0",
-            "sebastian/diff": "^3.0"
-        },
-        "require-dev": {
-            "codeception/specify": "*",
-            "vlucas/phpdotenv": "^3.0"
-        },
-        "time": "2020-12-28T14:00:26+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Codeception\\PHPUnit\\": "src/"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Davert",
-                "email": "davert.php@resend.cc"
-            }
-        ],
-        "description": "PHPUnit classes used by Codeception"
-    },
-    {
-        "name": "codeception/stub",
-        "version": "2.1.0",
-        "version_normalized": "2.1.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/Codeception/Stub.git",
-            "reference": "853657f988942f7afb69becf3fd0059f192c705a"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/Codeception/Stub/zipball/853657f988942f7afb69becf3fd0059f192c705a",
-            "reference": "853657f988942f7afb69becf3fd0059f192c705a",
-            "shasum": "",
-            "mirrors": [
-                {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+            ],
+            "description": "Gherkin DSL parser for PHP",
+            "homepage": "http://behat.org/",
+            "keywords": [
+                "BDD",
+                "Behat",
+                "Cucumber",
+                "DSL",
+                "gherkin",
+                "parser"
+            ],
+            "install-path": "../behat/gherkin"
+        },
+        {
+            "name": "bower-asset/bootstrap",
+            "version": "v3.3.7",
+            "version_normalized": "3.3.7.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/twbs/bootstrap.git",
+                "reference": "0b9c4a4007c44201dce9a6cc1a38407005c26c86"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/twbs/bootstrap/zipball/0b9c4a4007c44201dce9a6cc1a38407005c26c86",
+                "reference": "0b9c4a4007c44201dce9a6cc1a38407005c26c86"
+            },
+            "require": {
+                "bower-asset/jquery": ">=1.9.1,<4.0"
+            },
+            "type": "bower-asset",
+            "installation-source": "dist",
+            "license": [
+                "MIT"
+            ],
+            "install-path": "../bower-asset/bootstrap"
+        },
+        {
+            "name": "bower-asset/inputmask",
+            "version": "3.3.11",
+            "version_normalized": "3.3.11.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/RobinHerbots/Inputmask.git",
+                "reference": "5e670ad62f50c738388d4dcec78d2888505ad77b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/RobinHerbots/Inputmask/zipball/5e670ad62f50c738388d4dcec78d2888505ad77b",
+                "reference": "5e670ad62f50c738388d4dcec78d2888505ad77b"
+            },
+            "require": {
+                "bower-asset/jquery": ">=1.7"
+            },
+            "type": "bower-asset",
+            "installation-source": "dist",
+            "license": [
+                "http://opensource.org/licenses/mit-license.php"
+            ],
+            "install-path": "../bower-asset/inputmask"
+        },
+        {
+            "name": "bower-asset/jquery",
+            "version": "3.2.1",
+            "version_normalized": "3.2.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/jquery/jquery-dist.git",
+                "reference": "77d2a51d0520d2ee44173afdf4e40a9201f5964e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/jquery/jquery-dist/zipball/77d2a51d0520d2ee44173afdf4e40a9201f5964e",
+                "reference": "77d2a51d0520d2ee44173afdf4e40a9201f5964e"
+            },
+            "type": "bower-asset",
+            "installation-source": "dist",
+            "license": [
+                "MIT"
+            ],
+            "install-path": "../bower-asset/jquery"
+        },
+        {
+            "name": "bower-asset/punycode",
+            "version": "v1.3.2",
+            "version_normalized": "1.3.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/bestiejs/punycode.js.git",
+                "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/bestiejs/punycode.js/zipball/38c8d3131a82567bfef18da09f7f4db68c84f8a3",
+                "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3"
+            },
+            "type": "bower-asset",
+            "installation-source": "dist",
+            "install-path": "../bower-asset/punycode"
+        },
+        {
+            "name": "bower-asset/typeahead.js",
+            "version": "v0.11.1",
+            "version_normalized": "0.11.1.0",
+            "source": {
+                "type": "git",
+                "url": "git@github.com:twitter/typeahead.js.git",
+                "reference": "588440f66559714280628a4f9799f0c4eb880a4a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/twitter/typeahead.js/zipball/588440f66559714280628a4f9799f0c4eb880a4a",
+                "reference": "588440f66559714280628a4f9799f0c4eb880a4a"
+            },
+            "require": {
+                "bower-asset/jquery": ">=1.7"
+            },
+            "type": "bower-asset",
+            "installation-source": "dist",
+            "install-path": "../bower-asset/typeahead.js"
+        },
+        {
+            "name": "bower-asset/yii2-pjax",
+            "version": "2.0.7.1",
+            "version_normalized": "2.0.7.1",
+            "source": {
+                "type": "git",
+                "url": "git@github.com:yiisoft/jquery-pjax.git",
+                "reference": "aef7b953107264f00234902a3880eb50dafc48be"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/yiisoft/jquery-pjax/zipball/aef7b953107264f00234902a3880eb50dafc48be",
+                "reference": "aef7b953107264f00234902a3880eb50dafc48be"
+            },
+            "require": {
+                "bower-asset/jquery": ">=1.8"
+            },
+            "type": "bower-asset",
+            "installation-source": "dist",
+            "license": [
+                "MIT"
+            ],
+            "install-path": "../bower-asset/yii2-pjax"
+        },
+        {
+            "name": "cebe/markdown",
+            "version": "1.2.1",
+            "version_normalized": "1.2.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/cebe/markdown.git",
+                "reference": "9bac5e971dd391e2802dca5400bbeacbaea9eb86"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/cebe/markdown/zipball/9bac5e971dd391e2802dca5400bbeacbaea9eb86",
+                "reference": "9bac5e971dd391e2802dca5400bbeacbaea9eb86",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "lib-pcre": "*",
+                "php": ">=5.4.0"
+            },
+            "require-dev": {
+                "cebe/indent": "*",
+                "facebook/xhprof": "*@dev",
+                "phpunit/phpunit": "4.1.*"
+            },
+            "time": "2018-03-26T11:24:36+00:00",
+            "bin": [
+                "bin/markdown"
+            ],
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.2.x-dev"
                 }
-            ]
-        },
-        "require": {
-            "codeception/phpunit-wrapper": ">6.0.15 <6.1.0 | ^6.6.1 | ^7.7.1 | ^8.0.3"
-        },
-        "time": "2019-03-02T15:35:10+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Codeception\\": "src/"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "description": "Flexible Stub wrapper for PHPUnit's Mock Builder"
-    },
-    {
-        "name": "codeception/verify",
-        "version": "0.3.3",
-        "version_normalized": "0.3.3.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/Codeception/Verify.git",
-            "reference": "5d649dda453cd814dadc4bb053060cd2c6bb4b4c"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/Codeception/Verify/zipball/5d649dda453cd814dadc4bb053060cd2c6bb4b4c",
-            "reference": "5d649dda453cd814dadc4bb053060cd2c6bb4b4c",
-            "shasum": "",
-            "mirrors": [
-                {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "cebe\\markdown\\": ""
                 }
-            ]
-        },
-        "require-dev": {
-            "phpunit/phpunit": "~4.0"
-        },
-        "time": "2017-01-09T10:58:51+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "files": [
-                "src/Codeception/function.php"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Michael Bodnarchuk",
-                "email": "davert.php@mailican.com"
-            }
-        ],
-        "description": "BDD assertion library for PHPUnit"
-    },
-    {
-        "name": "doctrine/instantiator",
-        "version": "1.4.0",
-        "version_normalized": "1.4.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/doctrine/instantiator.git",
-            "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b",
-            "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b",
-            "shasum": "",
-            "mirrors": [
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Carsten Brandt",
+                    "email": "mail@cebe.cc",
+                    "homepage": "http://cebe.cc/",
+                    "role": "Creator"
                 }
-            ]
-        },
-        "require": {
-            "php": "^7.1 || ^8.0"
-        },
-        "require-dev": {
-            "doctrine/coding-standard": "^8.0",
-            "ext-pdo": "*",
-            "ext-phar": "*",
-            "phpbench/phpbench": "^0.13 || 1.0.0-alpha2",
-            "phpstan/phpstan": "^0.12",
-            "phpstan/phpstan-phpunit": "^0.12",
-            "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
-        },
-        "time": "2020-11-10T18:47:58+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Marco Pivetta",
-                "email": "ocramius@gmail.com",
-                "homepage": "https://ocramius.github.io/"
-            }
-        ],
-        "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
-        "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
-        "keywords": [
-            "constructor",
-            "instantiate"
-        ],
-        "funding": [
-            {
-                "url": "https://www.doctrine-project.org/sponsorship.html",
-                "type": "custom"
-            },
-            {
-                "url": "https://www.patreon.com/phpdoctrine",
-                "type": "patreon"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "doctrine/lexer",
-        "version": "1.2.1",
-        "version_normalized": "1.2.1.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/doctrine/lexer.git",
-            "reference": "e864bbf5904cb8f5bb334f99209b48018522f042"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/doctrine/lexer/zipball/e864bbf5904cb8f5bb334f99209b48018522f042",
-            "reference": "e864bbf5904cb8f5bb334f99209b48018522f042",
-            "shasum": "",
-            "mirrors": [
-                {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+            ],
+            "description": "A super fast, highly extensible markdown parser for PHP",
+            "homepage": "https://github.com/cebe/markdown#readme",
+            "keywords": [
+                "extensible",
+                "fast",
+                "gfm",
+                "markdown",
+                "markdown-extra"
+            ],
+            "install-path": "../cebe/markdown"
+        },
+        {
+            "name": "codeception/base",
+            "version": "2.5.6",
+            "version_normalized": "2.5.6.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Codeception/base.git",
+                "reference": "aace5bab5593c93d8473b620f70754135a1eb4f0"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Codeception/base/zipball/aace5bab5593c93d8473b620f70754135a1eb4f0",
+                "reference": "aace5bab5593c93d8473b620f70754135a1eb4f0",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "behat/gherkin": "^4.4.0",
+                "codeception/phpunit-wrapper": "^6.0.9|^7.0.6",
+                "codeception/stub": "^2.0",
+                "ext-curl": "*",
+                "ext-json": "*",
+                "ext-mbstring": "*",
+                "guzzlehttp/psr7": "~1.0",
+                "php": ">=5.6.0 <8.0",
+                "symfony/browser-kit": ">=2.7 <5.0",
+                "symfony/console": ">=2.7 <5.0",
+                "symfony/css-selector": ">=2.7 <5.0",
+                "symfony/dom-crawler": ">=2.7 <5.0",
+                "symfony/event-dispatcher": ">=2.7 <5.0",
+                "symfony/finder": ">=2.7 <5.0",
+                "symfony/yaml": ">=2.7 <5.0"
+            },
+            "require-dev": {
+                "codeception/specify": "~0.3",
+                "facebook/graph-sdk": "~5.3",
+                "flow/jsonpath": "~0.2",
+                "monolog/monolog": "~1.8",
+                "pda/pheanstalk": "~3.0",
+                "php-amqplib/php-amqplib": "~2.4",
+                "predis/predis": "^1.0",
+                "squizlabs/php_codesniffer": "~2.0",
+                "symfony/process": ">=2.7 <5.0",
+                "vlucas/phpdotenv": "^3.0"
+            },
+            "suggest": {
+                "aws/aws-sdk-php": "For using AWS Auth in REST module and Queue module",
+                "codeception/phpbuiltinserver": "Start and stop PHP built-in web server for your tests",
+                "codeception/specify": "BDD-style code blocks",
+                "codeception/verify": "BDD-style assertions",
+                "flow/jsonpath": "For using JSONPath in REST module",
+                "league/factory-muffin": "For DataFactory module",
+                "league/factory-muffin-faker": "For Faker support in DataFactory module",
+                "phpseclib/phpseclib": "for SFTP option in FTP Module",
+                "stecman/symfony-console-completion": "For BASH autocompletion",
+                "symfony/phpunit-bridge": "For phpunit-bridge support"
+            },
+            "time": "2019-04-24T11:36:34+00:00",
+            "bin": [
+                "codecept"
+            ],
+            "type": "library",
+            "extra": {
+                "branch-alias": []
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Codeception\\": "src/Codeception",
+                    "Codeception\\Extension\\": "ext"
                 }
-            ]
-        },
-        "require": {
-            "php": "^7.2 || ^8.0"
-        },
-        "require-dev": {
-            "doctrine/coding-standard": "^6.0",
-            "phpstan/phpstan": "^0.11.8",
-            "phpunit/phpunit": "^8.2"
-        },
-        "time": "2020-05-25T17:44:05+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "1.2.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Guilherme Blanco",
-                "email": "guilhermeblanco@gmail.com"
-            },
-            {
-                "name": "Roman Borschel",
-                "email": "roman@code-factory.org"
-            },
-            {
-                "name": "Johannes Schmitt",
-                "email": "schmittjoh@gmail.com"
-            }
-        ],
-        "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.",
-        "homepage": "https://www.doctrine-project.org/projects/lexer.html",
-        "keywords": [
-            "annotations",
-            "docblock",
-            "lexer",
-            "parser",
-            "php"
-        ],
-        "funding": [
-            {
-                "url": "https://www.doctrine-project.org/sponsorship.html",
-                "type": "custom"
-            },
-            {
-                "url": "https://www.patreon.com/phpdoctrine",
-                "type": "patreon"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "egulias/email-validator",
-        "version": "3.1.2",
-        "version_normalized": "3.1.2.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/egulias/EmailValidator.git",
-            "reference": "ee0db30118f661fb166bcffbf5d82032df484697"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ee0db30118f661fb166bcffbf5d82032df484697",
-            "reference": "ee0db30118f661fb166bcffbf5d82032df484697",
-            "shasum": "",
-            "mirrors": [
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Michael Bodnarchuk",
+                    "email": "davert@mail.ua",
+                    "homepage": "http://codegyre.com"
                 }
-            ]
-        },
-        "require": {
-            "doctrine/lexer": "^1.2",
-            "php": ">=7.2",
-            "symfony/polyfill-intl-idn": "^1.15"
-        },
-        "require-dev": {
-            "php-coveralls/php-coveralls": "^2.2",
-            "phpunit/phpunit": "^8.5.8|^9.3.3",
-            "vimeo/psalm": "^4"
-        },
-        "suggest": {
-            "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation"
-        },
-        "time": "2021-10-11T09:18:27+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "3.0.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Egulias\\EmailValidator\\": "src"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Eduardo Gulias Davis"
-            }
-        ],
-        "description": "A library for validating emails against several RFCs",
-        "homepage": "https://github.com/egulias/EmailValidator",
-        "keywords": [
-            "email",
-            "emailvalidation",
-            "emailvalidator",
-            "validation",
-            "validator"
-        ],
-        "funding": [
-            {
-                "url": "https://github.com/egulias",
-                "type": "github"
-            }
-        ]
-    },
-    {
-        "name": "ezyang/htmlpurifier",
-        "version": "v4.13.0",
-        "version_normalized": "4.13.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/ezyang/htmlpurifier.git",
-            "reference": "08e27c97e4c6ed02f37c5b2b20488046c8d90d75"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/08e27c97e4c6ed02f37c5b2b20488046c8d90d75",
-            "reference": "08e27c97e4c6ed02f37c5b2b20488046c8d90d75",
-            "shasum": "",
-            "mirrors": [
-                {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+            ],
+            "description": "BDD-style testing framework",
+            "homepage": "http://codeception.com/",
+            "keywords": [
+                "BDD",
+                "TDD",
+                "acceptance testing",
+                "functional testing",
+                "unit testing"
+            ],
+            "abandoned": true,
+            "install-path": "../codeception/base"
+        },
+        {
+            "name": "codeception/phpunit-wrapper",
+            "version": "7.8.2",
+            "version_normalized": "7.8.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Codeception/phpunit-wrapper.git",
+                "reference": "cafed18048826790c527843f9b85e8cc79b866f1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Codeception/phpunit-wrapper/zipball/cafed18048826790c527843f9b85e8cc79b866f1",
+                "reference": "cafed18048826790c527843f9b85e8cc79b866f1",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "phpunit/php-code-coverage": "^6.0",
+                "phpunit/phpunit": "7.5.*",
+                "sebastian/comparator": "^3.0",
+                "sebastian/diff": "^3.0"
+            },
+            "require-dev": {
+                "codeception/specify": "*",
+                "vlucas/phpdotenv": "^3.0"
+            },
+            "time": "2020-12-28T14:00:26+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Codeception\\PHPUnit\\": "src/"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=5.2"
-        },
-        "require-dev": {
-            "simpletest/simpletest": "dev-master#72de02a7b80c6bb8864ef9bf66d41d2f58f826bd"
-        },
-        "time": "2020-06-29T00:56:53+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-0": {
-                "HTMLPurifier": "library/"
-            },
-            "files": [
-                "library/HTMLPurifier.composer.php"
-            ],
-            "exclude-from-classmap": [
-                "/library/HTMLPurifier/Language/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "LGPL-2.1-or-later"
-        ],
-        "authors": [
-            {
-                "name": "Edward Z. Yang",
-                "email": "admin@htmlpurifier.org",
-                "homepage": "http://ezyang.com"
-            }
-        ],
-        "description": "Standards compliant HTML filter written in PHP",
-        "homepage": "http://htmlpurifier.org/",
-        "keywords": [
-            "html"
-        ]
-    },
-    {
-        "name": "fakerphp/faker",
-        "version": "v1.17.0",
-        "version_normalized": "1.17.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/FakerPHP/Faker.git",
-            "reference": "b85e9d44eae8c52cca7aa0939483611f7232b669"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/b85e9d44eae8c52cca7aa0939483611f7232b669",
-            "reference": "b85e9d44eae8c52cca7aa0939483611f7232b669",
-            "shasum": "",
-            "mirrors": [
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Davert",
+                    "email": "davert.php@resend.cc"
                 }
-            ]
-        },
-        "require": {
-            "php": "^7.1 || ^8.0",
-            "psr/container": "^1.0 || ^2.0",
-            "symfony/deprecation-contracts": "^2.2 || ^3.0"
-        },
-        "conflict": {
-            "fzaninotto/faker": "*"
-        },
-        "require-dev": {
-            "bamarni/composer-bin-plugin": "^1.4.1",
-            "ext-intl": "*",
-            "symfony/phpunit-bridge": "^4.4 || ^5.2"
-        },
-        "suggest": {
-            "ext-curl": "Required by Faker\\Provider\\Image to download images.",
-            "ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.",
-            "ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.",
-            "ext-mbstring": "Required for multibyte Unicode string functionality."
-        },
-        "time": "2021-12-05T17:14:47+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-main": "v1.17-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Faker\\": "src/Faker/"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "François Zaninotto"
-            }
-        ],
-        "description": "Faker is a PHP library that generates fake data for you.",
-        "keywords": [
-            "data",
-            "faker",
-            "fixtures"
-        ]
-    },
-    {
-        "name": "godruoyi/php-snowflake",
-        "version": "1.1.1",
-        "version_normalized": "1.1.1.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/godruoyi/php-snowflake.git",
-            "reference": "d8cbe72ed375b45033b7042e3d03340ce4fa479f"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/godruoyi/php-snowflake/zipball/d8cbe72ed375b45033b7042e3d03340ce4fa479f",
-            "reference": "d8cbe72ed375b45033b7042e3d03340ce4fa479f",
-            "shasum": "",
-            "mirrors": [
-                {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+            ],
+            "description": "PHPUnit classes used by Codeception",
+            "install-path": "../codeception/phpunit-wrapper"
+        },
+        {
+            "name": "codeception/stub",
+            "version": "2.1.0",
+            "version_normalized": "2.1.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Codeception/Stub.git",
+                "reference": "853657f988942f7afb69becf3fd0059f192c705a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Codeception/Stub/zipball/853657f988942f7afb69becf3fd0059f192c705a",
+                "reference": "853657f988942f7afb69becf3fd0059f192c705a",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "codeception/phpunit-wrapper": ">6.0.15 <6.1.0 | ^6.6.1 | ^7.7.1 | ^8.0.3"
+            },
+            "time": "2019-03-02T15:35:10+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Codeception\\": "src/"
                 }
-            ]
-        },
-        "require-dev": {
-            "phpunit/phpunit": "~7"
-        },
-        "time": "2021-05-25T05:56:30+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Godruoyi\\Snowflake\\": "src"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Godruoyi",
-                "email": "g@godruoyi.com"
-            }
-        ],
-        "description": "An ID Generator for PHP based on Snowflake Algorithm (Twitter announced).",
-        "homepage": "https://github.com/godruoyi/php-snowflake",
-        "keywords": [
-            "Unique ID",
-            "laravel snowflake",
-            "order id",
-            "php snowflake",
-            "php unique id",
-            "snowflake algorithm",
-            "unique order id"
-        ],
-        "funding": [
-            {
-                "url": "https://images.godruoyi.com/wechat.png",
-                "type": "custom"
-            },
-            {
-                "url": "https://github.com/godruoyi",
-                "type": "github"
-            }
-        ]
-    },
-    {
-        "name": "guzzlehttp/psr7",
-        "version": "1.8.3",
-        "version_normalized": "1.8.3.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/guzzle/psr7.git",
-            "reference": "1afdd860a2566ed3c2b0b4a3de6e23434a79ec85"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/guzzle/psr7/zipball/1afdd860a2566ed3c2b0b4a3de6e23434a79ec85",
-            "reference": "1afdd860a2566ed3c2b0b4a3de6e23434a79ec85",
-            "shasum": "",
-            "mirrors": [
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "Flexible Stub wrapper for PHPUnit's Mock Builder",
+            "install-path": "../codeception/stub"
+        },
+        {
+            "name": "codeception/verify",
+            "version": "0.3.3",
+            "version_normalized": "0.3.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Codeception/Verify.git",
+                "reference": "5d649dda453cd814dadc4bb053060cd2c6bb4b4c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Codeception/Verify/zipball/5d649dda453cd814dadc4bb053060cd2c6bb4b4c",
+                "reference": "5d649dda453cd814dadc4bb053060cd2c6bb4b4c",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require-dev": {
+                "phpunit/phpunit": "~4.0"
+            },
+            "time": "2017-01-09T10:58:51+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "files": [
+                    "src/Codeception/function.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Michael Bodnarchuk",
+                    "email": "davert.php@mailican.com"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=5.4.0",
-            "psr/http-message": "~1.0",
-            "ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
-        },
-        "provide": {
-            "psr/http-message-implementation": "1.0"
-        },
-        "require-dev": {
-            "ext-zlib": "*",
-            "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10"
-        },
-        "suggest": {
-            "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
-        },
-        "time": "2021-10-05T13:56:00+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "1.7-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "GuzzleHttp\\Psr7\\": "src/"
-            },
-            "files": [
-                "src/functions_include.php"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Graham Campbell",
-                "email": "hello@gjcampbell.co.uk",
-                "homepage": "https://github.com/GrahamCampbell"
-            },
-            {
-                "name": "Michael Dowling",
-                "email": "mtdowling@gmail.com",
-                "homepage": "https://github.com/mtdowling"
-            },
-            {
-                "name": "George Mponos",
-                "email": "gmponos@gmail.com",
-                "homepage": "https://github.com/gmponos"
-            },
-            {
-                "name": "Tobias Nyholm",
-                "email": "tobias.nyholm@gmail.com",
-                "homepage": "https://github.com/Nyholm"
-            },
-            {
-                "name": "Márk Sági-Kazár",
-                "email": "mark.sagikazar@gmail.com",
-                "homepage": "https://github.com/sagikazarmark"
-            },
-            {
-                "name": "Tobias Schultze",
-                "email": "webmaster@tubo-world.de",
-                "homepage": "https://github.com/Tobion"
-            }
-        ],
-        "description": "PSR-7 message implementation that also provides common utility methods",
-        "keywords": [
-            "http",
-            "message",
-            "psr-7",
-            "request",
-            "response",
-            "stream",
-            "uri",
-            "url"
-        ],
-        "funding": [
-            {
-                "url": "https://github.com/GrahamCampbell",
-                "type": "github"
-            },
-            {
-                "url": "https://github.com/Nyholm",
-                "type": "github"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "maennchen/zipstream-php",
-        "version": "2.1.0",
-        "version_normalized": "2.1.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/maennchen/ZipStream-PHP.git",
-            "reference": "c4c5803cc1f93df3d2448478ef79394a5981cc58"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/c4c5803cc1f93df3d2448478ef79394a5981cc58",
-            "reference": "c4c5803cc1f93df3d2448478ef79394a5981cc58",
-            "shasum": "",
-            "mirrors": [
-                {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+            ],
+            "description": "BDD assertion library for PHPUnit",
+            "install-path": "../codeception/verify"
+        },
+        {
+            "name": "doctrine/instantiator",
+            "version": "1.4.0",
+            "version_normalized": "1.4.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/doctrine/instantiator.git",
+                "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b",
+                "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "^7.1 || ^8.0"
+            },
+            "require-dev": {
+                "doctrine/coding-standard": "^8.0",
+                "ext-pdo": "*",
+                "ext-phar": "*",
+                "phpbench/phpbench": "^0.13 || 1.0.0-alpha2",
+                "phpstan/phpstan": "^0.12",
+                "phpstan/phpstan-phpunit": "^0.12",
+                "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
+            },
+            "time": "2020-11-10T18:47:58+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
                 }
-            ]
-        },
-        "require": {
-            "myclabs/php-enum": "^1.5",
-            "php": ">= 7.1",
-            "psr/http-message": "^1.0",
-            "symfony/polyfill-mbstring": "^1.0"
-        },
-        "require-dev": {
-            "ext-zip": "*",
-            "guzzlehttp/guzzle": ">= 6.3",
-            "mikey179/vfsstream": "^1.6",
-            "phpunit/phpunit": ">= 7.5"
-        },
-        "time": "2020-05-30T13:11:16+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "ZipStream\\": "src/"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Paul Duncan",
-                "email": "pabs@pablotron.org"
-            },
-            {
-                "name": "Jonatan Männchen",
-                "email": "jonatan@maennchen.ch"
-            },
-            {
-                "name": "Jesse Donat",
-                "email": "donatj@gmail.com"
-            },
-            {
-                "name": "András Kolesár",
-                "email": "kolesar@kolesar.hu"
-            }
-        ],
-        "description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.",
-        "keywords": [
-            "stream",
-            "zip"
-        ],
-        "funding": [
-            {
-                "url": "https://opencollective.com/zipstream",
-                "type": "open_collective"
-            }
-        ]
-    },
-    {
-        "name": "markbaker/complex",
-        "version": "3.0.1",
-        "version_normalized": "3.0.1.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/MarkBaker/PHPComplex.git",
-            "reference": "ab8bc271e404909db09ff2d5ffa1e538085c0f22"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/ab8bc271e404909db09ff2d5ffa1e538085c0f22",
-            "reference": "ab8bc271e404909db09ff2d5ffa1e538085c0f22",
-            "shasum": "",
-            "mirrors": [
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Marco Pivetta",
+                    "email": "ocramius@gmail.com",
+                    "homepage": "https://ocramius.github.io/"
                 }
-            ]
-        },
-        "require": {
-            "php": "^7.2 || ^8.0"
-        },
-        "require-dev": {
-            "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
-            "phpcompatibility/php-compatibility": "^9.0",
-            "phpunit/phpunit": "^7.0 || ^8.0 || ^9.3",
-            "squizlabs/php_codesniffer": "^3.4"
-        },
-        "time": "2021-06-29T15:32:53+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Complex\\": "classes/src/"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Mark Baker",
-                "email": "mark@lange.demon.co.uk"
-            }
-        ],
-        "description": "PHP Class for working with complex numbers",
-        "homepage": "https://github.com/MarkBaker/PHPComplex",
-        "keywords": [
-            "complex",
-            "mathematics"
-        ]
-    },
-    {
-        "name": "markbaker/matrix",
-        "version": "3.0.0",
-        "version_normalized": "3.0.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/MarkBaker/PHPMatrix.git",
-            "reference": "c66aefcafb4f6c269510e9ac46b82619a904c576"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/c66aefcafb4f6c269510e9ac46b82619a904c576",
-            "reference": "c66aefcafb4f6c269510e9ac46b82619a904c576",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+            "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
+            "keywords": [
+                "constructor",
+                "instantiate"
+            ],
+            "funding": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
-                }
-            ]
-        },
-        "require": {
-            "php": "^7.1 || ^8.0"
-        },
-        "require-dev": {
-            "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
-            "phpcompatibility/php-compatibility": "^9.0",
-            "phpdocumentor/phpdocumentor": "2.*",
-            "phploc/phploc": "^4.0",
-            "phpmd/phpmd": "2.*",
-            "phpunit/phpunit": "^7.0 || ^8.0 || ^9.3",
-            "sebastian/phpcpd": "^4.0",
-            "squizlabs/php_codesniffer": "^3.4"
-        },
-        "time": "2021-07-01T19:01:15+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Matrix\\": "classes/src/"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Mark Baker",
-                "email": "mark@demon-angel.eu"
-            }
-        ],
-        "description": "PHP Class for working with matrices",
-        "homepage": "https://github.com/MarkBaker/PHPMatrix",
-        "keywords": [
-            "mathematics",
-            "matrix",
-            "vector"
-        ]
-    },
-    {
-        "name": "myclabs/deep-copy",
-        "version": "1.10.2",
-        "version_normalized": "1.10.2.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/myclabs/DeepCopy.git",
-            "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220",
-            "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220",
-            "shasum": "",
-            "mirrors": [
+                    "url": "https://www.doctrine-project.org/sponsorship.html",
+                    "type": "custom"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
-                }
-            ]
-        },
-        "require": {
-            "php": "^7.1 || ^8.0"
-        },
-        "replace": {
-            "myclabs/deep-copy": "self.version"
-        },
-        "require-dev": {
-            "doctrine/collections": "^1.0",
-            "doctrine/common": "^2.6",
-            "phpunit/phpunit": "^7.1"
-        },
-        "time": "2020-11-13T09:40:50+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "DeepCopy\\": "src/DeepCopy/"
-            },
-            "files": [
-                "src/DeepCopy/deep_copy.php"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "description": "Create deep copies (clones) of your objects",
-        "keywords": [
-            "clone",
-            "copy",
-            "duplicate",
-            "object",
-            "object graph"
-        ],
-        "funding": [
-            {
-                "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "myclabs/php-enum",
-        "version": "1.8.3",
-        "version_normalized": "1.8.3.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/myclabs/php-enum.git",
-            "reference": "b942d263c641ddb5190929ff840c68f78713e937"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/myclabs/php-enum/zipball/b942d263c641ddb5190929ff840c68f78713e937",
-            "reference": "b942d263c641ddb5190929ff840c68f78713e937",
-            "shasum": "",
-            "mirrors": [
+                    "url": "https://www.patreon.com/phpdoctrine",
+                    "type": "patreon"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
+                    "type": "tidelift"
                 }
-            ]
-        },
-        "require": {
-            "ext-json": "*",
-            "php": "^7.3 || ^8.0"
-        },
-        "require-dev": {
-            "phpunit/phpunit": "^9.5",
-            "squizlabs/php_codesniffer": "1.*",
-            "vimeo/psalm": "^4.6.2"
-        },
-        "time": "2021-07-05T08:18:36+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "MyCLabs\\Enum\\": "src/"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "PHP Enum contributors",
-                "homepage": "https://github.com/myclabs/php-enum/graphs/contributors"
-            }
-        ],
-        "description": "PHP Enum implementation",
-        "homepage": "http://github.com/myclabs/php-enum",
-        "keywords": [
-            "enum"
-        ],
-        "funding": [
-            {
-                "url": "https://github.com/mnapoli",
-                "type": "github"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/myclabs/php-enum",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "paragonie/random_compat",
-        "version": "v9.99.100",
-        "version_normalized": "9.99.100.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/paragonie/random_compat.git",
-            "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a",
-            "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a",
-            "shasum": "",
-            "mirrors": [
-                {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+            ],
+            "install-path": "../doctrine/instantiator"
+        },
+        {
+            "name": "doctrine/lexer",
+            "version": "1.2.1",
+            "version_normalized": "1.2.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/doctrine/lexer.git",
+                "reference": "e864bbf5904cb8f5bb334f99209b48018522f042"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/doctrine/lexer/zipball/e864bbf5904cb8f5bb334f99209b48018522f042",
+                "reference": "e864bbf5904cb8f5bb334f99209b48018522f042",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "^7.2 || ^8.0"
+            },
+            "require-dev": {
+                "doctrine/coding-standard": "^6.0",
+                "phpstan/phpstan": "^0.11.8",
+                "phpunit/phpunit": "^8.2"
+            },
+            "time": "2020-05-25T17:44:05+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.2.x-dev"
                 }
-            ]
-        },
-        "require": {
-            "php": ">= 7"
-        },
-        "require-dev": {
-            "phpunit/phpunit": "4.*|5.*",
-            "vimeo/psalm": "^1"
-        },
-        "suggest": {
-            "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
-        },
-        "time": "2020-10-15T08:29:30+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Paragon Initiative Enterprises",
-                "email": "security@paragonie.com",
-                "homepage": "https://paragonie.com"
-            }
-        ],
-        "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
-        "keywords": [
-            "csprng",
-            "polyfill",
-            "pseudorandom",
-            "random"
-        ]
-    },
-    {
-        "name": "phar-io/manifest",
-        "version": "1.0.3",
-        "version_normalized": "1.0.3.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/phar-io/manifest.git",
-            "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
-            "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
-            "shasum": "",
-            "mirrors": [
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Guilherme Blanco",
+                    "email": "guilhermeblanco@gmail.com"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Roman Borschel",
+                    "email": "roman@code-factory.org"
+                },
+                {
+                    "name": "Johannes Schmitt",
+                    "email": "schmittjoh@gmail.com"
                 }
-            ]
-        },
-        "require": {
-            "ext-dom": "*",
-            "ext-phar": "*",
-            "phar-io/version": "^2.0",
-            "php": "^5.6 || ^7.0"
-        },
-        "time": "2018-07-08T19:23:20+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "1.0.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "classmap": [
-                "src/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Arne Blankerts",
-                "email": "arne@blankerts.de",
-                "role": "Developer"
-            },
-            {
-                "name": "Sebastian Heuer",
-                "email": "sebastian@phpeople.de",
-                "role": "Developer"
-            },
-            {
-                "name": "Sebastian Bergmann",
-                "email": "sebastian@phpunit.de",
-                "role": "Developer"
-            }
-        ],
-        "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)"
-    },
-    {
-        "name": "phar-io/version",
-        "version": "2.0.1",
-        "version_normalized": "2.0.1.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/phar-io/version.git",
-            "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6",
-            "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.",
+            "homepage": "https://www.doctrine-project.org/projects/lexer.html",
+            "keywords": [
+                "annotations",
+                "docblock",
+                "lexer",
+                "parser",
+                "php"
+            ],
+            "funding": [
+                {
+                    "url": "https://www.doctrine-project.org/sponsorship.html",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://www.patreon.com/phpdoctrine",
+                    "type": "patreon"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer",
+                    "type": "tidelift"
                 }
-            ]
-        },
-        "require": {
-            "php": "^5.6 || ^7.0"
-        },
-        "time": "2018-07-08T19:19:57+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "classmap": [
-                "src/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Arne Blankerts",
-                "email": "arne@blankerts.de",
-                "role": "Developer"
-            },
-            {
-                "name": "Sebastian Heuer",
-                "email": "sebastian@phpeople.de",
-                "role": "Developer"
-            },
-            {
-                "name": "Sebastian Bergmann",
-                "email": "sebastian@phpunit.de",
-                "role": "Developer"
-            }
-        ],
-        "description": "Library for handling version information and constraints"
-    },
-    {
-        "name": "phpdocumentor/reflection-common",
-        "version": "2.2.0",
-        "version_normalized": "2.2.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
-            "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
-            "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "install-path": "../doctrine/lexer"
+        },
+        {
+            "name": "egulias/email-validator",
+            "version": "3.1.2",
+            "version_normalized": "3.1.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/egulias/EmailValidator.git",
+                "reference": "ee0db30118f661fb166bcffbf5d82032df484697"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ee0db30118f661fb166bcffbf5d82032df484697",
+                "reference": "ee0db30118f661fb166bcffbf5d82032df484697",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "doctrine/lexer": "^1.2",
+                "php": ">=7.2",
+                "symfony/polyfill-intl-idn": "^1.15"
+            },
+            "require-dev": {
+                "php-coveralls/php-coveralls": "^2.2",
+                "phpunit/phpunit": "^8.5.8|^9.3.3",
+                "vimeo/psalm": "^4"
+            },
+            "suggest": {
+                "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation"
+            },
+            "time": "2021-10-11T09:18:27+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.0.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Egulias\\EmailValidator\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Eduardo Gulias Davis"
                 }
-            ]
-        },
-        "require": {
-            "php": "^7.2 || ^8.0"
-        },
-        "time": "2020-06-27T09:03:43+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-2.x": "2.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "phpDocumentor\\Reflection\\": "src/"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Jaap van Otterdijk",
-                "email": "opensource@ijaap.nl"
-            }
-        ],
-        "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
-        "homepage": "http://www.phpdoc.org",
-        "keywords": [
-            "FQSEN",
-            "phpDocumentor",
-            "phpdoc",
-            "reflection",
-            "static analysis"
-        ]
-    },
-    {
-        "name": "phpdocumentor/reflection-docblock",
-        "version": "5.3.0",
-        "version_normalized": "5.3.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
-            "reference": "622548b623e81ca6d78b721c5e029f4ce664f170"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170",
-            "reference": "622548b623e81ca6d78b721c5e029f4ce664f170",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "description": "A library for validating emails against several RFCs",
+            "homepage": "https://github.com/egulias/EmailValidator",
+            "keywords": [
+                "email",
+                "emailvalidation",
+                "emailvalidator",
+                "validation",
+                "validator"
+            ],
+            "funding": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "url": "https://github.com/egulias",
+                    "type": "github"
                 }
-            ]
-        },
-        "require": {
-            "ext-filter": "*",
-            "php": "^7.2 || ^8.0",
-            "phpdocumentor/reflection-common": "^2.2",
-            "phpdocumentor/type-resolver": "^1.3",
-            "webmozart/assert": "^1.9.1"
-        },
-        "require-dev": {
-            "mockery/mockery": "~1.3.2",
-            "psalm/phar": "^4.8"
-        },
-        "time": "2021-10-19T17:43:47+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "5.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "phpDocumentor\\Reflection\\": "src"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Mike van Riel",
-                "email": "me@mikevanriel.com"
-            },
-            {
-                "name": "Jaap van Otterdijk",
-                "email": "account@ijaap.nl"
-            }
-        ],
-        "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock."
-    },
-    {
-        "name": "phpdocumentor/type-resolver",
-        "version": "1.5.1",
-        "version_normalized": "1.5.1.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/phpDocumentor/TypeResolver.git",
-            "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/a12f7e301eb7258bb68acd89d4aefa05c2906cae",
-            "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "install-path": "../egulias/email-validator"
+        },
+        {
+            "name": "ezyang/htmlpurifier",
+            "version": "v4.13.0",
+            "version_normalized": "4.13.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/ezyang/htmlpurifier.git",
+                "reference": "08e27c97e4c6ed02f37c5b2b20488046c8d90d75"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/08e27c97e4c6ed02f37c5b2b20488046c8d90d75",
+                "reference": "08e27c97e4c6ed02f37c5b2b20488046c8d90d75",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=5.2"
+            },
+            "require-dev": {
+                "simpletest/simpletest": "dev-master#72de02a7b80c6bb8864ef9bf66d41d2f58f826bd"
+            },
+            "time": "2020-06-29T00:56:53+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-0": {
+                    "HTMLPurifier": "library/"
+                },
+                "files": [
+                    "library/HTMLPurifier.composer.php"
+                ],
+                "exclude-from-classmap": [
+                    "/library/HTMLPurifier/Language/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "LGPL-2.1-or-later"
+            ],
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Edward Z. Yang",
+                    "email": "admin@htmlpurifier.org",
+                    "homepage": "http://ezyang.com"
                 }
-            ]
-        },
-        "require": {
-            "php": "^7.2 || ^8.0",
-            "phpdocumentor/reflection-common": "^2.0"
-        },
-        "require-dev": {
-            "ext-tokenizer": "*",
-            "psalm/phar": "^4.8"
-        },
-        "time": "2021-10-02T14:08:47+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-1.x": "1.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "phpDocumentor\\Reflection\\": "src"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Mike van Riel",
-                "email": "me@mikevanriel.com"
-            }
-        ],
-        "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names"
-    },
-    {
-        "name": "phpoffice/phpspreadsheet",
-        "version": "1.20.0",
-        "version_normalized": "1.20.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
-            "reference": "44436f270bb134b4a94670f3d020a85dfa0a3c02"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/44436f270bb134b4a94670f3d020a85dfa0a3c02",
-            "reference": "44436f270bb134b4a94670f3d020a85dfa0a3c02",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "description": "Standards compliant HTML filter written in PHP",
+            "homepage": "http://htmlpurifier.org/",
+            "keywords": [
+                "html"
+            ],
+            "install-path": "../ezyang/htmlpurifier"
+        },
+        {
+            "name": "fakerphp/faker",
+            "version": "v1.17.0",
+            "version_normalized": "1.17.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/FakerPHP/Faker.git",
+                "reference": "b85e9d44eae8c52cca7aa0939483611f7232b669"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/b85e9d44eae8c52cca7aa0939483611f7232b669",
+                "reference": "b85e9d44eae8c52cca7aa0939483611f7232b669",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "^7.1 || ^8.0",
+                "psr/container": "^1.0 || ^2.0",
+                "symfony/deprecation-contracts": "^2.2 || ^3.0"
+            },
+            "conflict": {
+                "fzaninotto/faker": "*"
+            },
+            "require-dev": {
+                "bamarni/composer-bin-plugin": "^1.4.1",
+                "ext-intl": "*",
+                "symfony/phpunit-bridge": "^4.4 || ^5.2"
+            },
+            "suggest": {
+                "ext-curl": "Required by Faker\\Provider\\Image to download images.",
+                "ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.",
+                "ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.",
+                "ext-mbstring": "Required for multibyte Unicode string functionality."
+            },
+            "time": "2021-12-05T17:14:47+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "v1.17-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Faker\\": "src/Faker/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "François Zaninotto"
                 }
-            ]
-        },
-        "require": {
-            "ext-ctype": "*",
-            "ext-dom": "*",
-            "ext-fileinfo": "*",
-            "ext-gd": "*",
-            "ext-iconv": "*",
-            "ext-libxml": "*",
-            "ext-mbstring": "*",
-            "ext-simplexml": "*",
-            "ext-xml": "*",
-            "ext-xmlreader": "*",
-            "ext-xmlwriter": "*",
-            "ext-zip": "*",
-            "ext-zlib": "*",
-            "ezyang/htmlpurifier": "^4.13",
-            "maennchen/zipstream-php": "^2.1",
-            "markbaker/complex": "^3.0",
-            "markbaker/matrix": "^3.0",
-            "php": "^7.3 || ^8.0",
-            "psr/http-client": "^1.0",
-            "psr/http-factory": "^1.0",
-            "psr/simple-cache": "^1.0"
-        },
-        "require-dev": {
-            "dealerdirect/phpcodesniffer-composer-installer": "dev-master",
-            "dompdf/dompdf": "^1.0",
-            "friendsofphp/php-cs-fixer": "^3.2",
-            "jpgraph/jpgraph": "^4.0",
-            "mpdf/mpdf": "^8.0",
-            "phpcompatibility/php-compatibility": "^9.3",
-            "phpstan/phpstan": "^1.1",
-            "phpstan/phpstan-phpunit": "^1.0",
-            "phpunit/phpunit": "^8.5 || ^9.0",
-            "squizlabs/php_codesniffer": "^3.6",
-            "tecnickcom/tcpdf": "^6.4"
-        },
-        "suggest": {
-            "dompdf/dompdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)",
-            "jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
-            "mpdf/mpdf": "Option for rendering PDF with PDF Writer",
-            "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)"
-        },
-        "time": "2021-11-23T15:23:42+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Maarten Balliauw",
-                "homepage": "https://blog.maartenballiauw.be"
-            },
-            {
-                "name": "Mark Baker",
-                "homepage": "https://markbakeruk.net"
-            },
-            {
-                "name": "Franck Lefevre",
-                "homepage": "https://rootslabs.net"
-            },
-            {
-                "name": "Erik Tilt"
-            },
-            {
-                "name": "Adrien Crivelli"
-            }
-        ],
-        "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
-        "homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
-        "keywords": [
-            "OpenXML",
-            "excel",
-            "gnumeric",
-            "ods",
-            "php",
-            "spreadsheet",
-            "xls",
-            "xlsx"
-        ]
-    },
-    {
-        "name": "phpspec/php-diff",
-        "version": "v1.1.3",
-        "version_normalized": "1.1.3.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/phpspec/php-diff.git",
-            "reference": "fc1156187f9f6c8395886fe85ed88a0a245d72e9"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/phpspec/php-diff/zipball/fc1156187f9f6c8395886fe85ed88a0a245d72e9",
-            "reference": "fc1156187f9f6c8395886fe85ed88a0a245d72e9",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "description": "Faker is a PHP library that generates fake data for you.",
+            "keywords": [
+                "data",
+                "faker",
+                "fixtures"
+            ],
+            "install-path": "../fakerphp/faker"
+        },
+        {
+            "name": "godruoyi/php-snowflake",
+            "version": "1.1.1",
+            "version_normalized": "1.1.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/godruoyi/php-snowflake.git",
+                "reference": "d8cbe72ed375b45033b7042e3d03340ce4fa479f"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/godruoyi/php-snowflake/zipball/d8cbe72ed375b45033b7042e3d03340ce4fa479f",
+                "reference": "d8cbe72ed375b45033b7042e3d03340ce4fa479f",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require-dev": {
+                "phpunit/phpunit": "~7"
+            },
+            "time": "2021-05-25T05:56:30+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Godruoyi\\Snowflake\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Godruoyi",
+                    "email": "g@godruoyi.com"
                 }
-            ]
-        },
-        "time": "2020-09-18T13:47:07+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "1.0.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-0": {
-                "Diff": "lib/"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Chris Boulton",
-                "homepage": "http://github.com/chrisboulton"
-            }
-        ],
-        "description": "A comprehensive library for generating differences between two hashable objects (strings or arrays)."
-    },
-    {
-        "name": "phpspec/prophecy",
-        "version": "v1.15.0",
-        "version_normalized": "1.15.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/phpspec/prophecy.git",
-            "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
-            "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "description": "An ID Generator for PHP based on Snowflake Algorithm (Twitter announced).",
+            "homepage": "https://github.com/godruoyi/php-snowflake",
+            "keywords": [
+                "Unique ID",
+                "laravel snowflake",
+                "order id",
+                "php snowflake",
+                "php unique id",
+                "snowflake algorithm",
+                "unique order id"
+            ],
+            "funding": [
+                {
+                    "url": "https://images.godruoyi.com/wechat.png",
+                    "type": "custom"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "url": "https://github.com/godruoyi",
+                    "type": "github"
                 }
-            ]
-        },
-        "require": {
-            "doctrine/instantiator": "^1.2",
-            "php": "^7.2 || ~8.0, <8.2",
-            "phpdocumentor/reflection-docblock": "^5.2",
-            "sebastian/comparator": "^3.0 || ^4.0",
-            "sebastian/recursion-context": "^3.0 || ^4.0"
-        },
-        "require-dev": {
-            "phpspec/phpspec": "^6.0 || ^7.0",
-            "phpunit/phpunit": "^8.0 || ^9.0"
-        },
-        "time": "2021-12-08T12:19:24+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "1.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Prophecy\\": "src/Prophecy"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Konstantin Kudryashov",
-                "email": "ever.zet@gmail.com",
-                "homepage": "http://everzet.com"
-            },
-            {
-                "name": "Marcello Duarte",
-                "email": "marcello.duarte@gmail.com"
-            }
-        ],
-        "description": "Highly opinionated mocking framework for PHP 5.3+",
-        "homepage": "https://github.com/phpspec/prophecy",
-        "keywords": [
-            "Double",
-            "Dummy",
-            "fake",
-            "mock",
-            "spy",
-            "stub"
-        ]
-    },
-    {
-        "name": "phpunit/php-code-coverage",
-        "version": "6.1.4",
-        "version_normalized": "6.1.4.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
-            "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
-            "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
-            "shasum": "",
-            "mirrors": [
-                {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+            ],
+            "install-path": "../godruoyi/php-snowflake"
+        },
+        {
+            "name": "guzzlehttp/psr7",
+            "version": "1.8.3",
+            "version_normalized": "1.8.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/guzzle/psr7.git",
+                "reference": "1afdd860a2566ed3c2b0b4a3de6e23434a79ec85"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/guzzle/psr7/zipball/1afdd860a2566ed3c2b0b4a3de6e23434a79ec85",
+                "reference": "1afdd860a2566ed3c2b0b4a3de6e23434a79ec85",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=5.4.0",
+                "psr/http-message": "~1.0",
+                "ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
+            },
+            "provide": {
+                "psr/http-message-implementation": "1.0"
+            },
+            "require-dev": {
+                "ext-zlib": "*",
+                "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10"
+            },
+            "suggest": {
+                "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
+            },
+            "time": "2021-10-05T13:56:00+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.7-dev"
                 }
-            ]
-        },
-        "require": {
-            "ext-dom": "*",
-            "ext-xmlwriter": "*",
-            "php": "^7.1",
-            "phpunit/php-file-iterator": "^2.0",
-            "phpunit/php-text-template": "^1.2.1",
-            "phpunit/php-token-stream": "^3.0",
-            "sebastian/code-unit-reverse-lookup": "^1.0.1",
-            "sebastian/environment": "^3.1 || ^4.0",
-            "sebastian/version": "^2.0.1",
-            "theseer/tokenizer": "^1.1"
-        },
-        "require-dev": {
-            "phpunit/phpunit": "^7.0"
-        },
-        "suggest": {
-            "ext-xdebug": "^2.6.0"
-        },
-        "time": "2018-10-31T16:06:48+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "6.1-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "classmap": [
-                "src/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Sebastian Bergmann",
-                "email": "sebastian@phpunit.de",
-                "role": "lead"
-            }
-        ],
-        "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
-        "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
-        "keywords": [
-            "coverage",
-            "testing",
-            "xunit"
-        ]
-    },
-    {
-        "name": "phpunit/php-file-iterator",
-        "version": "2.0.5",
-        "version_normalized": "2.0.5.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
-            "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5",
-            "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5",
-            "shasum": "",
-            "mirrors": [
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "GuzzleHttp\\Psr7\\": "src/"
+                },
+                "files": [
+                    "src/functions_include.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
-                }
-            ]
-        },
-        "require": {
-            "php": ">=7.1"
-        },
-        "require-dev": {
-            "phpunit/phpunit": "^8.5"
-        },
-        "time": "2021-12-02T12:42:26+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "2.0.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "classmap": [
-                "src/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Sebastian Bergmann",
-                "email": "sebastian@phpunit.de",
-                "role": "lead"
-            }
-        ],
-        "description": "FilterIterator implementation that filters files based on a list of suffixes.",
-        "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
-        "keywords": [
-            "filesystem",
-            "iterator"
-        ],
-        "funding": [
-            {
-                "url": "https://github.com/sebastianbergmann",
-                "type": "github"
-            }
-        ]
-    },
-    {
-        "name": "phpunit/php-text-template",
-        "version": "1.2.1",
-        "version_normalized": "1.2.1.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/sebastianbergmann/php-text-template.git",
-            "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
-            "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
-            "shasum": "",
-            "mirrors": [
+                    "name": "Graham Campbell",
+                    "email": "hello@gjcampbell.co.uk",
+                    "homepage": "https://github.com/GrahamCampbell"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
-                }
-            ]
-        },
-        "require": {
-            "php": ">=5.3.3"
-        },
-        "time": "2015-06-21T13:50:34+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "classmap": [
-                "src/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Sebastian Bergmann",
-                "email": "sebastian@phpunit.de",
-                "role": "lead"
-            }
-        ],
-        "description": "Simple template engine.",
-        "homepage": "https://github.com/sebastianbergmann/php-text-template/",
-        "keywords": [
-            "template"
-        ]
-    },
-    {
-        "name": "phpunit/php-timer",
-        "version": "2.1.3",
-        "version_normalized": "2.1.3.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/sebastianbergmann/php-timer.git",
-            "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662",
-            "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662",
-            "shasum": "",
-            "mirrors": [
+                    "name": "Michael Dowling",
+                    "email": "mtdowling@gmail.com",
+                    "homepage": "https://github.com/mtdowling"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
-                }
-            ]
-        },
-        "require": {
-            "php": ">=7.1"
-        },
-        "require-dev": {
-            "phpunit/phpunit": "^8.5"
-        },
-        "time": "2020-11-30T08:20:02+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "2.1-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "classmap": [
-                "src/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Sebastian Bergmann",
-                "email": "sebastian@phpunit.de",
-                "role": "lead"
-            }
-        ],
-        "description": "Utility class for timing",
-        "homepage": "https://github.com/sebastianbergmann/php-timer/",
-        "keywords": [
-            "timer"
-        ],
-        "funding": [
-            {
-                "url": "https://github.com/sebastianbergmann",
-                "type": "github"
-            }
-        ]
-    },
-    {
-        "name": "phpunit/php-token-stream",
-        "version": "3.1.3",
-        "version_normalized": "3.1.3.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/sebastianbergmann/php-token-stream.git",
-            "reference": "9c1da83261628cb24b6a6df371b6e312b3954768"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/9c1da83261628cb24b6a6df371b6e312b3954768",
-            "reference": "9c1da83261628cb24b6a6df371b6e312b3954768",
-            "shasum": "",
-            "mirrors": [
+                    "name": "George Mponos",
+                    "email": "gmponos@gmail.com",
+                    "homepage": "https://github.com/gmponos"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
-                }
-            ]
-        },
-        "require": {
-            "ext-tokenizer": "*",
-            "php": ">=7.1"
-        },
-        "require-dev": {
-            "phpunit/phpunit": "^7.0"
-        },
-        "time": "2021-07-26T12:15:06+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "3.1-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "classmap": [
-                "src/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Sebastian Bergmann",
-                "email": "sebastian@phpunit.de"
-            }
-        ],
-        "description": "Wrapper around PHP's tokenizer extension.",
-        "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
-        "keywords": [
-            "tokenizer"
-        ],
-        "funding": [
-            {
-                "url": "https://github.com/sebastianbergmann",
-                "type": "github"
-            }
-        ],
-        "abandoned": true
-    },
-    {
-        "name": "phpunit/phpunit",
-        "version": "7.5.20",
-        "version_normalized": "7.5.20.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/sebastianbergmann/phpunit.git",
-            "reference": "9467db479d1b0487c99733bb1e7944d32deded2c"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9467db479d1b0487c99733bb1e7944d32deded2c",
-            "reference": "9467db479d1b0487c99733bb1e7944d32deded2c",
-            "shasum": "",
-            "mirrors": [
+                    "name": "Tobias Nyholm",
+                    "email": "tobias.nyholm@gmail.com",
+                    "homepage": "https://github.com/Nyholm"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
-                }
-            ]
-        },
-        "require": {
-            "doctrine/instantiator": "^1.1",
-            "ext-dom": "*",
-            "ext-json": "*",
-            "ext-libxml": "*",
-            "ext-mbstring": "*",
-            "ext-xml": "*",
-            "myclabs/deep-copy": "^1.7",
-            "phar-io/manifest": "^1.0.2",
-            "phar-io/version": "^2.0",
-            "php": "^7.1",
-            "phpspec/prophecy": "^1.7",
-            "phpunit/php-code-coverage": "^6.0.7",
-            "phpunit/php-file-iterator": "^2.0.1",
-            "phpunit/php-text-template": "^1.2.1",
-            "phpunit/php-timer": "^2.1",
-            "sebastian/comparator": "^3.0",
-            "sebastian/diff": "^3.0",
-            "sebastian/environment": "^4.0",
-            "sebastian/exporter": "^3.1",
-            "sebastian/global-state": "^2.0",
-            "sebastian/object-enumerator": "^3.0.3",
-            "sebastian/resource-operations": "^2.0",
-            "sebastian/version": "^2.0.1"
-        },
-        "conflict": {
-            "phpunit/phpunit-mock-objects": "*"
-        },
-        "require-dev": {
-            "ext-pdo": "*"
-        },
-        "suggest": {
-            "ext-soap": "*",
-            "ext-xdebug": "*",
-            "phpunit/php-invoker": "^2.0"
-        },
-        "time": "2020-01-08T08:45:45+00:00",
-        "bin": [
-            "phpunit"
-        ],
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "7.5-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "classmap": [
-                "src/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Sebastian Bergmann",
-                "email": "sebastian@phpunit.de",
-                "role": "lead"
-            }
-        ],
-        "description": "The PHP Unit Testing framework.",
-        "homepage": "https://phpunit.de/",
-        "keywords": [
-            "phpunit",
-            "testing",
-            "xunit"
-        ]
-    },
-    {
-        "name": "psr/container",
-        "version": "1.1.2",
-        "version_normalized": "1.1.2.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/php-fig/container.git",
-            "reference": "513e0666f7216c7459170d56df27dfcefe1689ea"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea",
-            "reference": "513e0666f7216c7459170d56df27dfcefe1689ea",
-            "shasum": "",
-            "mirrors": [
+                    "name": "Márk Sági-Kazár",
+                    "email": "mark.sagikazar@gmail.com",
+                    "homepage": "https://github.com/sagikazarmark"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Tobias Schultze",
+                    "email": "webmaster@tubo-world.de",
+                    "homepage": "https://github.com/Tobion"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=7.4.0"
-        },
-        "time": "2021-11-05T16:50:12+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Psr\\Container\\": "src/"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "PHP-FIG",
-                "homepage": "https://www.php-fig.org/"
-            }
-        ],
-        "description": "Common Container Interface (PHP FIG PSR-11)",
-        "homepage": "https://github.com/php-fig/container",
-        "keywords": [
-            "PSR-11",
-            "container",
-            "container-interface",
-            "container-interop",
-            "psr"
-        ]
-    },
-    {
-        "name": "psr/http-client",
-        "version": "1.0.1",
-        "version_normalized": "1.0.1.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/php-fig/http-client.git",
-            "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
-            "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "description": "PSR-7 message implementation that also provides common utility methods",
+            "keywords": [
+                "http",
+                "message",
+                "psr-7",
+                "request",
+                "response",
+                "stream",
+                "uri",
+                "url"
+            ],
+            "funding": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
-                }
-            ]
-        },
-        "require": {
-            "php": "^7.0 || ^8.0",
-            "psr/http-message": "^1.0"
-        },
-        "time": "2020-06-29T06:28:15+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "1.0.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Psr\\Http\\Client\\": "src/"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "PHP-FIG",
-                "homepage": "http://www.php-fig.org/"
-            }
-        ],
-        "description": "Common interface for HTTP clients",
-        "homepage": "https://github.com/php-fig/http-client",
-        "keywords": [
-            "http",
-            "http-client",
-            "psr",
-            "psr-18"
-        ]
-    },
-    {
-        "name": "psr/http-factory",
-        "version": "1.0.1",
-        "version_normalized": "1.0.1.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/php-fig/http-factory.git",
-            "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
-            "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
-            "shasum": "",
-            "mirrors": [
+                    "url": "https://github.com/GrahamCampbell",
+                    "type": "github"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
-                }
-            ]
-        },
-        "require": {
-            "php": ">=7.0.0",
-            "psr/http-message": "^1.0"
-        },
-        "time": "2019-04-30T12:38:16+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "1.0.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Psr\\Http\\Message\\": "src/"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "PHP-FIG",
-                "homepage": "http://www.php-fig.org/"
-            }
-        ],
-        "description": "Common interfaces for PSR-7 HTTP message factories",
-        "keywords": [
-            "factory",
-            "http",
-            "message",
-            "psr",
-            "psr-17",
-            "psr-7",
-            "request",
-            "response"
-        ]
-    },
-    {
-        "name": "psr/http-message",
-        "version": "1.0.1",
-        "version_normalized": "1.0.1.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/php-fig/http-message.git",
-            "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
-            "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
-            "shasum": "",
-            "mirrors": [
+                    "url": "https://github.com/Nyholm",
+                    "type": "github"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7",
+                    "type": "tidelift"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=5.3.0"
-        },
-        "time": "2016-08-06T14:39:51+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "1.0.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Psr\\Http\\Message\\": "src/"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "PHP-FIG",
-                "homepage": "http://www.php-fig.org/"
-            }
-        ],
-        "description": "Common interface for HTTP messages",
-        "homepage": "https://github.com/php-fig/http-message",
-        "keywords": [
-            "http",
-            "http-message",
-            "psr",
-            "psr-7",
-            "request",
-            "response"
-        ]
-    },
-    {
-        "name": "psr/simple-cache",
-        "version": "1.0.1",
-        "version_normalized": "1.0.1.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/php-fig/simple-cache.git",
-            "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
-            "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
-            "shasum": "",
-            "mirrors": [
-                {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+            ],
+            "install-path": "../guzzlehttp/psr7"
+        },
+        {
+            "name": "maennchen/zipstream-php",
+            "version": "2.1.0",
+            "version_normalized": "2.1.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/maennchen/ZipStream-PHP.git",
+                "reference": "c4c5803cc1f93df3d2448478ef79394a5981cc58"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/c4c5803cc1f93df3d2448478ef79394a5981cc58",
+                "reference": "c4c5803cc1f93df3d2448478ef79394a5981cc58",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "myclabs/php-enum": "^1.5",
+                "php": ">= 7.1",
+                "psr/http-message": "^1.0",
+                "symfony/polyfill-mbstring": "^1.0"
+            },
+            "require-dev": {
+                "ext-zip": "*",
+                "guzzlehttp/guzzle": ">= 6.3",
+                "mikey179/vfsstream": "^1.6",
+                "phpunit/phpunit": ">= 7.5"
+            },
+            "time": "2020-05-30T13:11:16+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "ZipStream\\": "src/"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=5.3.0"
-        },
-        "time": "2017-10-23T01:57:42+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "1.0.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Psr\\SimpleCache\\": "src/"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "PHP-FIG",
-                "homepage": "http://www.php-fig.org/"
-            }
-        ],
-        "description": "Common interfaces for simple caching",
-        "keywords": [
-            "cache",
-            "caching",
-            "psr",
-            "psr-16",
-            "simple-cache"
-        ]
-    },
-    {
-        "name": "ralouphie/getallheaders",
-        "version": "3.0.3",
-        "version_normalized": "3.0.3.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/ralouphie/getallheaders.git",
-            "reference": "120b605dfeb996808c31b6477290a714d356e822"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
-            "reference": "120b605dfeb996808c31b6477290a714d356e822",
-            "shasum": "",
-            "mirrors": [
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
-                }
-            ]
-        },
-        "require": {
-            "php": ">=5.6"
-        },
-        "require-dev": {
-            "php-coveralls/php-coveralls": "^2.1",
-            "phpunit/phpunit": "^5 || ^6.5"
-        },
-        "time": "2019-03-08T08:55:37+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "files": [
-                "src/getallheaders.php"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Ralph Khattar",
-                "email": "ralph.khattar@gmail.com"
-            }
-        ],
-        "description": "A polyfill for getallheaders."
-    },
-    {
-        "name": "sebastian/code-unit-reverse-lookup",
-        "version": "1.0.2",
-        "version_normalized": "1.0.2.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
-            "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619",
-            "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619",
-            "shasum": "",
-            "mirrors": [
+                    "name": "Paul Duncan",
+                    "email": "pabs@pablotron.org"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
-                }
-            ]
-        },
-        "require": {
-            "php": ">=5.6"
-        },
-        "require-dev": {
-            "phpunit/phpunit": "^8.5"
-        },
-        "time": "2020-11-30T08:15:22+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "1.0.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "classmap": [
-                "src/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Sebastian Bergmann",
-                "email": "sebastian@phpunit.de"
-            }
-        ],
-        "description": "Looks up which function or method a line of code belongs to",
-        "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
-        "funding": [
-            {
-                "url": "https://github.com/sebastianbergmann",
-                "type": "github"
-            }
-        ]
-    },
-    {
-        "name": "sebastian/comparator",
-        "version": "3.0.3",
-        "version_normalized": "3.0.3.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/sebastianbergmann/comparator.git",
-            "reference": "1071dfcef776a57013124ff35e1fc41ccd294758"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758",
-            "reference": "1071dfcef776a57013124ff35e1fc41ccd294758",
-            "shasum": "",
-            "mirrors": [
+                    "name": "Jonatan Männchen",
+                    "email": "jonatan@maennchen.ch"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
-                }
-            ]
-        },
-        "require": {
-            "php": ">=7.1",
-            "sebastian/diff": "^3.0",
-            "sebastian/exporter": "^3.1"
-        },
-        "require-dev": {
-            "phpunit/phpunit": "^8.5"
-        },
-        "time": "2020-11-30T08:04:30+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "3.0-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "classmap": [
-                "src/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Sebastian Bergmann",
-                "email": "sebastian@phpunit.de"
-            },
-            {
-                "name": "Jeff Welch",
-                "email": "whatthejeff@gmail.com"
-            },
-            {
-                "name": "Volker Dusch",
-                "email": "github@wallbash.com"
-            },
-            {
-                "name": "Bernhard Schussek",
-                "email": "bschussek@2bepublished.at"
-            }
-        ],
-        "description": "Provides the functionality to compare PHP values for equality",
-        "homepage": "https://github.com/sebastianbergmann/comparator",
-        "keywords": [
-            "comparator",
-            "compare",
-            "equality"
-        ],
-        "funding": [
-            {
-                "url": "https://github.com/sebastianbergmann",
-                "type": "github"
-            }
-        ]
-    },
-    {
-        "name": "sebastian/diff",
-        "version": "3.0.3",
-        "version_normalized": "3.0.3.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/sebastianbergmann/diff.git",
-            "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211",
-            "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211",
-            "shasum": "",
-            "mirrors": [
+                    "name": "Jesse Donat",
+                    "email": "donatj@gmail.com"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "András Kolesár",
+                    "email": "kolesar@kolesar.hu"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=7.1"
-        },
-        "require-dev": {
-            "phpunit/phpunit": "^7.5 || ^8.0",
-            "symfony/process": "^2 || ^3.3 || ^4"
-        },
-        "time": "2020-11-30T07:59:04+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "3.0-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "classmap": [
-                "src/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Sebastian Bergmann",
-                "email": "sebastian@phpunit.de"
-            },
-            {
-                "name": "Kore Nordmann",
-                "email": "mail@kore-nordmann.de"
-            }
-        ],
-        "description": "Diff implementation",
-        "homepage": "https://github.com/sebastianbergmann/diff",
-        "keywords": [
-            "diff",
-            "udiff",
-            "unidiff",
-            "unified diff"
-        ],
-        "funding": [
-            {
-                "url": "https://github.com/sebastianbergmann",
-                "type": "github"
-            }
-        ]
-    },
-    {
-        "name": "sebastian/environment",
-        "version": "4.2.4",
-        "version_normalized": "4.2.4.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/sebastianbergmann/environment.git",
-            "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0",
-            "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.",
+            "keywords": [
+                "stream",
+                "zip"
+            ],
+            "funding": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "url": "https://opencollective.com/zipstream",
+                    "type": "open_collective"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=7.1"
-        },
-        "require-dev": {
-            "phpunit/phpunit": "^7.5"
-        },
-        "suggest": {
-            "ext-posix": "*"
-        },
-        "time": "2020-11-30T07:53:42+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "4.2-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "classmap": [
-                "src/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Sebastian Bergmann",
-                "email": "sebastian@phpunit.de"
-            }
-        ],
-        "description": "Provides functionality to handle HHVM/PHP environments",
-        "homepage": "http://www.github.com/sebastianbergmann/environment",
-        "keywords": [
-            "Xdebug",
-            "environment",
-            "hhvm"
-        ],
-        "funding": [
-            {
-                "url": "https://github.com/sebastianbergmann",
-                "type": "github"
-            }
-        ]
-    },
-    {
-        "name": "sebastian/exporter",
-        "version": "3.1.4",
-        "version_normalized": "3.1.4.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/sebastianbergmann/exporter.git",
-            "reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/0c32ea2e40dbf59de29f3b49bf375176ce7dd8db",
-            "reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db",
-            "shasum": "",
-            "mirrors": [
-                {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+            ],
+            "install-path": "../maennchen/zipstream-php"
+        },
+        {
+            "name": "markbaker/complex",
+            "version": "3.0.1",
+            "version_normalized": "3.0.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/MarkBaker/PHPComplex.git",
+                "reference": "ab8bc271e404909db09ff2d5ffa1e538085c0f22"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/ab8bc271e404909db09ff2d5ffa1e538085c0f22",
+                "reference": "ab8bc271e404909db09ff2d5ffa1e538085c0f22",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "^7.2 || ^8.0"
+            },
+            "require-dev": {
+                "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
+                "phpcompatibility/php-compatibility": "^9.0",
+                "phpunit/phpunit": "^7.0 || ^8.0 || ^9.3",
+                "squizlabs/php_codesniffer": "^3.4"
+            },
+            "time": "2021-06-29T15:32:53+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Complex\\": "classes/src/"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=7.0",
-            "sebastian/recursion-context": "^3.0"
-        },
-        "require-dev": {
-            "ext-mbstring": "*",
-            "phpunit/phpunit": "^8.5"
-        },
-        "time": "2021-11-11T13:51:24+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "3.1.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "classmap": [
-                "src/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Sebastian Bergmann",
-                "email": "sebastian@phpunit.de"
-            },
-            {
-                "name": "Jeff Welch",
-                "email": "whatthejeff@gmail.com"
-            },
-            {
-                "name": "Volker Dusch",
-                "email": "github@wallbash.com"
-            },
-            {
-                "name": "Adam Harvey",
-                "email": "aharvey@php.net"
-            },
-            {
-                "name": "Bernhard Schussek",
-                "email": "bschussek@gmail.com"
-            }
-        ],
-        "description": "Provides the functionality to export PHP variables for visualization",
-        "homepage": "http://www.github.com/sebastianbergmann/exporter",
-        "keywords": [
-            "export",
-            "exporter"
-        ],
-        "funding": [
-            {
-                "url": "https://github.com/sebastianbergmann",
-                "type": "github"
-            }
-        ]
-    },
-    {
-        "name": "sebastian/global-state",
-        "version": "2.0.0",
-        "version_normalized": "2.0.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/sebastianbergmann/global-state.git",
-            "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
-            "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
-            "shasum": "",
-            "mirrors": [
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Mark Baker",
+                    "email": "mark@lange.demon.co.uk"
                 }
-            ]
-        },
-        "require": {
-            "php": "^7.0"
-        },
-        "require-dev": {
-            "phpunit/phpunit": "^6.0"
-        },
-        "suggest": {
-            "ext-uopz": "*"
-        },
-        "time": "2017-04-27T15:39:26+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "2.0-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "classmap": [
-                "src/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Sebastian Bergmann",
-                "email": "sebastian@phpunit.de"
-            }
-        ],
-        "description": "Snapshotting of global state",
-        "homepage": "http://www.github.com/sebastianbergmann/global-state",
-        "keywords": [
-            "global state"
-        ]
-    },
-    {
-        "name": "sebastian/object-enumerator",
-        "version": "3.0.4",
-        "version_normalized": "3.0.4.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/sebastianbergmann/object-enumerator.git",
-            "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
-            "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
-            "shasum": "",
-            "mirrors": [
-                {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+            ],
+            "description": "PHP Class for working with complex numbers",
+            "homepage": "https://github.com/MarkBaker/PHPComplex",
+            "keywords": [
+                "complex",
+                "mathematics"
+            ],
+            "install-path": "../markbaker/complex"
+        },
+        {
+            "name": "markbaker/matrix",
+            "version": "3.0.0",
+            "version_normalized": "3.0.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/MarkBaker/PHPMatrix.git",
+                "reference": "c66aefcafb4f6c269510e9ac46b82619a904c576"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/c66aefcafb4f6c269510e9ac46b82619a904c576",
+                "reference": "c66aefcafb4f6c269510e9ac46b82619a904c576",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "^7.1 || ^8.0"
+            },
+            "require-dev": {
+                "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
+                "phpcompatibility/php-compatibility": "^9.0",
+                "phpdocumentor/phpdocumentor": "2.*",
+                "phploc/phploc": "^4.0",
+                "phpmd/phpmd": "2.*",
+                "phpunit/phpunit": "^7.0 || ^8.0 || ^9.3",
+                "sebastian/phpcpd": "^4.0",
+                "squizlabs/php_codesniffer": "^3.4"
+            },
+            "time": "2021-07-01T19:01:15+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Matrix\\": "classes/src/"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=7.0",
-            "sebastian/object-reflector": "^1.1.1",
-            "sebastian/recursion-context": "^3.0"
-        },
-        "require-dev": {
-            "phpunit/phpunit": "^6.0"
-        },
-        "time": "2020-11-30T07:40:27+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "3.0.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "classmap": [
-                "src/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Sebastian Bergmann",
-                "email": "sebastian@phpunit.de"
-            }
-        ],
-        "description": "Traverses array structures and object graphs to enumerate all referenced objects",
-        "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
-        "funding": [
-            {
-                "url": "https://github.com/sebastianbergmann",
-                "type": "github"
-            }
-        ]
-    },
-    {
-        "name": "sebastian/object-reflector",
-        "version": "1.1.2",
-        "version_normalized": "1.1.2.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/sebastianbergmann/object-reflector.git",
-            "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
-            "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
-            "shasum": "",
-            "mirrors": [
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Mark Baker",
+                    "email": "mark@demon-angel.eu"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=7.0"
-        },
-        "require-dev": {
-            "phpunit/phpunit": "^6.0"
-        },
-        "time": "2020-11-30T07:37:18+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "1.1-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "classmap": [
-                "src/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Sebastian Bergmann",
-                "email": "sebastian@phpunit.de"
-            }
-        ],
-        "description": "Allows reflection of object attributes, including inherited and non-public ones",
-        "homepage": "https://github.com/sebastianbergmann/object-reflector/",
-        "funding": [
-            {
-                "url": "https://github.com/sebastianbergmann",
-                "type": "github"
-            }
-        ]
-    },
-    {
-        "name": "sebastian/recursion-context",
-        "version": "3.0.1",
-        "version_normalized": "3.0.1.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/sebastianbergmann/recursion-context.git",
-            "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb",
-            "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb",
-            "shasum": "",
-            "mirrors": [
-                {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+            ],
+            "description": "PHP Class for working with matrices",
+            "homepage": "https://github.com/MarkBaker/PHPMatrix",
+            "keywords": [
+                "mathematics",
+                "matrix",
+                "vector"
+            ],
+            "install-path": "../markbaker/matrix"
+        },
+        {
+            "name": "monolog/monolog",
+            "version": "2.8.0",
+            "version_normalized": "2.8.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Seldaek/monolog.git",
+                "reference": "720488632c590286b88b80e62aa3d3d551ad4a50"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Seldaek/monolog/zipball/720488632c590286b88b80e62aa3d3d551ad4a50",
+                "reference": "720488632c590286b88b80e62aa3d3d551ad4a50",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.2",
+                "psr/log": "^1.0.1 || ^2.0 || ^3.0"
+            },
+            "provide": {
+                "psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0"
+            },
+            "require-dev": {
+                "aws/aws-sdk-php": "^2.4.9 || ^3.0",
+                "doctrine/couchdb": "~1.0@dev",
+                "elasticsearch/elasticsearch": "^7 || ^8",
+                "ext-json": "*",
+                "graylog2/gelf-php": "^1.4.2",
+                "guzzlehttp/guzzle": "^7.4",
+                "guzzlehttp/psr7": "^2.2",
+                "mongodb/mongodb": "^1.8",
+                "php-amqplib/php-amqplib": "~2.4 || ^3",
+                "phpspec/prophecy": "^1.15",
+                "phpstan/phpstan": "^0.12.91",
+                "phpunit/phpunit": "^8.5.14",
+                "predis/predis": "^1.1 || ^2.0",
+                "rollbar/rollbar": "^1.3 || ^2 || ^3",
+                "ruflin/elastica": "^7",
+                "swiftmailer/swiftmailer": "^5.3|^6.0",
+                "symfony/mailer": "^5.4 || ^6",
+                "symfony/mime": "^5.4 || ^6"
+            },
+            "suggest": {
+                "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
+                "doctrine/couchdb": "Allow sending log messages to a CouchDB server",
+                "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client",
+                "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
+                "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler",
+                "ext-mbstring": "Allow to work properly with unicode symbols",
+                "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)",
+                "ext-openssl": "Required to send log messages using SSL",
+                "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)",
+                "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
+                "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)",
+                "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
+                "rollbar/rollbar": "Allow sending log messages to Rollbar",
+                "ruflin/elastica": "Allow sending log messages to an Elastic Search server"
+            },
+            "time": "2022-07-24T11:55:47+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "2.x-dev"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=7.0"
-        },
-        "require-dev": {
-            "phpunit/phpunit": "^6.0"
-        },
-        "time": "2020-11-30T07:34:24+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "3.0.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "classmap": [
-                "src/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Sebastian Bergmann",
-                "email": "sebastian@phpunit.de"
-            },
-            {
-                "name": "Jeff Welch",
-                "email": "whatthejeff@gmail.com"
-            },
-            {
-                "name": "Adam Harvey",
-                "email": "aharvey@php.net"
-            }
-        ],
-        "description": "Provides functionality to recursively process PHP variables",
-        "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
-        "funding": [
-            {
-                "url": "https://github.com/sebastianbergmann",
-                "type": "github"
-            }
-        ]
-    },
-    {
-        "name": "sebastian/resource-operations",
-        "version": "2.0.2",
-        "version_normalized": "2.0.2.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/sebastianbergmann/resource-operations.git",
-            "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3",
-            "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3",
-            "shasum": "",
-            "mirrors": [
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Monolog\\": "src/Monolog"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be",
+                    "homepage": "https://seld.be"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=7.1"
-        },
-        "time": "2020-11-30T07:30:19+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "2.0-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "classmap": [
-                "src/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Sebastian Bergmann",
-                "email": "sebastian@phpunit.de"
-            }
-        ],
-        "description": "Provides a list of PHP built-in functions that operate on resources",
-        "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
-        "funding": [
-            {
-                "url": "https://github.com/sebastianbergmann",
-                "type": "github"
-            }
-        ]
-    },
-    {
-        "name": "sebastian/version",
-        "version": "2.0.1",
-        "version_normalized": "2.0.1.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/sebastianbergmann/version.git",
-            "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
-            "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
+            "homepage": "https://github.com/Seldaek/monolog",
+            "keywords": [
+                "log",
+                "logging",
+                "psr-3"
+            ],
+            "support": {
+                "issues": "https://github.com/Seldaek/monolog/issues",
+                "source": "https://github.com/Seldaek/monolog/tree/2.8.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/Seldaek",
+                    "type": "github"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "url": "https://tidelift.com/funding/github/packagist/monolog/monolog",
+                    "type": "tidelift"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=5.6"
-        },
-        "time": "2016-10-03T07:35:21+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "2.0.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "classmap": [
-                "src/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Sebastian Bergmann",
-                "email": "sebastian@phpunit.de",
-                "role": "lead"
-            }
-        ],
-        "description": "Library that helps with managing the version number of Git-hosted PHP projects",
-        "homepage": "https://github.com/sebastianbergmann/version"
-    },
-    {
-        "name": "sunmoon/yii2-phpspreadsheet",
-        "version": "1.2.0",
-        "version_normalized": "1.2.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/arieslee/yii2-phpspreadsheet.git",
-            "reference": "51fc4d0183eb81e654b3360ac18e631fc4b89c09"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/arieslee/yii2-phpspreadsheet/zipball/51fc4d0183eb81e654b3360ac18e631fc4b89c09",
-            "reference": "51fc4d0183eb81e654b3360ac18e631fc4b89c09",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "install-path": "../monolog/monolog"
+        },
+        {
+            "name": "myclabs/deep-copy",
+            "version": "1.10.2",
+            "version_normalized": "1.10.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/myclabs/DeepCopy.git",
+                "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220",
+                "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "^7.1 || ^8.0"
+            },
+            "replace": {
+                "myclabs/deep-copy": "self.version"
+            },
+            "require-dev": {
+                "doctrine/collections": "^1.0",
+                "doctrine/common": "^2.6",
+                "phpunit/phpunit": "^7.1"
+            },
+            "time": "2020-11-13T09:40:50+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "DeepCopy\\": "src/DeepCopy/"
+                },
+                "files": [
+                    "src/DeepCopy/deep_copy.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "Create deep copies (clones) of your objects",
+            "keywords": [
+                "clone",
+                "copy",
+                "duplicate",
+                "object",
+                "object graph"
+            ],
+            "funding": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
+                    "type": "tidelift"
                 }
-            ]
-        },
-        "require": {
-            "phpoffice/phpspreadsheet": "*",
-            "yiisoft/yii2": "^2.0.15"
-        },
-        "time": "2019-02-18T03:02:43+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "sunmoon\\phpspreadsheet\\": "src"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Sunmoon",
-                "email": "forphp@qq.com",
-                "homepage": "https://blog.iw3c.com",
-                "role": "Developer"
-            }
-        ],
-        "description": "Yii2处理Excel文件, 修改自moonlandsoft/yii2-phpexcel。",
-        "homepage": "https://github.com/arieslee/yii2-phpspreadsheet"
-    },
-    {
-        "name": "swiftmailer/swiftmailer",
-        "version": "v6.3.0",
-        "version_normalized": "6.3.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/swiftmailer/swiftmailer.git",
-            "reference": "8a5d5072dca8f48460fce2f4131fcc495eec654c"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/8a5d5072dca8f48460fce2f4131fcc495eec654c",
-            "reference": "8a5d5072dca8f48460fce2f4131fcc495eec654c",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "install-path": "../myclabs/deep-copy"
+        },
+        {
+            "name": "myclabs/php-enum",
+            "version": "1.8.3",
+            "version_normalized": "1.8.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/myclabs/php-enum.git",
+                "reference": "b942d263c641ddb5190929ff840c68f78713e937"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/myclabs/php-enum/zipball/b942d263c641ddb5190929ff840c68f78713e937",
+                "reference": "b942d263c641ddb5190929ff840c68f78713e937",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "ext-json": "*",
+                "php": "^7.3 || ^8.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.5",
+                "squizlabs/php_codesniffer": "1.*",
+                "vimeo/psalm": "^4.6.2"
+            },
+            "time": "2021-07-05T08:18:36+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "MyCLabs\\Enum\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "PHP Enum contributors",
+                    "homepage": "https://github.com/myclabs/php-enum/graphs/contributors"
                 }
-            ]
-        },
-        "require": {
-            "egulias/email-validator": "^2.0|^3.1",
-            "php": ">=7.0.0",
-            "symfony/polyfill-iconv": "^1.0",
-            "symfony/polyfill-intl-idn": "^1.10",
-            "symfony/polyfill-mbstring": "^1.0"
-        },
-        "require-dev": {
-            "mockery/mockery": "^1.0",
-            "symfony/phpunit-bridge": "^4.4|^5.4"
-        },
-        "suggest": {
-            "ext-intl": "Needed to support internationalized email addresses"
-        },
-        "time": "2021-10-18T15:26:12+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "6.2-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "files": [
-                "lib/swift_required.php"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Chris Corbyn"
-            },
-            {
-                "name": "Fabien Potencier",
-                "email": "fabien@symfony.com"
-            }
-        ],
-        "description": "Swiftmailer, free feature-rich PHP mailer",
-        "homepage": "https://swiftmailer.symfony.com",
-        "keywords": [
-            "email",
-            "mail",
-            "mailer"
-        ],
-        "funding": [
-            {
-                "url": "https://github.com/fabpot",
-                "type": "github"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/swiftmailer/swiftmailer",
-                "type": "tidelift"
-            }
-        ],
-        "abandoned": "symfony/mailer"
-    },
-    {
-        "name": "symfony/browser-kit",
-        "version": "v4.4.27",
-        "version_normalized": "4.4.27.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/symfony/browser-kit.git",
-            "reference": "9629d1524d8ced5a4ec3e94abdbd638b4ec8319b"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/symfony/browser-kit/zipball/9629d1524d8ced5a4ec3e94abdbd638b4ec8319b",
-            "reference": "9629d1524d8ced5a4ec3e94abdbd638b4ec8319b",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "description": "PHP Enum implementation",
+            "homepage": "http://github.com/myclabs/php-enum",
+            "keywords": [
+                "enum"
+            ],
+            "funding": [
+                {
+                    "url": "https://github.com/mnapoli",
+                    "type": "github"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "url": "https://tidelift.com/funding/github/packagist/myclabs/php-enum",
+                    "type": "tidelift"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=7.1.3",
-            "symfony/dom-crawler": "^3.4|^4.0|^5.0",
-            "symfony/polyfill-php80": "^1.16"
-        },
-        "require-dev": {
-            "symfony/css-selector": "^3.4|^4.0|^5.0",
-            "symfony/http-client": "^4.3|^5.0",
-            "symfony/mime": "^4.3|^5.0",
-            "symfony/process": "^3.4|^4.0|^5.0"
-        },
-        "suggest": {
-            "symfony/process": ""
-        },
-        "time": "2021-07-21T12:19:41+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Symfony\\Component\\BrowserKit\\": ""
-            },
-            "exclude-from-classmap": [
-                "/Tests/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Fabien Potencier",
-                "email": "fabien@symfony.com"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "https://symfony.com/contributors"
-            }
-        ],
-        "description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically",
-        "homepage": "https://symfony.com",
-        "funding": [
-            {
-                "url": "https://symfony.com/sponsor",
-                "type": "custom"
-            },
-            {
-                "url": "https://github.com/fabpot",
-                "type": "github"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "symfony/console",
-        "version": "v4.4.34",
-        "version_normalized": "4.4.34.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/symfony/console.git",
-            "reference": "329b3a75cc6b16d435ba1b1a41df54a53382a3f0"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/symfony/console/zipball/329b3a75cc6b16d435ba1b1a41df54a53382a3f0",
-            "reference": "329b3a75cc6b16d435ba1b1a41df54a53382a3f0",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "install-path": "../myclabs/php-enum"
+        },
+        {
+            "name": "paragonie/random_compat",
+            "version": "v9.99.100",
+            "version_normalized": "9.99.100.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/paragonie/random_compat.git",
+                "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a",
+                "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">= 7"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "4.*|5.*",
+                "vimeo/psalm": "^1"
+            },
+            "suggest": {
+                "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
+            },
+            "time": "2020-10-15T08:29:30+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Paragon Initiative Enterprises",
+                    "email": "security@paragonie.com",
+                    "homepage": "https://paragonie.com"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=7.1.3",
-            "symfony/polyfill-mbstring": "~1.0",
-            "symfony/polyfill-php73": "^1.8",
-            "symfony/polyfill-php80": "^1.16",
-            "symfony/service-contracts": "^1.1|^2"
-        },
-        "conflict": {
-            "psr/log": ">=3",
-            "symfony/dependency-injection": "<3.4",
-            "symfony/event-dispatcher": "<4.3|>=5",
-            "symfony/lock": "<4.4",
-            "symfony/process": "<3.3"
-        },
-        "provide": {
-            "psr/log-implementation": "1.0|2.0"
-        },
-        "require-dev": {
-            "psr/log": "^1|^2",
-            "symfony/config": "^3.4|^4.0|^5.0",
-            "symfony/dependency-injection": "^3.4|^4.0|^5.0",
-            "symfony/event-dispatcher": "^4.3",
-            "symfony/lock": "^4.4|^5.0",
-            "symfony/process": "^3.4|^4.0|^5.0",
-            "symfony/var-dumper": "^4.3|^5.0"
-        },
-        "suggest": {
-            "psr/log": "For using the console logger",
-            "symfony/event-dispatcher": "",
-            "symfony/lock": "",
-            "symfony/process": ""
-        },
-        "time": "2021-11-04T12:23:33+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Symfony\\Component\\Console\\": ""
-            },
-            "exclude-from-classmap": [
-                "/Tests/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Fabien Potencier",
-                "email": "fabien@symfony.com"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "https://symfony.com/contributors"
-            }
-        ],
-        "description": "Eases the creation of beautiful and testable command line interfaces",
-        "homepage": "https://symfony.com",
-        "funding": [
-            {
-                "url": "https://symfony.com/sponsor",
-                "type": "custom"
-            },
-            {
-                "url": "https://github.com/fabpot",
-                "type": "github"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "symfony/css-selector",
-        "version": "v4.4.27",
-        "version_normalized": "4.4.27.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/symfony/css-selector.git",
-            "reference": "5194f18bd80d106f11efa8f7cd0fbdcc3af96ce6"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/symfony/css-selector/zipball/5194f18bd80d106f11efa8f7cd0fbdcc3af96ce6",
-            "reference": "5194f18bd80d106f11efa8f7cd0fbdcc3af96ce6",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
+            "keywords": [
+                "csprng",
+                "polyfill",
+                "pseudorandom",
+                "random"
+            ],
+            "install-path": "../paragonie/random_compat"
+        },
+        {
+            "name": "phar-io/manifest",
+            "version": "1.0.3",
+            "version_normalized": "1.0.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phar-io/manifest.git",
+                "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
+                "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "ext-dom": "*",
+                "ext-phar": "*",
+                "phar-io/version": "^2.0",
+                "php": "^5.6 || ^7.0"
+            },
+            "time": "2018-07-08T19:23:20+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Arne Blankerts",
+                    "email": "arne@blankerts.de",
+                    "role": "Developer"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Sebastian Heuer",
+                    "email": "sebastian@phpeople.de",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "Developer"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=7.1.3",
-            "symfony/polyfill-php80": "^1.16"
-        },
-        "time": "2021-07-21T12:19:41+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Symfony\\Component\\CssSelector\\": ""
-            },
-            "exclude-from-classmap": [
-                "/Tests/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Fabien Potencier",
-                "email": "fabien@symfony.com"
-            },
-            {
-                "name": "Jean-François Simon",
-                "email": "jeanfrancois.simon@sensiolabs.com"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "https://symfony.com/contributors"
-            }
-        ],
-        "description": "Converts CSS selectors to XPath expressions",
-        "homepage": "https://symfony.com",
-        "funding": [
-            {
-                "url": "https://symfony.com/sponsor",
-                "type": "custom"
-            },
-            {
-                "url": "https://github.com/fabpot",
-                "type": "github"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "symfony/deprecation-contracts",
-        "version": "v2.5.0",
-        "version_normalized": "2.5.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/symfony/deprecation-contracts.git",
-            "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8",
-            "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
+            "install-path": "../phar-io/manifest"
+        },
+        {
+            "name": "phar-io/version",
+            "version": "2.0.1",
+            "version_normalized": "2.0.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phar-io/version.git",
+                "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6",
+                "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "^5.6 || ^7.0"
+            },
+            "time": "2018-07-08T19:19:57+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Arne Blankerts",
+                    "email": "arne@blankerts.de",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Sebastian Heuer",
+                    "email": "sebastian@phpeople.de",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "Developer"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=7.1"
-        },
-        "time": "2021-07-12T14:48:14+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-main": "2.5-dev"
-            },
-            "thanks": {
-                "name": "symfony/contracts",
-                "url": "https://github.com/symfony/contracts"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "files": [
-                "function.php"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Nicolas Grekas",
-                "email": "p@tchwork.com"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "https://symfony.com/contributors"
-            }
-        ],
-        "description": "A generic function and convention to trigger deprecation notices",
-        "homepage": "https://symfony.com",
-        "funding": [
-            {
-                "url": "https://symfony.com/sponsor",
-                "type": "custom"
-            },
-            {
-                "url": "https://github.com/fabpot",
-                "type": "github"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "symfony/dom-crawler",
-        "version": "v4.4.30",
-        "version_normalized": "4.4.30.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/symfony/dom-crawler.git",
-            "reference": "4632ae3567746c7e915c33c67a2fb6ab746090c4"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/4632ae3567746c7e915c33c67a2fb6ab746090c4",
-            "reference": "4632ae3567746c7e915c33c67a2fb6ab746090c4",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "description": "Library for handling version information and constraints",
+            "install-path": "../phar-io/version"
+        },
+        {
+            "name": "phpdocumentor/reflection-common",
+            "version": "2.2.0",
+            "version_normalized": "2.2.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
+                "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
+                "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "^7.2 || ^8.0"
+            },
+            "time": "2020-06-27T09:03:43+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-2.x": "2.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "phpDocumentor\\Reflection\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jaap van Otterdijk",
+                    "email": "opensource@ijaap.nl"
+                }
+            ],
+            "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
+            "homepage": "http://www.phpdoc.org",
+            "keywords": [
+                "FQSEN",
+                "phpDocumentor",
+                "phpdoc",
+                "reflection",
+                "static analysis"
+            ],
+            "install-path": "../phpdocumentor/reflection-common"
+        },
+        {
+            "name": "phpdocumentor/reflection-docblock",
+            "version": "5.3.0",
+            "version_normalized": "5.3.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+                "reference": "622548b623e81ca6d78b721c5e029f4ce664f170"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170",
+                "reference": "622548b623e81ca6d78b721c5e029f4ce664f170",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "ext-filter": "*",
+                "php": "^7.2 || ^8.0",
+                "phpdocumentor/reflection-common": "^2.2",
+                "phpdocumentor/type-resolver": "^1.3",
+                "webmozart/assert": "^1.9.1"
+            },
+            "require-dev": {
+                "mockery/mockery": "~1.3.2",
+                "psalm/phar": "^4.8"
+            },
+            "time": "2021-10-19T17:43:47+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "5.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "phpDocumentor\\Reflection\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Mike van Riel",
+                    "email": "me@mikevanriel.com"
+                },
+                {
+                    "name": "Jaap van Otterdijk",
+                    "email": "account@ijaap.nl"
+                }
+            ],
+            "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
+            "install-path": "../phpdocumentor/reflection-docblock"
+        },
+        {
+            "name": "phpdocumentor/type-resolver",
+            "version": "1.5.1",
+            "version_normalized": "1.5.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpDocumentor/TypeResolver.git",
+                "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/a12f7e301eb7258bb68acd89d4aefa05c2906cae",
+                "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "^7.2 || ^8.0",
+                "phpdocumentor/reflection-common": "^2.0"
+            },
+            "require-dev": {
+                "ext-tokenizer": "*",
+                "psalm/phar": "^4.8"
+            },
+            "time": "2021-10-02T14:08:47+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-1.x": "1.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "phpDocumentor\\Reflection\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Mike van Riel",
+                    "email": "me@mikevanriel.com"
+                }
+            ],
+            "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
+            "install-path": "../phpdocumentor/type-resolver"
+        },
+        {
+            "name": "phpoffice/phpspreadsheet",
+            "version": "1.20.0",
+            "version_normalized": "1.20.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
+                "reference": "44436f270bb134b4a94670f3d020a85dfa0a3c02"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/44436f270bb134b4a94670f3d020a85dfa0a3c02",
+                "reference": "44436f270bb134b4a94670f3d020a85dfa0a3c02",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "ext-ctype": "*",
+                "ext-dom": "*",
+                "ext-fileinfo": "*",
+                "ext-gd": "*",
+                "ext-iconv": "*",
+                "ext-libxml": "*",
+                "ext-mbstring": "*",
+                "ext-simplexml": "*",
+                "ext-xml": "*",
+                "ext-xmlreader": "*",
+                "ext-xmlwriter": "*",
+                "ext-zip": "*",
+                "ext-zlib": "*",
+                "ezyang/htmlpurifier": "^4.13",
+                "maennchen/zipstream-php": "^2.1",
+                "markbaker/complex": "^3.0",
+                "markbaker/matrix": "^3.0",
+                "php": "^7.3 || ^8.0",
+                "psr/http-client": "^1.0",
+                "psr/http-factory": "^1.0",
+                "psr/simple-cache": "^1.0"
+            },
+            "require-dev": {
+                "dealerdirect/phpcodesniffer-composer-installer": "dev-master",
+                "dompdf/dompdf": "^1.0",
+                "friendsofphp/php-cs-fixer": "^3.2",
+                "jpgraph/jpgraph": "^4.0",
+                "mpdf/mpdf": "^8.0",
+                "phpcompatibility/php-compatibility": "^9.3",
+                "phpstan/phpstan": "^1.1",
+                "phpstan/phpstan-phpunit": "^1.0",
+                "phpunit/phpunit": "^8.5 || ^9.0",
+                "squizlabs/php_codesniffer": "^3.6",
+                "tecnickcom/tcpdf": "^6.4"
+            },
+            "suggest": {
+                "dompdf/dompdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)",
+                "jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
+                "mpdf/mpdf": "Option for rendering PDF with PDF Writer",
+                "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)"
+            },
+            "time": "2021-11-23T15:23:42+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Maarten Balliauw",
+                    "homepage": "https://blog.maartenballiauw.be"
+                },
+                {
+                    "name": "Mark Baker",
+                    "homepage": "https://markbakeruk.net"
+                },
+                {
+                    "name": "Franck Lefevre",
+                    "homepage": "https://rootslabs.net"
+                },
+                {
+                    "name": "Erik Tilt"
+                },
+                {
+                    "name": "Adrien Crivelli"
+                }
+            ],
+            "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
+            "homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
+            "keywords": [
+                "OpenXML",
+                "excel",
+                "gnumeric",
+                "ods",
+                "php",
+                "spreadsheet",
+                "xls",
+                "xlsx"
+            ],
+            "install-path": "../phpoffice/phpspreadsheet"
+        },
+        {
+            "name": "phpspec/php-diff",
+            "version": "v1.1.3",
+            "version_normalized": "1.1.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpspec/php-diff.git",
+                "reference": "fc1156187f9f6c8395886fe85ed88a0a245d72e9"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpspec/php-diff/zipball/fc1156187f9f6c8395886fe85ed88a0a245d72e9",
+                "reference": "fc1156187f9f6c8395886fe85ed88a0a245d72e9",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "time": "2020-09-18T13:47:07+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-0": {
+                    "Diff": "lib/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Chris Boulton",
+                    "homepage": "http://github.com/chrisboulton"
+                }
+            ],
+            "description": "A comprehensive library for generating differences between two hashable objects (strings or arrays).",
+            "install-path": "../phpspec/php-diff"
+        },
+        {
+            "name": "phpspec/prophecy",
+            "version": "v1.15.0",
+            "version_normalized": "1.15.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpspec/prophecy.git",
+                "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
+                "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "doctrine/instantiator": "^1.2",
+                "php": "^7.2 || ~8.0, <8.2",
+                "phpdocumentor/reflection-docblock": "^5.2",
+                "sebastian/comparator": "^3.0 || ^4.0",
+                "sebastian/recursion-context": "^3.0 || ^4.0"
+            },
+            "require-dev": {
+                "phpspec/phpspec": "^6.0 || ^7.0",
+                "phpunit/phpunit": "^8.0 || ^9.0"
+            },
+            "time": "2021-12-08T12:19:24+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Prophecy\\": "src/Prophecy"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Konstantin Kudryashov",
+                    "email": "ever.zet@gmail.com",
+                    "homepage": "http://everzet.com"
+                },
+                {
+                    "name": "Marcello Duarte",
+                    "email": "marcello.duarte@gmail.com"
+                }
+            ],
+            "description": "Highly opinionated mocking framework for PHP 5.3+",
+            "homepage": "https://github.com/phpspec/prophecy",
+            "keywords": [
+                "Double",
+                "Dummy",
+                "fake",
+                "mock",
+                "spy",
+                "stub"
+            ],
+            "install-path": "../phpspec/prophecy"
+        },
+        {
+            "name": "phpunit/php-code-coverage",
+            "version": "6.1.4",
+            "version_normalized": "6.1.4.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+                "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
+                "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "ext-dom": "*",
+                "ext-xmlwriter": "*",
+                "php": "^7.1",
+                "phpunit/php-file-iterator": "^2.0",
+                "phpunit/php-text-template": "^1.2.1",
+                "phpunit/php-token-stream": "^3.0",
+                "sebastian/code-unit-reverse-lookup": "^1.0.1",
+                "sebastian/environment": "^3.1 || ^4.0",
+                "sebastian/version": "^2.0.1",
+                "theseer/tokenizer": "^1.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^7.0"
+            },
+            "suggest": {
+                "ext-xdebug": "^2.6.0"
+            },
+            "time": "2018-10-31T16:06:48+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "6.1-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
+            "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
+            "keywords": [
+                "coverage",
+                "testing",
+                "xunit"
+            ],
+            "install-path": "../phpunit/php-code-coverage"
+        },
+        {
+            "name": "phpunit/php-file-iterator",
+            "version": "2.0.5",
+            "version_normalized": "2.0.5.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+                "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5",
+                "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^8.5"
+            },
+            "time": "2021-12-02T12:42:26+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "FilterIterator implementation that filters files based on a list of suffixes.",
+            "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
+            "keywords": [
+                "filesystem",
+                "iterator"
+            ],
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "install-path": "../phpunit/php-file-iterator"
+        },
+        {
+            "name": "phpunit/php-text-template",
+            "version": "1.2.1",
+            "version_normalized": "1.2.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-text-template.git",
+                "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+                "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "time": "2015-06-21T13:50:34+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Simple template engine.",
+            "homepage": "https://github.com/sebastianbergmann/php-text-template/",
+            "keywords": [
+                "template"
+            ],
+            "install-path": "../phpunit/php-text-template"
+        },
+        {
+            "name": "phpunit/php-timer",
+            "version": "2.1.3",
+            "version_normalized": "2.1.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-timer.git",
+                "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662",
+                "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^8.5"
+            },
+            "time": "2020-11-30T08:20:02+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.1-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Utility class for timing",
+            "homepage": "https://github.com/sebastianbergmann/php-timer/",
+            "keywords": [
+                "timer"
+            ],
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "install-path": "../phpunit/php-timer"
+        },
+        {
+            "name": "phpunit/php-token-stream",
+            "version": "3.1.3",
+            "version_normalized": "3.1.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-token-stream.git",
+                "reference": "9c1da83261628cb24b6a6df371b6e312b3954768"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/9c1da83261628cb24b6a6df371b6e312b3954768",
+                "reference": "9c1da83261628cb24b6a6df371b6e312b3954768",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "ext-tokenizer": "*",
+                "php": ">=7.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^7.0"
+            },
+            "time": "2021-07-26T12:15:06+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.1-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Wrapper around PHP's tokenizer extension.",
+            "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
+            "keywords": [
+                "tokenizer"
+            ],
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "abandoned": true,
+            "install-path": "../phpunit/php-token-stream"
+        },
+        {
+            "name": "phpunit/phpunit",
+            "version": "7.5.20",
+            "version_normalized": "7.5.20.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/phpunit.git",
+                "reference": "9467db479d1b0487c99733bb1e7944d32deded2c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9467db479d1b0487c99733bb1e7944d32deded2c",
+                "reference": "9467db479d1b0487c99733bb1e7944d32deded2c",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "doctrine/instantiator": "^1.1",
+                "ext-dom": "*",
+                "ext-json": "*",
+                "ext-libxml": "*",
+                "ext-mbstring": "*",
+                "ext-xml": "*",
+                "myclabs/deep-copy": "^1.7",
+                "phar-io/manifest": "^1.0.2",
+                "phar-io/version": "^2.0",
+                "php": "^7.1",
+                "phpspec/prophecy": "^1.7",
+                "phpunit/php-code-coverage": "^6.0.7",
+                "phpunit/php-file-iterator": "^2.0.1",
+                "phpunit/php-text-template": "^1.2.1",
+                "phpunit/php-timer": "^2.1",
+                "sebastian/comparator": "^3.0",
+                "sebastian/diff": "^3.0",
+                "sebastian/environment": "^4.0",
+                "sebastian/exporter": "^3.1",
+                "sebastian/global-state": "^2.0",
+                "sebastian/object-enumerator": "^3.0.3",
+                "sebastian/resource-operations": "^2.0",
+                "sebastian/version": "^2.0.1"
+            },
+            "conflict": {
+                "phpunit/phpunit-mock-objects": "*"
+            },
+            "require-dev": {
+                "ext-pdo": "*"
+            },
+            "suggest": {
+                "ext-soap": "*",
+                "ext-xdebug": "*",
+                "phpunit/php-invoker": "^2.0"
+            },
+            "time": "2020-01-08T08:45:45+00:00",
+            "bin": [
+                "phpunit"
+            ],
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "7.5-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "The PHP Unit Testing framework.",
+            "homepage": "https://phpunit.de/",
+            "keywords": [
+                "phpunit",
+                "testing",
+                "xunit"
+            ],
+            "install-path": "../phpunit/phpunit"
+        },
+        {
+            "name": "psr/container",
+            "version": "1.1.2",
+            "version_normalized": "1.1.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/container.git",
+                "reference": "513e0666f7216c7459170d56df27dfcefe1689ea"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea",
+                "reference": "513e0666f7216c7459170d56df27dfcefe1689ea",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.4.0"
+            },
+            "time": "2021-11-05T16:50:12+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Container\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "https://www.php-fig.org/"
+                }
+            ],
+            "description": "Common Container Interface (PHP FIG PSR-11)",
+            "homepage": "https://github.com/php-fig/container",
+            "keywords": [
+                "PSR-11",
+                "container",
+                "container-interface",
+                "container-interop",
+                "psr"
+            ],
+            "install-path": "../psr/container"
+        },
+        {
+            "name": "psr/http-client",
+            "version": "1.0.1",
+            "version_normalized": "1.0.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/http-client.git",
+                "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
+                "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "^7.0 || ^8.0",
+                "psr/http-message": "^1.0"
+            },
+            "time": "2020-06-29T06:28:15+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Http\\Client\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interface for HTTP clients",
+            "homepage": "https://github.com/php-fig/http-client",
+            "keywords": [
+                "http",
+                "http-client",
+                "psr",
+                "psr-18"
+            ],
+            "install-path": "../psr/http-client"
+        },
+        {
+            "name": "psr/http-factory",
+            "version": "1.0.1",
+            "version_normalized": "1.0.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/http-factory.git",
+                "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
+                "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.0.0",
+                "psr/http-message": "^1.0"
+            },
+            "time": "2019-04-30T12:38:16+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Http\\Message\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interfaces for PSR-7 HTTP message factories",
+            "keywords": [
+                "factory",
+                "http",
+                "message",
+                "psr",
+                "psr-17",
+                "psr-7",
+                "request",
+                "response"
+            ],
+            "install-path": "../psr/http-factory"
+        },
+        {
+            "name": "psr/http-message",
+            "version": "1.0.1",
+            "version_normalized": "1.0.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/http-message.git",
+                "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
+                "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "time": "2016-08-06T14:39:51+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Http\\Message\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interface for HTTP messages",
+            "homepage": "https://github.com/php-fig/http-message",
+            "keywords": [
+                "http",
+                "http-message",
+                "psr",
+                "psr-7",
+                "request",
+                "response"
+            ],
+            "install-path": "../psr/http-message"
+        },
+        {
+            "name": "psr/log",
+            "version": "1.1.4",
+            "version_normalized": "1.1.4.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/log.git",
+                "reference": "d49695b909c3b7628b6289db5479a1c204601f11"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
+                "reference": "d49695b909c3b7628b6289db5479a1c204601f11",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "time": "2021-05-03T11:20:27+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.1.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Log\\": "Psr/Log/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "https://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interface for logging libraries",
+            "homepage": "https://github.com/php-fig/log",
+            "keywords": [
+                "log",
+                "psr",
+                "psr-3"
+            ],
+            "support": {
+                "source": "https://github.com/php-fig/log/tree/1.1.4"
+            },
+            "install-path": "../psr/log"
+        },
+        {
+            "name": "psr/simple-cache",
+            "version": "1.0.1",
+            "version_normalized": "1.0.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/simple-cache.git",
+                "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
+                "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "time": "2017-10-23T01:57:42+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Psr\\SimpleCache\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interfaces for simple caching",
+            "keywords": [
+                "cache",
+                "caching",
+                "psr",
+                "psr-16",
+                "simple-cache"
+            ],
+            "install-path": "../psr/simple-cache"
+        },
+        {
+            "name": "ralouphie/getallheaders",
+            "version": "3.0.3",
+            "version_normalized": "3.0.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/ralouphie/getallheaders.git",
+                "reference": "120b605dfeb996808c31b6477290a714d356e822"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
+                "reference": "120b605dfeb996808c31b6477290a714d356e822",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=5.6"
+            },
+            "require-dev": {
+                "php-coveralls/php-coveralls": "^2.1",
+                "phpunit/phpunit": "^5 || ^6.5"
+            },
+            "time": "2019-03-08T08:55:37+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "files": [
+                    "src/getallheaders.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Ralph Khattar",
+                    "email": "ralph.khattar@gmail.com"
+                }
+            ],
+            "description": "A polyfill for getallheaders.",
+            "install-path": "../ralouphie/getallheaders"
+        },
+        {
+            "name": "sebastian/code-unit-reverse-lookup",
+            "version": "1.0.2",
+            "version_normalized": "1.0.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
+                "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619",
+                "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=5.6"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^8.5"
+            },
+            "time": "2020-11-30T08:15:22+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Looks up which function or method a line of code belongs to",
+            "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "install-path": "../sebastian/code-unit-reverse-lookup"
+        },
+        {
+            "name": "sebastian/comparator",
+            "version": "3.0.3",
+            "version_normalized": "3.0.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/comparator.git",
+                "reference": "1071dfcef776a57013124ff35e1fc41ccd294758"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758",
+                "reference": "1071dfcef776a57013124ff35e1fc41ccd294758",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1",
+                "sebastian/diff": "^3.0",
+                "sebastian/exporter": "^3.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^8.5"
+            },
+            "time": "2020-11-30T08:04:30+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.0-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                },
+                {
+                    "name": "Jeff Welch",
+                    "email": "whatthejeff@gmail.com"
+                },
+                {
+                    "name": "Volker Dusch",
+                    "email": "github@wallbash.com"
+                },
+                {
+                    "name": "Bernhard Schussek",
+                    "email": "bschussek@2bepublished.at"
+                }
+            ],
+            "description": "Provides the functionality to compare PHP values for equality",
+            "homepage": "https://github.com/sebastianbergmann/comparator",
+            "keywords": [
+                "comparator",
+                "compare",
+                "equality"
+            ],
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "install-path": "../sebastian/comparator"
+        },
+        {
+            "name": "sebastian/diff",
+            "version": "3.0.3",
+            "version_normalized": "3.0.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/diff.git",
+                "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211",
+                "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^7.5 || ^8.0",
+                "symfony/process": "^2 || ^3.3 || ^4"
+            },
+            "time": "2020-11-30T07:59:04+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.0-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                },
+                {
+                    "name": "Kore Nordmann",
+                    "email": "mail@kore-nordmann.de"
+                }
+            ],
+            "description": "Diff implementation",
+            "homepage": "https://github.com/sebastianbergmann/diff",
+            "keywords": [
+                "diff",
+                "udiff",
+                "unidiff",
+                "unified diff"
+            ],
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "install-path": "../sebastian/diff"
+        },
+        {
+            "name": "sebastian/environment",
+            "version": "4.2.4",
+            "version_normalized": "4.2.4.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/environment.git",
+                "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0",
+                "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^7.5"
+            },
+            "suggest": {
+                "ext-posix": "*"
+            },
+            "time": "2020-11-30T07:53:42+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "4.2-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Provides functionality to handle HHVM/PHP environments",
+            "homepage": "http://www.github.com/sebastianbergmann/environment",
+            "keywords": [
+                "Xdebug",
+                "environment",
+                "hhvm"
+            ],
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "install-path": "../sebastian/environment"
+        },
+        {
+            "name": "sebastian/exporter",
+            "version": "3.1.4",
+            "version_normalized": "3.1.4.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/exporter.git",
+                "reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/0c32ea2e40dbf59de29f3b49bf375176ce7dd8db",
+                "reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.0",
+                "sebastian/recursion-context": "^3.0"
+            },
+            "require-dev": {
+                "ext-mbstring": "*",
+                "phpunit/phpunit": "^8.5"
+            },
+            "time": "2021-11-11T13:51:24+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.1.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                },
+                {
+                    "name": "Jeff Welch",
+                    "email": "whatthejeff@gmail.com"
+                },
+                {
+                    "name": "Volker Dusch",
+                    "email": "github@wallbash.com"
+                },
+                {
+                    "name": "Adam Harvey",
+                    "email": "aharvey@php.net"
+                },
+                {
+                    "name": "Bernhard Schussek",
+                    "email": "bschussek@gmail.com"
+                }
+            ],
+            "description": "Provides the functionality to export PHP variables for visualization",
+            "homepage": "http://www.github.com/sebastianbergmann/exporter",
+            "keywords": [
+                "export",
+                "exporter"
+            ],
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "install-path": "../sebastian/exporter"
+        },
+        {
+            "name": "sebastian/global-state",
+            "version": "2.0.0",
+            "version_normalized": "2.0.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/global-state.git",
+                "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
+                "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "^7.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^6.0"
+            },
+            "suggest": {
+                "ext-uopz": "*"
+            },
+            "time": "2017-04-27T15:39:26+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Snapshotting of global state",
+            "homepage": "http://www.github.com/sebastianbergmann/global-state",
+            "keywords": [
+                "global state"
+            ],
+            "install-path": "../sebastian/global-state"
+        },
+        {
+            "name": "sebastian/object-enumerator",
+            "version": "3.0.4",
+            "version_normalized": "3.0.4.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/object-enumerator.git",
+                "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
+                "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.0",
+                "sebastian/object-reflector": "^1.1.1",
+                "sebastian/recursion-context": "^3.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^6.0"
+            },
+            "time": "2020-11-30T07:40:27+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.0.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Traverses array structures and object graphs to enumerate all referenced objects",
+            "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "install-path": "../sebastian/object-enumerator"
+        },
+        {
+            "name": "sebastian/object-reflector",
+            "version": "1.1.2",
+            "version_normalized": "1.1.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/object-reflector.git",
+                "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
+                "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^6.0"
+            },
+            "time": "2020-11-30T07:37:18+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.1-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Allows reflection of object attributes, including inherited and non-public ones",
+            "homepage": "https://github.com/sebastianbergmann/object-reflector/",
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "install-path": "../sebastian/object-reflector"
+        },
+        {
+            "name": "sebastian/recursion-context",
+            "version": "3.0.1",
+            "version_normalized": "3.0.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/recursion-context.git",
+                "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb",
+                "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^6.0"
+            },
+            "time": "2020-11-30T07:34:24+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.0.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                },
+                {
+                    "name": "Jeff Welch",
+                    "email": "whatthejeff@gmail.com"
+                },
+                {
+                    "name": "Adam Harvey",
+                    "email": "aharvey@php.net"
+                }
+            ],
+            "description": "Provides functionality to recursively process PHP variables",
+            "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "install-path": "../sebastian/recursion-context"
+        },
+        {
+            "name": "sebastian/resource-operations",
+            "version": "2.0.2",
+            "version_normalized": "2.0.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/resource-operations.git",
+                "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3",
+                "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "time": "2020-11-30T07:30:19+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Provides a list of PHP built-in functions that operate on resources",
+            "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "install-path": "../sebastian/resource-operations"
+        },
+        {
+            "name": "sebastian/version",
+            "version": "2.0.1",
+            "version_normalized": "2.0.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/version.git",
+                "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
+                "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=5.6"
+            },
+            "time": "2016-10-03T07:35:21+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Library that helps with managing the version number of Git-hosted PHP projects",
+            "homepage": "https://github.com/sebastianbergmann/version",
+            "install-path": "../sebastian/version"
+        },
+        {
+            "name": "sunmoon/yii2-phpspreadsheet",
+            "version": "1.2.0",
+            "version_normalized": "1.2.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/arieslee/yii2-phpspreadsheet.git",
+                "reference": "51fc4d0183eb81e654b3360ac18e631fc4b89c09"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/arieslee/yii2-phpspreadsheet/zipball/51fc4d0183eb81e654b3360ac18e631fc4b89c09",
+                "reference": "51fc4d0183eb81e654b3360ac18e631fc4b89c09",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "phpoffice/phpspreadsheet": "*",
+                "yiisoft/yii2": "^2.0.15"
+            },
+            "time": "2019-02-18T03:02:43+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "sunmoon\\phpspreadsheet\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Sunmoon",
+                    "email": "forphp@qq.com",
+                    "homepage": "https://blog.iw3c.com",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Yii2处理Excel文件, 修改自moonlandsoft/yii2-phpexcel。",
+            "homepage": "https://github.com/arieslee/yii2-phpspreadsheet",
+            "install-path": "../sunmoon/yii2-phpspreadsheet"
+        },
+        {
+            "name": "swiftmailer/swiftmailer",
+            "version": "v6.3.0",
+            "version_normalized": "6.3.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/swiftmailer/swiftmailer.git",
+                "reference": "8a5d5072dca8f48460fce2f4131fcc495eec654c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/8a5d5072dca8f48460fce2f4131fcc495eec654c",
+                "reference": "8a5d5072dca8f48460fce2f4131fcc495eec654c",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "egulias/email-validator": "^2.0|^3.1",
+                "php": ">=7.0.0",
+                "symfony/polyfill-iconv": "^1.0",
+                "symfony/polyfill-intl-idn": "^1.10",
+                "symfony/polyfill-mbstring": "^1.0"
+            },
+            "require-dev": {
+                "mockery/mockery": "^1.0",
+                "symfony/phpunit-bridge": "^4.4|^5.4"
+            },
+            "suggest": {
+                "ext-intl": "Needed to support internationalized email addresses"
+            },
+            "time": "2021-10-18T15:26:12+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "6.2-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "files": [
+                    "lib/swift_required.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Chris Corbyn"
+                },
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                }
+            ],
+            "description": "Swiftmailer, free feature-rich PHP mailer",
+            "homepage": "https://swiftmailer.symfony.com",
+            "keywords": [
+                "email",
+                "mail",
+                "mailer"
+            ],
+            "funding": [
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/swiftmailer/swiftmailer",
+                    "type": "tidelift"
+                }
+            ],
+            "abandoned": "symfony/mailer",
+            "install-path": "../swiftmailer/swiftmailer"
+        },
+        {
+            "name": "symfony/browser-kit",
+            "version": "v4.4.27",
+            "version_normalized": "4.4.27.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/browser-kit.git",
+                "reference": "9629d1524d8ced5a4ec3e94abdbd638b4ec8319b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/browser-kit/zipball/9629d1524d8ced5a4ec3e94abdbd638b4ec8319b",
+                "reference": "9629d1524d8ced5a4ec3e94abdbd638b4ec8319b",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1.3",
+                "symfony/dom-crawler": "^3.4|^4.0|^5.0",
+                "symfony/polyfill-php80": "^1.16"
+            },
+            "require-dev": {
+                "symfony/css-selector": "^3.4|^4.0|^5.0",
+                "symfony/http-client": "^4.3|^5.0",
+                "symfony/mime": "^4.3|^5.0",
+                "symfony/process": "^3.4|^4.0|^5.0"
+            },
+            "suggest": {
+                "symfony/process": ""
+            },
+            "time": "2021-07-21T12:19:41+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\BrowserKit\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically",
+            "homepage": "https://symfony.com",
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/browser-kit"
+        },
+        {
+            "name": "symfony/console",
+            "version": "v4.4.34",
+            "version_normalized": "4.4.34.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/console.git",
+                "reference": "329b3a75cc6b16d435ba1b1a41df54a53382a3f0"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/console/zipball/329b3a75cc6b16d435ba1b1a41df54a53382a3f0",
+                "reference": "329b3a75cc6b16d435ba1b1a41df54a53382a3f0",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1.3",
+                "symfony/polyfill-mbstring": "~1.0",
+                "symfony/polyfill-php73": "^1.8",
+                "symfony/polyfill-php80": "^1.16",
+                "symfony/service-contracts": "^1.1|^2"
+            },
+            "conflict": {
+                "psr/log": ">=3",
+                "symfony/dependency-injection": "<3.4",
+                "symfony/event-dispatcher": "<4.3|>=5",
+                "symfony/lock": "<4.4",
+                "symfony/process": "<3.3"
+            },
+            "provide": {
+                "psr/log-implementation": "1.0|2.0"
+            },
+            "require-dev": {
+                "psr/log": "^1|^2",
+                "symfony/config": "^3.4|^4.0|^5.0",
+                "symfony/dependency-injection": "^3.4|^4.0|^5.0",
+                "symfony/event-dispatcher": "^4.3",
+                "symfony/lock": "^4.4|^5.0",
+                "symfony/process": "^3.4|^4.0|^5.0",
+                "symfony/var-dumper": "^4.3|^5.0"
+            },
+            "suggest": {
+                "psr/log": "For using the console logger",
+                "symfony/event-dispatcher": "",
+                "symfony/lock": "",
+                "symfony/process": ""
+            },
+            "time": "2021-11-04T12:23:33+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Console\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Eases the creation of beautiful and testable command line interfaces",
+            "homepage": "https://symfony.com",
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/console"
+        },
+        {
+            "name": "symfony/css-selector",
+            "version": "v4.4.27",
+            "version_normalized": "4.4.27.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/css-selector.git",
+                "reference": "5194f18bd80d106f11efa8f7cd0fbdcc3af96ce6"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/css-selector/zipball/5194f18bd80d106f11efa8f7cd0fbdcc3af96ce6",
+                "reference": "5194f18bd80d106f11efa8f7cd0fbdcc3af96ce6",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1.3",
+                "symfony/polyfill-php80": "^1.16"
+            },
+            "time": "2021-07-21T12:19:41+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\CssSelector\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Jean-François Simon",
+                    "email": "jeanfrancois.simon@sensiolabs.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Converts CSS selectors to XPath expressions",
+            "homepage": "https://symfony.com",
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/css-selector"
+        },
+        {
+            "name": "symfony/deprecation-contracts",
+            "version": "v2.5.0",
+            "version_normalized": "2.5.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/deprecation-contracts.git",
+                "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8",
+                "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "time": "2021-07-12T14:48:14+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "2.5-dev"
+                },
+                "thanks": {
+                    "name": "symfony/contracts",
+                    "url": "https://github.com/symfony/contracts"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "files": [
+                    "function.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "A generic function and convention to trigger deprecation notices",
+            "homepage": "https://symfony.com",
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/deprecation-contracts"
+        },
+        {
+            "name": "symfony/dom-crawler",
+            "version": "v4.4.30",
+            "version_normalized": "4.4.30.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/dom-crawler.git",
+                "reference": "4632ae3567746c7e915c33c67a2fb6ab746090c4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/4632ae3567746c7e915c33c67a2fb6ab746090c4",
+                "reference": "4632ae3567746c7e915c33c67a2fb6ab746090c4",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1.3",
+                "symfony/polyfill-ctype": "~1.8",
+                "symfony/polyfill-mbstring": "~1.0",
+                "symfony/polyfill-php80": "^1.16"
+            },
+            "conflict": {
+                "masterminds/html5": "<2.6"
+            },
+            "require-dev": {
+                "masterminds/html5": "^2.6",
+                "symfony/css-selector": "^3.4|^4.0|^5.0"
+            },
+            "suggest": {
+                "symfony/css-selector": ""
+            },
+            "time": "2021-08-28T15:40:01+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\DomCrawler\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Eases DOM navigation for HTML and XML documents",
+            "homepage": "https://symfony.com",
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/dom-crawler"
+        },
+        {
+            "name": "symfony/event-dispatcher",
+            "version": "v4.4.34",
+            "version_normalized": "4.4.34.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/event-dispatcher.git",
+                "reference": "1a024b45369c9d55d76b6b8a241bd20c9ea1cbd8"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/1a024b45369c9d55d76b6b8a241bd20c9ea1cbd8",
+                "reference": "1a024b45369c9d55d76b6b8a241bd20c9ea1cbd8",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1.3",
+                "symfony/event-dispatcher-contracts": "^1.1",
+                "symfony/polyfill-php80": "^1.16"
+            },
+            "conflict": {
+                "symfony/dependency-injection": "<3.4"
+            },
+            "provide": {
+                "psr/event-dispatcher-implementation": "1.0",
+                "symfony/event-dispatcher-implementation": "1.1"
+            },
+            "require-dev": {
+                "psr/log": "^1|^2|^3",
+                "symfony/config": "^3.4|^4.0|^5.0",
+                "symfony/dependency-injection": "^3.4|^4.0|^5.0",
+                "symfony/error-handler": "~3.4|~4.4",
+                "symfony/expression-language": "^3.4|^4.0|^5.0",
+                "symfony/http-foundation": "^3.4|^4.0|^5.0",
+                "symfony/service-contracts": "^1.1|^2",
+                "symfony/stopwatch": "^3.4|^4.0|^5.0"
+            },
+            "suggest": {
+                "symfony/dependency-injection": "",
+                "symfony/http-kernel": ""
+            },
+            "time": "2021-11-15T14:42:25+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\EventDispatcher\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
+            "homepage": "https://symfony.com",
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/event-dispatcher"
+        },
+        {
+            "name": "symfony/event-dispatcher-contracts",
+            "version": "v1.1.11",
+            "version_normalized": "1.1.11.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/event-dispatcher-contracts.git",
+                "reference": "01e9a4efac0ee33a05dfdf93b346f62e7d0e998c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/01e9a4efac0ee33a05dfdf93b346f62e7d0e998c",
+                "reference": "01e9a4efac0ee33a05dfdf93b346f62e7d0e998c",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1.3"
+            },
+            "suggest": {
+                "psr/event-dispatcher": "",
+                "symfony/event-dispatcher-implementation": ""
+            },
+            "time": "2021-03-23T15:25:38+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.1-dev"
+                },
+                "thanks": {
+                    "name": "symfony/contracts",
+                    "url": "https://github.com/symfony/contracts"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Contracts\\EventDispatcher\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Generic abstractions related to dispatching event",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "abstractions",
+                "contracts",
+                "decoupling",
+                "interfaces",
+                "interoperability",
+                "standards"
+            ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/event-dispatcher-contracts"
+        },
+        {
+            "name": "symfony/finder",
+            "version": "v4.4.30",
+            "version_normalized": "4.4.30.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/finder.git",
+                "reference": "70362f1e112280d75b30087c7598b837c1b468b6"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/finder/zipball/70362f1e112280d75b30087c7598b837c1b468b6",
+                "reference": "70362f1e112280d75b30087c7598b837c1b468b6",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1.3",
+                "symfony/polyfill-php80": "^1.16"
+            },
+            "time": "2021-08-04T20:31:23+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Finder\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Finds files and directories via an intuitive fluent interface",
+            "homepage": "https://symfony.com",
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/finder"
+        },
+        {
+            "name": "symfony/polyfill-ctype",
+            "version": "v1.23.0",
+            "version_normalized": "1.23.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-ctype.git",
+                "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce",
+                "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "suggest": {
+                "ext-ctype": "For best performance"
+            },
+            "time": "2021-02-19T12:13:01+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.23-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Polyfill\\Ctype\\": ""
+                },
+                "files": [
+                    "bootstrap.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Gert de Pagter",
+                    "email": "BackEndTea@gmail.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for ctype functions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "ctype",
+                "polyfill",
+                "portable"
+            ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/polyfill-ctype"
+        },
+        {
+            "name": "symfony/polyfill-iconv",
+            "version": "v1.23.0",
+            "version_normalized": "1.23.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-iconv.git",
+                "reference": "63b5bb7db83e5673936d6e3b8b3e022ff6474933"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/63b5bb7db83e5673936d6e3b8b3e022ff6474933",
+                "reference": "63b5bb7db83e5673936d6e3b8b3e022ff6474933",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "suggest": {
+                "ext-iconv": "For best performance"
+            },
+            "time": "2021-05-27T09:27:20+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.23-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Polyfill\\Iconv\\": ""
+                },
+                "files": [
+                    "bootstrap.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for the Iconv extension",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "iconv",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/polyfill-iconv"
+        },
+        {
+            "name": "symfony/polyfill-intl-idn",
+            "version": "v1.23.0",
+            "version_normalized": "1.23.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-intl-idn.git",
+                "reference": "65bd267525e82759e7d8c4e8ceea44f398838e65"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/65bd267525e82759e7d8c4e8ceea44f398838e65",
+                "reference": "65bd267525e82759e7d8c4e8ceea44f398838e65",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1",
+                "symfony/polyfill-intl-normalizer": "^1.10",
+                "symfony/polyfill-php72": "^1.10"
+            },
+            "suggest": {
+                "ext-intl": "For best performance"
+            },
+            "time": "2021-05-27T09:27:20+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.23-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Polyfill\\Intl\\Idn\\": ""
+                },
+                "files": [
+                    "bootstrap.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Laurent Bassin",
+                    "email": "laurent@bassin.info"
+                },
+                {
+                    "name": "Trevor Rowbotham",
+                    "email": "trevor.rowbotham@pm.me"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "idn",
+                "intl",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/polyfill-intl-idn"
+        },
+        {
+            "name": "symfony/polyfill-intl-normalizer",
+            "version": "v1.23.0",
+            "version_normalized": "1.23.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
+                "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8",
+                "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "suggest": {
+                "ext-intl": "For best performance"
+            },
+            "time": "2021-02-19T12:13:01+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.23-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
+                },
+                "files": [
+                    "bootstrap.php"
+                ],
+                "classmap": [
+                    "Resources/stubs"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for intl's Normalizer class and related functions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "intl",
+                "normalizer",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/polyfill-intl-normalizer"
+        },
+        {
+            "name": "symfony/polyfill-mbstring",
+            "version": "v1.23.1",
+            "version_normalized": "1.23.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-mbstring.git",
+                "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6",
+                "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "suggest": {
+                "ext-mbstring": "For best performance"
+            },
+            "time": "2021-05-27T12:26:48+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.23-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Polyfill\\Mbstring\\": ""
+                },
+                "files": [
+                    "bootstrap.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for the Mbstring extension",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "mbstring",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/polyfill-mbstring"
+        },
+        {
+            "name": "symfony/polyfill-php72",
+            "version": "v1.23.0",
+            "version_normalized": "1.23.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-php72.git",
+                "reference": "9a142215a36a3888e30d0a9eeea9766764e96976"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976",
+                "reference": "9a142215a36a3888e30d0a9eeea9766764e96976",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "time": "2021-05-27T09:17:38+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.23-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Polyfill\\Php72\\": ""
+                },
+                "files": [
+                    "bootstrap.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/polyfill-php72"
+        },
+        {
+            "name": "symfony/polyfill-php73",
+            "version": "v1.23.0",
+            "version_normalized": "1.23.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-php73.git",
+                "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fba8933c384d6476ab14fb7b8526e5287ca7e010",
+                "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "time": "2021-02-19T12:13:01+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.23-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Polyfill\\Php73\\": ""
+                },
+                "files": [
+                    "bootstrap.php"
+                ],
+                "classmap": [
+                    "Resources/stubs"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/polyfill-php73"
+        },
+        {
+            "name": "symfony/polyfill-php80",
+            "version": "v1.23.1",
+            "version_normalized": "1.23.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-php80.git",
+                "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be",
+                "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "time": "2021-07-28T13:41:28+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.23-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Polyfill\\Php80\\": ""
+                },
+                "files": [
+                    "bootstrap.php"
+                ],
+                "classmap": [
+                    "Resources/stubs"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Ion Bazan",
+                    "email": "ion.bazan@gmail.com"
+                },
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/polyfill-php80"
+        },
+        {
+            "name": "symfony/service-contracts",
+            "version": "v2.5.0",
+            "version_normalized": "2.5.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/service-contracts.git",
+                "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/service-contracts/zipball/1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc",
+                "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.2.5",
+                "psr/container": "^1.1",
+                "symfony/deprecation-contracts": "^2.1"
+            },
+            "conflict": {
+                "ext-psr": "<1.1|>=2"
+            },
+            "suggest": {
+                "symfony/service-implementation": ""
+            },
+            "time": "2021-11-04T16:48:04+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "2.5-dev"
+                },
+                "thanks": {
+                    "name": "symfony/contracts",
+                    "url": "https://github.com/symfony/contracts"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Contracts\\Service\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Generic abstractions related to writing services",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "abstractions",
+                "contracts",
+                "decoupling",
+                "interfaces",
+                "interoperability",
+                "standards"
+            ],
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/service-contracts"
+        },
+        {
+            "name": "symfony/yaml",
+            "version": "v4.4.34",
+            "version_normalized": "4.4.34.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/yaml.git",
+                "reference": "2c309e258adeb9970229042be39b360d34986fad"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/2c309e258adeb9970229042be39b360d34986fad",
+                "reference": "2c309e258adeb9970229042be39b360d34986fad",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": ">=7.1.3",
+                "symfony/polyfill-ctype": "~1.8"
+            },
+            "conflict": {
+                "symfony/console": "<3.4"
+            },
+            "require-dev": {
+                "symfony/console": "^3.4|^4.0|^5.0"
+            },
+            "suggest": {
+                "symfony/console": "For validating YAML files using the lint command"
+            },
+            "time": "2021-11-18T18:49:23+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Yaml\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Loads and dumps YAML files",
+            "homepage": "https://symfony.com",
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/yaml"
+        },
+        {
+            "name": "theseer/tokenizer",
+            "version": "1.2.1",
+            "version_normalized": "1.2.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/theseer/tokenizer.git",
+                "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e",
+                "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "ext-dom": "*",
+                "ext-tokenizer": "*",
+                "ext-xmlwriter": "*",
+                "php": "^7.2 || ^8.0"
+            },
+            "time": "2021-07-28T10:34:58+00:00",
+            "type": "library",
+            "installation-source": "dist",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Arne Blankerts",
+                    "email": "arne@blankerts.de",
+                    "role": "Developer"
+                }
+            ],
+            "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
+            "funding": [
+                {
+                    "url": "https://github.com/theseer",
+                    "type": "github"
+                }
+            ],
+            "install-path": "../theseer/tokenizer"
+        },
+        {
+            "name": "webmozart/assert",
+            "version": "1.10.0",
+            "version_normalized": "1.10.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/webmozarts/assert.git",
+                "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25",
+                "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "php": "^7.2 || ^8.0",
+                "symfony/polyfill-ctype": "^1.8"
+            },
+            "conflict": {
+                "phpstan/phpstan": "<0.12.20",
+                "vimeo/psalm": "<4.6.1 || 4.6.2"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^8.5.13"
+            },
+            "time": "2021-03-09T10:59:23+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.10-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Webmozart\\Assert\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Bernhard Schussek",
+                    "email": "bschussek@gmail.com"
+                }
+            ],
+            "description": "Assertions to validate method input/output with nice error messages.",
+            "keywords": [
+                "assert",
+                "check",
+                "validate"
+            ],
+            "install-path": "../webmozart/assert"
+        },
+        {
+            "name": "yiisoft/yii2",
+            "version": "2.0.43",
+            "version_normalized": "2.0.43.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/yiisoft/yii2-framework.git",
+                "reference": "f370955faa3067d9b27879aaf14b0978a805cd59"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/f370955faa3067d9b27879aaf14b0978a805cd59",
+                "reference": "f370955faa3067d9b27879aaf14b0978a805cd59",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "bower-asset/inputmask": "~3.2.2 | ~3.3.5",
+                "bower-asset/jquery": "3.6.*@stable | 3.5.*@stable | 3.4.*@stable | 3.3.*@stable | 3.2.*@stable | 3.1.*@stable | 2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable",
+                "bower-asset/punycode": "1.3.*",
+                "bower-asset/yii2-pjax": "~2.0.1",
+                "cebe/markdown": "~1.0.0 | ~1.1.0 | ~1.2.0",
+                "ext-ctype": "*",
+                "ext-mbstring": "*",
+                "ezyang/htmlpurifier": "~4.6",
+                "lib-pcre": "*",
+                "paragonie/random_compat": ">=1",
+                "php": ">=5.4.0",
+                "yiisoft/yii2-composer": "~2.0.4"
+            },
+            "time": "2021-08-09T17:38:43+00:00",
+            "bin": [
+                "yii"
+            ],
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "yii\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Qiang Xue",
+                    "email": "qiang.xue@gmail.com",
+                    "homepage": "https://www.yiiframework.com/",
+                    "role": "Founder and project lead"
+                },
+                {
+                    "name": "Alexander Makarov",
+                    "email": "sam@rmcreative.ru",
+                    "homepage": "https://rmcreative.ru/",
+                    "role": "Core framework development"
+                },
+                {
+                    "name": "Maurizio Domba",
+                    "homepage": "http://mdomba.info/",
+                    "role": "Core framework development"
+                },
+                {
+                    "name": "Carsten Brandt",
+                    "email": "mail@cebe.cc",
+                    "homepage": "https://cebe.cc/",
+                    "role": "Core framework development"
+                },
+                {
+                    "name": "Timur Ruziev",
+                    "email": "resurtm@gmail.com",
+                    "homepage": "http://resurtm.com/",
+                    "role": "Core framework development"
+                },
+                {
+                    "name": "Paul Klimov",
+                    "email": "klimov.paul@gmail.com",
+                    "role": "Core framework development"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
-                }
-            ]
-        },
-        "require": {
-            "php": ">=7.1.3",
-            "symfony/polyfill-ctype": "~1.8",
-            "symfony/polyfill-mbstring": "~1.0",
-            "symfony/polyfill-php80": "^1.16"
-        },
-        "conflict": {
-            "masterminds/html5": "<2.6"
-        },
-        "require-dev": {
-            "masterminds/html5": "^2.6",
-            "symfony/css-selector": "^3.4|^4.0|^5.0"
-        },
-        "suggest": {
-            "symfony/css-selector": ""
-        },
-        "time": "2021-08-28T15:40:01+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Symfony\\Component\\DomCrawler\\": ""
-            },
-            "exclude-from-classmap": [
-                "/Tests/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Fabien Potencier",
-                "email": "fabien@symfony.com"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "https://symfony.com/contributors"
-            }
-        ],
-        "description": "Eases DOM navigation for HTML and XML documents",
-        "homepage": "https://symfony.com",
-        "funding": [
-            {
-                "url": "https://symfony.com/sponsor",
-                "type": "custom"
-            },
-            {
-                "url": "https://github.com/fabpot",
-                "type": "github"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "symfony/event-dispatcher",
-        "version": "v4.4.34",
-        "version_normalized": "4.4.34.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/symfony/event-dispatcher.git",
-            "reference": "1a024b45369c9d55d76b6b8a241bd20c9ea1cbd8"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/1a024b45369c9d55d76b6b8a241bd20c9ea1cbd8",
-            "reference": "1a024b45369c9d55d76b6b8a241bd20c9ea1cbd8",
-            "shasum": "",
-            "mirrors": [
+                    "name": "Dmitry Naumenko",
+                    "email": "d.naumenko.a@gmail.com",
+                    "role": "Core framework development"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Boudewijn Vahrmeijer",
+                    "email": "info@dynasource.eu",
+                    "homepage": "http://dynasource.eu",
+                    "role": "Core framework development"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=7.1.3",
-            "symfony/event-dispatcher-contracts": "^1.1",
-            "symfony/polyfill-php80": "^1.16"
-        },
-        "conflict": {
-            "symfony/dependency-injection": "<3.4"
-        },
-        "provide": {
-            "psr/event-dispatcher-implementation": "1.0",
-            "symfony/event-dispatcher-implementation": "1.1"
-        },
-        "require-dev": {
-            "psr/log": "^1|^2|^3",
-            "symfony/config": "^3.4|^4.0|^5.0",
-            "symfony/dependency-injection": "^3.4|^4.0|^5.0",
-            "symfony/error-handler": "~3.4|~4.4",
-            "symfony/expression-language": "^3.4|^4.0|^5.0",
-            "symfony/http-foundation": "^3.4|^4.0|^5.0",
-            "symfony/service-contracts": "^1.1|^2",
-            "symfony/stopwatch": "^3.4|^4.0|^5.0"
-        },
-        "suggest": {
-            "symfony/dependency-injection": "",
-            "symfony/http-kernel": ""
-        },
-        "time": "2021-11-15T14:42:25+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Symfony\\Component\\EventDispatcher\\": ""
-            },
-            "exclude-from-classmap": [
-                "/Tests/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Fabien Potencier",
-                "email": "fabien@symfony.com"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "https://symfony.com/contributors"
-            }
-        ],
-        "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
-        "homepage": "https://symfony.com",
-        "funding": [
-            {
-                "url": "https://symfony.com/sponsor",
-                "type": "custom"
-            },
-            {
-                "url": "https://github.com/fabpot",
-                "type": "github"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "symfony/event-dispatcher-contracts",
-        "version": "v1.1.11",
-        "version_normalized": "1.1.11.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/symfony/event-dispatcher-contracts.git",
-            "reference": "01e9a4efac0ee33a05dfdf93b346f62e7d0e998c"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/01e9a4efac0ee33a05dfdf93b346f62e7d0e998c",
-            "reference": "01e9a4efac0ee33a05dfdf93b346f62e7d0e998c",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "description": "Yii PHP Framework Version 2",
+            "homepage": "https://www.yiiframework.com/",
+            "keywords": [
+                "framework",
+                "yii2"
+            ],
+            "funding": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
-                }
-            ]
-        },
-        "require": {
-            "php": ">=7.1.3"
-        },
-        "suggest": {
-            "psr/event-dispatcher": "",
-            "symfony/event-dispatcher-implementation": ""
-        },
-        "time": "2021-03-23T15:25:38+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-main": "1.1-dev"
-            },
-            "thanks": {
-                "name": "symfony/contracts",
-                "url": "https://github.com/symfony/contracts"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Symfony\\Contracts\\EventDispatcher\\": ""
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Nicolas Grekas",
-                "email": "p@tchwork.com"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "https://symfony.com/contributors"
-            }
-        ],
-        "description": "Generic abstractions related to dispatching event",
-        "homepage": "https://symfony.com",
-        "keywords": [
-            "abstractions",
-            "contracts",
-            "decoupling",
-            "interfaces",
-            "interoperability",
-            "standards"
-        ],
-        "funding": [
-            {
-                "url": "https://symfony.com/sponsor",
-                "type": "custom"
-            },
-            {
-                "url": "https://github.com/fabpot",
-                "type": "github"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "symfony/finder",
-        "version": "v4.4.30",
-        "version_normalized": "4.4.30.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/symfony/finder.git",
-            "reference": "70362f1e112280d75b30087c7598b837c1b468b6"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/symfony/finder/zipball/70362f1e112280d75b30087c7598b837c1b468b6",
-            "reference": "70362f1e112280d75b30087c7598b837c1b468b6",
-            "shasum": "",
-            "mirrors": [
+                    "url": "https://github.com/yiisoft",
+                    "type": "github"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
-                }
-            ]
-        },
-        "require": {
-            "php": ">=7.1.3",
-            "symfony/polyfill-php80": "^1.16"
-        },
-        "time": "2021-08-04T20:31:23+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Symfony\\Component\\Finder\\": ""
-            },
-            "exclude-from-classmap": [
-                "/Tests/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Fabien Potencier",
-                "email": "fabien@symfony.com"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "https://symfony.com/contributors"
-            }
-        ],
-        "description": "Finds files and directories via an intuitive fluent interface",
-        "homepage": "https://symfony.com",
-        "funding": [
-            {
-                "url": "https://symfony.com/sponsor",
-                "type": "custom"
-            },
-            {
-                "url": "https://github.com/fabpot",
-                "type": "github"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "symfony/polyfill-ctype",
-        "version": "v1.23.0",
-        "version_normalized": "1.23.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/symfony/polyfill-ctype.git",
-            "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce",
-            "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce",
-            "shasum": "",
-            "mirrors": [
+                    "url": "https://opencollective.com/yiisoft",
+                    "type": "open_collective"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2",
+                    "type": "tidelift"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=7.1"
-        },
-        "suggest": {
-            "ext-ctype": "For best performance"
-        },
-        "time": "2021-02-19T12:13:01+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-main": "1.23-dev"
-            },
-            "thanks": {
-                "name": "symfony/polyfill",
-                "url": "https://github.com/symfony/polyfill"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Symfony\\Polyfill\\Ctype\\": ""
-            },
-            "files": [
-                "bootstrap.php"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Gert de Pagter",
-                "email": "BackEndTea@gmail.com"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "https://symfony.com/contributors"
-            }
-        ],
-        "description": "Symfony polyfill for ctype functions",
-        "homepage": "https://symfony.com",
-        "keywords": [
-            "compatibility",
-            "ctype",
-            "polyfill",
-            "portable"
-        ],
-        "funding": [
-            {
-                "url": "https://symfony.com/sponsor",
-                "type": "custom"
-            },
-            {
-                "url": "https://github.com/fabpot",
-                "type": "github"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "symfony/polyfill-iconv",
-        "version": "v1.23.0",
-        "version_normalized": "1.23.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/symfony/polyfill-iconv.git",
-            "reference": "63b5bb7db83e5673936d6e3b8b3e022ff6474933"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/63b5bb7db83e5673936d6e3b8b3e022ff6474933",
-            "reference": "63b5bb7db83e5673936d6e3b8b3e022ff6474933",
-            "shasum": "",
-            "mirrors": [
-                {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+            ],
+            "install-path": "../yiisoft/yii2"
+        },
+        {
+            "name": "yiisoft/yii2-bootstrap",
+            "version": "2.0.11",
+            "version_normalized": "2.0.11.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/yiisoft/yii2-bootstrap.git",
+                "reference": "83d144f4089adaa7064ad60dc4c1436daa2eb30e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/yiisoft/yii2-bootstrap/zipball/83d144f4089adaa7064ad60dc4c1436daa2eb30e",
+                "reference": "83d144f4089adaa7064ad60dc4c1436daa2eb30e",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "bower-asset/bootstrap": "3.4.* | 3.3.* | 3.2.* | 3.1.*",
+                "yiisoft/yii2": "~2.0.6"
+            },
+            "require-dev": {
+                "cweagans/composer-patches": "^1.7",
+                "phpunit/phpunit": "4.8.34"
+            },
+            "time": "2021-08-09T20:54:06+00:00",
+            "type": "yii2-extension",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0.x-dev"
+                },
+                "patches": {
+                    "phpunit/phpunit-mock-objects": {
+                        "Fix PHP 7 and 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_mock_objects.patch"
+                    },
+                    "phpunit/phpunit": {
+                        "Fix PHP 7 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php7.patch",
+                        "Fix PHP 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php8.patch"
+                    }
                 }
-            ]
-        },
-        "require": {
-            "php": ">=7.1"
-        },
-        "suggest": {
-            "ext-iconv": "For best performance"
-        },
-        "time": "2021-05-27T09:27:20+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-main": "1.23-dev"
-            },
-            "thanks": {
-                "name": "symfony/polyfill",
-                "url": "https://github.com/symfony/polyfill"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Symfony\\Polyfill\\Iconv\\": ""
-            },
-            "files": [
-                "bootstrap.php"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Nicolas Grekas",
-                "email": "p@tchwork.com"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "https://symfony.com/contributors"
-            }
-        ],
-        "description": "Symfony polyfill for the Iconv extension",
-        "homepage": "https://symfony.com",
-        "keywords": [
-            "compatibility",
-            "iconv",
-            "polyfill",
-            "portable",
-            "shim"
-        ],
-        "funding": [
-            {
-                "url": "https://symfony.com/sponsor",
-                "type": "custom"
-            },
-            {
-                "url": "https://github.com/fabpot",
-                "type": "github"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "symfony/polyfill-intl-idn",
-        "version": "v1.23.0",
-        "version_normalized": "1.23.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/symfony/polyfill-intl-idn.git",
-            "reference": "65bd267525e82759e7d8c4e8ceea44f398838e65"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/65bd267525e82759e7d8c4e8ceea44f398838e65",
-            "reference": "65bd267525e82759e7d8c4e8ceea44f398838e65",
-            "shasum": "",
-            "mirrors": [
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "yii\\bootstrap\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Qiang Xue",
+                    "email": "qiang.xue@gmail.com",
+                    "homepage": "http://www.yiiframework.com/"
+                },
+                {
+                    "name": "Alexander Makarov",
+                    "email": "sam@rmcreative.ru",
+                    "homepage": "http://rmcreative.ru/"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Antonio Ramirez",
+                    "email": "amigo.cobos@gmail.com"
+                },
+                {
+                    "name": "Paul Klimov",
+                    "email": "klimov.paul@gmail.com"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=7.1",
-            "symfony/polyfill-intl-normalizer": "^1.10",
-            "symfony/polyfill-php72": "^1.10"
-        },
-        "suggest": {
-            "ext-intl": "For best performance"
-        },
-        "time": "2021-05-27T09:27:20+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-main": "1.23-dev"
-            },
-            "thanks": {
-                "name": "symfony/polyfill",
-                "url": "https://github.com/symfony/polyfill"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Symfony\\Polyfill\\Intl\\Idn\\": ""
-            },
-            "files": [
-                "bootstrap.php"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Laurent Bassin",
-                "email": "laurent@bassin.info"
-            },
-            {
-                "name": "Trevor Rowbotham",
-                "email": "trevor.rowbotham@pm.me"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "https://symfony.com/contributors"
-            }
-        ],
-        "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
-        "homepage": "https://symfony.com",
-        "keywords": [
-            "compatibility",
-            "idn",
-            "intl",
-            "polyfill",
-            "portable",
-            "shim"
-        ],
-        "funding": [
-            {
-                "url": "https://symfony.com/sponsor",
-                "type": "custom"
-            },
-            {
-                "url": "https://github.com/fabpot",
-                "type": "github"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "symfony/polyfill-intl-normalizer",
-        "version": "v1.23.0",
-        "version_normalized": "1.23.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
-            "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8",
-            "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "description": "The Twitter Bootstrap extension for the Yii framework",
+            "keywords": [
+                "bootstrap",
+                "yii2"
+            ],
+            "funding": [
+                {
+                    "url": "https://github.com/yiisoft",
+                    "type": "github"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "url": "https://opencollective.com/yiisoft",
+                    "type": "open_collective"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2-bootstrap",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../yiisoft/yii2-bootstrap"
+        },
+        {
+            "name": "yiisoft/yii2-composer",
+            "version": "2.0.10",
+            "version_normalized": "2.0.10.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/yiisoft/yii2-composer.git",
+                "reference": "94bb3f66e779e2774f8776d6e1bdeab402940510"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/yiisoft/yii2-composer/zipball/94bb3f66e779e2774f8776d6e1bdeab402940510",
+                "reference": "94bb3f66e779e2774f8776d6e1bdeab402940510",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "composer-plugin-api": "^1.0 | ^2.0"
+            },
+            "require-dev": {
+                "composer/composer": "^1.0 | ^2.0@dev",
+                "phpunit/phpunit": "<7"
+            },
+            "time": "2020-06-24T00:04:01+00:00",
+            "type": "composer-plugin",
+            "extra": {
+                "class": "yii\\composer\\Plugin",
+                "branch-alias": {
+                    "dev-master": "2.0.x-dev"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=7.1"
-        },
-        "suggest": {
-            "ext-intl": "For best performance"
-        },
-        "time": "2021-02-19T12:13:01+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-main": "1.23-dev"
-            },
-            "thanks": {
-                "name": "symfony/polyfill",
-                "url": "https://github.com/symfony/polyfill"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
             },
-            "files": [
-                "bootstrap.php"
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "yii\\composer\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
             ],
-            "classmap": [
-                "Resources/stubs"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Nicolas Grekas",
-                "email": "p@tchwork.com"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "https://symfony.com/contributors"
-            }
-        ],
-        "description": "Symfony polyfill for intl's Normalizer class and related functions",
-        "homepage": "https://symfony.com",
-        "keywords": [
-            "compatibility",
-            "intl",
-            "normalizer",
-            "polyfill",
-            "portable",
-            "shim"
-        ],
-        "funding": [
-            {
-                "url": "https://symfony.com/sponsor",
-                "type": "custom"
-            },
-            {
-                "url": "https://github.com/fabpot",
-                "type": "github"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "symfony/polyfill-mbstring",
-        "version": "v1.23.1",
-        "version_normalized": "1.23.1.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/symfony/polyfill-mbstring.git",
-            "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6",
-            "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6",
-            "shasum": "",
-            "mirrors": [
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
-                }
-            ]
-        },
-        "require": {
-            "php": ">=7.1"
-        },
-        "suggest": {
-            "ext-mbstring": "For best performance"
-        },
-        "time": "2021-05-27T12:26:48+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-main": "1.23-dev"
-            },
-            "thanks": {
-                "name": "symfony/polyfill",
-                "url": "https://github.com/symfony/polyfill"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Symfony\\Polyfill\\Mbstring\\": ""
-            },
-            "files": [
-                "bootstrap.php"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Nicolas Grekas",
-                "email": "p@tchwork.com"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "https://symfony.com/contributors"
-            }
-        ],
-        "description": "Symfony polyfill for the Mbstring extension",
-        "homepage": "https://symfony.com",
-        "keywords": [
-            "compatibility",
-            "mbstring",
-            "polyfill",
-            "portable",
-            "shim"
-        ],
-        "funding": [
-            {
-                "url": "https://symfony.com/sponsor",
-                "type": "custom"
-            },
-            {
-                "url": "https://github.com/fabpot",
-                "type": "github"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "symfony/polyfill-php72",
-        "version": "v1.23.0",
-        "version_normalized": "1.23.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/symfony/polyfill-php72.git",
-            "reference": "9a142215a36a3888e30d0a9eeea9766764e96976"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976",
-            "reference": "9a142215a36a3888e30d0a9eeea9766764e96976",
-            "shasum": "",
-            "mirrors": [
+                    "name": "Qiang Xue",
+                    "email": "qiang.xue@gmail.com"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Carsten Brandt",
+                    "email": "mail@cebe.cc"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=7.1"
-        },
-        "time": "2021-05-27T09:17:38+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-main": "1.23-dev"
-            },
-            "thanks": {
-                "name": "symfony/polyfill",
-                "url": "https://github.com/symfony/polyfill"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Symfony\\Polyfill\\Php72\\": ""
-            },
-            "files": [
-                "bootstrap.php"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Nicolas Grekas",
-                "email": "p@tchwork.com"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "https://symfony.com/contributors"
-            }
-        ],
-        "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
-        "homepage": "https://symfony.com",
-        "keywords": [
-            "compatibility",
-            "polyfill",
-            "portable",
-            "shim"
-        ],
-        "funding": [
-            {
-                "url": "https://symfony.com/sponsor",
-                "type": "custom"
-            },
-            {
-                "url": "https://github.com/fabpot",
-                "type": "github"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "symfony/polyfill-php73",
-        "version": "v1.23.0",
-        "version_normalized": "1.23.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/symfony/polyfill-php73.git",
-            "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fba8933c384d6476ab14fb7b8526e5287ca7e010",
-            "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "description": "The composer plugin for Yii extension installer",
+            "keywords": [
+                "composer",
+                "extension installer",
+                "yii2"
+            ],
+            "funding": [
+                {
+                    "url": "https://github.com/yiisoft",
+                    "type": "github"
+                },
+                {
+                    "url": "https://opencollective.com/yiisoft",
+                    "type": "open_collective"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2-composer",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../yiisoft/yii2-composer"
+        },
+        {
+            "name": "yiisoft/yii2-debug",
+            "version": "2.0.14",
+            "version_normalized": "2.0.14.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/yiisoft/yii2-debug.git",
+                "reference": "dc5a4a8529de1a41dbb037dbabf1f3f93002f21d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/yiisoft/yii2-debug/zipball/dc5a4a8529de1a41dbb037dbabf1f3f93002f21d",
+                "reference": "dc5a4a8529de1a41dbb037dbabf1f3f93002f21d",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "yiisoft/yii2": "~2.0.13",
+                "yiisoft/yii2-bootstrap": "~2.0.0"
+            },
+            "time": "2018-09-23T21:41:04+00:00",
+            "type": "yii2-extension",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0.x-dev"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=7.1"
-        },
-        "time": "2021-02-19T12:13:01+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-main": "1.23-dev"
-            },
-            "thanks": {
-                "name": "symfony/polyfill",
-                "url": "https://github.com/symfony/polyfill"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Symfony\\Polyfill\\Php73\\": ""
             },
-            "files": [
-                "bootstrap.php"
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "yii\\debug\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
             ],
-            "classmap": [
-                "Resources/stubs"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Nicolas Grekas",
-                "email": "p@tchwork.com"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "https://symfony.com/contributors"
-            }
-        ],
-        "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
-        "homepage": "https://symfony.com",
-        "keywords": [
-            "compatibility",
-            "polyfill",
-            "portable",
-            "shim"
-        ],
-        "funding": [
-            {
-                "url": "https://symfony.com/sponsor",
-                "type": "custom"
-            },
-            {
-                "url": "https://github.com/fabpot",
-                "type": "github"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "symfony/polyfill-php80",
-        "version": "v1.23.1",
-        "version_normalized": "1.23.1.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/symfony/polyfill-php80.git",
-            "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be",
-            "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be",
-            "shasum": "",
-            "mirrors": [
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Qiang Xue",
+                    "email": "qiang.xue@gmail.com"
+                }
+            ],
+            "description": "The debugger extension for the Yii framework",
+            "keywords": [
+                "debug",
+                "debugger",
+                "yii2"
+            ],
+            "install-path": "../yiisoft/yii2-debug"
+        },
+        {
+            "name": "yiisoft/yii2-faker",
+            "version": "2.0.5",
+            "version_normalized": "2.0.5.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/yiisoft/yii2-faker.git",
+                "reference": "8c361657143bfaea58ff7dcc9bf51f1991a46f5d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/yiisoft/yii2-faker/zipball/8c361657143bfaea58ff7dcc9bf51f1991a46f5d",
+                "reference": "8c361657143bfaea58ff7dcc9bf51f1991a46f5d",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "fakerphp/faker": "~1.9|~1.10",
+                "yiisoft/yii2": "~2.0.0"
+            },
+            "require-dev": {
+                "cweagans/composer-patches": "^1.7",
+                "phpunit/phpunit": "4.8.34"
+            },
+            "time": "2020-11-10T12:27:35+00:00",
+            "type": "yii2-extension",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0.x-dev"
+                },
+                "composer-exit-on-patch-failure": true,
+                "patches": {
+                    "phpunit/phpunit-mock-objects": {
+                        "Fix PHP 7 and 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_mock_objects.patch"
+                    },
+                    "phpunit/phpunit": {
+                        "Fix PHP 7 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php7.patch",
+                        "Fix PHP 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php8.patch"
+                    }
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "yii\\faker\\": "src"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=7.1"
-        },
-        "time": "2021-07-28T13:41:28+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-main": "1.23-dev"
-            },
-            "thanks": {
-                "name": "symfony/polyfill",
-                "url": "https://github.com/symfony/polyfill"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Symfony\\Polyfill\\Php80\\": ""
             },
-            "files": [
-                "bootstrap.php"
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
             ],
-            "classmap": [
-                "Resources/stubs"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Ion Bazan",
-                "email": "ion.bazan@gmail.com"
-            },
-            {
-                "name": "Nicolas Grekas",
-                "email": "p@tchwork.com"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "https://symfony.com/contributors"
-            }
-        ],
-        "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
-        "homepage": "https://symfony.com",
-        "keywords": [
-            "compatibility",
-            "polyfill",
-            "portable",
-            "shim"
-        ],
-        "funding": [
-            {
-                "url": "https://symfony.com/sponsor",
-                "type": "custom"
-            },
-            {
-                "url": "https://github.com/fabpot",
-                "type": "github"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "symfony/service-contracts",
-        "version": "v2.5.0",
-        "version_normalized": "2.5.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/symfony/service-contracts.git",
-            "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/symfony/service-contracts/zipball/1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc",
-            "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc",
-            "shasum": "",
-            "mirrors": [
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Mark Jebri",
+                    "email": "mark.github@yandex.ru"
                 }
-            ]
-        },
-        "require": {
-            "php": ">=7.2.5",
-            "psr/container": "^1.1",
-            "symfony/deprecation-contracts": "^2.1"
-        },
-        "conflict": {
-            "ext-psr": "<1.1|>=2"
-        },
-        "suggest": {
-            "symfony/service-implementation": ""
-        },
-        "time": "2021-11-04T16:48:04+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-main": "2.5-dev"
-            },
-            "thanks": {
-                "name": "symfony/contracts",
-                "url": "https://github.com/symfony/contracts"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Symfony\\Contracts\\Service\\": ""
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Nicolas Grekas",
-                "email": "p@tchwork.com"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "https://symfony.com/contributors"
-            }
-        ],
-        "description": "Generic abstractions related to writing services",
-        "homepage": "https://symfony.com",
-        "keywords": [
-            "abstractions",
-            "contracts",
-            "decoupling",
-            "interfaces",
-            "interoperability",
-            "standards"
-        ],
-        "funding": [
-            {
-                "url": "https://symfony.com/sponsor",
-                "type": "custom"
-            },
-            {
-                "url": "https://github.com/fabpot",
-                "type": "github"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "symfony/yaml",
-        "version": "v4.4.34",
-        "version_normalized": "4.4.34.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/symfony/yaml.git",
-            "reference": "2c309e258adeb9970229042be39b360d34986fad"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/symfony/yaml/zipball/2c309e258adeb9970229042be39b360d34986fad",
-            "reference": "2c309e258adeb9970229042be39b360d34986fad",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "description": "Fixture generator. The Faker integration for the Yii framework.",
+            "keywords": [
+                "Fixture",
+                "faker",
+                "yii2"
+            ],
+            "funding": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
-                }
-            ]
-        },
-        "require": {
-            "php": ">=7.1.3",
-            "symfony/polyfill-ctype": "~1.8"
-        },
-        "conflict": {
-            "symfony/console": "<3.4"
-        },
-        "require-dev": {
-            "symfony/console": "^3.4|^4.0|^5.0"
-        },
-        "suggest": {
-            "symfony/console": "For validating YAML files using the lint command"
-        },
-        "time": "2021-11-18T18:49:23+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Symfony\\Component\\Yaml\\": ""
-            },
-            "exclude-from-classmap": [
-                "/Tests/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Fabien Potencier",
-                "email": "fabien@symfony.com"
-            },
-            {
-                "name": "Symfony Community",
-                "homepage": "https://symfony.com/contributors"
-            }
-        ],
-        "description": "Loads and dumps YAML files",
-        "homepage": "https://symfony.com",
-        "funding": [
-            {
-                "url": "https://symfony.com/sponsor",
-                "type": "custom"
-            },
-            {
-                "url": "https://github.com/fabpot",
-                "type": "github"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "theseer/tokenizer",
-        "version": "1.2.1",
-        "version_normalized": "1.2.1.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/theseer/tokenizer.git",
-            "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e",
-            "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
-            "shasum": "",
-            "mirrors": [
+                    "url": "https://github.com/yiisoft",
+                    "type": "github"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
-                }
-            ]
-        },
-        "require": {
-            "ext-dom": "*",
-            "ext-tokenizer": "*",
-            "ext-xmlwriter": "*",
-            "php": "^7.2 || ^8.0"
-        },
-        "time": "2021-07-28T10:34:58+00:00",
-        "type": "library",
-        "installation-source": "dist",
-        "autoload": {
-            "classmap": [
-                "src/"
-            ]
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Arne Blankerts",
-                "email": "arne@blankerts.de",
-                "role": "Developer"
-            }
-        ],
-        "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
-        "funding": [
-            {
-                "url": "https://github.com/theseer",
-                "type": "github"
-            }
-        ]
-    },
-    {
-        "name": "webmozart/assert",
-        "version": "1.10.0",
-        "version_normalized": "1.10.0.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/webmozarts/assert.git",
-            "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25",
-            "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25",
-            "shasum": "",
-            "mirrors": [
+                    "url": "https://opencollective.com/yiisoft",
+                    "type": "open_collective"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2-faker",
+                    "type": "tidelift"
                 }
-            ]
-        },
-        "require": {
-            "php": "^7.2 || ^8.0",
-            "symfony/polyfill-ctype": "^1.8"
-        },
-        "conflict": {
-            "phpstan/phpstan": "<0.12.20",
-            "vimeo/psalm": "<4.6.1 || 4.6.2"
-        },
-        "require-dev": {
-            "phpunit/phpunit": "^8.5.13"
-        },
-        "time": "2021-03-09T10:59:23+00:00",
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "1.10-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "Webmozart\\Assert\\": "src/"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "MIT"
-        ],
-        "authors": [
-            {
-                "name": "Bernhard Schussek",
-                "email": "bschussek@gmail.com"
-            }
-        ],
-        "description": "Assertions to validate method input/output with nice error messages.",
-        "keywords": [
-            "assert",
-            "check",
-            "validate"
-        ]
-    },
-    {
-        "name": "yiisoft/yii2",
-        "version": "2.0.43",
-        "version_normalized": "2.0.43.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/yiisoft/yii2-framework.git",
-            "reference": "f370955faa3067d9b27879aaf14b0978a805cd59"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/f370955faa3067d9b27879aaf14b0978a805cd59",
-            "reference": "f370955faa3067d9b27879aaf14b0978a805cd59",
-            "shasum": "",
-            "mirrors": [
-                {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+            ],
+            "install-path": "../yiisoft/yii2-faker"
+        },
+        {
+            "name": "yiisoft/yii2-gii",
+            "version": "2.0.8",
+            "version_normalized": "2.0.8.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/yiisoft/yii2-gii.git",
+                "reference": "c02adc552bcf3a0ef6f3694a9dcbf209f4885ab1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/yiisoft/yii2-gii/zipball/c02adc552bcf3a0ef6f3694a9dcbf209f4885ab1",
+                "reference": "c02adc552bcf3a0ef6f3694a9dcbf209f4885ab1",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "bower-asset/typeahead.js": "0.10.* | ~0.11.0",
+                "phpspec/php-diff": ">=1.0.2",
+                "yiisoft/yii2": "~2.0.14",
+                "yiisoft/yii2-bootstrap": "~2.0.0"
+            },
+            "time": "2018-12-08T10:07:49+00:00",
+            "type": "yii2-extension",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0.x-dev"
                 }
-            ]
-        },
-        "require": {
-            "bower-asset/inputmask": "~3.2.2 | ~3.3.5",
-            "bower-asset/jquery": "3.6.*@stable | 3.5.*@stable | 3.4.*@stable | 3.3.*@stable | 3.2.*@stable | 3.1.*@stable | 2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable",
-            "bower-asset/punycode": "1.3.*",
-            "bower-asset/yii2-pjax": "~2.0.1",
-            "cebe/markdown": "~1.0.0 | ~1.1.0 | ~1.2.0",
-            "ext-ctype": "*",
-            "ext-mbstring": "*",
-            "ezyang/htmlpurifier": "~4.6",
-            "lib-pcre": "*",
-            "paragonie/random_compat": ">=1",
-            "php": ">=5.4.0",
-            "yiisoft/yii2-composer": "~2.0.4"
-        },
-        "time": "2021-08-09T17:38:43+00:00",
-        "bin": [
-            "yii"
-        ],
-        "type": "library",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "2.0.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "yii\\": ""
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Qiang Xue",
-                "email": "qiang.xue@gmail.com",
-                "homepage": "https://www.yiiframework.com/",
-                "role": "Founder and project lead"
-            },
-            {
-                "name": "Alexander Makarov",
-                "email": "sam@rmcreative.ru",
-                "homepage": "https://rmcreative.ru/",
-                "role": "Core framework development"
-            },
-            {
-                "name": "Maurizio Domba",
-                "homepage": "http://mdomba.info/",
-                "role": "Core framework development"
-            },
-            {
-                "name": "Carsten Brandt",
-                "email": "mail@cebe.cc",
-                "homepage": "https://cebe.cc/",
-                "role": "Core framework development"
-            },
-            {
-                "name": "Timur Ruziev",
-                "email": "resurtm@gmail.com",
-                "homepage": "http://resurtm.com/",
-                "role": "Core framework development"
-            },
-            {
-                "name": "Paul Klimov",
-                "email": "klimov.paul@gmail.com",
-                "role": "Core framework development"
-            },
-            {
-                "name": "Dmitry Naumenko",
-                "email": "d.naumenko.a@gmail.com",
-                "role": "Core framework development"
-            },
-            {
-                "name": "Boudewijn Vahrmeijer",
-                "email": "info@dynasource.eu",
-                "homepage": "http://dynasource.eu",
-                "role": "Core framework development"
-            }
-        ],
-        "description": "Yii PHP Framework Version 2",
-        "homepage": "https://www.yiiframework.com/",
-        "keywords": [
-            "framework",
-            "yii2"
-        ],
-        "funding": [
-            {
-                "url": "https://github.com/yiisoft",
-                "type": "github"
-            },
-            {
-                "url": "https://opencollective.com/yiisoft",
-                "type": "open_collective"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "yiisoft/yii2-bootstrap",
-        "version": "2.0.11",
-        "version_normalized": "2.0.11.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/yiisoft/yii2-bootstrap.git",
-            "reference": "83d144f4089adaa7064ad60dc4c1436daa2eb30e"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/yiisoft/yii2-bootstrap/zipball/83d144f4089adaa7064ad60dc4c1436daa2eb30e",
-            "reference": "83d144f4089adaa7064ad60dc4c1436daa2eb30e",
-            "shasum": "",
-            "mirrors": [
-                {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "yii\\gii\\": "src"
                 }
-            ]
-        },
-        "require": {
-            "bower-asset/bootstrap": "3.4.* | 3.3.* | 3.2.* | 3.1.*",
-            "yiisoft/yii2": "~2.0.6"
-        },
-        "require-dev": {
-            "cweagans/composer-patches": "^1.7",
-            "phpunit/phpunit": "4.8.34"
-        },
-        "time": "2021-08-09T20:54:06+00:00",
-        "type": "yii2-extension",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "2.0.x-dev"
             },
-            "patches": {
-                "phpunit/phpunit-mock-objects": {
-                    "Fix PHP 7 and 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_mock_objects.patch"
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Qiang Xue",
+                    "email": "qiang.xue@gmail.com"
+                }
+            ],
+            "description": "The Gii extension for the Yii framework",
+            "keywords": [
+                "code generator",
+                "gii",
+                "yii2"
+            ],
+            "install-path": "../yiisoft/yii2-gii"
+        },
+        {
+            "name": "yiisoft/yii2-httpclient",
+            "version": "2.0.14",
+            "version_normalized": "2.0.14.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/yiisoft/yii2-httpclient.git",
+                "reference": "50d670d2e1a30a354c27aeebf806a2db16954836"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/yiisoft/yii2-httpclient/zipball/50d670d2e1a30a354c27aeebf806a2db16954836",
+                "reference": "50d670d2e1a30a354c27aeebf806a2db16954836",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "paragonie/random_compat": ">=1",
+                "yiisoft/yii2": "~2.0.13"
+            },
+            "require-dev": {
+                "cweagans/composer-patches": "^1.7",
+                "phpunit/phpunit": "4.8.34"
+            },
+            "time": "2021-08-09T21:10:49+00:00",
+            "type": "yii2-extension",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0.x-dev"
                 },
-                "phpunit/phpunit": {
-                    "Fix PHP 7 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php7.patch",
-                    "Fix PHP 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php8.patch"
+                "composer-exit-on-patch-failure": true,
+                "patches": {
+                    "phpunit/phpunit-mock-objects": {
+                        "Fix PHP 7 and 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_mock_objects.patch"
+                    },
+                    "phpunit/phpunit": {
+                        "Fix PHP 7 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php7.patch",
+                        "Fix PHP 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php8.patch"
+                    }
                 }
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "yii\\bootstrap\\": "src"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Qiang Xue",
-                "email": "qiang.xue@gmail.com",
-                "homepage": "http://www.yiiframework.com/"
-            },
-            {
-                "name": "Alexander Makarov",
-                "email": "sam@rmcreative.ru",
-                "homepage": "http://rmcreative.ru/"
-            },
-            {
-                "name": "Antonio Ramirez",
-                "email": "amigo.cobos@gmail.com"
-            },
-            {
-                "name": "Paul Klimov",
-                "email": "klimov.paul@gmail.com"
-            }
-        ],
-        "description": "The Twitter Bootstrap extension for the Yii framework",
-        "keywords": [
-            "bootstrap",
-            "yii2"
-        ],
-        "funding": [
-            {
-                "url": "https://github.com/yiisoft",
-                "type": "github"
-            },
-            {
-                "url": "https://opencollective.com/yiisoft",
-                "type": "open_collective"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2-bootstrap",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "yiisoft/yii2-composer",
-        "version": "2.0.10",
-        "version_normalized": "2.0.10.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/yiisoft/yii2-composer.git",
-            "reference": "94bb3f66e779e2774f8776d6e1bdeab402940510"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/yiisoft/yii2-composer/zipball/94bb3f66e779e2774f8776d6e1bdeab402940510",
-            "reference": "94bb3f66e779e2774f8776d6e1bdeab402940510",
-            "shasum": "",
-            "mirrors": [
-                {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "yii\\httpclient\\": "src"
                 }
-            ]
-        },
-        "require": {
-            "composer-plugin-api": "^1.0 | ^2.0"
-        },
-        "require-dev": {
-            "composer/composer": "^1.0 | ^2.0@dev",
-            "phpunit/phpunit": "<7"
-        },
-        "time": "2020-06-24T00:04:01+00:00",
-        "type": "composer-plugin",
-        "extra": {
-            "class": "yii\\composer\\Plugin",
-            "branch-alias": {
-                "dev-master": "2.0.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "yii\\composer\\": ""
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Qiang Xue",
-                "email": "qiang.xue@gmail.com"
-            },
-            {
-                "name": "Carsten Brandt",
-                "email": "mail@cebe.cc"
-            }
-        ],
-        "description": "The composer plugin for Yii extension installer",
-        "keywords": [
-            "composer",
-            "extension installer",
-            "yii2"
-        ],
-        "funding": [
-            {
-                "url": "https://github.com/yiisoft",
-                "type": "github"
-            },
-            {
-                "url": "https://opencollective.com/yiisoft",
-                "type": "open_collective"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2-composer",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "yiisoft/yii2-debug",
-        "version": "2.0.14",
-        "version_normalized": "2.0.14.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/yiisoft/yii2-debug.git",
-            "reference": "dc5a4a8529de1a41dbb037dbabf1f3f93002f21d"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/yiisoft/yii2-debug/zipball/dc5a4a8529de1a41dbb037dbabf1f3f93002f21d",
-            "reference": "dc5a4a8529de1a41dbb037dbabf1f3f93002f21d",
-            "shasum": "",
-            "mirrors": [
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Paul Klimov",
+                    "email": "klimov.paul@gmail.com"
                 }
-            ]
-        },
-        "require": {
-            "yiisoft/yii2": "~2.0.13",
-            "yiisoft/yii2-bootstrap": "~2.0.0"
-        },
-        "time": "2018-09-23T21:41:04+00:00",
-        "type": "yii2-extension",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "2.0.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "yii\\debug\\": "src"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Qiang Xue",
-                "email": "qiang.xue@gmail.com"
-            }
-        ],
-        "description": "The debugger extension for the Yii framework",
-        "keywords": [
-            "debug",
-            "debugger",
-            "yii2"
-        ]
-    },
-    {
-        "name": "yiisoft/yii2-faker",
-        "version": "2.0.5",
-        "version_normalized": "2.0.5.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/yiisoft/yii2-faker.git",
-            "reference": "8c361657143bfaea58ff7dcc9bf51f1991a46f5d"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/yiisoft/yii2-faker/zipball/8c361657143bfaea58ff7dcc9bf51f1991a46f5d",
-            "reference": "8c361657143bfaea58ff7dcc9bf51f1991a46f5d",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "description": "HTTP client extension for the Yii framework",
+            "keywords": [
+                "curl",
+                "http",
+                "httpclient",
+                "yii2"
+            ],
+            "funding": [
+                {
+                    "url": "https://github.com/yiisoft",
+                    "type": "github"
+                },
+                {
+                    "url": "https://opencollective.com/yiisoft",
+                    "type": "open_collective"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2-httpclient",
+                    "type": "tidelift"
                 }
-            ]
-        },
-        "require": {
-            "fakerphp/faker": "~1.9|~1.10",
-            "yiisoft/yii2": "~2.0.0"
-        },
-        "require-dev": {
-            "cweagans/composer-patches": "^1.7",
-            "phpunit/phpunit": "4.8.34"
-        },
-        "time": "2020-11-10T12:27:35+00:00",
-        "type": "yii2-extension",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "2.0.x-dev"
-            },
-            "composer-exit-on-patch-failure": true,
-            "patches": {
-                "phpunit/phpunit-mock-objects": {
-                    "Fix PHP 7 and 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_mock_objects.patch"
-                },
-                "phpunit/phpunit": {
-                    "Fix PHP 7 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php7.patch",
-                    "Fix PHP 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php8.patch"
-                }
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "yii\\faker\\": "src"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Mark Jebri",
-                "email": "mark.github@yandex.ru"
-            }
-        ],
-        "description": "Fixture generator. The Faker integration for the Yii framework.",
-        "keywords": [
-            "Fixture",
-            "faker",
-            "yii2"
-        ],
-        "funding": [
-            {
-                "url": "https://github.com/yiisoft",
-                "type": "github"
-            },
-            {
-                "url": "https://opencollective.com/yiisoft",
-                "type": "open_collective"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2-faker",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "yiisoft/yii2-gii",
-        "version": "2.0.8",
-        "version_normalized": "2.0.8.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/yiisoft/yii2-gii.git",
-            "reference": "c02adc552bcf3a0ef6f3694a9dcbf209f4885ab1"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/yiisoft/yii2-gii/zipball/c02adc552bcf3a0ef6f3694a9dcbf209f4885ab1",
-            "reference": "c02adc552bcf3a0ef6f3694a9dcbf209f4885ab1",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "install-path": "../yiisoft/yii2-httpclient"
+        },
+        {
+            "name": "yiisoft/yii2-mongodb",
+            "version": "2.1.12",
+            "version_normalized": "2.1.12.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/yiisoft/yii2-mongodb.git",
+                "reference": "4a74369a2b233f2def02579766e1eceadb8964be"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/yiisoft/yii2-mongodb/zipball/4a74369a2b233f2def02579766e1eceadb8964be",
+                "reference": "4a74369a2b233f2def02579766e1eceadb8964be",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "ext-mongodb": ">=1.0.0",
+                "paragonie/random_compat": ">=1",
+                "yiisoft/yii2": "~2.0.39"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "4.8.27|~5.7.21|^6.2"
+            },
+            "time": "2021-08-09T21:15:42+00:00",
+            "type": "yii2-extension",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.1.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "yii\\mongodb\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Paul Klimov",
+                    "email": "klimov.paul@gmail.com"
                 }
-            ]
-        },
-        "require": {
-            "bower-asset/typeahead.js": "0.10.* | ~0.11.0",
-            "phpspec/php-diff": ">=1.0.2",
-            "yiisoft/yii2": "~2.0.14",
-            "yiisoft/yii2-bootstrap": "~2.0.0"
-        },
-        "time": "2018-12-08T10:07:49+00:00",
-        "type": "yii2-extension",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "2.0.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "yii\\gii\\": "src"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Qiang Xue",
-                "email": "qiang.xue@gmail.com"
-            }
-        ],
-        "description": "The Gii extension for the Yii framework",
-        "keywords": [
-            "code generator",
-            "gii",
-            "yii2"
-        ]
-    },
-    {
-        "name": "yiisoft/yii2-httpclient",
-        "version": "2.0.14",
-        "version_normalized": "2.0.14.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/yiisoft/yii2-httpclient.git",
-            "reference": "50d670d2e1a30a354c27aeebf806a2db16954836"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/yiisoft/yii2-httpclient/zipball/50d670d2e1a30a354c27aeebf806a2db16954836",
-            "reference": "50d670d2e1a30a354c27aeebf806a2db16954836",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "description": "MongoDB extension for the Yii framework",
+            "keywords": [
+                "GridFS",
+                "active-record",
+                "mongo",
+                "mongodb",
+                "yii2"
+            ],
+            "funding": [
+                {
+                    "url": "https://github.com/yiisoft",
+                    "type": "github"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "url": "https://opencollective.com/yiisoft",
+                    "type": "open_collective"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2-mongodb",
+                    "type": "tidelift"
                 }
-            ]
-        },
-        "require": {
-            "paragonie/random_compat": ">=1",
-            "yiisoft/yii2": "~2.0.13"
-        },
-        "require-dev": {
-            "cweagans/composer-patches": "^1.7",
-            "phpunit/phpunit": "4.8.34"
-        },
-        "time": "2021-08-09T21:10:49+00:00",
-        "type": "yii2-extension",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "2.0.x-dev"
-            },
-            "composer-exit-on-patch-failure": true,
-            "patches": {
-                "phpunit/phpunit-mock-objects": {
-                    "Fix PHP 7 and 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_mock_objects.patch"
-                },
-                "phpunit/phpunit": {
-                    "Fix PHP 7 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php7.patch",
-                    "Fix PHP 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php8.patch"
-                }
-            }
-        },
-        "installation-source": "dist",
-        "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"
-        ],
-        "funding": [
-            {
-                "url": "https://github.com/yiisoft",
-                "type": "github"
-            },
-            {
-                "url": "https://opencollective.com/yiisoft",
-                "type": "open_collective"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2-httpclient",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "yiisoft/yii2-mongodb",
-        "version": "2.1.12",
-        "version_normalized": "2.1.12.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/yiisoft/yii2-mongodb.git",
-            "reference": "4a74369a2b233f2def02579766e1eceadb8964be"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/yiisoft/yii2-mongodb/zipball/4a74369a2b233f2def02579766e1eceadb8964be",
-            "reference": "4a74369a2b233f2def02579766e1eceadb8964be",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "install-path": "../yiisoft/yii2-mongodb"
+        },
+        {
+            "name": "yiisoft/yii2-redis",
+            "version": "2.0.16",
+            "version_normalized": "2.0.16.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/yiisoft/yii2-redis.git",
+                "reference": "1b9efe97d8add594256b51089fbf7a56f31e3c9c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/yiisoft/yii2-redis/zipball/1b9efe97d8add594256b51089fbf7a56f31e3c9c",
+                "reference": "1b9efe97d8add594256b51089fbf7a56f31e3c9c",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "ext-openssl": "*",
+                "yiisoft/yii2": "~2.0.39"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "<7",
+                "yiisoft/yii2-dev": "~2.0.39"
+            },
+            "time": "2021-10-04T11:28:17+00:00",
+            "type": "yii2-extension",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "yii\\redis\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Carsten Brandt",
+                    "email": "mail@cebe.cc"
                 }
-            ]
-        },
-        "require": {
-            "ext-mongodb": ">=1.0.0",
-            "paragonie/random_compat": ">=1",
-            "yiisoft/yii2": "~2.0.39"
-        },
-        "require-dev": {
-            "phpunit/phpunit": "4.8.27|~5.7.21|^6.2"
-        },
-        "time": "2021-08-09T21:15:42+00:00",
-        "type": "yii2-extension",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "2.1.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "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"
-        ],
-        "funding": [
-            {
-                "url": "https://github.com/yiisoft",
-                "type": "github"
-            },
-            {
-                "url": "https://opencollective.com/yiisoft",
-                "type": "open_collective"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2-mongodb",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "yiisoft/yii2-redis",
-        "version": "2.0.16",
-        "version_normalized": "2.0.16.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/yiisoft/yii2-redis.git",
-            "reference": "1b9efe97d8add594256b51089fbf7a56f31e3c9c"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/yiisoft/yii2-redis/zipball/1b9efe97d8add594256b51089fbf7a56f31e3c9c",
-            "reference": "1b9efe97d8add594256b51089fbf7a56f31e3c9c",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "description": "Redis Cache, Session and ActiveRecord for the Yii framework",
+            "keywords": [
+                "active-record",
+                "cache",
+                "redis",
+                "session",
+                "yii2"
+            ],
+            "funding": [
+                {
+                    "url": "https://github.com/yiisoft",
+                    "type": "github"
+                },
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "url": "https://opencollective.com/yiisoft",
+                    "type": "open_collective"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2-redis",
+                    "type": "tidelift"
                 }
-            ]
-        },
-        "require": {
-            "ext-openssl": "*",
-            "yiisoft/yii2": "~2.0.39"
-        },
-        "require-dev": {
-            "phpunit/phpunit": "<7",
-            "yiisoft/yii2-dev": "~2.0.39"
-        },
-        "time": "2021-10-04T11:28:17+00:00",
-        "type": "yii2-extension",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "2.0.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "yii\\redis\\": "src"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Carsten Brandt",
-                "email": "mail@cebe.cc"
-            }
-        ],
-        "description": "Redis Cache, Session and ActiveRecord for the Yii framework",
-        "keywords": [
-            "active-record",
-            "cache",
-            "redis",
-            "session",
-            "yii2"
-        ],
-        "funding": [
-            {
-                "url": "https://github.com/yiisoft",
-                "type": "github"
-            },
-            {
-                "url": "https://opencollective.com/yiisoft",
-                "type": "open_collective"
-            },
-            {
-                "url": "https://tidelift.com/funding/github/packagist/yiisoft/yii2-redis",
-                "type": "tidelift"
-            }
-        ]
-    },
-    {
-        "name": "yiisoft/yii2-swiftmailer",
-        "version": "2.1.2",
-        "version_normalized": "2.1.2.0",
-        "source": {
-            "type": "git",
-            "url": "https://github.com/yiisoft/yii2-swiftmailer.git",
-            "reference": "09659a55959f9e64b8178d842b64a9ffae42b994"
-        },
-        "dist": {
-            "type": "zip",
-            "url": "https://api.github.com/repos/yiisoft/yii2-swiftmailer/zipball/09659a55959f9e64b8178d842b64a9ffae42b994",
-            "reference": "09659a55959f9e64b8178d842b64a9ffae42b994",
-            "shasum": "",
-            "mirrors": [
+            ],
+            "install-path": "../yiisoft/yii2-redis"
+        },
+        {
+            "name": "yiisoft/yii2-swiftmailer",
+            "version": "2.1.2",
+            "version_normalized": "2.1.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/yiisoft/yii2-swiftmailer.git",
+                "reference": "09659a55959f9e64b8178d842b64a9ffae42b994"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/yiisoft/yii2-swiftmailer/zipball/09659a55959f9e64b8178d842b64a9ffae42b994",
+                "reference": "09659a55959f9e64b8178d842b64a9ffae42b994",
+                "shasum": "",
+                "mirrors": [
+                    {
+                        "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+                        "preferred": true
+                    }
+                ]
+            },
+            "require": {
+                "swiftmailer/swiftmailer": "~6.0",
+                "yiisoft/yii2": ">=2.0.4"
+            },
+            "time": "2018-09-23T22:00:47+00:00",
+            "type": "yii2-extension",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.1.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "yii\\swiftmailer\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
                 {
-                    "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
-                    "preferred": true
+                    "name": "Paul Klimov",
+                    "email": "klimov.paul@gmail.com"
                 }
-            ]
-        },
-        "require": {
-            "swiftmailer/swiftmailer": "~6.0",
-            "yiisoft/yii2": ">=2.0.4"
-        },
-        "time": "2018-09-23T22:00:47+00:00",
-        "type": "yii2-extension",
-        "extra": {
-            "branch-alias": {
-                "dev-master": "2.1.x-dev"
-            }
-        },
-        "installation-source": "dist",
-        "autoload": {
-            "psr-4": {
-                "yii\\swiftmailer\\": "src"
-            }
-        },
-        "notification-url": "https://packagist.org/downloads/",
-        "license": [
-            "BSD-3-Clause"
-        ],
-        "authors": [
-            {
-                "name": "Paul Klimov",
-                "email": "klimov.paul@gmail.com"
-            }
-        ],
-        "description": "The SwiftMailer integration for the Yii framework",
-        "keywords": [
-            "email",
-            "mail",
-            "mailer",
-            "swift",
-            "swiftmailer",
-            "yii2"
-        ]
-    }
-]
+            ],
+            "description": "The SwiftMailer integration for the Yii framework",
+            "keywords": [
+                "email",
+                "mail",
+                "mailer",
+                "swift",
+                "swiftmailer",
+                "yii2"
+            ],
+            "install-path": "../yiisoft/yii2-swiftmailer"
+        }
+    ],
+    "dev": true,
+    "dev-package-names": [
+        "behat/gherkin",
+        "bower-asset/typeahead.js",
+        "codeception/base",
+        "codeception/phpunit-wrapper",
+        "codeception/stub",
+        "codeception/verify",
+        "doctrine/instantiator",
+        "fakerphp/faker",
+        "guzzlehttp/psr7",
+        "myclabs/deep-copy",
+        "phar-io/manifest",
+        "phar-io/version",
+        "phpdocumentor/reflection-common",
+        "phpdocumentor/reflection-docblock",
+        "phpdocumentor/type-resolver",
+        "phpspec/php-diff",
+        "phpspec/prophecy",
+        "phpunit/php-code-coverage",
+        "phpunit/php-file-iterator",
+        "phpunit/php-text-template",
+        "phpunit/php-timer",
+        "phpunit/php-token-stream",
+        "phpunit/phpunit",
+        "psr/container",
+        "ralouphie/getallheaders",
+        "sebastian/code-unit-reverse-lookup",
+        "sebastian/comparator",
+        "sebastian/diff",
+        "sebastian/environment",
+        "sebastian/exporter",
+        "sebastian/global-state",
+        "sebastian/object-enumerator",
+        "sebastian/object-reflector",
+        "sebastian/recursion-context",
+        "sebastian/resource-operations",
+        "sebastian/version",
+        "symfony/browser-kit",
+        "symfony/console",
+        "symfony/css-selector",
+        "symfony/deprecation-contracts",
+        "symfony/dom-crawler",
+        "symfony/event-dispatcher",
+        "symfony/event-dispatcher-contracts",
+        "symfony/finder",
+        "symfony/polyfill-ctype",
+        "symfony/polyfill-php73",
+        "symfony/polyfill-php80",
+        "symfony/service-contracts",
+        "symfony/yaml",
+        "theseer/tokenizer",
+        "webmozart/assert",
+        "yiisoft/yii2-debug",
+        "yiisoft/yii2-faker",
+        "yiisoft/yii2-gii"
+    ]
+}

+ 27 - 8
vendor/composer/installed.php

@@ -1,11 +1,11 @@
 <?php return array(
     'root' => array(
-        'pretty_version' => '1.0.0+no-version-set',
-        'version' => '1.0.0.0',
+        'pretty_version' => 'dev-master',
+        'version' => 'dev-master',
         'type' => 'project',
         'install_path' => __DIR__ . '/../../',
         'aliases' => array(),
-        'reference' => NULL,
+        'reference' => '0f13189868b03eac76766e36a2c19c88fba38db2',
         'name' => 'yiisoft/yii2-app-advanced',
         'dev' => true,
     ),
@@ -217,6 +217,15 @@
             'reference' => 'c66aefcafb4f6c269510e9ac46b82619a904c576',
             'dev_requirement' => false,
         ),
+        'monolog/monolog' => array(
+            'pretty_version' => '2.8.0',
+            'version' => '2.8.0.0',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../monolog/monolog',
+            'aliases' => array(),
+            'reference' => '720488632c590286b88b80e62aa3d3d551ad4a50',
+            'dev_requirement' => false,
+        ),
         'myclabs/deep-copy' => array(
             'pretty_version' => '1.10.2',
             'version' => '1.10.2.0',
@@ -421,10 +430,20 @@
                 0 => '1.0',
             ),
         ),
+        'psr/log' => array(
+            'pretty_version' => '1.1.4',
+            'version' => '1.1.4.0',
+            'type' => 'library',
+            'install_path' => __DIR__ . '/../psr/log',
+            'aliases' => array(),
+            'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11',
+            'dev_requirement' => false,
+        ),
         'psr/log-implementation' => array(
-            'dev_requirement' => true,
+            'dev_requirement' => false,
             'provided' => array(
-                0 => '1.0|2.0',
+                0 => '1.0.0 || 2.0.0 || 3.0.0',
+                1 => '1.0|2.0',
             ),
         ),
         'psr/simple-cache' => array(
@@ -758,12 +777,12 @@
             'dev_requirement' => false,
         ),
         'yiisoft/yii2-app-advanced' => array(
-            'pretty_version' => '1.0.0+no-version-set',
-            'version' => '1.0.0.0',
+            'pretty_version' => 'dev-master',
+            'version' => 'dev-master',
             'type' => 'project',
             'install_path' => __DIR__ . '/../../',
             'aliases' => array(),
-            'reference' => NULL,
+            'reference' => '0f13189868b03eac76766e36a2c19c88fba38db2',
             'dev_requirement' => false,
         ),
         'yiisoft/yii2-bootstrap' => array(

+ 608 - 0
vendor/monolog/monolog/CHANGELOG.md

@@ -0,0 +1,608 @@
+### 2.8.0 (2022-07-24)
+
+  * Deprecated `CubeHandler` and `PHPConsoleHandler` as both projects are abandoned and those should not be used anymore (#1734)
+  * Added RFC 5424 level (`7` to `0`) support to `Logger::log` and `Logger::addRecord` to increase interoperability (#1723)
+  * Added support for `__toString` for objects which are not json serializable in `JsonFormatter` (#1733)
+  * Added `GoogleCloudLoggingFormatter` (#1719)
+  * Added support for Predis 2.x (#1732)
+  * Added `AmqpHandler->setExtraAttributes` to allow configuring attributes when using an AMQPExchange (#1724)
+  * Fixed serialization/unserialization of handlers to make sure private properties are included (#1727)
+  * Fixed allowInlineLineBreaks in LineFormatter causing issues with windows paths containing `\n` or `\r` sequences (#1720)
+  * Fixed max normalization depth not being taken into account when formatting exceptions with a deep chain of previous exceptions (#1726)
+  * Fixed PHP 8.2 deprecation warnings (#1722)
+  * Fixed rare race condition or filesystem issue where StreamHandler is unable to create the directory the log should go into yet it exists already (#1678)
+
+### 2.7.0 (2022-06-09)
+
+  * Added `$datetime` parameter to `Logger::addRecord` as low level API to allow logging into the past or future (#1682)
+  * Added `Logger::useLoggingLoopDetection` to allow disabling cyclic logging detection in concurrent frameworks (#1681)
+  * Fixed handling of fatal errors if callPrevious is disabled in ErrorHandler (#1670)
+  * Marked the reusable `Monolog\Test\TestCase` class as `@internal` to make sure PHPStorm does not show it above PHPUnit, you may still use it to test your own handlers/etc though (#1677)
+  * Fixed RotatingFileHandler issue when the date format contained slashes (#1671)
+
+### 2.6.0 (2022-05-10)
+
+  * Deprecated `SwiftMailerHandler`, use `SymfonyMailerHandler` instead
+  * Added `SymfonyMailerHandler` (#1663)
+  * Added ElasticSearch 8.x support to the ElasticsearchHandler (#1662)
+  * Added a way to filter/modify stack traces in LineFormatter (#1665)
+  * Fixed UdpSocket not being able to reopen/reconnect after close()
+  * Fixed infinite loops if a Handler is triggering logging while handling log records
+
+### 2.5.0 (2022-04-08)
+
+  * Added `callType` to IntrospectionProcessor (#1612)
+  * Fixed AsMonologProcessor syntax to be compatible with PHP 7.2 (#1651)
+
+### 2.4.0 (2022-03-14)
+
+  * Added [`Monolog\LogRecord`](src/Monolog/LogRecord.php) interface that can be used to type-hint records like `array|\Monolog\LogRecord $record` to be forward compatible with the upcoming Monolog 3 changes
+  * Added `includeStacktraces` constructor params to LineFormatter & JsonFormatter (#1603)
+  * Added `persistent`, `timeout`, `writingTimeout`, `connectionTimeout`, `chunkSize` constructor params to SocketHandler and derivatives (#1600)
+  * Added `AsMonologProcessor` PHP attribute which can help autowiring / autoconfiguration of processors if frameworks / integrations decide to make use of it. This is useless when used purely with Monolog (#1637)
+  * Added support for keeping native BSON types as is in MongoDBFormatter (#1620)
+  * Added support for a `user_agent` key in WebProcessor, disabled by default but you can use it by configuring the $extraFields you want (#1613)
+  * Added support for username/userIcon in SlackWebhookHandler (#1617)
+  * Added extension points to BrowserConsoleHandler (#1593)
+  * Added record message/context/extra info to exceptions thrown when a StreamHandler cannot open its stream to avoid completely losing the data logged (#1630)
+  * Fixed error handler signature to accept a null $context which happens with internal PHP errors (#1614)
+  * Fixed a few setter methods not returning `self` (#1609)
+  * Fixed handling of records going over the max Telegram message length (#1616)
+
+### 2.3.5 (2021-10-01)
+
+  * Fixed regression in StreamHandler since 2.3.3 on systems with the memory_limit set to >=20GB (#1592)
+
+### 2.3.4 (2021-09-15)
+
+  * Fixed support for psr/log 3.x (#1589)
+
+### 2.3.3 (2021-09-14)
+
+  * Fixed memory usage when using StreamHandler and calling stream_get_contents on the resource you passed to it (#1578, #1577)
+  * Fixed support for psr/log 2.x (#1587)
+  * Fixed some type annotations
+
+### 2.3.2 (2021-07-23)
+
+  * Fixed compatibility with PHP 7.2 - 7.4 when experiencing PCRE errors (#1568)
+
+### 2.3.1 (2021-07-14)
+
+  * Fixed Utils::getClass handling of anonymous classes not being fully compatible with PHP 8 (#1563)
+  * Fixed some `@inheritDoc` annotations having the wrong case
+
+### 2.3.0 (2021-07-05)
+
+  * Added a ton of PHPStan type annotations as well as type aliases on Monolog\Logger for Record, Level and LevelName that you can import (#1557)
+  * Added ability to customize date format when using JsonFormatter (#1561)
+  * Fixed FilterHandler not calling reset on its internal handler when reset() is called on it (#1531)
+  * Fixed SyslogUdpHandler not setting the timezone correctly on DateTimeImmutable instances (#1540)
+  * Fixed StreamHandler thread safety - chunk size set to 2GB now to avoid interlacing when doing concurrent writes (#1553)
+
+### 2.2.0 (2020-12-14)
+
+  * Added JSON_PARTIAL_OUTPUT_ON_ERROR to default json encoding flags, to avoid dropping entire context data or even records due to an invalid subset of it somewhere
+  * Added setDateFormat to NormalizerFormatter (and Line/Json formatters by extension) to allow changing this after object creation
+  * Added RedisPubSubHandler to log records to a Redis channel using PUBLISH
+  * Added support for Elastica 7, and deprecated the $type argument of ElasticaFormatter which is not in use anymore as of Elastica 7
+  * Added support for millisecond write timeouts in SocketHandler, you can now pass floats to setWritingTimeout, e.g. 0.2 is 200ms
+  * Added support for unix sockets in SyslogUdpHandler (set $port to 0 to make the $host a unix socket)
+  * Added handleBatch support for TelegramBotHandler
+  * Added RFC5424e extended date format including milliseconds to SyslogUdpHandler
+  * Added support for configuring handlers with numeric level values in strings (coming from e.g. env vars)
+  * Fixed Wildfire/FirePHP/ChromePHP handling of unicode characters
+  * Fixed PHP 8 issues in SyslogUdpHandler
+  * Fixed internal type error when mbstring is missing
+
+### 2.1.1 (2020-07-23)
+
+  * Fixed removing of json encoding options
+  * Fixed type hint of $level not accepting strings in SendGridHandler and OverflowHandler
+  * Fixed SwiftMailerHandler not accepting email templates with an empty subject
+  * Fixed array access on null in RavenHandler
+  * Fixed unique_id in WebProcessor not being disableable
+
+### 2.1.0 (2020-05-22)
+
+  * Added `JSON_INVALID_UTF8_SUBSTITUTE` to default json flags, so that invalid UTF8 characters now get converted to [�](https://en.wikipedia.org/wiki/Specials_(Unicode_block)#Replacement_character) instead of being converted from ISO-8859-15 to UTF8 as it was before, which was hardly a comprehensive solution
+  * Added `$ignoreEmptyContextAndExtra` option to JsonFormatter to skip empty context/extra entirely from the output
+  * Added `$parseMode`, `$disableWebPagePreview` and `$disableNotification` options to TelegramBotHandler
+  * Added tentative support for PHP 8
+  * NormalizerFormatter::addJsonEncodeOption and removeJsonEncodeOption are now public to allow modifying default json flags
+  * Fixed GitProcessor type error when there is no git repo present
+  * Fixed normalization of SoapFault objects containing deeply nested objects as "detail"
+  * Fixed support for relative paths in RotatingFileHandler
+
+### 2.0.2 (2019-12-20)
+
+  * Fixed ElasticsearchHandler swallowing exceptions details when failing to index log records
+  * Fixed normalization of SoapFault objects containing non-strings as "detail" in LineFormatter
+  * Fixed formatting of resources in JsonFormatter
+  * Fixed RedisHandler failing to use MULTI properly when passed a proxied Redis instance (e.g. in Symfony with lazy services)
+  * Fixed FilterHandler triggering a notice when handleBatch was filtering all records passed to it
+  * Fixed Turkish locale messing up the conversion of level names to their constant values
+
+### 2.0.1 (2019-11-13)
+
+  * Fixed normalization of Traversables to avoid traversing them as not all of them are rewindable
+  * Fixed setFormatter/getFormatter to forward to the nested handler in FilterHandler, FingersCrossedHandler, BufferHandler, OverflowHandler and SamplingHandler
+  * Fixed BrowserConsoleHandler formatting when using multiple styles
+  * Fixed normalization of exception codes to be always integers even for PDOException which have them as numeric strings
+  * Fixed normalization of SoapFault objects containing non-strings as "detail"
+  * Fixed json encoding across all handlers to always attempt recovery of non-UTF-8 strings instead of failing the whole encoding
+  * Fixed ChromePHPHandler to avoid sending more data than latest Chrome versions allow in headers (4KB down from 256KB).
+  * Fixed type error in BrowserConsoleHandler when the context array of log records was not associative.
+
+### 2.0.0 (2019-08-30)
+
+  * BC Break: This is a major release, see [UPGRADE.md](UPGRADE.md) for details if you are coming from a 1.x release
+  * BC Break: Logger methods log/debug/info/notice/warning/error/critical/alert/emergency now have explicit void return types
+  * Added FallbackGroupHandler which works like the WhatFailureGroupHandler but stops dispatching log records as soon as one handler accepted it
+  * Fixed support for UTF-8 when cutting strings to avoid cutting a multibyte-character in half
+  * Fixed normalizers handling of exception backtraces to avoid serializing arguments in some cases
+  * Fixed date timezone handling in SyslogUdpHandler
+
+### 2.0.0-beta2 (2019-07-06)
+
+  * BC Break: This is a major release, see [UPGRADE.md](UPGRADE.md) for details if you are coming from a 1.x release
+  * BC Break: PHP 7.2 is now the minimum required PHP version.
+  * BC Break: Removed SlackbotHandler, RavenHandler and HipChatHandler, see [UPGRADE.md](UPGRADE.md) for details
+  * Added OverflowHandler which will only flush log records to its nested handler when reaching a certain amount of logs (i.e. only pass through when things go really bad)
+  * Added TelegramBotHandler to log records to a [Telegram](https://core.telegram.org/bots/api) bot account
+  * Added support for JsonSerializable when normalizing exceptions
+  * Added support for RFC3164 (outdated BSD syslog protocol) to SyslogUdpHandler
+  * Added SoapFault details to formatted exceptions
+  * Fixed DeduplicationHandler silently failing to start when file could not be opened
+  * Fixed issue in GroupHandler and WhatFailureGroupHandler where setting multiple processors would duplicate records
+  * Fixed GelfFormatter losing some data when one attachment was too long
+  * Fixed issue in SignalHandler restarting syscalls functionality
+  * Improved performance of LogglyHandler when sending multiple logs in a single request
+
+### 2.0.0-beta1 (2018-12-08)
+
+  * BC Break: This is a major release, see [UPGRADE.md](UPGRADE.md) for details if you are coming from a 1.x release
+  * BC Break: PHP 7.1 is now the minimum required PHP version.
+  * BC Break: Quite a few interface changes, only relevant if you implemented your own handlers/processors/formatters
+  * BC Break: Removed non-PSR-3 methods to add records, all the `add*` (e.g. `addWarning`) methods as well as `emerg`, `crit`, `err` and `warn`
+  * BC Break: The record timezone is now set per Logger instance and not statically anymore
+  * BC Break: There is no more default handler configured on empty Logger instances
+  * BC Break: ElasticSearchHandler renamed to ElasticaHandler
+  * BC Break: Various handler-specific breaks, see [UPGRADE.md](UPGRADE.md) for details
+  * Added scalar type hints and return hints in all the places it was possible. Switched strict_types on for more reliability.
+  * Added DateTimeImmutable support, all record datetime are now immutable, and will toString/json serialize with the correct date format, including microseconds (unless disabled)
+  * Added timezone and microseconds to the default date format
+  * Added SendGridHandler to use the SendGrid API to send emails
+  * Added LogmaticHandler to use the Logmatic.io API to store log records
+  * Added SqsHandler to send log records to an AWS SQS queue
+  * Added ElasticsearchHandler to send records via the official ES library. Elastica users should now use ElasticaHandler instead of ElasticSearchHandler
+  * Added NoopHandler which is similar to the NullHandle but does not prevent the bubbling of log records to handlers further down the configuration, useful for temporarily disabling a handler in configuration files
+  * Added ProcessHandler to write log output to the STDIN of a given process
+  * Added HostnameProcessor that adds the machine's hostname to log records
+  * Added a `$dateFormat` option to the PsrLogMessageProcessor which lets you format DateTime instances nicely
+  * Added support for the PHP 7.x `mongodb` extension in the MongoDBHandler
+  * Fixed many minor issues in various handlers, and probably added a few regressions too
+
+### 1.26.1 (2021-05-28)
+
+  * Fixed PHP 8.1 deprecation warning
+
+### 1.26.0 (2020-12-14)
+
+  * Added $dateFormat and $removeUsedContextFields arguments to PsrLogMessageProcessor (backport from 2.x)
+
+### 1.25.5 (2020-07-23)
+
+  * Fixed array access on null in RavenHandler
+  * Fixed unique_id in WebProcessor not being disableable
+
+### 1.25.4 (2020-05-22)
+
+  * Fixed GitProcessor type error when there is no git repo present
+  * Fixed normalization of SoapFault objects containing deeply nested objects as "detail"
+  * Fixed support for relative paths in RotatingFileHandler
+
+### 1.25.3 (2019-12-20)
+
+  * Fixed formatting of resources in JsonFormatter
+  * Fixed RedisHandler failing to use MULTI properly when passed a proxied Redis instance (e.g. in Symfony with lazy services)
+  * Fixed FilterHandler triggering a notice when handleBatch was filtering all records passed to it
+  * Fixed Turkish locale messing up the conversion of level names to their constant values
+
+### 1.25.2 (2019-11-13)
+
+  * Fixed normalization of Traversables to avoid traversing them as not all of them are rewindable
+  * Fixed setFormatter/getFormatter to forward to the nested handler in FilterHandler, FingersCrossedHandler, BufferHandler and SamplingHandler
+  * Fixed BrowserConsoleHandler formatting when using multiple styles
+  * Fixed normalization of exception codes to be always integers even for PDOException which have them as numeric strings
+  * Fixed normalization of SoapFault objects containing non-strings as "detail"
+  * Fixed json encoding across all handlers to always attempt recovery of non-UTF-8 strings instead of failing the whole encoding
+
+### 1.25.1 (2019-09-06)
+
+  * Fixed forward-compatible interfaces to be compatible with Monolog 1.x too.
+
+### 1.25.0 (2019-09-06)
+
+  * Deprecated SlackbotHandler, use SlackWebhookHandler or SlackHandler instead
+  * Deprecated RavenHandler, use sentry/sentry 2.x and their Sentry\Monolog\Handler instead
+  * Deprecated HipChatHandler, migrate to Slack and use SlackWebhookHandler or SlackHandler instead
+  * Added forward-compatible interfaces and traits FormattableHandlerInterface, FormattableHandlerTrait, ProcessableHandlerInterface, ProcessableHandlerTrait. If you use modern PHP and want to make code compatible with Monolog 1 and 2 this can help. You will have to require at least Monolog 1.25 though.
+  * Added support for RFC3164 (outdated BSD syslog protocol) to SyslogUdpHandler
+  * Fixed issue in GroupHandler and WhatFailureGroupHandler where setting multiple processors would duplicate records
+  * Fixed issue in SignalHandler restarting syscalls functionality
+  * Fixed normalizers handling of exception backtraces to avoid serializing arguments in some cases
+  * Fixed ZendMonitorHandler to work with the latest Zend Server versions
+  * Fixed ChromePHPHandler to avoid sending more data than latest Chrome versions allow in headers (4KB down from 256KB).
+
+### 1.24.0 (2018-11-05)
+
+  * BC Notice: If you are extending any of the Monolog's Formatters' `normalize` method, make sure you add the new `$depth = 0` argument to your function signature to avoid strict PHP warnings.
+  * Added a `ResettableInterface` in order to reset/reset/clear/flush handlers and processors
+  * Added a `ProcessorInterface` as an optional way to label a class as being a processor (mostly useful for autowiring dependency containers)
+  * Added a way to log signals being received using Monolog\SignalHandler
+  * Added ability to customize error handling at the Logger level using Logger::setExceptionHandler
+  * Added InsightOpsHandler to migrate users of the LogEntriesHandler
+  * Added protection to NormalizerFormatter against circular and very deep structures, it now stops normalizing at a depth of 9
+  * Added capture of stack traces to ErrorHandler when logging PHP errors
+  * Added RavenHandler support for a `contexts` context or extra key to forward that to Sentry's contexts
+  * Added forwarding of context info to FluentdFormatter
+  * Added SocketHandler::setChunkSize to override the default chunk size in case you must send large log lines to rsyslog for example
+  * Added ability to extend/override BrowserConsoleHandler
+  * Added SlackWebhookHandler::getWebhookUrl and SlackHandler::getToken to enable class extensibility
+  * Added SwiftMailerHandler::getSubjectFormatter to enable class extensibility
+  * Dropped official support for HHVM in test builds
+  * Fixed normalization of exception traces when call_user_func is used to avoid serializing objects and the data they contain
+  * Fixed naming of fields in Slack handler, all field names are now capitalized in all cases
+  * Fixed HipChatHandler bug where slack dropped messages randomly
+  * Fixed normalization of objects in Slack handlers
+  * Fixed support for PHP7's Throwable in NewRelicHandler
+  * Fixed race bug when StreamHandler sometimes incorrectly reported it failed to create a directory
+  * Fixed table row styling issues in HtmlFormatter
+  * Fixed RavenHandler dropping the message when logging exception
+  * Fixed WhatFailureGroupHandler skipping processors when using handleBatch
+    and implement it where possible
+  * Fixed display of anonymous class names
+
+### 1.23.0 (2017-06-19)
+
+  * Improved SyslogUdpHandler's support for RFC5424 and added optional `$ident` argument
+  * Fixed GelfHandler truncation to be per field and not per message
+  * Fixed compatibility issue with PHP <5.3.6
+  * Fixed support for headless Chrome in ChromePHPHandler
+  * Fixed support for latest Aws SDK in DynamoDbHandler
+  * Fixed support for SwiftMailer 6.0+ in SwiftMailerHandler
+
+### 1.22.1 (2017-03-13)
+
+  * Fixed lots of minor issues in the new Slack integrations
+  * Fixed support for allowInlineLineBreaks in LineFormatter when formatting exception backtraces
+
+### 1.22.0 (2016-11-26)
+
+  * Added SlackbotHandler and SlackWebhookHandler to set up Slack integration more easily
+  * Added MercurialProcessor to add mercurial revision and branch names to log records
+  * Added support for AWS SDK v3 in DynamoDbHandler
+  * Fixed fatal errors occurring when normalizing generators that have been fully consumed
+  * Fixed RollbarHandler to include a level (rollbar level), monolog_level (original name), channel and datetime (unix)
+  * Fixed RollbarHandler not flushing records automatically, calling close() explicitly is not necessary anymore
+  * Fixed SyslogUdpHandler to avoid sending empty frames
+  * Fixed a few PHP 7.0 and 7.1 compatibility issues
+
+### 1.21.0 (2016-07-29)
+
+  * Break: Reverted the addition of $context when the ErrorHandler handles regular php errors from 1.20.0 as it was causing issues
+  * Added support for more formats in RotatingFileHandler::setFilenameFormat as long as they have Y, m and d in order
+  * Added ability to format the main line of text the SlackHandler sends by explicitly setting a formatter on the handler
+  * Added information about SoapFault instances in NormalizerFormatter
+  * Added $handleOnlyReportedErrors option on ErrorHandler::registerErrorHandler (default true) to allow logging of all errors no matter the error_reporting level
+
+### 1.20.0 (2016-07-02)
+
+  * Added FingersCrossedHandler::activate() to manually trigger the handler regardless of the activation policy
+  * Added StreamHandler::getUrl to retrieve the stream's URL
+  * Added ability to override addRow/addTitle in HtmlFormatter
+  * Added the $context to context information when the ErrorHandler handles a regular php error
+  * Deprecated RotatingFileHandler::setFilenameFormat to only support 3 formats: Y, Y-m and Y-m-d
+  * Fixed WhatFailureGroupHandler to work with PHP7 throwables
+  * Fixed a few minor bugs
+
+### 1.19.0 (2016-04-12)
+
+  * Break: StreamHandler will not close streams automatically that it does not own. If you pass in a stream (not a path/url), then it will not close it for you. You can retrieve those using getStream() if needed
+  * Added DeduplicationHandler to remove duplicate records from notifications across multiple requests, useful for email or other notifications on errors
+  * Added ability to use `%message%` and other LineFormatter replacements in the subject line of emails sent with NativeMailHandler and SwiftMailerHandler
+  * Fixed HipChatHandler handling of long messages
+
+### 1.18.2 (2016-04-02)
+
+  * Fixed ElasticaFormatter to use more precise dates
+  * Fixed GelfMessageFormatter sending too long messages
+
+### 1.18.1 (2016-03-13)
+
+  * Fixed SlackHandler bug where slack dropped messages randomly
+  * Fixed RedisHandler issue when using with the PHPRedis extension
+  * Fixed AmqpHandler content-type being incorrectly set when using with the AMQP extension
+  * Fixed BrowserConsoleHandler regression
+
+### 1.18.0 (2016-03-01)
+
+  * Added optional reduction of timestamp precision via `Logger->useMicrosecondTimestamps(false)`, disabling it gets you a bit of performance boost but reduces the precision to the second instead of microsecond
+  * Added possibility to skip some extra stack frames in IntrospectionProcessor if you have some library wrapping Monolog that is always adding frames
+  * Added `Logger->withName` to clone a logger (keeping all handlers) with a new name
+  * Added FluentdFormatter for the Fluentd unix socket protocol
+  * Added HandlerWrapper base class to ease the creation of handler wrappers, just extend it and override as needed
+  * Added support for replacing context sub-keys using `%context.*%` in LineFormatter
+  * Added support for `payload` context value in RollbarHandler
+  * Added setRelease to RavenHandler to describe the application version, sent with every log
+  * Added support for `fingerprint` context value in RavenHandler
+  * Fixed JSON encoding errors that would gobble up the whole log record, we now handle those more gracefully by dropping chars as needed
+  * Fixed write timeouts in SocketHandler and derivatives, set to 10sec by default, lower it with `setWritingTimeout()`
+  * Fixed PHP7 compatibility with regard to Exception/Throwable handling in a few places
+
+### 1.17.2 (2015-10-14)
+
+  * Fixed ErrorHandler compatibility with non-Monolog PSR-3 loggers
+  * Fixed SlackHandler handling to use slack functionalities better
+  * Fixed SwiftMailerHandler bug when sending multiple emails they all had the same id
+  * Fixed 5.3 compatibility regression
+
+### 1.17.1 (2015-08-31)
+
+  * Fixed RollbarHandler triggering PHP notices
+
+### 1.17.0 (2015-08-30)
+
+  * Added support for `checksum` and `release` context/extra values in RavenHandler
+  * Added better support for exceptions in RollbarHandler
+  * Added UidProcessor::getUid
+  * Added support for showing the resource type in NormalizedFormatter
+  * Fixed IntrospectionProcessor triggering PHP notices
+
+### 1.16.0 (2015-08-09)
+
+  * Added IFTTTHandler to notify ifttt.com triggers
+  * Added Logger::setHandlers() to allow setting/replacing all handlers
+  * Added $capSize in RedisHandler to cap the log size
+  * Fixed StreamHandler creation of directory to only trigger when the first log write happens
+  * Fixed bug in the handling of curl failures
+  * Fixed duplicate logging of fatal errors when both error and fatal error handlers are registered in monolog's ErrorHandler
+  * Fixed missing fatal errors records with handlers that need to be closed to flush log records
+  * Fixed TagProcessor::addTags support for associative arrays
+
+### 1.15.0 (2015-07-12)
+
+  * Added addTags and setTags methods to change a TagProcessor
+  * Added automatic creation of directories if they are missing for a StreamHandler to open a log file
+  * Added retry functionality to Loggly, Cube and Mandrill handlers so they retry up to 5 times in case of network failure
+  * Fixed process exit code being incorrectly reset to 0 if ErrorHandler::registerExceptionHandler was used
+  * Fixed HTML/JS escaping in BrowserConsoleHandler
+  * Fixed JSON encoding errors being silently suppressed (PHP 5.5+ only)
+
+### 1.14.0 (2015-06-19)
+
+  * Added PHPConsoleHandler to send record to Chrome's PHP Console extension and library
+  * Added support for objects implementing __toString in the NormalizerFormatter
+  * Added support for HipChat's v2 API in HipChatHandler
+  * Added Logger::setTimezone() to initialize the timezone monolog should use in case date.timezone isn't correct for your app
+  * Added an option to send formatted message instead of the raw record on PushoverHandler via ->useFormattedMessage(true)
+  * Fixed curl errors being silently suppressed
+
+### 1.13.1 (2015-03-09)
+
+  * Fixed regression in HipChat requiring a new token to be created
+
+### 1.13.0 (2015-03-05)
+
+  * Added Registry::hasLogger to check for the presence of a logger instance
+  * Added context.user support to RavenHandler
+  * Added HipChat API v2 support in the HipChatHandler
+  * Added NativeMailerHandler::addParameter to pass params to the mail() process
+  * Added context data to SlackHandler when $includeContextAndExtra is true
+  * Added ability to customize the Swift_Message per-email in SwiftMailerHandler
+  * Fixed SwiftMailerHandler to lazily create message instances if a callback is provided
+  * Fixed serialization of INF and NaN values in Normalizer and LineFormatter
+
+### 1.12.0 (2014-12-29)
+
+  * Break: HandlerInterface::isHandling now receives a partial record containing only a level key. This was always the intent and does not break any Monolog handler but is strictly speaking a BC break and you should check if you relied on any other field in your own handlers.
+  * Added PsrHandler to forward records to another PSR-3 logger
+  * Added SamplingHandler to wrap around a handler and include only every Nth record
+  * Added MongoDBFormatter to support better storage with MongoDBHandler (it must be enabled manually for now)
+  * Added exception codes in the output of most formatters
+  * Added LineFormatter::includeStacktraces to enable exception stack traces in logs (uses more than one line)
+  * Added $useShortAttachment to SlackHandler to minify attachment size and $includeExtra to append extra data
+  * Added $host to HipChatHandler for users of private instances
+  * Added $transactionName to NewRelicHandler and support for a transaction_name context value
+  * Fixed MandrillHandler to avoid outputting API call responses
+  * Fixed some non-standard behaviors in SyslogUdpHandler
+
+### 1.11.0 (2014-09-30)
+
+  * Break: The NewRelicHandler extra and context data are now prefixed with extra_ and context_ to avoid clashes. Watch out if you have scripts reading those from the API and rely on names
+  * Added WhatFailureGroupHandler to suppress any exception coming from the wrapped handlers and avoid chain failures if a logging service fails
+  * Added MandrillHandler to send emails via the Mandrillapp.com API
+  * Added SlackHandler to log records to a Slack.com account
+  * Added FleepHookHandler to log records to a Fleep.io account
+  * Added LogglyHandler::addTag to allow adding tags to an existing handler
+  * Added $ignoreEmptyContextAndExtra to LineFormatter to avoid empty [] at the end
+  * Added $useLocking to StreamHandler and RotatingFileHandler to enable flock() while writing
+  * Added support for PhpAmqpLib in the AmqpHandler
+  * Added FingersCrossedHandler::clear and BufferHandler::clear to reset them between batches in long running jobs
+  * Added support for adding extra fields from $_SERVER in the WebProcessor
+  * Fixed support for non-string values in PrsLogMessageProcessor
+  * Fixed SwiftMailer messages being sent with the wrong date in long running scripts
+  * Fixed minor PHP 5.6 compatibility issues
+  * Fixed BufferHandler::close being called twice
+
+### 1.10.0 (2014-06-04)
+
+  * Added Logger::getHandlers() and Logger::getProcessors() methods
+  * Added $passthruLevel argument to FingersCrossedHandler to let it always pass some records through even if the trigger level is not reached
+  * Added support for extra data in NewRelicHandler
+  * Added $expandNewlines flag to the ErrorLogHandler to create multiple log entries when a message has multiple lines
+
+### 1.9.1 (2014-04-24)
+
+  * Fixed regression in RotatingFileHandler file permissions
+  * Fixed initialization of the BufferHandler to make sure it gets flushed after receiving records
+  * Fixed ChromePHPHandler and FirePHPHandler's activation strategies to be more conservative
+
+### 1.9.0 (2014-04-20)
+
+  * Added LogEntriesHandler to send logs to a LogEntries account
+  * Added $filePermissions to tweak file mode on StreamHandler and RotatingFileHandler
+  * Added $useFormatting flag to MemoryProcessor to make it send raw data in bytes
+  * Added support for table formatting in FirePHPHandler via the table context key
+  * Added a TagProcessor to add tags to records, and support for tags in RavenHandler
+  * Added $appendNewline flag to the JsonFormatter to enable using it when logging to files
+  * Added sound support to the PushoverHandler
+  * Fixed multi-threading support in StreamHandler
+  * Fixed empty headers issue when ChromePHPHandler received no records
+  * Fixed default format of the ErrorLogHandler
+
+### 1.8.0 (2014-03-23)
+
+  * Break: the LineFormatter now strips newlines by default because this was a bug, set $allowInlineLineBreaks to true if you need them
+  * Added BrowserConsoleHandler to send logs to any browser's console via console.log() injection in the output
+  * Added FilterHandler to filter records and only allow those of a given list of levels through to the wrapped handler
+  * Added FlowdockHandler to send logs to a Flowdock account
+  * Added RollbarHandler to send logs to a Rollbar account
+  * Added HtmlFormatter to send prettier log emails with colors for each log level
+  * Added GitProcessor to add the current branch/commit to extra record data
+  * Added a Monolog\Registry class to allow easier global access to pre-configured loggers
+  * Added support for the new official graylog2/gelf-php lib for GelfHandler, upgrade if you can by replacing the mlehner/gelf-php requirement
+  * Added support for HHVM
+  * Added support for Loggly batch uploads
+  * Added support for tweaking the content type and encoding in NativeMailerHandler
+  * Added $skipClassesPartials to tweak the ignored classes in the IntrospectionProcessor
+  * Fixed batch request support in GelfHandler
+
+### 1.7.0 (2013-11-14)
+
+  * Added ElasticSearchHandler to send logs to an Elastic Search server
+  * Added DynamoDbHandler and ScalarFormatter to send logs to Amazon's Dynamo DB
+  * Added SyslogUdpHandler to send logs to a remote syslogd server
+  * Added LogglyHandler to send logs to a Loggly account
+  * Added $level to IntrospectionProcessor so it only adds backtraces when needed
+  * Added $version to LogstashFormatter to allow using the new v1 Logstash format
+  * Added $appName to NewRelicHandler
+  * Added configuration of Pushover notification retries/expiry
+  * Added $maxColumnWidth to NativeMailerHandler to change the 70 chars default
+  * Added chainability to most setters for all handlers
+  * Fixed RavenHandler batch processing so it takes the message from the record with highest priority
+  * Fixed HipChatHandler batch processing so it sends all messages at once
+  * Fixed issues with eAccelerator
+  * Fixed and improved many small things
+
+### 1.6.0 (2013-07-29)
+
+  * Added HipChatHandler to send logs to a HipChat chat room
+  * Added ErrorLogHandler to send logs to PHP's error_log function
+  * Added NewRelicHandler to send logs to NewRelic's service
+  * Added Monolog\ErrorHandler helper class to register a Logger as exception/error/fatal handler
+  * Added ChannelLevelActivationStrategy for the FingersCrossedHandler to customize levels by channel
+  * Added stack traces output when normalizing exceptions (json output & co)
+  * Added Monolog\Logger::API constant (currently 1)
+  * Added support for ChromePHP's v4.0 extension
+  * Added support for message priorities in PushoverHandler, see $highPriorityLevel and $emergencyLevel
+  * Added support for sending messages to multiple users at once with the PushoverHandler
+  * Fixed RavenHandler's support for batch sending of messages (when behind a Buffer or FingersCrossedHandler)
+  * Fixed normalization of Traversables with very large data sets, only the first 1000 items are shown now
+  * Fixed issue in RotatingFileHandler when an open_basedir restriction is active
+  * Fixed minor issues in RavenHandler and bumped the API to Raven 0.5.0
+  * Fixed SyslogHandler issue when many were used concurrently with different facilities
+
+### 1.5.0 (2013-04-23)
+
+  * Added ProcessIdProcessor to inject the PID in log records
+  * Added UidProcessor to inject a unique identifier to all log records of one request/run
+  * Added support for previous exceptions in the LineFormatter exception serialization
+  * Added Monolog\Logger::getLevels() to get all available levels
+  * Fixed ChromePHPHandler so it avoids sending headers larger than Chrome can handle
+
+### 1.4.1 (2013-04-01)
+
+  * Fixed exception formatting in the LineFormatter to be more minimalistic
+  * Fixed RavenHandler's handling of context/extra data, requires Raven client >0.1.0
+  * Fixed log rotation in RotatingFileHandler to work with long running scripts spanning multiple days
+  * Fixed WebProcessor array access so it checks for data presence
+  * Fixed Buffer, Group and FingersCrossed handlers to make use of their processors
+
+### 1.4.0 (2013-02-13)
+
+  * Added RedisHandler to log to Redis via the Predis library or the phpredis extension
+  * Added ZendMonitorHandler to log to the Zend Server monitor
+  * Added the possibility to pass arrays of handlers and processors directly in the Logger constructor
+  * Added `$useSSL` option to the PushoverHandler which is enabled by default
+  * Fixed ChromePHPHandler and FirePHPHandler issue when multiple instances are used simultaneously
+  * Fixed header injection capability in the NativeMailHandler
+
+### 1.3.1 (2013-01-11)
+
+  * Fixed LogstashFormatter to be usable with stream handlers
+  * Fixed GelfMessageFormatter levels on Windows
+
+### 1.3.0 (2013-01-08)
+
+  * Added PSR-3 compliance, the `Monolog\Logger` class is now an instance of `Psr\Log\LoggerInterface`
+  * Added PsrLogMessageProcessor that you can selectively enable for full PSR-3 compliance
+  * Added LogstashFormatter (combine with SocketHandler or StreamHandler to send logs to Logstash)
+  * Added PushoverHandler to send mobile notifications
+  * Added CouchDBHandler and DoctrineCouchDBHandler
+  * Added RavenHandler to send data to Sentry servers
+  * Added support for the new MongoClient class in MongoDBHandler
+  * Added microsecond precision to log records' timestamps
+  * Added `$flushOnOverflow` param to BufferHandler to flush by batches instead of losing
+    the oldest entries
+  * Fixed normalization of objects with cyclic references
+
+### 1.2.1 (2012-08-29)
+
+  * Added new $logopts arg to SyslogHandler to provide custom openlog options
+  * Fixed fatal error in SyslogHandler
+
+### 1.2.0 (2012-08-18)
+
+  * Added AmqpHandler (for use with AMQP servers)
+  * Added CubeHandler
+  * Added NativeMailerHandler::addHeader() to send custom headers in mails
+  * Added the possibility to specify more than one recipient in NativeMailerHandler
+  * Added the possibility to specify float timeouts in SocketHandler
+  * Added NOTICE and EMERGENCY levels to conform with RFC 5424
+  * Fixed the log records to use the php default timezone instead of UTC
+  * Fixed BufferHandler not being flushed properly on PHP fatal errors
+  * Fixed normalization of exotic resource types
+  * Fixed the default format of the SyslogHandler to avoid duplicating datetimes in syslog
+
+### 1.1.0 (2012-04-23)
+
+  * Added Monolog\Logger::isHandling() to check if a handler will
+    handle the given log level
+  * Added ChromePHPHandler
+  * Added MongoDBHandler
+  * Added GelfHandler (for use with Graylog2 servers)
+  * Added SocketHandler (for use with syslog-ng for example)
+  * Added NormalizerFormatter
+  * Added the possibility to change the activation strategy of the FingersCrossedHandler
+  * Added possibility to show microseconds in logs
+  * Added `server` and `referer` to WebProcessor output
+
+### 1.0.2 (2011-10-24)
+
+  * Fixed bug in IE with large response headers and FirePHPHandler
+
+### 1.0.1 (2011-08-25)
+
+  * Added MemoryPeakUsageProcessor and MemoryUsageProcessor
+  * Added Monolog\Logger::getName() to get a logger's channel name
+
+### 1.0.0 (2011-07-06)
+
+  * Added IntrospectionProcessor to get info from where the logger was called
+  * Fixed WebProcessor in CLI
+
+### 1.0.0-RC1 (2011-07-01)
+
+  * Initial release

+ 19 - 0
vendor/monolog/monolog/LICENSE

@@ -0,0 +1,19 @@
+Copyright (c) 2011-2020 Jordi Boggiano
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

+ 112 - 0
vendor/monolog/monolog/README.md

@@ -0,0 +1,112 @@
+# Monolog - Logging for PHP [![Continuous Integration](https://github.com/Seldaek/monolog/workflows/Continuous%20Integration/badge.svg?branch=main)](https://github.com/Seldaek/monolog/actions)
+
+[![Total Downloads](https://img.shields.io/packagist/dt/monolog/monolog.svg)](https://packagist.org/packages/monolog/monolog)
+[![Latest Stable Version](https://img.shields.io/packagist/v/monolog/monolog.svg)](https://packagist.org/packages/monolog/monolog)
+
+
+Monolog sends your logs to files, sockets, inboxes, databases and various
+web services. See the complete list of handlers below. Special handlers
+allow you to build advanced logging strategies.
+
+This library implements the [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md)
+interface that you can type-hint against in your own libraries to keep
+a maximum of interoperability. You can also use it in your applications to
+make sure you can always use another compatible logger at a later time.
+As of 1.11.0 Monolog public APIs will also accept PSR-3 log levels.
+Internally Monolog still uses its own level scheme since it predates PSR-3.
+
+## Installation
+
+Install the latest version with
+
+```bash
+$ composer require monolog/monolog
+```
+
+## Basic Usage
+
+```php
+<?php
+
+use Monolog\Logger;
+use Monolog\Handler\StreamHandler;
+
+// create a log channel
+$log = new Logger('name');
+$log->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING));
+
+// add records to the log
+$log->warning('Foo');
+$log->error('Bar');
+```
+
+## Documentation
+
+- [Usage Instructions](doc/01-usage.md)
+- [Handlers, Formatters and Processors](doc/02-handlers-formatters-processors.md)
+- [Utility Classes](doc/03-utilities.md)
+- [Extending Monolog](doc/04-extending.md)
+- [Log Record Structure](doc/message-structure.md)
+
+## Support Monolog Financially
+
+Get supported Monolog and help fund the project with the [Tidelift Subscription](https://tidelift.com/subscription/pkg/packagist-monolog-monolog?utm_source=packagist-monolog-monolog&utm_medium=referral&utm_campaign=enterprise) or via [GitHub sponsorship](https://github.com/sponsors/Seldaek). 
+
+Tidelift delivers commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use.
+
+## Third Party Packages
+
+Third party handlers, formatters and processors are
+[listed in the wiki](https://github.com/Seldaek/monolog/wiki/Third-Party-Packages). You
+can also add your own there if you publish one.
+
+## About
+
+### Requirements
+
+- Monolog `^2.0` works with PHP 7.2 or above, use Monolog `^1.25` for PHP 5.3+ support.
+
+### Support
+
+Monolog 1.x support is somewhat limited at this point and only important fixes will be done. You should migrate to Monolog 2 where possible to benefit from all the latest features and fixes.
+
+### Submitting bugs and feature requests
+
+Bugs and feature request are tracked on [GitHub](https://github.com/Seldaek/monolog/issues)
+
+### Framework Integrations
+
+- Frameworks and libraries using [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md)
+  can be used very easily with Monolog since it implements the interface.
+- [Symfony](http://symfony.com) comes out of the box with Monolog.
+- [Laravel](http://laravel.com/) comes out of the box with Monolog.
+- [Lumen](http://lumen.laravel.com/) comes out of the box with Monolog.
+- [PPI](https://github.com/ppi/framework) comes out of the box with Monolog.
+- [CakePHP](http://cakephp.org/) is usable with Monolog via the [cakephp-monolog](https://github.com/jadb/cakephp-monolog) plugin.
+- [Slim](http://www.slimframework.com/) is usable with Monolog via the [Slim-Monolog](https://github.com/Flynsarmy/Slim-Monolog) log writer.
+- [XOOPS 2.6](http://xoops.org/) comes out of the box with Monolog.
+- [Aura.Web_Project](https://github.com/auraphp/Aura.Web_Project) comes out of the box with Monolog.
+- [Nette Framework](http://nette.org/en/) is usable with Monolog via the [contributte/monolog](https://github.com/contributte/monolog) or [orisai/nette-monolog](https://github.com/orisai/nette-monolog) extensions.
+- [Proton Micro Framework](https://github.com/alexbilbie/Proton) comes out of the box with Monolog.
+- [FuelPHP](http://fuelphp.com/) comes out of the box with Monolog.
+- [Equip Framework](https://github.com/equip/framework) comes out of the box with Monolog.
+- [Yii 2](http://www.yiiframework.com/) is usable with Monolog via the [yii2-monolog](https://github.com/merorafael/yii2-monolog) or [yii2-psr-log-target](https://github.com/samdark/yii2-psr-log-target) plugins.
+- [Hawkbit Micro Framework](https://github.com/HawkBitPhp/hawkbit) comes out of the box with Monolog.
+- [SilverStripe 4](https://www.silverstripe.org/) comes out of the box with Monolog.
+- [Drupal](https://www.drupal.org/) is usable with Monolog via the [monolog](https://www.drupal.org/project/monolog) module.
+- [Aimeos ecommerce framework](https://aimeos.org/) is usable with Monolog via the [ai-monolog](https://github.com/aimeos/ai-monolog) extension.
+- [Magento](https://magento.com/) comes out of the box with Monolog.
+
+### Author
+
+Jordi Boggiano - <j.boggiano@seld.be> - <http://twitter.com/seldaek><br />
+See also the list of [contributors](https://github.com/Seldaek/monolog/contributors) who participated in this project.
+
+### License
+
+Monolog is licensed under the MIT License - see the [LICENSE](LICENSE) file for details
+
+### Acknowledgements
+
+This library is heavily inspired by Python's [Logbook](https://logbook.readthedocs.io/en/stable/)
+library, although most concepts have been adjusted to fit to the PHP world.

+ 72 - 0
vendor/monolog/monolog/UPGRADE.md

@@ -0,0 +1,72 @@
+### 2.0.0
+
+- `Monolog\Logger::API` can be used to distinguish between a Monolog `1` and `2`
+  install of Monolog when writing integration code.
+
+- Removed non-PSR-3 methods to add records, all the `add*` (e.g. `addWarning`)
+  methods as well as `emerg`, `crit`, `err` and `warn`.
+
+- DateTime are now formatted with a timezone and microseconds (unless disabled).
+  Various formatters and log output might be affected, which may mess with log parsing
+  in some cases.
+
+- The `datetime` in every record array is now a DateTimeImmutable, not that you
+  should have been modifying these anyway.
+
+- The timezone is now set per Logger instance and not statically, either
+  via ->setTimezone or passed in the constructor. Calls to Logger::setTimezone
+  should be converted.
+
+- `HandlerInterface` has been split off and two new interfaces now exist for
+  more granular controls: `ProcessableHandlerInterface` and
+  `FormattableHandlerInterface`. Handlers not extending `AbstractHandler`
+  should make sure to implement the relevant interfaces.
+
+- `HandlerInterface` now requires the `close` method to be implemented. This
+  only impacts you if you implement the interface yourself, but you can extend
+  the new `Monolog\Handler\Handler` base class too.
+
+- There is no more default handler configured on empty Logger instances, if
+  you were relying on that you will not get any output anymore, make sure to
+  configure the handler you need.
+
+#### LogglyFormatter
+
+- The records' `datetime` is not sent anymore. Only `timestamp` is sent to Loggly.
+
+#### AmqpHandler
+
+- Log levels are not shortened to 4 characters anymore. e.g. a warning record
+  will be sent using the `warning.channel` routing key instead of `warn.channel`
+  as in 1.x.
+- The exchange name does not default to 'log' anymore, and it is completely ignored
+  now for the AMQP extension users. Only PHPAmqpLib uses it if provided.
+
+#### RotatingFileHandler
+
+- The file name format must now contain `{date}` and the date format must be set
+  to one of the predefined FILE_PER_* constants to avoid issues with file rotation.
+  See `setFilenameFormat`.
+
+#### LogstashFormatter
+
+- Removed Logstash V0 support
+- Context/extra prefix has been removed in favor of letting users configure the exact key being sent
+- Context/extra data are now sent as an object instead of single keys
+
+#### HipChatHandler
+
+- Removed deprecated HipChat handler, migrate to Slack and use SlackWebhookHandler or SlackHandler instead
+
+#### SlackbotHandler
+
+- Removed deprecated SlackbotHandler handler, use SlackWebhookHandler or SlackHandler instead
+
+#### RavenHandler
+
+- Removed deprecated RavenHandler handler, use sentry/sentry 2.x and their Sentry\Monolog\Handler instead
+
+#### ElasticSearchHandler
+
+- As support for the official Elasticsearch library was added, the former ElasticSearchHandler has been
+  renamed to ElasticaHandler and the new one added as ElasticsearchHandler.

Vissa filer visades inte eftersom för många filer har ändrats