Bladeren bron

Merge branch 'new-version' into dev

# Conflicts:
#	console/controllers/ToolController.php
kevin_zhangl 2 jaren geleden
bovenliggende
commit
8f400149cf
82 gewijzigde bestanden met toevoegingen van 9449 en 4985 verwijderingen
  1. 10 0
      backendApi/config/menu.php
  2. 6 0
      backendApi/config/urlManagerRules.php
  3. 1 1
      backendApi/modules/v1/controllers/BaseController.php
  4. 51 0
      backendApi/modules/v1/controllers/ConfigController.php
  5. 91 0
      backendApi/modules/v1/controllers/ShopController.php
  6. 38 0
      backendApi/modules/v1/controllers/UserController.php
  7. 7 3
      backendApi/modules/v1/models/lists/bonus/FlowBalanceList.php
  8. 252 252
      backendApi/modules/v1/models/lists/bonus/FlowBonusList.php
  9. 5 1
      backendApi/modules/v1/models/lists/bonus/FlowExchangePointsList.php
  10. 212 208
      backendApi/modules/v1/models/lists/bonus/FlowReconsumePointsList.php
  11. 1 0
      backendApi/modules/v1/models/lists/log/AdminHandleList.php
  12. 7 7
      backendApi/modules/v1/models/lists/shop/GoodsList.php
  13. 59 2
      backendApi/modules/v1/models/lists/shop/OrderList.php
  14. 91 0
      backendApi/modules/v1/models/lists/shop/OrderPeriodAdjustList.php
  15. 102 0
      backendApi/modules/v1/models/lists/user/ChangeHighestEmpLevelList.php
  16. 5 1
      backendEle/package.json
  17. 292 269
      backendEle/src/router/index.js
  18. 119 0
      backendEle/src/views/config/user-online.vue
  19. 2 2
      backendEle/src/views/finance/change-balance-opt.vue
  20. 324 313
      backendEle/src/views/finance/withdraw.vue
  21. 5 9
      backendEle/src/views/shop/goods-add.vue
  22. 4 5
      backendEle/src/views/shop/index.vue
  23. 126 9
      backendEle/src/views/shop/order-list.vue
  24. 197 0
      backendEle/src/views/shop/order-period-adjust.vue
  25. 201 0
      backendEle/src/views/user/change-highest-emp-level-list.vue
  26. 4 4
      common/config/config-devlopment.php
  27. 4 4
      common/config/config-product.php
  28. 24 11
      common/config/main.php
  29. 21 0
      common/config/params.php
  30. 159 0
      common/helpers/IPay88.php
  31. 379 0
      common/helpers/Logistics.php
  32. 54 0
      common/helpers/Tool.php
  33. 854 853
      common/helpers/user/Balance.php
  34. 202 201
      common/helpers/user/Cash.php
  35. 10 0
      common/helpers/user/Info.php
  36. 97 0
      common/models/ApproachDecOrder.php
  37. 141 0
      common/models/ApproachOrder.php
  38. 71 0
      common/models/ApproachOrderCall.php
  39. 75 0
      common/models/ApproachOrderGoods.php
  40. 62 0
      common/models/HighestEmpLevelLog.php
  41. 49 0
      common/models/OrderPeriodAdjust.php
  42. 15 0
      common/models/Period.php
  43. 2 0
      common/models/ReceiveAddress.php
  44. 7 1
      common/models/ShopGoods.php
  45. 27 21
      common/models/Withdraw.php
  46. 101 0
      common/models/WstOrderCall.php
  47. 492 0
      common/models/forms/ApproachOrderForm.php
  48. 916 916
      common/models/forms/DeclarationForm.php
  49. 9 9
      common/models/forms/DeclarationUpgradeForm.php
  50. 146 0
      common/models/forms/HighestEmpLevelLogForm.php
  51. 22 14
      common/models/forms/OrderDeleteForm.php
  52. 10 12
      common/models/forms/OrderForm.php
  53. 152 0
      common/models/forms/OrderPeriodAdjustForm.php
  54. 7 3
      common/models/forms/ReceiveAddressForm.php
  55. 18 7
      common/models/forms/ShopGoodsForm.php
  56. 4 2
      common/models/forms/TransferForm.php
  57. 3 3
      common/models/forms/WithdrawForm.php
  58. 2 1
      composer.json
  59. 62 19
      console/controllers/ToolController.php
  60. 22 2
      frontendApi/config/params.php
  61. 6 1
      frontendApi/config/urlManagerRules.php
  62. 416 0
      frontendApi/modules/v1/components/IPay88.php
  63. 1037 1029
      frontendApi/modules/v1/controllers/BonusController.php
  64. 1 1
      frontendApi/modules/v1/controllers/ConfigController.php
  65. 328 22
      frontendApi/modules/v1/controllers/ShopController.php
  66. 1 1
      frontendEle/.gitignore
  67. 12 0
      frontendEle/src/router/index.js
  68. 10 0
      frontendEle/src/views/config/receive-address-edit.vue
  69. 2 1
      frontendEle/src/views/config/receive-address-list.vue
  70. 56 58
      frontendEle/src/views/finance/transfer-add.vue
  71. 47 10
      frontendEle/src/views/shop/index.vue
  72. 207 103
      frontendEle/src/views/shop/order-list.vue
  73. 462 0
      frontendEle/src/views/shop/order-overseas.vue
  74. 3 0
      frontendEle/src/views/shop/order.vue
  75. 259 260
      frontendEle/src/views/user/dec.vue
  76. 15 2
      vendor/autoload.php
  77. 27 14
      vendor/composer/ClassLoader.php
  78. 19 12
      vendor/composer/InstalledVersions.php
  79. 10 17
      vendor/composer/autoload_real.php
  80. 0 170
      vendor/composer/installed.json
  81. 94 113
      vendor/composer/installed.php
  82. 6 6
      vendor/yiisoft/yii2/web/ErrorHandler.php

+ 10 - 0
backendApi/config/menu.php

@@ -60,6 +60,9 @@ return [
             ['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,],
 
+            ['name'=>'订单期数调整', 'class'=>'', 'icon'=>'', 'controller'=>'shop', 'action'=>'order-period-adjust', 'routePath'=>'shop/order-period-adjust', 'show'=>1,],
+            ['name'=>'订单详情', 'class'=>'', 'icon'=>'', 'controller'=>'shop', 'action'=>'order-detail', 'routePath'=>'shop/order-detail', 'show'=>0,],
+            ['name'=>'期数检查', 'class'=>'', 'icon'=>'', 'controller'=>'shop', 'action'=>'period-inspect', 'routePath'=>'shop/period-inspect', 'show'=>0,],
         ]
     ],
     'user'=>[
@@ -142,6 +145,8 @@ return [
 //            ['name'=>'会员历史年度最高聘级表', 'class'=>'', 'icon'=>'', 'controller'=>'user', 'action'=>'year-highest-emp-lv', 'routePath'=>'user/year-highest-emp-lv', 'show'=>1,],
 //            ['name'=>'会员历史年度最高聘级表导出', 'class'=>'', 'icon'=>'', 'controller'=>'user', 'action'=>'user/year-highest-emp-lv-export', 'routePath'=>'user/user/year-highest-emp-lv-export', 'show'=>0,],
             //['name'=>'修改会员前台显示聘级', 'class'=>'', 'icon'=>'', 'controller'=>'user', 'action'=>'change-show-emp-level', 'routePath'=>'user/change-show-emp-level', 'show'=>1,],
+            ['name'=>'会员最高聘级调整', 'class'=>'', 'icon'=>'', 'controller'=>'user', 'action'=>'change-user-dec-level', 'routePath'=>'user/change-highest-emp-level-list', 'show'=>1,],
+            ['name'=>'修改会员最高聘级', 'class'=>'', 'icon'=>'', 'controller'=>'user', 'action'=>'change-user-dec-level', 'routePath'=>'user/change-highest-emp-level', 'show'=>0,],
         ]
     ],
     'atlas'=>[
@@ -334,6 +339,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,],
@@ -499,6 +508,7 @@ return [
             ['name'=>'编辑会员聘级', 'class'=>'', 'icon'=>'', 'controller'=>'config', 'action'=>'emp-level-edit', 'routePath'=>'config/emp-level-edit', 'show'=>0,],
             ['name'=>'报单中心级别配置', 'class'=>'', 'icon'=>'', 'controller'=>'config', 'action'=>'dec-role', 'routePath'=>'config/dec-role', 'show'=>1,],
             ['name'=>'编辑报单中心级别', 'class'=>'', 'icon'=>'', 'controller'=>'config', 'action'=>'dec-role-edit', 'routePath'=>'config/dec-role-edit', 'show'=>0,],
+            ['name'=>'用户在线统计', 'class'=>'', 'icon'=>'', 'controller'=>'config', 'action'=>'user-online', 'routePath'=>'config/user-online', 'show'=>1,],
         ],
     ],
 ];

+ 6 - 0
backendApi/config/urlManagerRules.php

@@ -66,6 +66,9 @@ return [
             'POST import-order-standard' => 'import-order-standard',
             'GET remain-pv' => 'remain-pv',
             'GET flow-remain-pv' => 'flow-remain-pv',
+            'GET,POST order-period-adjust' => 'order-period-adjust',
+            'GET order-detail' => 'order-detail',
+            'GET period-inspect' => 'period-inspect',
         ],
     ],
     [
@@ -167,6 +170,8 @@ return [
             'GET status-audit-export' => 'status-audit-export',
             'GET year-highest-emp-lv-export' => 'year-highest-emp-lv-export',
             'POST recharge-to-user' => 'recharge-to-user',
+            'GET change-highest-emp-level-list' => 'change-highest-emp-level-list',
+            'POST change-highest-emp-level' => 'change-highest-emp-level',
         ],
     ],
     [
@@ -296,6 +301,7 @@ return [
             'POST,GET sms' => 'sms',
             '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',

+ 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/ConfigController.php

@@ -9,6 +9,8 @@
 namespace backendApi\modules\v1\controllers;
 
 use backendApi\modules\v1\models\Admin;
+use backendApi\modules\v1\models\User;
+use common\components\Redis;
 use common\helpers\Cache;
 use common\helpers\Date;
 use common\helpers\Form;
@@ -824,6 +826,55 @@ class ConfigController extends BaseController {
         return static::notice('更新服务协议成功');
     }
 
+    /**
+     * 获取当前在线用户
+     * @return mixed
+     * @throws \yii\base\InvalidConfigException
+     * @throws \yii\web\HttpException
+     */
+    public function actionUserOnline() {
+        $params = Yii::$app->request->get();
+        $page = $params['page'];
+        $pageSize = $params['pageSize'];
+        $redisKey = $params['filterStatus'] == 1 ? 'user:timeOut' : 'admin:timeOut';
+        $redisKeyUserInfo = 'user:baseInfo';
+
+        $tokens = Yii::$app->tokenRedis->hgetall($redisKey);
+        $timeOut = Yii::$app->params['operationTimeOut'];
+        $currentTime = time();
+        $user_info = [];
+        if($tokens && is_array($tokens)){
+            foreach($tokens as $k=>$v){
+                //判断是否是hash的key
+                $last_time = Yii::$app->tokenRedis->hget($redisKey,$v);
+                if($last_time && ( $currentTime - $last_time < $timeOut )){
+                    if( $params['filterStatus'] == 1){
+                        $user_data = json_decode(Yii::$app->tokenRedis->hget($redisKeyUserInfo,$v),true);
+                        $user_info['list'][$k]['ID'] = $user_data['USER_NAME'];
+                        $user_info['list'][$k]['REAL_NAME'] = $user_data['REAL_NAME'];
+                        $user_info['list'][$k]['UPDATE_TIME'] = date('Y-m-d H:i:s',$last_time);
+                    } else {
+                        $user_data = User::find()->where(['ID'=>$v])->asArray()->one();
+                        $user_info['list'][$k]['ID'] = $user_data['ADMIN_NAME'];
+                        $user_info['list'][$k]['REAL_NAME'] = $user_data['REAL_NAME'];
+                        $user_info['list'][$k]['UPDATE_TIME'] = date('Y-m-d H:i:s',$last_time);
+                    }
+
+                }
+            }
+        }
+        if($user_info){
+            $user_info['list'] = array_values($user_info['list']);
+            $totalCount = count($user_info['list']);
+            $limit = ($page - 1) * $pageSize;
+            array_multisort(array_column($user_info['list'],'UPDATE_TIME'), SORT_DESC,$user_info['list']);
+            $user_info['list'] = array_slice($user_info['list'],$limit,$pageSize);
+            $user_info['totalCount'] = $totalCount;
+            $user_info['pageSize'] = $pageSize;
+        }
+        return static::notice($user_info);
+    }
+
     public static function actionInitRegionXls() {
         BaiduRegion::deleteAll();
         BaiduRegion::importXls(0,1000);

+ 91 - 0
backendApi/modules/v1/controllers/ShopController.php

@@ -14,6 +14,7 @@ use backendApi\modules\v1\models\lists\shop\DecOrderList;
 use backendApi\modules\v1\models\lists\shop\GoodsList;
 use backendApi\modules\v1\models\lists\shop\OrderDecList;
 use backendApi\modules\v1\models\lists\shop\OrderList;
+use backendApi\modules\v1\models\lists\shop\OrderPeriodAdjustList;
 use backendApi\modules\v1\models\lists\shop\OrderShopList;
 use backendApi\modules\v1\models\lists\shop\OrderStandardList;
 use backendApi\modules\v1\models\lists\shop\PackageList;
@@ -35,8 +36,11 @@ use common\models\forms\ExcelOrderShopForm;
 use common\models\forms\ExcelOrderStandardForm;
 use common\models\forms\OrderDeleteForm;
 use common\models\forms\OrderForm;
+use common\models\forms\OrderPeriodAdjustForm;
 use common\models\forms\ShopGoodsForm;
 use common\models\forms\UploadForm;
+use common\models\Order;
+use common\models\Period;
 use common\models\ShopGoods;
 use yii\web\UploadedFile;
 use yii\base\Exception;
@@ -364,9 +368,14 @@ class ShopController extends BaseController {
             'PERIOD_NUM'=> 'O.PERIOD_NUM',
             'CREATED_AT'=> 'O.CREATED_AT',
         ]);
+//        $condition = ' 1=1 ' . $filter['condition'];
+//        $params = $filter['params'];
+//        $condition .= $condition ? ' AND O.IS_DELETE=0' : ' O.IS_DELETE=0';
+
         $condition = $filter['condition'];
         $params = $filter['params'];
         $condition .= ' AND O.IS_DELETE=0';
+
         $listObj = new OrderList();
         $data = $listObj->getList(['condition'=>$condition, 'params'=>$params]);
         return static::notice($data);
@@ -399,7 +408,9 @@ class ShopController extends BaseController {
             'PERIOD_NUM'=> 'O.PERIOD_NUM',
             'CREATED_AT'=> 'O.CREATED_AT',
         ]);
+//        $filter['condition'] = !$filter['condition'] ? '1=1 AND O.IS_DELETE=0' : ('O.IS_DELETE=0 ' . $filter['condition']);
         $filter['condition'] .= ' AND O.IS_DELETE=0';
+
         $form = new ShopExportForm();
         $result = $form->run($filter, '订单列表');
         if (!$result) {
@@ -684,4 +695,84 @@ class ShopController extends BaseController {
         $data = $listObj->getList(['condition'=>$condition, 'params'=>$params]);
         return static::notice($data);
     }
+
+    /**
+     * 订单详情
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionOrderDetail()
+    {
+        $orderSn = \Yii::$app->request->get('orderSn');
+        $order = Order::findOneAsArray('SN=:SN', [':SN' => $orderSn]);
+        if (!$order) {
+            return static::notice('订单不存在', 400);
+        }
+        $order['ORDER_TYPE'] = $order['ORDER_TYPE'] === 'ZC' ? '首单' : '复消';
+        // 如果当前订单所在期数已挂网,则不可调整
+        $period = Period::getInfoByPeriodNum($order['PERIOD_NUM']);
+        if (!$period) {
+            return static::notice('期数无效', 400);
+        }
+        if ($period['IS_SENT'] > 0) {
+            return static::notice('订单已挂网', 400);
+        }
+        // 根据订单期数查询可调整期数
+        $availablePeriod = [];
+        if ($order['PERIOD_NUM']) {
+            $availablePeriod = Period::getPeriodList(+$order['PERIOD_NUM'] - 1);
+            foreach ($availablePeriod as $k => $item) {
+                $availablePeriod[$k]['disabled'] = (+$item['IS_SENT'] > 0) || ($order['PERIOD_NUM'] == $item['PERIOD_NUM']);
+            }
+        }
+
+        return static::notice(['order' => $order, 'availablePeriod' => $availablePeriod]);
+    }
+
+    /**
+     * 期数检查
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionPeriodInspect()
+    {
+        $modernPeriod = \Yii::$app->request->get('modernPeriod');
+        $period = Period::getInfoByPeriodNum($modernPeriod);
+        if (!$period) {
+            return static::notice('期数不存在', 400);
+        }
+        if ($period['IS_SENT'] > 0) {
+            return static::notice('调整后的期数已未挂网', 400);
+        }
+    }
+
+    /**
+     * 调整订单期数
+     * @return mixed
+     * @throws Exception
+     * @throws \yii\db\Exception
+     * @throws \yii\web\HttpException
+     */
+    public function actionOrderPeriodAdjust()
+    {
+        if (\Yii::$app->request->isPost) {
+            $formModel = new OrderPeriodAdjustForm();
+            $formModel->scenario = 'orderPeriodAdjust';
+            if ($formModel->load(\Yii::$app->request->post(), '') && $formModel->periodAdjust()) {
+                return static::notice('成功');
+            } else {
+                return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
+            }
+        } else {
+            $filter = $this->filterCondition([
+                'ORDER_SN' => 'P.ORDER_SN',
+                'ORIGIN_PERIOD'=> 'P.ORIGIN_PERIOD',
+                'MODERN_PERIOD'=> 'P.MODERN_PERIOD',
+                'CREATED_AT'=> 'P.CREATED_AT',
+            ]);
+            $listObj = new OrderPeriodAdjustList();
+            $data = $listObj->getList(['condition' => $filter['condition'], 'params' => $filter['params']]);
+            return static::notice($data);
+        }
+    }
 }

+ 38 - 0
backendApi/modules/v1/controllers/UserController.php

@@ -12,6 +12,8 @@ use backendApi\modules\v1\components\UserAuth;
 use backendApi\modules\v1\models\Admin;
 use backendApi\modules\v1\models\exportForms\UserExportForm;
 use backendApi\modules\v1\models\lists\user\BindList;
+use backendApi\modules\v1\models\lists\user\ChangeEmpLevelList;
+use backendApi\modules\v1\models\lists\user\ChangeHighestEmpLevelList;
 use backendApi\modules\v1\models\lists\user\DecLevelList;
 use backendApi\modules\v1\models\lists\user\GroupList;
 use backendApi\modules\v1\models\lists\user\IndexList;
@@ -37,6 +39,7 @@ use common\models\forms\CloseDecForm;
 use common\models\forms\CloseLoginForm;
 use common\models\forms\DecLevelLogForm;
 use common\models\forms\DecRoleLogForm;
+use common\models\forms\HighestEmpLevelLogForm;
 use common\models\forms\NetMoveForm;
 use common\models\forms\RechargeForm;
 use common\models\forms\ReconsumeForm;
@@ -2229,4 +2232,39 @@ class UserController extends BaseController
         }
         return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
     }
+
+    /**
+     * 会员最高聘级变动记录.
+     * @return mixed
+     * @throws \yii\base\Exception
+     * @throws \yii\web\HttpException
+     */
+    public function actionChangeHighestEmpLevelList()
+    {
+        $filter = $this->filterCondition([
+            'USER_NAME' => 'CU.USER_NAME',
+            'CREATED_AT' => 'LL.CREATED_AT',
+            'ADMIN_NAME' => 'ADM.ADMIN_NAME',
+        ]);
+        $condition = $filter['condition'];
+        $params = $filter['params'];
+        $listObj = new ChangeHighestEmpLevelList();
+        $data = $listObj->getList(['condition' => $condition, 'params' => $params]);
+
+        return static::notice($data);
+    }
+    /**
+     * 调整会员最高聘级.
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionChangeHighestEmpLevel()
+    {
+        if (Yii::$app->request->isPost) {
+            return parent::edit(HighestEmpLevelLogForm::class, '修改会员最高聘级成功', 'adminChange', ['adminChange',], null, function ($form, $result) {
+
+            });
+        }
+        return static::notice('无效请求', 400);
+    }
 }

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

@@ -26,9 +26,9 @@ class FlowBalanceList extends \common\libs\dataList\DataList implements DataList
      * @throws \yii\base\Exception
      */
     public function dataHandle() {
-        
+
         $this->listData = FlowWallet::lists($this->condition, $this->params, [
-            'select' => 'FW.TRANSFER_SN,FW.USER_ID,FW.AMOUNT,FW.TOTAL,FW.IS_INCR,FW.REMARK,FW.PERIOD_NUM,FW.CALC_MONTH,FW.CREATED_AT,
+            'select' => 'FW.ORDER_SN,FW.TRANSFER_SN,FW.USER_ID,FW.AMOUNT,FW.TOTAL,FW.IS_INCR,FW.REMARK,FW.PERIOD_NUM,FW.CALC_MONTH,FW.CREATED_AT,
             U.USER_NAME,U.REAL_NAME,U.IS_DEC',
             'orderBy' => 'FW.CREATED_AT DESC,FW.SORT DESC',
             'from' => FlowWallet::tableName() . ' AS FW',
@@ -189,6 +189,10 @@ class FlowBalanceList extends \common\libs\dataList\DataList implements DataList
                     'header' => '流水号',
                     'headerOther' => ['width' => '250'],
                 ],
+                'ORDER_SN' => [
+                    'header' => '订单号',
+                    'headerOther' => ['width' => '250'],
+                ],
             ];
         }
         return $this->columns;
@@ -223,4 +227,4 @@ class FlowBalanceList extends \common\libs\dataList\DataList implements DataList
         }
         return $this->filterTypes;
     }
-}
+}

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

@@ -1,252 +1,252 @@
-<?php
-
-namespace backendApi\modules\v1\models\lists\bonus;
-
-use common\helpers\Cache;
-use common\helpers\user\Info;
-use common\libs\dataList\column\Price;
-use common\libs\dataList\column\YesNo;
-use common\libs\dataList\DataListInterface;
-use common\models\DealType;
-use common\models\FlowBonus;
-use common\libs\dataList\column\DateTime;
-use Yii;
-
-class FlowBonusList extends \common\libs\dataList\DataList implements DataListInterface {
-    /**
-     * 列表名称
-     * @return string
-     */
-    public function getListName() {
-        return '奖金流水';
-    }
-
-    /**
-     * 列表筛选到的数据
-     * @throws \yii\base\Exception
-     */
-    public function dataHandle() {
-        $this->listData = FlowBonus::lists($this->condition, $this->params, [
-            'select' => 'FB.*,U.USER_NAME,U.REAL_NAME,U.IS_DEC',
-            'orderBy' => 'FB.CREATED_AT DESC,FB.SORT DESC,FB.AUTO_SORT DESC,FB.ID DESC',
-            'from' => FlowBonus::tableName() . ' AS FB',
-            'join' => [
-                ['LEFT JOIN', \common\models\User::tableName() . ' AS U', 'FB.USER_ID=U.ID'],
-            ],
-            'page' => $this->page,
-            'pageSize' => $this->pageSize,
-        ]);
-        foreach ($this->listData['list'] as $key => $value) {
-            //$userInfo = Info::baseInfoZh($value['USER_ID']);
-            //$this->listData['list'][$key] = array_merge($userInfo, $value);
-            $this->listData['list'][$key]['DEAL_TYPE_NAME'] = DealType::getAllTypesForShow()[$value['DEAL_TYPE_ID']]['TYPE_NAME'] ?? '';
-            $this->listData['list'][$key]['LAST_DEC_LV_NAME'] = Cache::getDecLevelConfig()[$value['LAST_DEC_LV']]['LEVEL_NAME'] ?? '';
-            $this->listData['list'][$key]['LAST_EMP_LV_NAME'] = Cache::getEmpLevelConfig()[$value['LAST_EMP_LV']]['LEVEL_NAME'] ?? '';
-            $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,
-                'CREATED_AT' => [
-                    'header' => '创建时间',
-                    'value' => function ($row) {
-                        return (new DateTime([
-                            'value' => $row['CREATED_AT'],
-                        ]))->result();
-                    },
-                    'headerOther' => ['width' => '170'],
-                ],
-                'PERIOD_NUM' => '期数',
-                'CALC_MONTH' => '结算月',
-                'DEAL_TYPE_NAME' => [
-                    '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']
-                    ],
-                ],
-                'LAST_DEC_LV_NAME' => [
-                    'header' => '会员级别',
-                    'headerOther' => [
-                        'width' => '110',
-                    ],
-                    'valueOther' => [
-                        'tag' => ['type' => 'warning', 'size' => 'small', 'class' => 'no-border']
-                    ],
-                ],
-                'LAST_EMP_LV_NAME' => [
-                    'header' => '最新聘级',
-                    'headerOther' => [
-                        'width' => '130',
-                    ],
-                    'valueOther' => [
-                        'tag' => ['type' => 'warning', 'size' => 'small', 'class' => 'no-border']
-                    ],
-                ],
-//                'LAST_STATUS_NAME' => [
-//                    'header' => '会员状态',
-//                    'headerOther' => ['width' => '110'],
-//                ],
-//                'SYSTEM_NAME' => [
-//                    'header' => '体系',
-//                    'headerOther' => ['width' => '200'],
-//                ],
-                'IS_DEC' => [
-                    'header' => '是否报单中心',
-                    'value' => function ($row) {
-                        return (new YesNo([
-                            'value' => $row['IS_DEC'],
-                        ]))->result();
-                    },
-                    'headerOther' => function ($row) {
-                        return [
-                            'width' => '120',
-                        ];
-                    },
-                    'valueOther' => function ($row) {
-                        return [
-                            'tag' => ['type' => (isset($row['IS_DEC']) && $row['IS_DEC']) ? 'success' : 'info', 'size' => 'small']
-                        ];
-                    },
-                ],
-//                'DEC_ROLE_NAME' => [
-//                    'header' => '报单中心级别',
-//                    'headerOther' => ['width' => '110'],
-//                ],
-//                'IS_DIRECT_SELLER' => [
-//                    'header' => '是否直销员',
-//                    'value' => function ($row) {
-//                        return (new YesNo([
-//                            'value' => $row['IS_DIRECT_SELLER'],
-//                        ]))->result();
-//                    },
-//                    'headerOther' => function ($row) {
-//                        return [
-//                            'width' => '120',
-//                        ];
-//                    },
-//                    'valueOther' => function ($row) {
-//                        return [
-//                            'tag' => ['type' => (isset($row['IS_DIRECT_SELLER']) && $row['IS_DIRECT_SELLER']) ? 'success' : 'info', 'size' => 'small']
-//                        ];
-//                    },
-//                ],
-                'BEFORE_BALANCE' => [
-                    'header' => '交易前余额',
-                    'value' => function ($row) {
-                        return (new Price([
-                            'value' => $row['TOTAL'] - $row['AMOUNT'],
-                        ]))->result();
-                    },
-                    'headerOther' => [
-                        'width' => '150',
-                    ],
-                ],
-                'AMOUNT' => [
-                    'header' => '交易额',
-                    'value' => function ($row) {
-                        $result = (new Price([
-                            'value' => $row['AMOUNT'],
-                        ]))->result();
-                        return $row['IS_INCR'] > 0 ? '+' . $result : $result;
-                    },
-                    'headerOther' => [
-                        'width' => '150',
-                        'prop' => 'BONUS',
-                    ],
-                    'valueOther' => function ($row) {
-                        if ($row['IS_INCR'] > 0) {
-                            $type = 'success';
-                        } elseif ($row['IS_INCR'] == 0) {
-                            $type = 'danger';
-                        } else {
-                            $type = 'info';
-                        }
-                        return [
-                            'tag' => ['type' => $type, 'size' => 'small']
-                        ];
-                    },
-                ],
-                'TOTAL' => [
-                    'header' => '交易后余额',
-                    'value' => function ($row) {
-                        return (new Price([
-                            'value' => $row['TOTAL'],
-                        ]))->result();
-                    },
-                    'headerOther' => [
-                        'width' => '150',
-                    ],
-                ],
-                'ADMIN_NAME' => [
-                    'header' => '操作人',
-                    'headerOther' => ['width' => '110'],
-                ],
-                'REMARK' => [
-                    'header' => '备注',
-                    'headerOther' => ['width' => '250'],
-                ],
-                'TRANSFER_SN' => [
-                    'header' => '流水号',
-                    'headerOther' => ['width' => '250'],
-                ],
-            ];
-        }
-        return $this->columns;
-    }
-
-    /**
-     * 前台用于筛选的类型集合
-     * @return mixed
-     */
-    public function getFilterTypes() {
-        if (!$this->filterTypes) {
-            $this->filterTypes = [
-                'CREATED_AT' => ['isUserTable' => false, 'name' => '创建时间', 'other' => 'date'],
-                'PERIOD_NUM' => ['isUserTable' => false, 'name' => '期数'],
-                'CALC_MONTH' => ['isUserTable' => false, 'name' => '结算月', 'other' => 'month'],
-                'DEAL_TYPE_NAME' => ['isUserTable' => false, 'name' => '交易类型', 'other' => 'dealTypes'],
-                'USER_NAME' => ['isUserTable' => false, 'name' => '会员编号'],
-                'REAL_NAME' => ['isUserTable' => false, 'name' => '会员姓名'],
-                'LAST_DEC_LV_NAME' => ['isUserTable' => false, 'name' => '会员级别', 'other' => 'decLevel'],
-                'LAST_EMP_LV_NAME' => ['isUserTable' => false, 'name' => '聘级', 'other' => 'empLevel'],
-//                'LAST_STATUS_NAME' => ['isUserTable' => false, 'name' => '会员状态', 'other' => 'status'],
-//                'SYSTEM_NAME' => ['isUserTable' => true, 'name' => '体系', 'other' => 'systems'],
-                'IS_DEC' => ['isUserTable' => false, 'name' => '是否报单中心', 'other' => 'yesOrNo'],
-//                'DEC_ROLE_NAME' => ['isUserTable' => true, 'name' => '报单中心级别', 'other' => 'decRole'],
-//                'IS_DIRECT_SELLER' => ['isUserTable' => true, 'name' => '是否直销员', 'other' => 'yesOrNo'],
-                'AMOUNT' => ['isUserTable' => false, 'name' => '交易额'],
-                'TOTAL' => ['isUserTable' => false, 'name' => '交易后余额'],
-                'ADMIN_NAME' => ['isUserTable' => false, 'name' => '操作人'],
-                'REMARK' => ['isUserTable' => false, 'name' => '备注'],
-                'TRANSFER_SN' => ['isUserTable' => false, 'name' => '流水号'],
-            ];
-        }
-        return $this->filterTypes;
-    }
-}
+<?php
+
+namespace backendApi\modules\v1\models\lists\bonus;
+
+use common\helpers\Cache;
+use common\helpers\user\Info;
+use common\libs\dataList\column\Price;
+use common\libs\dataList\column\YesNo;
+use common\libs\dataList\DataListInterface;
+use common\models\DealType;
+use common\models\FlowBonus;
+use common\libs\dataList\column\DateTime;
+use Yii;
+
+class FlowBonusList extends \common\libs\dataList\DataList implements DataListInterface {
+    /**
+     * 列表名称
+     * @return string
+     */
+    public function getListName() {
+        return '奖金流水';
+    }
+
+    /**
+     * 列表筛选到的数据
+     * @throws \yii\base\Exception
+     */
+    public function dataHandle() {
+        $this->listData = FlowBonus::lists($this->condition, $this->params, [
+            'select' => 'FB.*,U.USER_NAME,U.REAL_NAME,U.IS_DEC',
+            'orderBy' => 'FB.CREATED_AT DESC,FB.SORT DESC,FB.AUTO_SORT DESC,FB.ID DESC',
+            'from' => FlowBonus::tableName() . ' AS FB',
+            'join' => [
+                ['LEFT JOIN', \common\models\User::tableName() . ' AS U', 'FB.USER_ID=U.ID'],
+            ],
+            'page' => $this->page,
+            'pageSize' => $this->pageSize,
+        ]);
+        foreach ($this->listData['list'] as $key => $value) {
+            //$userInfo = Info::baseInfoZh($value['USER_ID']);
+            //$this->listData['list'][$key] = array_merge($userInfo, $value);
+            $this->listData['list'][$key]['DEAL_TYPE_NAME'] = DealType::getAllTypesForShow()[$value['DEAL_TYPE_ID']]['TYPE_NAME'] ?? '';
+            $this->listData['list'][$key]['LAST_DEC_LV_NAME'] = Cache::getDecLevelConfig()[$value['LAST_DEC_LV']]['LEVEL_NAME'] ?? '';
+            $this->listData['list'][$key]['LAST_EMP_LV_NAME'] = Cache::getEmpLevelConfig()[$value['LAST_EMP_LV']]['LEVEL_NAME'] ?? '';
+            $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,
+                'CREATED_AT' => [
+                    'header' => '创建时间',
+                    'value' => function ($row) {
+                        return (new DateTime([
+                            'value' => $row['CREATED_AT'],
+                        ]))->result();
+                    },
+                    'headerOther' => ['width' => '170'],
+                ],
+                'PERIOD_NUM' => '期数',
+                'CALC_MONTH' => '结算月',
+                'DEAL_TYPE_NAME' => [
+                    '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']
+                    ],
+                ],
+                'LAST_DEC_LV_NAME' => [
+                    'header' => '会员级别',
+                    'headerOther' => [
+                        'width' => '110',
+                    ],
+                    'valueOther' => [
+                        'tag' => ['type' => 'warning', 'size' => 'small', 'class' => 'no-border']
+                    ],
+                ],
+                'LAST_EMP_LV_NAME' => [
+                    'header' => '最新聘级',
+                    'headerOther' => [
+                        'width' => '130',
+                    ],
+                    'valueOther' => [
+                        'tag' => ['type' => 'warning', 'size' => 'small', 'class' => 'no-border']
+                    ],
+                ],
+//                'LAST_STATUS_NAME' => [
+//                    'header' => '会员状态',
+//                    'headerOther' => ['width' => '110'],
+//                ],
+//                'SYSTEM_NAME' => [
+//                    'header' => '体系',
+//                    'headerOther' => ['width' => '200'],
+//                ],
+                'IS_DEC' => [
+                    'header' => '是否报单中心',
+                    'value' => function ($row) {
+                        return (new YesNo([
+                            'value' => $row['IS_DEC'],
+                        ]))->result();
+                    },
+                    'headerOther' => function ($row) {
+                        return [
+                            'width' => '120',
+                        ];
+                    },
+                    'valueOther' => function ($row) {
+                        return [
+                            'tag' => ['type' => (isset($row['IS_DEC']) && $row['IS_DEC']) ? 'success' : 'info', 'size' => 'small']
+                        ];
+                    },
+                ],
+//                'DEC_ROLE_NAME' => [
+//                    'header' => '报单中心级别',
+//                    'headerOther' => ['width' => '110'],
+//                ],
+//                'IS_DIRECT_SELLER' => [
+//                    'header' => '是否直销员',
+//                    'value' => function ($row) {
+//                        return (new YesNo([
+//                            'value' => $row['IS_DIRECT_SELLER'],
+//                        ]))->result();
+//                    },
+//                    'headerOther' => function ($row) {
+//                        return [
+//                            'width' => '120',
+//                        ];
+//                    },
+//                    'valueOther' => function ($row) {
+//                        return [
+//                            'tag' => ['type' => (isset($row['IS_DIRECT_SELLER']) && $row['IS_DIRECT_SELLER']) ? 'success' : 'info', 'size' => 'small']
+//                        ];
+//                    },
+//                ],
+                'BEFORE_BALANCE' => [
+                    'header' => '交易前余额',
+                    'value' => function ($row) {
+                        return (new Price([
+                            'value' => $row['TOTAL'] - $row['AMOUNT'],
+                        ]))->result();
+                    },
+                    'headerOther' => [
+                        'width' => '150',
+                    ],
+                ],
+                'AMOUNT' => [
+                    'header' => '交易额',
+                    'value' => function ($row) {
+                        $result = (new Price([
+                            'value' => $row['AMOUNT'],
+                        ]))->result();
+                        return $row['IS_INCR'] > 0 ? '+' . $result : $result;
+                    },
+                    'headerOther' => [
+                        'width' => '150',
+                        'prop' => 'BONUS',
+                    ],
+                    'valueOther' => function ($row) {
+                        if ($row['IS_INCR'] > 0) {
+                            $type = 'success';
+                        } elseif ($row['IS_INCR'] == 0) {
+                            $type = 'danger';
+                        } else {
+                            $type = 'info';
+                        }
+                        return [
+                            'tag' => ['type' => $type, 'size' => 'small']
+                        ];
+                    },
+                ],
+                'TOTAL' => [
+                    'header' => '交易后余额',
+                    'value' => function ($row) {
+                        return (new Price([
+                            'value' => $row['TOTAL'],
+                        ]))->result();
+                    },
+                    'headerOther' => [
+                        'width' => '150',
+                    ],
+                ],
+                'ADMIN_NAME' => [
+                    'header' => '操作人',
+                    'headerOther' => ['width' => '110'],
+                ],
+                'REMARK' => [
+                    'header' => '备注',
+                    'headerOther' => ['width' => '250'],
+                ],
+                'TRANSFER_SN' => [
+                    'header' => '流水号',
+                    'headerOther' => ['width' => '250'],
+                ],
+            ];
+        }
+        return $this->columns;
+    }
+
+    /**
+     * 前台用于筛选的类型集合
+     * @return mixed
+     */
+    public function getFilterTypes() {
+        if (!$this->filterTypes) {
+            $this->filterTypes = [
+                'CREATED_AT' => ['isUserTable' => false, 'name' => '创建时间', 'other' => 'date'],
+                'PERIOD_NUM' => ['isUserTable' => false, 'name' => '期数'],
+                'CALC_MONTH' => ['isUserTable' => false, 'name' => '结算月', 'other' => 'month'],
+                'DEAL_TYPE_NAME' => ['isUserTable' => false, 'name' => '交易类型', 'other' => 'dealTypes'],
+                'USER_NAME' => ['isUserTable' => false, 'name' => '会员编号'],
+                'REAL_NAME' => ['isUserTable' => false, 'name' => '会员姓名'],
+                'LAST_DEC_LV_NAME' => ['isUserTable' => false, 'name' => '会员级别', 'other' => 'decLevel'],
+                'LAST_EMP_LV_NAME' => ['isUserTable' => false, 'name' => '聘级', 'other' => 'empLevel'],
+//                'LAST_STATUS_NAME' => ['isUserTable' => false, 'name' => '会员状态', 'other' => 'status'],
+//                'SYSTEM_NAME' => ['isUserTable' => true, 'name' => '体系', 'other' => 'systems'],
+                'IS_DEC' => ['isUserTable' => false, 'name' => '是否报单中心', 'other' => 'yesOrNo'],
+//                'DEC_ROLE_NAME' => ['isUserTable' => true, 'name' => '报单中心级别', 'other' => 'decRole'],
+//                'IS_DIRECT_SELLER' => ['isUserTable' => true, 'name' => '是否直销员', 'other' => 'yesOrNo'],
+                'AMOUNT' => ['isUserTable' => false, 'name' => '交易额'],
+                'TOTAL' => ['isUserTable' => false, 'name' => '交易后余额'],
+                'ADMIN_NAME' => ['isUserTable' => false, 'name' => '操作人'],
+                'REMARK' => ['isUserTable' => false, 'name' => '备注'],
+                'TRANSFER_SN' => ['isUserTable' => false, 'name' => '流水号'],
+            ];
+        }
+        return $this->filterTypes;
+    }
+}

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

@@ -175,6 +175,10 @@ class FlowExchangePointsList extends \common\libs\dataList\DataList implements D
                     'header' => '备注',
                     'headerOther' => ['width' => '250'],
                 ],
+                'ORDER_SN' => [
+                    'header' => '订单号',
+                    'headerOther' => ['width' => '250'],
+                ],
             ];
         }
         return $this->columns;
@@ -204,4 +208,4 @@ class FlowExchangePointsList extends \common\libs\dataList\DataList implements D
         }
         return $this->filterTypes;
     }
-}
+}

+ 212 - 208
backendApi/modules/v1/models/lists/bonus/FlowReconsumePointsList.php

@@ -1,208 +1,212 @@
-<?php
-
-namespace backendApi\modules\v1\models\lists\bonus;
-
-use common\helpers\Cache;
-use common\helpers\user\Info;
-use common\libs\dataList\column\Price;
-use common\libs\dataList\column\YesNo;
-use common\libs\dataList\DataListInterface;
-use common\models\DealType;
-use common\libs\dataList\column\DateTime;
-use common\models\FlowCF;
-use common\models\FlowReconsumePoints;
-use Yii;
-
-class FlowReconsumePointsList extends \common\libs\dataList\DataList implements DataListInterface {
-    /**
-     * 列表名称
-     * @return string
-     */
-    public function getListName() {
-        return '复销点数流水';
-    }
-
-    /**
-     * 列表筛选到的数据
-     * @throws \yii\base\Exception
-     */
-    public function dataHandle() {
-        $this->listData = FlowReconsumePoints::lists($this->condition, $this->params, [
-            'orderBy' => 'CREATED_AT DESC, ID DESC',
-            'page' => $this->page,
-            'pageSize' => $this->pageSize,
-        ]);
-        foreach ($this->listData['list'] as $key => $value) {
-            $userInfo = Info::baseInfoZh($value['USER_ID']);
-            $this->listData['list'][$key] = array_merge($userInfo, $value);
-            $this->listData['list'][$key]['DEAL_TYPE_NAME'] = DealType::getAllTypesForShow()[$value['DEAL_TYPE_ID']]['TYPE_NAME'] ?? '';
-            $this->listData['list'][$key]['LAST_DEC_LV_NAME'] = Cache::getDecLevelConfig()[$value['LAST_DEC_LV']]['LEVEL_NAME'] ?? '';
-            $this->listData['list'][$key]['LAST_EMP_LV_NAME'] = Cache::getEmpLevelConfig()[$value['LAST_EMP_LV']]['LEVEL_NAME'] ?? '';
-            $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,
-                'CREATED_AT' => [
-                    'header' => '创建时间',
-                    'value' => function ($row) {
-                        return (new DateTime([
-                            'value' => $row['CREATED_AT'],
-                        ]))->result();
-                    },
-                    'headerOther' => ['width' => '170'],
-                ],
-                'PERIOD_NUM' => '期数',
-                'CALC_MONTH' => '结算月',
-                'DEAL_TYPE_NAME' => [
-                    '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']
-                    ],
-                ],
-                'LAST_DEC_LV_NAME' => [
-                    'header' => '会员级别',
-                    'headerOther' => [
-                        'width' => '110',
-                    ],
-                    'valueOther' => [
-                        'tag' => ['type' => 'warning', 'size' => 'small', 'class' => 'no-border']
-                    ],
-                ],
-                'LAST_EMP_LV_NAME' => [
-                    'header' => '聘级',
-                    'headerOther' => [
-                        'width' => '130',
-                    ],
-                    'valueOther' => [
-                        'tag' => ['type' => 'warning', 'size' => 'small', 'class' => 'no-border']
-                    ],
-                ],
-                'IS_DEC' => [
-                    'header' => '是否报单中心',
-                    'value' => function ($row) {
-                        return (new YesNo([
-                            'value' => $row['IS_DEC'],
-                        ]))->result();
-                    },
-                    'headerOther' => function ($row) {
-                        return [
-                            'width' => '120',
-                        ];
-                    },
-                    'valueOther' => function ($row) {
-                        return [
-                            'tag' => ['type' => (isset($row['IS_DEC']) && $row['IS_DEC']) ? 'success' : 'info', 'size' => 'small']
-                        ];
-                    },
-                ],
-                'BEFORE_BALANCE' => [
-                    'header' => '交易前余额',
-                    'value' => function ($row) {
-                        return (new Price([
-                            'value' => $row['TOTAL'] - $row['AMOUNT'],
-                        ]))->result();
-                    },
-                    'headerOther' => [
-                        'width' => '150',
-                    ],
-                ],
-                'AMOUNT' => [
-                    'header' => '交易额',
-                    'value' => function ($row) {
-                        $result = (new Price([
-                            'value' => $row['AMOUNT'],
-                        ]))->result();
-                        return $row['IS_INCR'] > 0 ? '+' . $result : $result;
-                    },
-                    'headerOther' => [
-                        'width' => '150',
-                        'prop' => 'BONUS',
-                    ],
-                    'valueOther' => function ($row) {
-                        if ($row['IS_INCR'] > 0) {
-                            $type = 'success';
-                        } elseif ($row['IS_INCR'] == 0) {
-                            $type = 'danger';
-                        } else {
-                            $type = 'info';
-                        }
-                        return [
-                            'tag' => ['type' => $type, 'size' => 'small']
-                        ];
-                    },
-                ],
-                'TOTAL' => [
-                    'header' => '交易后余额',
-                    'value' => function ($row) {
-                        return (new Price([
-                            'value' => $row['TOTAL'],
-                        ]))->result();
-                    },
-                    'headerOther' => [
-                        'width' => '150',
-                    ],
-                ],
-                'ADMIN_NAME' => [
-                    'header' => '操作人',
-                    'headerOther' => ['width' => '110'],
-                ],
-                'REMARK' => [
-                    'header' => '备注',
-                    'headerOther' => ['width' => '250'],
-                ],
-            ];
-        }
-        return $this->columns;
-    }
-
-    /**
-     * 前台用于筛选的类型集合
-     * @return mixed
-     */
-    public function getFilterTypes() {
-        if (!$this->filterTypes) {
-            $this->filterTypes = [
-                'CREATED_AT' => ['isUserTable' => false, 'name' => '创建时间', 'other' => 'date'],
-                'PERIOD_NUM' => ['isUserTable' => false, 'name' => '期数'],
-                'CALC_MONTH' => ['isUserTable' => false, 'name' => '结算月', 'other' => 'month'],
-                'DEAL_TYPE_NAME' => ['isUserTable' => false, 'name' => '交易类型', 'other' => 'dealTypes'],
-                'USER_NAME' => ['isUserTable' => true, 'name' => '会员编号'],
-                'REAL_NAME' => ['isUserTable' => true, 'name' => '会员姓名'],
-                'LAST_DEC_LV_NAME' => ['isUserTable' => false, 'name' => '会员级别', 'other' => 'decLevel'],
-                'LAST_EMP_LV_NAME' => ['isUserTable' => false, 'name' => '聘级', 'other' => 'empLevel'],
-                'IS_DEC' => ['isUserTable' => true, 'name' => '是否报单中心', 'other' => 'yesOrNo'],
-                'AMOUNT' => ['isUserTable' => false, 'name' => '交易额'],
-                'TOTAL' => ['isUserTable' => false, 'name' => '交易后余额'],
-                'ADMIN_NAME' => ['isUserTable' => false, 'name' => '操作人'],
-                'REMARK' => ['isUserTable' => false, 'name' => '备注'],
-            ];
-        }
-        return $this->filterTypes;
-    }
-}
+<?php
+
+namespace backendApi\modules\v1\models\lists\bonus;
+
+use common\helpers\Cache;
+use common\helpers\user\Info;
+use common\libs\dataList\column\Price;
+use common\libs\dataList\column\YesNo;
+use common\libs\dataList\DataListInterface;
+use common\models\DealType;
+use common\libs\dataList\column\DateTime;
+use common\models\FlowCF;
+use common\models\FlowReconsumePoints;
+use Yii;
+
+class FlowReconsumePointsList extends \common\libs\dataList\DataList implements DataListInterface {
+    /**
+     * 列表名称
+     * @return string
+     */
+    public function getListName() {
+        return '复销点数流水';
+    }
+
+    /**
+     * 列表筛选到的数据
+     * @throws \yii\base\Exception
+     */
+    public function dataHandle() {
+        $this->listData = FlowReconsumePoints::lists($this->condition, $this->params, [
+            'orderBy' => 'CREATED_AT DESC, ID DESC',
+            'page' => $this->page,
+            'pageSize' => $this->pageSize,
+        ]);
+        foreach ($this->listData['list'] as $key => $value) {
+            $userInfo = Info::baseInfoZh($value['USER_ID']);
+            $this->listData['list'][$key] = array_merge($userInfo, $value);
+            $this->listData['list'][$key]['DEAL_TYPE_NAME'] = DealType::getAllTypesForShow()[$value['DEAL_TYPE_ID']]['TYPE_NAME'] ?? '';
+            $this->listData['list'][$key]['LAST_DEC_LV_NAME'] = Cache::getDecLevelConfig()[$value['LAST_DEC_LV']]['LEVEL_NAME'] ?? '';
+            $this->listData['list'][$key]['LAST_EMP_LV_NAME'] = Cache::getEmpLevelConfig()[$value['LAST_EMP_LV']]['LEVEL_NAME'] ?? '';
+            $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,
+                'CREATED_AT' => [
+                    'header' => '创建时间',
+                    'value' => function ($row) {
+                        return (new DateTime([
+                            'value' => $row['CREATED_AT'],
+                        ]))->result();
+                    },
+                    'headerOther' => ['width' => '170'],
+                ],
+                'PERIOD_NUM' => '期数',
+                'CALC_MONTH' => '结算月',
+                'DEAL_TYPE_NAME' => [
+                    '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']
+                    ],
+                ],
+                'LAST_DEC_LV_NAME' => [
+                    'header' => '会员级别',
+                    'headerOther' => [
+                        'width' => '110',
+                    ],
+                    'valueOther' => [
+                        'tag' => ['type' => 'warning', 'size' => 'small', 'class' => 'no-border']
+                    ],
+                ],
+                'LAST_EMP_LV_NAME' => [
+                    'header' => '聘级',
+                    'headerOther' => [
+                        'width' => '130',
+                    ],
+                    'valueOther' => [
+                        'tag' => ['type' => 'warning', 'size' => 'small', 'class' => 'no-border']
+                    ],
+                ],
+                'IS_DEC' => [
+                    'header' => '是否报单中心',
+                    'value' => function ($row) {
+                        return (new YesNo([
+                            'value' => $row['IS_DEC'],
+                        ]))->result();
+                    },
+                    'headerOther' => function ($row) {
+                        return [
+                            'width' => '120',
+                        ];
+                    },
+                    'valueOther' => function ($row) {
+                        return [
+                            'tag' => ['type' => (isset($row['IS_DEC']) && $row['IS_DEC']) ? 'success' : 'info', 'size' => 'small']
+                        ];
+                    },
+                ],
+                'BEFORE_BALANCE' => [
+                    'header' => '交易前余额',
+                    'value' => function ($row) {
+                        return (new Price([
+                            'value' => $row['TOTAL'] - $row['AMOUNT'],
+                        ]))->result();
+                    },
+                    'headerOther' => [
+                        'width' => '150',
+                    ],
+                ],
+                'AMOUNT' => [
+                    'header' => '交易额',
+                    'value' => function ($row) {
+                        $result = (new Price([
+                            'value' => $row['AMOUNT'],
+                        ]))->result();
+                        return $row['IS_INCR'] > 0 ? '+' . $result : $result;
+                    },
+                    'headerOther' => [
+                        'width' => '150',
+                        'prop' => 'BONUS',
+                    ],
+                    'valueOther' => function ($row) {
+                        if ($row['IS_INCR'] > 0) {
+                            $type = 'success';
+                        } elseif ($row['IS_INCR'] == 0) {
+                            $type = 'danger';
+                        } else {
+                            $type = 'info';
+                        }
+                        return [
+                            'tag' => ['type' => $type, 'size' => 'small']
+                        ];
+                    },
+                ],
+                'TOTAL' => [
+                    'header' => '交易后余额',
+                    'value' => function ($row) {
+                        return (new Price([
+                            'value' => $row['TOTAL'],
+                        ]))->result();
+                    },
+                    'headerOther' => [
+                        'width' => '150',
+                    ],
+                ],
+                'ADMIN_NAME' => [
+                    'header' => '操作人',
+                    'headerOther' => ['width' => '110'],
+                ],
+                'REMARK' => [
+                    'header' => '备注',
+                    'headerOther' => ['width' => '250'],
+                ],
+                'ORDER_SN' => [
+                    'header' => '订单号',
+                    'headerOther' => ['width' => '250'],
+                ],
+            ];
+        }
+        return $this->columns;
+    }
+
+    /**
+     * 前台用于筛选的类型集合
+     * @return mixed
+     */
+    public function getFilterTypes() {
+        if (!$this->filterTypes) {
+            $this->filterTypes = [
+                'CREATED_AT' => ['isUserTable' => false, 'name' => '创建时间', 'other' => 'date'],
+                'PERIOD_NUM' => ['isUserTable' => false, 'name' => '期数'],
+                'CALC_MONTH' => ['isUserTable' => false, 'name' => '结算月', 'other' => 'month'],
+                'DEAL_TYPE_NAME' => ['isUserTable' => false, 'name' => '交易类型', 'other' => 'dealTypes'],
+                'USER_NAME' => ['isUserTable' => true, 'name' => '会员编号'],
+                'REAL_NAME' => ['isUserTable' => true, 'name' => '会员姓名'],
+                'LAST_DEC_LV_NAME' => ['isUserTable' => false, 'name' => '会员级别', 'other' => 'decLevel'],
+                'LAST_EMP_LV_NAME' => ['isUserTable' => false, 'name' => '聘级', 'other' => 'empLevel'],
+                'IS_DEC' => ['isUserTable' => true, 'name' => '是否报单中心', 'other' => 'yesOrNo'],
+                'AMOUNT' => ['isUserTable' => false, 'name' => '交易额'],
+                'TOTAL' => ['isUserTable' => false, 'name' => '交易后余额'],
+                'ADMIN_NAME' => ['isUserTable' => false, 'name' => '操作人'],
+                'REMARK' => ['isUserTable' => false, 'name' => '备注'],
+            ];
+        }
+        return $this->filterTypes;
+    }
+}

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

@@ -156,6 +156,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],

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

@@ -47,13 +47,13 @@ class GoodsList extends \common\libs\dataList\DataList implements DataListInterf
                     'header' => '商品编号',
                     'headerOther' => ['width' => '200'],
                 ],
-                // 'TYPE' => [
-                //     'header' => '商品来源',
-                //     'value' => function($row){
-                //         return ShopGoods::GOODS_TYPE[$row['TYPE']]['name'];
-                //     },
-                //     'headerOther' => ['width' => '150'],
-                // ],
+                'CATE_ID' => [
+                    'header' => '商品来源',
+                    'value' => function($row){
+                        return ShopGoods::GOODS_TYPE[$row['CATE_ID']]['name'];
+                    },
+                    'headerOther' => ['width' => '150'],
+                ],
                 'SELL_DISCOUNT' => [
                     'header' => '商品折扣',
                     'value' => function($row) {

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

@@ -5,10 +5,15 @@ use common\helpers\Cache;
 use common\helpers\Tool;
 use common\helpers\user\Info;
 use common\libs\dataList\DataListInterface;
+use common\models\ApproachOrder;
+use common\models\ApproachOrderGoods;
 use common\models\Order;
 use common\models\OrderGoods;
+use common\models\ShopGoods;
 use common\models\User;
 use common\libs\dataList\column\DateTime;
+use yii\data\Pagination;
+use yii\db\Query;
 
 class OrderList extends \common\libs\dataList\DataList implements DataListInterface
 {
@@ -44,6 +49,53 @@ class OrderList extends \common\libs\dataList\DataList implements DataListInterf
         }
     }
 
+    /**
+     * 列表筛选到的数据
+     */
+//    public function dataHandle()
+//    {
+//        $orderQuery = Order::find()
+//            ->alias('O')
+//            ->where($this->condition, $this->params)
+//            ->select('O.*,U.REAL_NAME,U.DEC_ID,OG.REAL_PRICE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV')
+//            ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID')
+//            ->join('LEFT JOIN', OrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN')
+//            ->orderBy('O.CREATED_AT DESC');
+//
+//        // 订单中间表只查询待支付和支付失败的订单
+//        $this->params[':NOT_PAID'] = \Yii::$app->params['orderStatus']['notPaid']['value'];   // 待支付
+//        $this->params[':FAIL_PAID'] = \Yii::$app->params['orderStatus']['failPaid']['value'];   // 支付失败
+//        $orderStandardQuery = ApproachOrder::find()
+//            ->alias('O')
+//            ->where($this->condition . ' AND (O.STATUS = :NOT_PAID OR O.STATUS = :FAIL_PAID)', $this->params)
+//            ->select('O.*,U.REAL_NAME,U.DEC_ID,OG.REAL_PRICE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV')
+//            ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID')
+//            ->join('LEFT JOIN', ApproachOrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN')
+//            ->orderBy('O.CREATED_AT DESC');
+//
+//        $queryAll = $orderQuery->union($orderStandardQuery, true);
+//        $query = (new Query())->from(['Q' => $queryAll])->select('Q.*')->distinct()->orderBy(['CREATED_AT' => SORT_DESC]);
+//
+//        $totalCount = $query->count();
+//        $pagination = new Pagination(['totalCount' => $totalCount, 'pageSize' => \Yii::$app->request->get('pageSize')]);
+//        $lists = $query->offset($pagination->offset)->limit($pagination->limit)->all();
+//
+//        $this->listData = [
+//            'list' => $lists,
+//            'currentPage'=>$pagination->page,
+//            'totalPages'=>$pagination->pageCount,
+//            'startNum' => $pagination->page * $pagination->pageSize + 1,
+//            'totalCount' => $pagination->totalCount,
+//            'pageSize' => $pagination->pageSize,
+//        ];
+//
+//        foreach ($this->listData['list'] as $key => $value) {
+//            $CREATE_USER_ID = Info::getUserIdByUserName($value['CREATE_USER']);
+//            $this->listData['list'][$key]['DEC_USER_NAME'] = Info::getUserNameByUserId($value['DEC_ID']);
+//            $this->listData['list'][$key]['CREATE_USER_NAME'] = Info::getUserRealNameByUserId($CREATE_USER_ID);
+//        }
+//    }
+
     /**
      * 要展示和导出的所有字段
      * @return array
@@ -53,7 +105,6 @@ class OrderList extends \common\libs\dataList\DataList implements DataListInterf
         if(!$this->columns){
             $this->columns = [
                 'ID' => null,
-                'SN' => null,
                 'DEC_SN' => null,
                 'USER_NAME' => [
                     'header' => '会员编号',
@@ -183,6 +234,8 @@ class OrderList extends \common\libs\dataList\DataList implements DataListInterf
                                 return '充值账户';
                             case 'exchange':
                                 return '兑换点数';
+                            case 'online':
+                                return '在线支付';
                             default:
                                 return '复消积分';
                         }
@@ -221,6 +274,10 @@ class OrderList extends \common\libs\dataList\DataList implements DataListInterf
                     },
                     'headerOther' => ['width' => '190'],
                 ],
+                'SEND_AT' => [
+                    'header' => '推送时间',
+                    'headerOther' => ['width' => '190'],
+                ],
                 'DELIVERY_AT' => [
                     'header' => '发货时间',
                     'value' => function ($row) {
@@ -245,7 +302,7 @@ class OrderList extends \common\libs\dataList\DataList implements DataListInterf
                     },
                 ],
                 'REAL_PV' => [
-                    'header' => '商品金额',
+                    'header' => '商品PV',
                     'headerOther' => [
                         'width' => '150',
                     ],

+ 91 - 0
backendApi/modules/v1/models/lists/shop/OrderPeriodAdjustList.php

@@ -0,0 +1,91 @@
+<?php
+namespace backendApi\modules\v1\models\lists\shop;
+
+use common\libs\dataList\DataListInterface;
+use common\models\Order;
+use common\models\OrderPeriodAdjust;
+use common\libs\dataList\column\DateTime;
+
+class OrderPeriodAdjustList extends \common\libs\dataList\DataList implements DataListInterface
+{
+    /**
+     * 列表名称
+     * @return string
+     */
+    public function getListName(){
+        return '订单期数调整列表';
+    }
+
+    /**
+     * 列表筛选到的数据
+     */
+    public function dataHandle()
+    {
+        $this->listData = OrderPeriodAdjust::lists($this->condition, $this->params, [
+            'select' => 'P.*,O.ORDER_TYPE',
+            'orderBy' => 'P.CREATED_AT DESC, P.ID DESC',
+            'from' => OrderPeriodAdjust::tableName() . ' AS P',
+            'join' => [
+                ['LEFT JOIN', Order::tableName() . ' AS O', 'P.ORDER_SN=O.SN'],
+            ],
+            'page' => $this->page,
+            'pageSize' => $this->pageSize,
+        ]);
+    }
+
+    /**
+     * 要展示和导出的所有字段
+     * @return array
+     */
+    public function getColumn(){
+        if (!$this->columns) {
+            $this->columns = [
+                'ID' => null,
+                'ORDER_SN' => [
+                    'header' => '订单号',
+                ],
+                'ORDER_TYPE' => [
+                    'header' => '订单类型',
+                    'value' => function ($row) {
+                        return $row['ORDER_TYPE'] == 'ZC' ? '首单' : '复消';
+                    },
+                ],
+                'ORIGIN_PERIOD' => [
+                    'header' => '调整前期数',
+                ],
+                'MODERN_PERIOD' => [
+                    'header' => '调整后期数',
+                ],
+                'CREATED_AT' => [
+                    'header' => '调整时间',
+                    'value' => function ($row) {
+                        return (new DateTime([
+                            'value' => $row['CREATED_AT'],
+                        ]))->result();
+                    },
+                ],
+                'ADMIN_ID' => [
+                    'header' => '操作人',
+                ],
+            ];
+        }
+        return $this->columns;
+    }
+
+    /**
+     * 前台用于筛选的类型集合
+     * @return mixed
+     */
+    public function getFilterTypes()
+    {
+        if (!$this->filterTypes) {
+            $this->filterTypes = [
+                'ORDER_SN' => ['name'=> '订单号'],
+                'ORIGIN_PERIOD'=> ['name'=> '调整前期数'],
+                'MODERN_PERIOD'=> ['name'=> '调整后期数'],
+                'CREATED_AT'=> ['name'=> '调整时间', 'other'=>'date'],
+            ];
+        }
+        return $this->filterTypes;
+    }
+}

+ 102 - 0
backendApi/modules/v1/models/lists/user/ChangeHighestEmpLevelList.php

@@ -0,0 +1,102 @@
+<?php
+namespace backendApi\modules\v1\models\lists\user;
+
+use backendApi\modules\v1\models\Admin;
+use common\helpers\Cache;
+use common\libs\dataList\DataListInterface;
+use common\models\HighestEmpLevelLog;
+use common\models\User;
+use common\libs\dataList\column\DateTime;
+use Yii;
+
+class ChangeHighestEmpLevelList extends \common\libs\dataList\DataList implements DataListInterface
+{
+    /**
+     * 列表名称
+     * @return string
+     */
+    public function getListName(){
+        return '会员最高聘级调整列表';
+    }
+
+    /**
+     * 列表筛选到的数据
+     */
+    public function dataHandle()
+    {
+        $this->listData = HighestEmpLevelLog::lists($this->condition, $this->params, [
+            'select' => 'LL.*, CU.USER_NAME, ADM.ADMIN_NAME',
+            'orderBy' => 'LL.CREATED_AT DESC, LL.ID DESC',
+            'from' => HighestEmpLevelLog::tableName() . ' AS LL',
+            'join' => [
+                ['LEFT JOIN', Admin::tableName() . ' AS ADM', 'LL.ADMIN_ID=ADM.ID'],
+                ['LEFT JOIN', User::tableName() . ' AS CU', 'LL.USER_ID=CU.ID'],
+            ],
+            'page' => $this->page,
+            'pageSize' => $this->pageSize,
+        ]);
+    }
+
+    /**
+     * 要展示和导出的所有字段
+     * @return array
+     */
+    public function getColumn() {
+        $empLevelConfig = Cache::getEmpLevelConfig();
+        if (!$this->columns) {
+            $this->columns = [
+                'ID' => null,
+                'USER_ID' => null,
+                'USER_NAME' => [
+                    'header' => '会员编号',
+                ],
+                'FROM_HIGHEST_EMP_LV_NAME' => [
+                    'header' => '调整前聘级',
+                    'value' => function($row) use($empLevelConfig) {
+                        return $empLevelConfig[$row['FROM_ID']]['LEVEL_NAME'] ?? '';
+                    },
+                    'valueOther' => [
+                        'tag'=>['type'=>'warning', 'size' => 'small', 'class'=>'no-border']
+                    ],
+                ],
+                'TO_HIGHEST_EMP_LV_NAME' => [
+                    'header' => '调整后聘级',
+                    'value' => function($row) use($empLevelConfig) {
+                        return $empLevelConfig[$row['TO_ID']]['LEVEL_NAME'] ?? '';
+                    },
+                    'valueOther' => [
+                        'tag'=>['type'=>'warning', 'size' => 'small', 'class'=>'no-border']
+                    ],
+                ],
+                'ADMIN_NAME' => [
+                    'header' => '操作管理员',
+                ],
+                'CREATED_AT' => [
+                    'header' => '创建时间',
+                    'value' => function($row) {
+                        return (new DateTime([
+                            'value' => $row['CREATED_AT'],
+                        ]))->result();
+                    },
+                ],
+            ];
+        }
+        return $this->columns;
+    }
+
+    /**
+     * 前台用于筛选的类型集合
+     * @return mixed
+     */
+    public function getFilterTypes()
+    {
+        if(!$this->filterTypes){
+            $this->filterTypes = [
+                'USER_NAME'=> ['isUserTable' => false,'name'=> '会员编号'],
+                'CREATED_AT' => ['isUserTable' => false, 'name' => '创建时间', 'other' => 'date'],
+                'ADMIN_NAME' => ['isUserTable' => false, 'name' => '操作管理员'],
+            ];
+        }
+        return $this->filterTypes;
+    }
+}

+ 5 - 1
backendEle/package.json

@@ -15,14 +15,17 @@
     "trial": "node build/trial.js"
   },
   "dependencies": {
+    "-": "0.0.1",
     "ajv": "^6.11.0",
     "axios": "^0.19.0",
     "babel-polyfill": "^6.26.0",
     "better-scroll": "^1.14.1",
     "countup.js": "^1.9.3",
     "echarts": "^4.1.0",
-    "element-ui": "2.9.1",
+    "http": "0.0.1-security",
+    "js": "^0.1.0",
     "nix-tinymce": "^1.0.7",
+    "parser": "^0.1.4",
     "ua-parser-js": "^0.7.20",
     "v-charts": "^1.16.20",
     "vue": "^2.5.21",
@@ -51,6 +54,7 @@
     "copy-webpack-plugin": "^4.0.1",
     "cross-spawn": "^5.0.1",
     "css-loader": "^0.28.0",
+    "element-ui": "^2.13.0",
     "eslint": "^4.19.1",
     "eslint-config-standard": "^10.2.1",
     "eslint-friendly-formatter": "^3.0.0",

File diff suppressed because it is too large
+ 292 - 269
backendEle/src/router/index.js


+ 119 - 0
backendEle/src/views/config/user-online.vue

@@ -0,0 +1,119 @@
+<template>
+  <div v-loading="loading">
+    <div class="white-box">
+      <el-tabs v-model="filterStatus" @tab-click="handleFilterStatusClick">
+        <el-tab-pane label="会员用户" name="1" :lazy="true"></el-tab-pane>
+        <el-tab-pane label="后台操作人" name="2" :lazy="true"></el-tab-pane>
+      </el-tabs>
+      <el-table :data="tableData" stripe style="width: 100%;" >
+        <el-table-column label="用户编号">
+          <template slot-scope="scope">
+            {{scope.row.ID}}
+          </template>
+        </el-table-column>
+        <el-table-column label="用户姓名">
+          <template slot-scope="scope">
+            {{scope.row.REAL_NAME}}
+          </template>
+        </el-table-column>
+        <el-table-column label="最后操作时间">
+          <template slot-scope="scope">
+            {{scope.row.UPDATE_TIME}}
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination :total="totalCount" :page_size="pageSize" @size-change="handleSizeChange" @current-change="handleCurrentChange"></pagination>
+    </div>
+  </div>
+</template>
+
+<script>
+  import network from '@/utils/network'
+  import tool from '@/utils/tool'
+  import FilterUser from '@/components/FilterUser'
+  import baseInfo from '@/utils/baseInfo'
+  import permission from '@/utils/permission'
+  import Pagination from '@/components/Pagination'
+  import filterHelper from '@/utils/filterHelper'
+
+  export default {
+    name: 'leo-balance-audit-table',
+    components: {FilterUser,Pagination},
+    mounted() {
+      network.getData('finance/change-balance-type').then(response => {
+        this.type = response.type
+        this.dealTypes = response.dealTypes
+        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(),
+        filterTypes: {},
+        filterModel: {},
+        filterStatus: '1',
+        filterData: null,
+        type: null,
+        dealTypes: null,
+        dialogEditLoading: false,
+        dialogAuditLoading: false,
+        dialogEditFormVisible: false,
+        dialogAuditFormVisible: false,
+        auditPassButtonStat: true,
+      }
+    },
+    methods: {
+      handleFilterStatusClick(tab, event) {
+        filterHelper.clearFilterOption(this)
+        this.getData()
+      },
+      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
+        let vueObj=this
+        filterData.filterStatus = this.filterStatus
+        network.getPageData(this, 'config/user-online', page, pageSize, filterData, function (response) {
+          vueObj.tableData = response.list
+        })
+      },
+      handleExport(){
+        this.$confirm(`确定要导出当前数据吗?`, '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          return network.getData(`finance/balance-audit-list-export`, this.filterModel)
+        }).then(response => {
+          this.$message({
+            message: response,
+            type: 'success'
+          })
+        }).catch(response => {
+
+        })
+      },
+    }
+  }
+</script>
+
+<style scoped>
+
+</style>

+ 2 - 2
backendEle/src/views/finance/change-balance-opt.vue

@@ -38,11 +38,11 @@
             <el-form-item label="备注">
               <el-input v-model="form.remark"></el-input>
             </el-form-item>
-            <el-form-item label="备注前台显示">
+            <!-- <el-form-item label="备注前台显示">
               <el-switch v-model="form.isShow" active-value="1" inactive-value="0">
               </el-switch>
             </el-form-item>
-            <el-form-item>
+            <el-form-item> -->
               <el-button type="primary" :loading="submitButtonStat" :disabled="getCodeStat" @click="onSubmit">提交</el-button>
             </el-form-item>
           </el-form>

+ 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>

+ 5 - 9
backendEle/src/views/shop/goods-add.vue

@@ -5,12 +5,11 @@
         <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-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>
@@ -189,10 +188,7 @@ export default {
       })
     },
     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

+ 4 - 5
backendEle/src/views/shop/index.vue

@@ -70,12 +70,11 @@
                     <el-form-item label="商品名称">
                         <el-input v-model="form.goodsName"></el-input>
                     </el-form-item>
-                    <!-- <el-form-item label="商品来源">
+                    <el-form-item label="商品来源">
                         <el-select v-model="form.type">
-                            <el-option v-for="(item,index) in goodsType" :key="index" :label="item.name"
-                                       :value="index"></el-option>
+                            <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>
                     <el-form-item label="会员折扣">
                         <el-input v-model="form.sellDiscount"></el-input>
                     </el-form-item>
@@ -353,7 +352,7 @@ export default {
         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.type = response.goodsInfo.CATE_ID
         vueObj.form.unit = response.goodsInfo.UNIT
         vueObj.form.marketPrice = response.goodsInfo.MARKET_PRICE
         vueObj.form.sellPrice = response.goodsInfo.SELL_PRICE

+ 126 - 9
backendEle/src/views/shop/order-list.vue

@@ -1,5 +1,5 @@
 <template>
-  <div v-loading="loading">
+  <div v-loading="loading" class="orderList">
     <div class="white-box">
       <div class="filter-box">
         <filter-user :filter-types="filterTypes" @select-value="handleFilterUser"></filter-user>
@@ -7,6 +7,7 @@
       <el-table ref="multipleTable" :data="tableData" style="width: 100%;"
                 :row-class-name="rowClassName"
                 @selection-change="handleSelectionChange"
+                @cell-click="openLogisticsQuery"
                 :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">
@@ -55,24 +56,56 @@
         <el-button type="primary" @click.native="handleDelivery">发货</el-button>
       </div>
     </el-dialog>
+
+    <el-dialog
+      :width="dialogWidth"
+      custom-class="logisticsQueryDialog"
+      title="物流动态"
+      :visible.sync="logisticsQueryDialog"
+      :before-close="logisticsQueryDialogHandleClose">
+      <div class="diaBody" v-loading="logisticsQueryLoading">
+        <el-tabs style="width: 100%!important" type="border-card" v-if="logisticsQueryList.length > 0">
+          <el-tab-pane  v-for="( item, index ) in logisticsQueryList" :key="index" :label="item.name">
+            <div class="block">
+              <el-timeline :reverse="reverse">
+                <el-timeline-item
+                  v-for="(activity, index2) in item.children"
+                  :key="index2"
+                  :icon="activity.icon"
+                  :color="activity.color"
+                  :size="activity.size"
+                  :timestamp="activity.date_action">
+                  <span class="timelineStatus">{{activity.order_status}}</span>
+                </el-timeline-item>
+              </el-timeline>
+            </div>
+
+          </el-tab-pane>
+        </el-tabs>
+        <el-empty v-if="logisticsQueryEmpty" :image-size="200"></el-empty>
+
+        <!--        <span slot="footer" class="dialog-footer">-->
+        <!--          <el-button @click="dialogVisible = false">取 消</el-button>-->
+        <!--        <el-button type="primary" @click="logisticsQueryDialog = false">确 定</el-button>-->
+        <!--      </span>-->
+      </div>
+
+    </el-dialog>
   </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'
+import network from '@/utils/network'
+import permission from '@/utils/permission'
+import tool from '@/utils/tool'
+import axios from 'axios'
 
 export default {
   name: 'shop_order-list',
   components: {FilterUser, Pagination},
-  mounted () {
-    this.getData()
-  },
   data () {
     return {
       tableHeaders: null,
@@ -94,9 +127,87 @@ export default {
         expressCompany: '',
         orderTrackNo: '',
       },
+      logisticsQueryDialog: false,
+      logisticsQueryList: [],
+      logisticsQueryLoading: false,
+      reverse: true,
+      logisticsQueryEmpty: false,
+      dialogWidth:0,
+      dialogTop:0
+    }
+  },
+  created() {
+    this.setDialogWidth()
+  },
+  mounted() {
+    this.getData()
+    window.onresize = () => {
+      return (() => {
+        this.setDialogWidth()
+      })()
     }
   },
   methods: {
+    setDialogWidth() {
+      var val = document.body.clientWidth
+      const def = 800 // 默认宽度
+      if (val > def) {
+        this.dialogWidth = '60%'
+        this.dialogTop = '15vh'
+      } else {
+        this.dialogWidth = '90%'
+        this.dialogTop = '1vh'
+      }
+    },
+    openLogisticsQuery(row, column, cell, event){
+      this.logisticsQueryEmpty = false
+      
+      if(column.label == "订单号"){
+        console.log(row.SEND_AT.value , row.STATUS, row.PAY_TYPE.value )
+        if((row.SEND_AT.value > 0 && row.STATUS == '1' && row.PAY_TYPE.value === '在线支付') === false ) return
+        let id = row.SN.value
+        this.logisticsQueryList = []
+        this.logisticsQueryDialog = true
+        this.logisticsQueryLoading = true
+        this.queryData(id).then(res => {
+          const data = res.data.data
+          let keysList = Object.keys(data)
+          let list = []
+          keysList.forEach((key, index) => {
+            let oneList = data[key]
+            oneList[ oneList.length - 1 ].color = '#0bbd87'
+            oneList[ oneList.length - 1 ].size = 'large'
+            // oneList[ oneList.length - 1 ].icon = 'el-icon-s-promotion'
+            let one = {
+              'name': key,
+              'children': oneList
+            }
+            list.push(one)
+          })
+          console.log(list)
+          this.logisticsQueryList = list
+          this.logisticsQueryLoading = false
+        }).catch((error) =>{
+          console.log(error);
+          this.logisticsQueryList = []
+          this.logisticsQueryEmpty = true
+          this.logisticsQueryLoading = false
+        })
+      }
+    },
+    openLogisticsQuery1 (data) {
+
+    },
+    async queryData (id) {
+      const link = 'https://taoplus.com.my/index.php?route=information/order_tracking/jsons&order_tracking_search=' + id
+      const ret = await axios.get(link)// await 后面也可以跟的是Promise实例对象
+      // console.log(ret)
+      return ret
+    },
+    logisticsQueryDialogHandleClose (done) {
+      this.logisticsQueryDialog = false
+    },
+
     rowClassName (val) {
       if (val.row) {
         let index = this.multipleSelection.findIndex(item => {
@@ -199,8 +310,14 @@ export default {
 </script>
 
 <style scoped>
-/deep/.el-table .selected-row {
+::v-deep.el-table .selected-row {
   background: #bce5ef;
   /*color: white;*/
 }
+.timelineStatus{
+  color: #409EFF;
+}
+.diaBody{
+  min-height: 20vh;
+}
 </style>

+ 197 - 0
backendEle/src/views/shop/order-period-adjust.vue

@@ -0,0 +1,197 @@
+<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">{{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">
+        <el-button type="primary" size="small" @click="visible = true" v-show="permission.hasPermission(`shop/order-adjust-period`)">调整订单期数</el-button>
+        <pagination :total="totalCount" :page_size="pageSize" @size-change="handleSizeChange" @current-change="handleCurrentChange"></pagination>
+      </div>
+    </div>
+
+    <el-dialog title="调整订单期数" :visible.sync="visible" width="50%">
+      <el-form ref="form" :model="form" label-width="250px" class="form-page">
+        <el-form-item label="订单编号" required clearable>
+          <el-input v-model="form.orderSn" @change="handleOrderSnChange"></el-input>
+        </el-form-item>
+        <el-form-item label="会员编号" v-show="order.USER_NAME">
+          <el-input v-model="order.USER_NAME" disabled></el-input>
+        </el-form-item>
+        <el-form-item label="订单类型" v-show="order.ORDER_TYPE">
+          <el-input v-model="order.ORDER_TYPE" disabled></el-input>
+        </el-form-item>
+        <el-form-item label="PV" v-show="order.PV">
+          <el-input v-model="order.PV" disabled></el-input>
+        </el-form-item>
+        <el-form-item label="订单金额" v-show="order.PAY_AMOUNT">
+          <el-input v-model="order.PAY_AMOUNT" disabled></el-input>
+        </el-form-item>
+        <el-form-item label="创建人编号" v-show="order.CREATE_USER">
+          <el-input v-model="order.CREATE_USER" disabled></el-input>
+        </el-form-item>
+        <el-form-item label="期数" v-show="order.PERIOD_NUM">
+          <el-input v-model="order.PERIOD_NUM" disabled></el-input>
+        </el-form-item>
+        <el-form-item label="调整期数" required>
+          <el-select v-model="form.modernPeriod" placeholder="请选择要调整到的期数">
+            <el-option v-for="item in availablePeriod" :key="item.PERIOD_NUM" :label="item.PERIOD_NUM" :value="item.PERIOD_NUM" :disabled="item.disabled"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="onSubmit" :loading="submitButtonStat">提交</el-button>
+        </el-form-item>
+      </el-form>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  import network from '@/utils/network'
+  import tool from '@/utils/tool'
+  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-period-adjust',
+    components: {FilterUser, Pagination},
+    mounted() {
+      this.getData()
+    },
+    data() {
+      return {
+        tableHeaders: null,
+        tableData: null,
+        tableHeight: window.innerHeight - 310,
+        loading: true,
+        currentPage: 1,
+        totalPages: 1,
+        totalCount: 1,
+        pageSize: 20,
+        tool: tool,
+        permission: permission,
+        filterTypes: null,
+        filterModel: {},
+
+        submitButtonStat: false,
+        visible: false,
+        form: {
+          orderSn: '',
+          modernPeriod: '',
+        },
+
+        order: {},
+        availablePeriod: null,
+      }
+    },
+    methods: {
+      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-period-adjust', page, pageSize, filterData, response => {
+            this.filterTypes = response.filterTypes
+            this.allData = response
+          })
+      },
+      handleOrderSnChange() {
+        if (this.form.orderSn) {
+          this.submitButtonStat = true
+          network.getData('shop/order-detail', { orderSn: this.form.orderSn }).then(response => {
+            this.order = response.order
+            this.availablePeriod = response.availablePeriod
+            if (response.availablePeriod && response.availablePeriod[0]) {
+              for (let period of response.availablePeriod) {
+                if (!period['disabled']) {
+                  this.form.modernPeriod = period['PERIOD_NUM']
+                  break
+                }
+              }
+            }
+
+            this.submitButtonStat = false
+          }).catch(error => {
+            this.$message({
+              message: error,
+              type: 'error'
+            })
+            this.submitButtonStat = false
+          })
+        }
+      },
+      handlePeriodChange() {
+        network.getData('shop/period-inspect', { modernPeriod: this.form.modernPeriod }).then(response => {
+
+        }).catch(error => {
+          this.$message({
+            message: error,
+            type: 'error'
+          })
+        })
+      },
+      onSubmit() {
+        this.$confirm('是否要修改当前订单期数?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this._handleSubmit()
+        }).catch(error => {
+          this.$message({
+            message: error,
+            type: 'error'
+          })
+          this.submitButtonStat = false
+        })
+      },
+      _handleSubmit() {
+        this.submitButtonStat = true
+        network.postData('shop/order-period-adjust', this.form).then(response => {
+          this.$message({
+            message: response,
+            type: 'success'
+          })
+          this.submitButtonStat = false
+          this._clearData()
+        }).catch(error => {
+          this.$message({
+            message: error,
+            type: 'error'
+          })
+          this.submitButtonStat = false
+        })
+      },
+      _clearData(){
+        this.form = {}
+        this.order = {}
+        this.visible = false
+        this.getData()
+      }
+    }
+  }
+</script>
+
+<style scoped>
+
+</style>

+ 201 - 0
backendEle/src/views/user/change-highest-emp-level-list.vue

@@ -0,0 +1,201 @@
+<template>
+  <div v-loading="loading">
+    <div class="white-box">
+      <div class="filter-box">
+        <filter-user ref="filterUser" :filter-types="filterTypes" @select-value="handleFilterUser"></filter-user>
+      </div>
+
+      <el-table :data="tableData" stripe style="width: 100%;" :height="tool.getTableHeight(true)">
+        <el-table-column v-for="(tableHeader, key) in tableHeaders" :key="key" :label="tableHeader.header" :width="tableHeader.other.width ? tableHeader.other.width : ''">
+          <template slot-scope="{row}">
+            <template v-if="row[tableHeader.index].other.tag" >
+              <el-tag :type="row[tableHeader.index].other.tag.type ? row[tableHeader.index].other.tag.type : null" :size="row[tableHeader.index].other.tag.size ? row[tableHeader.index].other.tag.size : null" :class="row[tableHeader.index].other.tag.class ? row[tableHeader.index].other.tag.class : null" >{{ row[tableHeader.index].value }}</el-tag>
+            </template>
+            <template v-else>
+              <div v-html="row[tableHeader.index].value"></div>
+            </template>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <div class="white-box-footer">
+        <el-button type="primary" size="small" @click="dialog = true" icon="el-icon-plus" v-show="permission.hasPermission(`user/change-user-dec-level`)">调整最高聘级</el-button>
+
+        <pagination :total="totalCount" :page_size="pageSize" @size-change="handleSizeChange" @current-change="handleCurrentChange"></pagination>
+      </div>
+    </div>
+
+    <el-dialog title="调整最高聘级" :visible.sync="dialog" width="450px" :before-close="handleClose">
+      <el-form ref="form" :model="form" label-width="100px" class="form-dialog" size="mini">
+        <el-form-item label="会员编号" required>
+          <el-input placeholder="请输入会员编号" v-model.trim="form.userName" class="input-with-select">
+            <el-button slot="append" icon="el-icon-search" @click="handleQuery">查询</el-button>
+          </el-input>
+
+          <el-tag v-show="userInfo.REAL_NAME !== null" style="margin-top: 5px;">
+            会员姓名:{{ userInfo.REAL_NAME }}
+          </el-tag>
+          <el-tag v-show="userInfo.REAL_NAME !== null" v-for="(item,key) in empLevels" :label="item.LEVEL_NAME" :value="item.ID" :key="key" v-if="key === userInfo.EMP_LV" style="margin-top: 5px;">
+            最高聘级:{{item.LEVEL_NAME}}
+          </el-tag>
+        </el-form-item>
+        <el-form-item label="调整后聘级" required>
+          <el-select v-model="form.levelId" placeholder="请选择调整后聘级">
+            <el-option v-for="(item,key) in empLevels" :label="item.LEVEL_NAME" :value="item.ID" :key="key" :disabled="key === userInfo.EMP_LV"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="备注">
+          <el-input type="textarea" :rows="2" placeholder="" v-model="form.remark">
+          </el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-button size="mini" type="primary" @click="onSubmit" :loading="submitButtonStat">保 存</el-button>
+        </el-form-item>
+      </el-form>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  import network from '@/utils/network'
+  import tool from '@/utils/tool'
+  import FilterUser from '@/components/FilterUser'
+  import baseInfo from '@/utils/baseInfo'
+  import permission from '@/utils/permission'
+  import Pagination from '@/components/Pagination'
+  import filterHelper from '@/utils/filterHelper'
+
+  export default {
+    name: 'change-highest-emp-level-list',
+    components: {FilterUser,Pagination},
+    mounted() {
+      this.getData()
+    },
+    data() {
+      return {
+        tableHeaders: null,
+        tableData: null,
+        loading: true,
+        currentPage: 1,
+        totalPages: 1,
+        totalCount: 1,
+        pageSize: 20,
+        tool: tool,
+        permission: permission,
+        empLevels: baseInfo.empLevels(),
+        filterTypes: {},
+        filterModel: {},
+        filterStatus: '0',
+        dialog: false,
+        form: {
+          userName: null,
+          periodNum: null,
+          levelId: null,
+          remark: null
+        },
+        disabled: 0,
+        submitButtonStat: false,
+        userInfo: {
+          REAL_NAME: null,
+          EMP_LV: null
+        },
+      }
+    },
+    methods: {
+      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
+        let vueObj = this
+        filterData.filterStatus = this.filterStatus != -1 ? `=,${this.filterStatus}` : ''
+        network.getPageData(this, 'user/change-highest-emp-level-list', page, pageSize, filterData, function (response) {
+            vueObj.allData = response
+            vueObj.filterTypes = response.filterTypes
+        })
+      },
+      handleClose() {
+        this._clearData()
+        this.dialog = false
+      },
+      handleQuery() {
+        if (!this.form.userName.length) {
+          this.$message({
+            message: '请输入会员编号',
+            type: 'warning'
+          })
+          return false
+        }
+        network.getData('user/full-info', { userName: this.form.userName }).then(response => {
+          this.userInfo = response
+        })
+      },
+      onSubmit() {
+        if (!this.form.userName.length) {
+          this.$message({
+            message: '请输入会员编号',
+            type: 'warning'
+          })
+          return false
+        }
+        if (!this.form.levelId) {
+          this.$message({
+            message: '请选择调整后的最高聘级',
+            type: 'warning'
+          })
+          return false
+        }
+
+        let thisObj = this
+        thisObj.$confirm('是否要调整会员的最高聘级?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          thisObj._handleSubmit()
+        }).catch(() => {
+          this._clearData()
+        })
+      },
+      _handleSubmit() {
+        this.submitButtonStat = true
+        network.postData('user/change-highest-emp-level', this.form).then(response => {
+          this.$message({
+            message: response,
+            type: 'success'
+          })
+          this.submitButtonStat = false
+          this.dialog = false
+          this._clearData()
+          this.getData()
+        }).catch(() => {
+          this.submitButtonStat = false
+        })
+      },
+      _clearData() {
+        this.form = {
+          userName: null,
+          periodNum: null,
+          levelId: null,
+          remark: null
+        }
+        this.userInfo = {
+          REAL_NAME: null,
+          EMP_LV: null
+        }
+      }
+    }
+  }
+</script>
+
+<style scoped>
+.form-dialog .el-form-item > .el-form-item__content > .el-input, .form-dialog .el-form-item > .el-form-item__content > .el-cascader, .form-dialog .el-form-item > .el-form-item__content > .el-select, .form-dialog .el-form-item > .el-form-item__content > .el-textarea, .form-dialog .el-form-item > .el-form-item__content > .el-slider {
+  width: 300px !important;
+}
+</style>

+ 4 - 4
common/config/config-devlopment.php

@@ -9,11 +9,11 @@ return [
     // 奖金结算系统主库
     'db' => [
         // 数据库连接
-        'dsn' => 'mysql:host=localhost;dbname=aikang_test',
+        'dsn' => 'mysql:host=16.163.228.151;port=8051;dbname=nc_shaojiangjin_0329',
         // 数据库用户名
-        'username' => 'root',
+        'username' => 'black_tea_0309',
         // 数据库密码
-        'password' => '123456',
+        'password' => 'ndZ4MXYST7',
         // 数据库字符集
         'charset' => 'utf8',
         // 数据表前缀
@@ -100,4 +100,4 @@ return [
         'host' => '127.0.0.1',
         'port' => '9513',
     ],
-];
+];

+ 4 - 4
common/config/config-product.php

@@ -9,11 +9,11 @@ return [
     // 奖金结算系统主库
     'db' => [
         // 数据库连接
-        'dsn' => 'mysql:host=173.1.0.128;port=4000;dbname=aikang_db',
+        'dsn' => 'mysql:host=16.163.228.151;port=8051;dbname=nc_shaojiangjin_0329',
         // 数据库用户名
-        'username' => 'aikang',
+        'username' => 'black_tea_0309',
         // 数据库密码
-        'password' => 'xtuNQ7F&p0M&UhcE',
+        'password' => 'ndZ4MXYST7',
         // 数据库字符集
         'charset' => 'utf8',
         // 数据表前缀
@@ -100,4 +100,4 @@ return [
         'host' => '127.0.0.1',
         'port' => '9513',
     ],
-];
+];

+ 24 - 11
common/config/main.php

@@ -10,17 +10,17 @@ return [
     ],
     'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
     'components' => [
-//        'log' => [
-//            'targets' => [
-//                [
-//                    'class' => 'yii\log\FileTarget',
-//                    'levels' => ['error', 'warning', 'info'],
-//                    'categories' => ['yii\db\*', 'app\models\*'],
-//                    'logFile' => '@runtime/logs/sql.log',
-//                ],
-//                'db' => [ 'class' => 'yii\log\FileTarget'],
-//            ],
-//        ],
+        'log' => [
+            'targets' => [
+                [
+                    'class' => 'yii\log\FileTarget',
+                    'levels' => ['error', 'warning', 'info'],
+                    'categories' => ['yii\db\*', 'app\models\*'],
+                    'logFile' => '@runtime/logs/sql.log',
+                ],
+                'db' => [ 'class' => 'yii\log\FileTarget'],
+            ],
+        ],
         'db' => array_merge([
             'class' => 'yii\db\Connection',
             'enableSlaves' => false,
@@ -60,6 +60,19 @@ return [
         'swooleAsyncTimer' => [
             'class' => 'common\components\SwooleAsyncTimer',
         ],
+        // iPay88配置
+        'iPay88' => [
+            'class' => 'frontendApi\modules\v1\components\IPay88',
+            'merchantCode' => 'M08669', // 'M08669_S0002',  // M08669(prod)
+            'merchantKey' => 'SiYF6a0QYy', // '5Mb154IrY8',   // SiYF6a0QYy(prod)
+            'currencyCode' => 'CNY', //'CNY', // MYR(马来币) CNY(人民币)
+            'responseUrl' => 'https://nc-fele-mips.elken.com:8015/#/shop/order-list', //'https://www.ncshop2023.com/#/shop/order-list', // TODO: https://nc-fele-mips.elken.com:8015/#/shop/order-list(test)
+            'backendUrl' => 'https://nc-fapi-mips.elken.com:8013/v1/shop/verify-approach-order', //'https://fapi.ekhkad.com/v1/shop/verify-approach-order',  // https://nc-fapi-mips.elken.com:8013/v1/shop/verify-approach-order(test)
+            'requeryUrl' => 'https://payment.ipay88.com.my/epayment/enquiry.asp',
+            'paymentUrl' => 'https://payment.ipay88.com.my/epayment/entry.asp',
+            'recurringUrlSubscription' => 'https://www.ipay88.com/recurringpayment/webservice/RecurringPayment.asmx/Subscription',
+            'recurringUrlTermination' => 'https://www.ipay88.com/recurringpayment/webservice/RecurringPayment.asmx/Termination'
+        ],
     ],
     'controllerMap' => [
         'swoole_server' => [

+ 21 - 0
common/config/params.php

@@ -306,6 +306,14 @@ return [
             'value' => 6,
             'label' => '订单删除'
         ],
+        '-1' => [
+            'value' => -1,
+            'label' => 'Payment failed',//支付失败
+        ],
+        'failPaid' => [
+            'value' => -1,
+            'label' => 'Payment failed',//支付失败
+        ],
     ],
     'exportModule' => [
         'shop' => ['label' => '商城管理', 'value'=>'shop'],
@@ -332,4 +340,17 @@ return [
         'atUserIds'   => ['rob9muw'],
         'isAtAll'     => false,
     ],
+    // wst配置
+    'wst' => [
+        //  (prod)
+        'baseToken' => 'ZWxrZW5yZXN0OnNmMjM0ZmE3NHNn',
+        'agentId' => 'TP',
+        'userName' => 'elken',
+        'password' => 'elken0088',
+        // (test)
+        // 'baseToken' => 'dnRuX2FwaV90ZXN0Ond0cmV3cjI0MzI0ZmRz',
+        // 'agentId' => 'elg8',
+        // 'userName' => 'vtn',
+        // 'password' => '123456',
+    ],
 ];

+ 159 - 0
common/helpers/IPay88.php

@@ -0,0 +1,159 @@
+<?php
+
+namespace common\helpers;
+
+class IPay88
+{
+    /**
+     * 根据运行环境加载secretKey
+     */
+    public static function getSecretKey(): string
+    {
+         return YII_ENV == YII_ENV_PROD ? \Yii::$app->iPay88->liveSecretKey : \Yii::$app->iPay88->testSecretKey;
+//       return \Yii::$app->iPay88->testSecretKey;
+    }
+
+    /**
+     * 支付.
+     */
+    public static function transactionInit($currency, $amount, $email)
+    {
+        $secretKey = self::getSecretKey();
+
+        try {
+            $url = "https://api.paystack.co/transaction/initialize";
+            $fields = [
+                'email' => $email,
+                'amount' => $amount * 100
+            ];
+            $fields_string = http_build_query($fields);
+            //open connection
+            $curl = curl_init();
+
+            //set the url, number of POST vars, POST data
+            curl_setopt($curl,CURLOPT_URL, $url);
+            curl_setopt($curl,CURLOPT_POST, true);
+            curl_setopt($curl,CURLOPT_POSTFIELDS, $fields_string);
+            curl_setopt($curl, CURLOPT_HTTPHEADER, array(
+                "Authorization: Bearer {$secretKey}",
+                "Cache-Control: no-cache",
+            ));
+            //So that curl_exec returns the contents of the cURL; rather than echoing it
+            curl_setopt($curl,CURLOPT_RETURNTRANSFER, true);
+            //execute post
+            $result = curl_exec($curl);
+            $err = curl_error($curl);
+            curl_close($curl);
+            if ($err) {
+                return [
+                    'status'    => false,
+                    'message'   => $err,
+                ];
+            }
+
+            return json_decode($result, true);
+        } catch (\Exception $e) {
+            return [
+                'status'    => false,
+                'message'   => $e->getMessage(),
+            ];
+        }
+    }
+    /**
+     * 交易结果校验.
+     * @param $ref
+     * @return array
+     */
+    public static function transactionVerify($ref): array
+    {
+        $secretKey = self::getSecretKey();
+
+        try {
+            $curl = curl_init();
+            curl_setopt_array($curl, [
+                CURLOPT_URL => "https://api.paystack.co/transaction/verify/{$ref}",
+                CURLOPT_RETURNTRANSFER => true,
+                CURLOPT_ENCODING => "",
+                CURLOPT_MAXREDIRS => 10,
+                CURLOPT_TIMEOUT => 30,
+                CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
+                CURLOPT_CUSTOMREQUEST => "GET",
+                CURLOPT_HTTPHEADER => array(
+                    "Authorization: Bearer {$secretKey}",
+                    "Cache-Control: no-cache",
+                ),
+            ]);
+
+            $response = curl_exec($curl);
+            $err = curl_error($curl);
+            curl_close($curl);
+
+            if ($err) {
+                return [
+                    'status'    => false,
+                    'message'   => $err,
+                ];
+            }
+
+            return json_decode($response, true);
+        } catch (\Exception $e) {
+            return [
+                'status'    => false,
+                'message'   => $e->getMessage(),
+            ];
+        }
+    }
+
+    /**
+     * 交易退款.
+     * @param string $reference
+     * @param int $amount
+     * @return array
+     */
+    public static function transactionRefund(string $reference, int $amount)
+    {
+        $secretKey = self::getSecretKey();
+
+        try {
+            $url = "https://api.paystack.co/refund";
+            $fields = [
+                'transaction' => $reference,
+                'amount'      => $amount,
+            ];
+            $fields_string = http_build_query($fields);
+            //open connection
+            $curl = curl_init();
+
+            //set the url, number of POST vars, POST data
+            curl_setopt($curl, CURLOPT_URL, $url);
+            curl_setopt($curl, CURLOPT_POST, true);
+            curl_setopt($curl, CURLOPT_POSTFIELDS, $fields_string);
+            curl_setopt($curl, CURLOPT_HTTPHEADER, array(
+                "Authorization: Bearer {$secretKey}",
+                "Cache-Control: no-cache",
+            ));
+
+            //So that curl_exec returns the contents of the cURL; rather than echoing it
+            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+
+            //execute post
+            $response = curl_exec($curl);
+            $err = curl_error($curl);
+            curl_close($curl);
+
+            if ($err) {
+                return [
+                    'status'    => false,
+                    'message'   => $err,
+                ];
+            }
+
+            return json_decode($response, true);
+        } catch (\Exception $e) {
+            return [
+                'status'    => false,
+                'message'   => $e->getMessage(),
+            ];
+        }
+    }
+}

+ 379 - 0
common/helpers/Logistics.php

@@ -0,0 +1,379 @@
+<?php
+
+namespace common\helpers;
+
+use common\models\OrderGoods;
+use common\models\Region;
+use Yii;
+
+class Logistics
+{
+    const prodDomain = 'https//warehouse.taoplus.com.my';
+    const testDomain = 'http://warehouse.worldsyntech.com';
+
+    // 1.获取bearer token,此token是其他api调用时的必传参数.
+    const authenticationUrl = 'http://warehouse.taoplus.com.my/index.php?route=rest/admin_security/api_login&grant_type=client_credentials';
+    // 2.创建订单和产品(以前不存在/已提交的产品).
+    const createOrderUrl = 'http://warehouse.taoplus.com.my/index.php?route=rest/warehouse_api/add_order';
+    // 3.获取产品/包裹的重量和状态.
+    const getProductUrl = 'http://warehouse.worldsyntech.com/index.php?route=rest/warehouse_api/get_order_product';
+    // 4.获取订单重量,m3,包装的包裹数量,费用跟踪号码和状态.
+    const getOrderUrl = 'http://warehouse.worldsyntech.com/index.php?route=rest/warehouse_api/get_order';
+    // 5.通知仓库已经付款,包裹可以投递.
+    const notifyDeliveryUrl = 'http://warehouse.worldsyntech.com/index.php?route=rest/ warehouse_api/notify_delivery';
+    // 6.创建产品/包裹.
+    const addProductUrl = 'http://warehouse.worldsyntech.com/index.php?route=rest/warehouse_api/add_order_product';
+    // 7.创建交付订单并将现有产品绑定到订单.需要先调用接口6创建商品.
+    const createOrderSimpleUrl = 'http://warehouse.worldsyntech.com/index.php?route=rest/warehouse_api/add_order_simple';
+    // 8.计算订单费用,并将订单状态改为待付款.
+    const stockOutUrl = 'http://warehouse.worldsyntech.com/index.php?route=rest/warehouse_api/stock_out';
+    // 9.通知物流系统订单不可删除.error包含错误的订单ID.
+    const notifyOrderUndeletableUrl = 'http://warehouse.worldsyntech.com/index.php?route=rest/warehouse_api/notify_order_undeletable';
+    // 10.取消订单产品/包裹。它将状态更改为无效,并保留订单产品/包裹.
+    const cancelOrderProductUrl = 'http://warehouse.worldsyntech.com/index.php?route=rest/warehouse_api/cancel_order_product';
+    // 11.从数据库中删除订购产品/包裹.
+    const deleteOrderProductUrl = 'http://warehouse.worldsyntech.com/index.php?route=rest/warehouse_api/delete_order_product';
+    // 12.取消订单,状态改为无效,保留订单不删除.
+    const cancelOrderUrl = 'http://warehouse.worldsyntech.com/index.php?route=rest/warehouse_api/cancel_order';
+    // 13.从数据库中删除订单.
+    const deleteOrderUrl = 'http://warehouse.worldsyntech.com/index.php?route=rest/warehouse_api/delete_order';
+    // 14.运单追踪.
+    const trackOrderUrl = 'https://taoplus.com.my/index.php?route=information/order_tracking/json&order_tracking_search=';
+
+    // accessToken的缓存key
+    const wstLogisticsBearerTokenKey = 'wstLogisticsBearerToken';
+
+    // 国家
+    const country = 'China';
+
+    function __construct()
+    {
+//         if (!\Yii::$app->redis->get(self::wstLogisticsBearerTokenKey)) {
+            $this->getAuthentication();
+//         }
+    }
+
+    /**
+     * 通用curl接口.
+     * @param string $url api接口url
+     * @param array $request_body 参数
+     * @return mixed
+     */
+    function curl($url, $request_body)
+    {
+        $accessToken = \Yii::$app->redis->get(self::wstLogisticsBearerTokenKey);
+
+        $ch = curl_init($url);
+        header('Content-Type: application/json');
+        $authorization = "Authorization: Bearer " . $accessToken;
+        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json', $authorization]);
+        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($request_body));
+        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
+        $response = curl_exec($ch);
+        curl_close($ch);
+
+        return json_decode($response, true);
+    }
+
+    // 1.获取bearer token,此token是其他api调用时的必传参数.
+    function getAuthentication()
+    {
+        $request = [
+            'user_name' => Yii::$app->params['wst']['userName'],
+            'password' => Yii::$app->params['wst']['password'],
+            'agent_id' => Yii::$app->params['wst']['agentId'],
+        ];
+
+        $ch = curl_init(self::authenticationUrl);
+        header('Content-Type: application/json');
+        $authorization = "Authorization: Basic " . Yii::$app->params['wst']['baseToken'];
+        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json', $authorization]);
+        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($request));
+        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
+        $response = curl_exec($ch);
+
+        curl_close($ch);
+
+        $result = json_decode($response, true);
+        if ($result['success']) {
+            // token和过期时间写入redis
+            \Yii::$app->redis->set(self::wstLogisticsBearerTokenKey, $result['data']['access_token']);
+            \Yii::$app->redis->expire(self::wstLogisticsBearerTokenKey, $result['data']['expires_in']);
+        }
+    }
+
+    // 2.创建订单和产品(以前不存在/已提交的产品).
+    function createOrder($order)
+    {
+        $request = [
+            'order_no' => $order['SN'],   // 客户系统中的订单号
+            'delivery_method_id' => '60', // 快递方式ID. TODO: 133(test)
+            'warehouse_id' => '1',   // 仓库ID. TODO:
+            'country' => 'China',    // 收件人国家 Malaysia
+            'state' => Region::getCnName($order['PROVINCE']), // ,   // 收件人省 Johor(test)
+            'city' => Region::getCnName($order['CITY']) . Region::getCnName($order['COUNTY']),   // 收件市县
+            'post_code' => $order['ZIP_CODE'], // 收件人邮政编码
+            'address' => $order['ADDRESS'],    // 收件人送货地址
+            'consignee' => $order['CONSIGNEE_REAL_NAME'],  // 收货人姓名,使用订单中的收货人真实姓名
+            'consignee_ic_number' => $order['CONSIGNEE_ID_NO'], // 收件人身份证号
+            'telephone' => $order['MOBILE'],  // 收件人电话号码
+            'sender' => 'Elken',    // 发件人名字
+            'sender_country' => 'Malaysia',    // 发件人国家
+            'sender_state' => 'Selangor', // ,   // 发件人省
+            'sender_city' => 'Kuala Lumpur',   // 发件人市县
+            'sender_post_code' => '47620', // 发件人邮政编码
+            'sender_address' => '11, 2nd Floor, Jalan TP5, Taman Perindustrian UEP, Subang Jaya',    // 发件人地址
+            'sender_telephone' => '0380210088',  // 发件人电话号码
+            'volumetric_details' => '3*4*20',    // 规格
+        ];
+
+        // 查询商品
+        $orderGoods = OrderGoods::find()->where('ORDER_SN=:ORDER_SN', [':ORDER_SN' => $order['SN']])->select('ORDER_SN,REAL_PRICE,BUY_NUMS,SKU_CODE,GOODS_TITLE')->asArray()->all();
+
+        $products = [];
+        foreach ($orderGoods as $item) {
+            $products[] = [
+                'product_no' => $item['SKU_CODE'], // 客户系统中的产品编号
+                'product_name' => $item['GOODS_TITLE'],   // 产品名称
+                'tracking_number' => Date::today('Ymd') . $this->_random(10, 1),
+                'quantity' => $item['BUY_NUMS'],       // 产品数量
+                'total_price' => number_format(100, 2, '.', ''),    // 订单总金额,Decimal 方便通关,固定100马币
+                'currency_code' => 'MYR',  // 产品的货币代码. 如USD(美元),MYR(马来西亚林吉特),SGD(新加坡元),CNY(人民币)
+                'supplier' => 'MRT',    // 品牌
+                'remark' => '300ML', // 备注:规格
+            ];
+        }
+        $request['products'] = $products;
+
+        return $this->curl(self::createOrderUrl, $request);
+    }
+
+    // 3.获取产品/包裹的重量和状态.
+    function getProduct($order)
+    {
+        $request = [
+            'tracking_number' => '027300027300',
+        ];
+
+        $response = $this->curl(self::getProductUrl, $request);
+        LoggerTool::info($response);
+
+        return $response;
+    }
+
+    // 4.获取订单重量,m3,包装的包裹数量,费用跟踪号码和状态
+    function getOrder($order)
+    {
+        $request = [
+            'order_id' => 'elg8-785',
+        ];
+
+        $response = $this->curl(self::getOrderUrl, $request);
+        LoggerTool::info($response);
+
+        return $response;
+    }
+
+    // 5.通知仓库已经付款,包裹可以投递.
+    function notifyDelivery($order)
+    {
+        $request = [
+            'order_id' => 'elg8-785',
+        ];
+
+        $response = $this->curl(self::notifyDeliveryUrl, $request);
+        LoggerTool::info($response);
+
+        return $response;
+    }
+
+    // 6.创建产品/包裹.
+    function addProduct($orderProducts)
+    {
+        $products = [];
+        foreach ($orderProducts as $item) {
+            $products[] = [
+                "product_no" => $item['SKU_CODE'],
+                "product_name" => $item['GOODS_TITLE'],
+                "tracking_number" => '',
+                "quantity" => $item['BUY_NUMS'],
+                "total_price" => $item['REAL_PV'],
+                "currency_code" => "CNY",
+            ];
+        }
+
+        $request = [
+            'warehouse_id' => '1',
+            "products" => $products
+        ];
+
+        $response = $this->curl(self::addProductUrl, $request);
+        LoggerTool::info($response);
+        return $response;
+    }
+
+    // 7.创建交付订单并将现有产品绑定到订单.需要先调用接口6创建商品.
+    function createOrderSimple($order)
+    {
+        $request = [
+            "order_no" => "T-1000",
+            "delivery_method_id" => "39",
+            "warehouse_id" => "1",
+            "country" => "Malaysia",
+            "state" => "Pulau Pinang",
+            "city" => "Bukit Mertajam",
+            "post_code" => "14000",
+            "address" => "1584,JALAN NANGKA,TAMAN JAMBU MAWAR,14000 BUKIT MERTAJAM",
+            "consignee" => "TSA",
+            "consignee_ic_number" => "111111-11-1111",
+            "telephone" => "017-5423223",
+            "cod" => "CNY",
+            "cod_currency_code" => "100",
+            "address_area" => "",
+            "address_subdivision" => "",
+            "products" => [
+                [
+                    "product_no" => "12345",
+                    "tracking_number" => "2019061112A1",
+                ],
+                [
+                    "product_no" => "23456",
+                    "tracking_number" => "20190604_A12",
+                ]
+            ]
+        ];
+
+        $response = $this->curl(self::createOrderSimpleUrl, $request);
+        LoggerTool::info($response);
+
+        return $response;
+    }
+
+    // 8.根据货物重量计算订单费用,并更改订单状态为待付款
+    function stockOut($order)
+    {
+        $request = [
+            'order_id' => 'elg8-785',
+            'weight' => '2.5', // 订单重量(KG)
+        ];
+
+        $response = $this->curl(self::stockOutUrl, $request);
+        LoggerTool::info($response);
+
+        return $response;
+    }
+
+    // 9.通知物流系统订单不可删除. error包含错误的订单ID.
+    function notifyOrderUndeletable($order)
+    {
+        $request = [
+            'order_ids' => ['elg8-785']
+        ];
+
+        $response = $this->curl(self::notifyOrderUndeletableUrl, $request);
+        LoggerTool::info($response);
+
+        return $response;
+    }
+
+    // 10.取消订单产品/包裹。它将状态更改为无效,并保留订单产品/包裹.
+    function cancelOrderProduct($order)
+    {
+        $request = [
+            'order_product_ids' => ['15895', '15896', '15897']
+        ];
+
+        $response = $this->curl(self::cancelOrderProductUrl, $request);
+        LoggerTool::info($response);
+
+        return $response;
+    }
+
+    // 11.从数据库中删除订购产品/包裹.
+    function deleteOrderProduct($order)
+    {
+        $request = [
+            'order_product_ids' => ['15895', '15896', '15897']
+        ];
+
+        $response = $this->curl(self::deleteOrderProductUrl, $request);
+        LoggerTool::info($response);
+
+        return $response;
+    }
+
+    // 12.取消订单,状态改为无效,保留订单不删除.
+    function cancelOrder($order)
+    {
+        $request = [
+            'order_ids' => ['elg8-787', 'elg8-786']
+        ];
+
+        $response = $this->curl(self::cancelOrderUrl, $request);
+        LoggerTool::info($response);
+
+        return $response;
+    }
+
+    // 13.从数据库中删除订单.
+    function deleteOrder($order)
+    {
+        $request = [
+            'order_ids' => ['elg8-787', 'elg8-786']
+        ];
+
+        $response = $this->curl(self::deleteOrderUrl, $request);
+        LoggerTool::info($response);
+
+        return $response;
+    }
+
+    // 13.从数据库中删除订单.
+    function trackOrder($trackNo)
+    {
+        // 运单号
+        $trackNo = 'TBS10182495KJ2430';
+
+        $curl = curl_init();
+        curl_setopt($curl,CURLOPT_TIMEOUT,5000);
+        curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,false);
+        curl_setopt($curl,CURLOPT_SSL_VERIFYHOST,false);
+        curl_setopt($curl,CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
+        curl_setopt($curl,CURLOPT_URL, self::trackOrderUrl . $trackNo);
+        curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
+        $response = curl_exec($curl);
+        if (!$response) {
+            $error = curl_errno($curl);
+            curl_close($curl);
+            LoggerTool::error($error);
+            return false;
+        }
+        curl_close($curl);
+
+        $result = json_decode($response, true);
+        LoggerTool::info($result);
+
+        return $result['data'];
+    }
+
+    /**
+     * 生成随机数
+     * @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;
+    }
+}

+ 54 - 0
common/helpers/Tool.php

@@ -9,6 +9,8 @@
 namespace common\helpers;
 
 
+use common\models\ApproachOrderCall;
+use common\models\WstOrderCall;
 use Faker\Provider\Uuid;
 use yii\base\Exception;
 use yii\helpers\Url;
@@ -471,4 +473,56 @@ class Tool {
         $uuid = !$upper ? Uuid::uuid() : strtoupper(Uuid::uuid());
         return str_replace('-', $symbol, $uuid);
     }
+
+    /**
+     * iPay88订单写入MongoDB.
+     * @param $call
+     * @return void
+     * @throws \Exception
+     */
+    public static function approachOrderCall($call)
+    {
+        try {
+            $model = new ApproachOrderCall();
+            $model->sn = $call['RefNo'];
+            $model->TransId = $call['TransId'];
+            $model->Signature = $call['Signature'];
+            $model->data = $call;
+            $model->insert();
+        } catch (\yii\mongodb\Exception $e) {
+            LoggerTool::info($call);
+            LoggerTool::error(sprintf('[%s] [%s] [%s]', $e->getFile(), $e->getLine(), $e->getMessage()));
+        }
+    }
+
+    /**
+     * 订单推送wst系统回执写入mongo.
+     * @param $call
+     * @return void
+     * @throws \Exception
+     */
+    public static function wstOrderCall($call)
+    {
+        try {
+            $model = new WstOrderCall();
+            $model->order_id = $call['order_id'];
+            $model->order_no = $call['order_no'];
+            $model->warehouse_id = $call['warehouse_id'];
+            $model->delivery_method_name = $call['warehouse_id'];
+            $model->addon_service_name = $call['addon_service_name'];
+            $model->country = $call['country'];
+            $model->state = $call['state'];
+            $model->city = $call['city'];
+            $model->post_code = $call['post_code'];
+            $model->address = $call['address'];
+            $model->consignee = $call['consignee'];
+            $model->telephone = $call['telephone'];
+            $model->comment = $call['comment'];
+            $model->products = $call['products'];
+            $model->insert();
+        } catch (\yii\mongodb\Exception $e) {
+            LoggerTool::info($call);
+            LoggerTool::error(sprintf('[%s] [%s] [%s]', $e->getFile(), $e->getLine(), $e->getMessage()));
+        }
+    }
 }

+ 854 - 853
common/helpers/user/Balance.php

@@ -1,853 +1,854 @@
-<?php
-/**
- * Created by PhpStorm.
- * User: leo
- * Date: 2018/10/30
- * Time: 下午3:19
- */
-
-namespace common\helpers\user;
-
-use common\components\ActiveRecord;
-use common\helpers\Cache;
-use common\helpers\Date;
-use common\helpers\Form;
-use common\libs\lock\RedisLock;
-use common\models\FlowBonus;
-use common\models\FlowCF;
-use common\models\FlowLX;
-use common\models\FlowReconsumePoints;
-use common\models\InvoiceFlow;
-use common\models\Period;
-use common\models\DeclarationLevel;
-use common\models\DecRole;
-use common\models\FlowExchangePoints;
-use common\models\UserPeriodPoints;
-use common\models\UserWallet;
-use common\models\UserBonus;
-use common\models\UserInfo;
-use common\models\UserPeriodExchangePoints;
-use yii\base\Exception;
-use yii\db\Expression;
-
-class Balance {
-    const INCR_REDUCE = 0;      // 减少
-    const INCR_ADD = 1;         // 增加
-    const INCR_FREEZE = 2;      // 冻结
-    const INCR_UNFREEZE = 3;    // 解冻
-
-    const BONUS_BALANCE_LOCK_KEY = 'Bonus';
-    const RECONSUME_POINTS_BALANCE_LOCK_KEY = 'reconsumePoints';
-    const EXCHANGE_POINTS_BALANCE_LOCK_KEY = 'exchangePoints';
-    const CF_BALANCE_LOCK_KEY = 'CF';
-    const LX_BALANCE_LOCK_KEY = 'LX';
-    const INVOICE_BALANCE_LOCK_KEY = 'Invoice';
-
-    /**
-     * 发票流水
-     * @param $userId
-     * @param $amount
-     * @param $params
-     * @return bool
-     * @throws Exception
-     * @throws \yii\db\Exception
-     */
-    public static function changeInvoice($userId, $amount, $params) {
-        if ($amount == 0) return true;
-        $period = Period::instance();
-        if (!isset($params['PERIOD_NUM'])) {
-            $periodNum = $period->getNowPeriodNum();
-        } else {
-            $periodNum = $params['PERIOD_NUM'];
-        }
-        $calcYearMonth = $period->getYearMonth($periodNum);
-        // redis加锁(防止并发余额数值不准确出错)
-        $lockKey = self::INVOICE_BALANCE_LOCK_KEY . $userId;
-        if (RedisLock::instance()->lock($lockKey)) {
-            $userInfo = UserInfo::findOne(['USER_ID' => $userId]);
-            $totals = $userInfo->INVOICE_BALANCE + $amount;
-            $userInfo->INVOICE_BALANCE = $totals;
-            if (!$userInfo->save()) {
-                throw new \Exception(Form::formatErrorsForApi($userInfo->getErrors()));
-            }
-            //记录流水
-            $baseInfo = Info::baseInfoZh($userId);
-            $flowInsertData = [
-                'USER_ID' => $userId,
-                'REAL_NAME' => $baseInfo['REAL_NAME'],
-                'DEC_LV' => $baseInfo['DEC_LV'],
-                'EMP_LV' => $baseInfo['EMP_LV'],
-                'MOBILE' => $baseInfo['MOBILE'],
-                'REG_TYPE' => $userInfo['REG_TYPE'],
-                'REG_NAME' => $userInfo['REG_NAME'],
-                'CREDIT_CODE' => $userInfo['CREDIT_CODE'],
-                'SALE_NAME' => $params['SALE_NAME'] ?? null,
-                'TAXPAYER_NUMBER' => $params['TAXPAYER_NUMBER'] ?? null,
-                'INVOICE_SN' => $params['INVOICE_SN'] ?? null,
-                'INVOICE_ACCOUNT' => $params['INVOICE_ACCOUNT'] ?? null,
-                'TAX_ACCOUNT' => $params['TAX_ACCOUNT'] ?? null,
-                'OUTED_AT' => $params['OUTED_AT'] ?? 0,
-                'AMOUNT' => abs($amount),
-                'TOTAL' => $totals,
-                'WITHDRAW_SN' => $params['WITHDRAW_SN'] ?? null,
-                'IS_INCR' => $amount > 0 ? self::INCR_ADD : self::INCR_REDUCE,
-                'PERIOD_NUM' => $periodNum,
-                'CALC_MONTH' => $calcYearMonth,
-                'REMARK' => $params['REMARK'] ?? null,
-                'CREATE_ADMIN' => $params['CREATE_ADMIN'],
-                'CREATE_REMARK' => $params['CREATE_REMARK'] ?? null,
-                'CREATE_TIME' => $params['CREATE_TIME'],
-                'AUDIT_ADMIN' => $params['AUDIT_ADMIN'],
-                'AUDIT_REMARK' => $params['AUDIT_REMARK'] ?? null,
-                'AUDIT_TIME' => $params['AUDIT_TIME'],
-                'P_MONTH' => Date::ociToDate(),
-                'CREATED_AT' => $params['TIME'] ?? Date::nowTime(),
-            ];
-            InvoiceFlow::insertOne($flowInsertData);
-            unset($flowInsertData);
-            RedisLock::instance()->unlock($lockKey);
-        } else {
-            throw new Exception('流水产生错误');
-        }
-        return true;
-    }
-
-    /**
-     * 获取当前可用余额
-     * @param $userId
-     * @return int|mixed
-     */
-    public static function getAvailableBalance($userId) {
-        $oneData = UserBonus::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
-        if ($oneData) {
-            return $oneData['BONUS'] - $oneData['BONUS_FREEZE'];
-        } else {
-            return 0;
-        }
-    }
-
-    /**
-     * 获取当前车房养老奖余额
-     * @param $userId
-     * @return int|mixed
-     */
-    public static function getBalanceCF($userId) {
-        $oneData = UserBonus::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
-        if ($oneData) {
-            return $oneData['CF'];
-        } else {
-            return 0;
-        }
-    }
-
-    /**
-     * 获取当前复消积分余额
-     * @param $userId
-     * @return int|mixed
-     */
-    public static function getBalanceReconsumePoints($userId) {
-        $oneData = UserBonus::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
-        if ($oneData) {
-            return $oneData['RECONSUME_POINTS'];
-        } else {
-            return 0;
-        }
-    }
-
-    /**
-     * 获取当前兑换积分余额
-     * @param $userId
-     * @return int|mixed
-     */
-    public static function getBalanceExchangePoints($userId) {
-        $oneData = UserBonus::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
-        if ($oneData) {
-            return $oneData['EXCHANGE_POINTS'];
-        } else {
-            return 0;
-        }
-    }
-
-    /**
-     * 获取当前车房养老奖余额
-     * @param $userId
-     * @return int|mixed
-     */
-    public static function getBalanceLX($userId) {
-        $oneData = UserBonus::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
-        if ($oneData) {
-            return $oneData['LX'];
-        } else {
-            return 0;
-        }
-    }
-
-    /**
-     * 改变会员的余额
-     * @param $userId
-     * @param $type
-     * @param $amount
-     * @param array $params
-     * @param bool $allowMinus
-     * @return bool
-     * @throws Exception
-     * @throws \yii\db\Exception
-     */
-    public static function changeUserBonus($userId, $type, $amount, $params = [], $allowMinus = false) {
-        if (array_key_exists($type, UserBonus::TYPE)) {
-            $type = strtoupper($type);
-        }
-        if ($amount == 0) return true;
-        $period = Period::instance();
-        if (!isset($params['PERIOD_NUM'])) {
-            $periodNum = $period->getNowPeriodNum();
-        } else {
-            $periodNum = $params['PERIOD_NUM'];
-        }
-        $calcYearMonth = $period->getYearMonth($periodNum);
-        // redis加锁(防止并发余额数值不准确出错)
-        switch ($type) {
-            case 'BONUS':
-                $lockKey = self::BONUS_BALANCE_LOCK_KEY . $userId;
-                break;
-            case 'RECONSUME_POINTS':
-                $lockKey = self::RECONSUME_POINTS_BALANCE_LOCK_KEY . $userId;
-                break;
-            case 'EXCHANGE_POINTS':
-                $lockKey = self::EXCHANGE_POINTS_BALANCE_LOCK_KEY . $userId;
-                break;
-            case 'CF':
-                $lockKey = self::CF_BALANCE_LOCK_KEY . $userId;
-                break;
-            case 'LX':
-                $lockKey = self::LX_BALANCE_LOCK_KEY . $userId;
-                break;
-            default:
-                throw new Exception('流水类型错误');
-        }
-        if (RedisLock::instance()->lock($lockKey)) {
-            // 改变发奖
-            $paramData = [];
-            $oneUserBonusModel = UserBonus::findOne(['USER_ID' => $userId]);
-            if ($oneUserBonusModel) {
-                $paramData[$type] = new Expression($type.' + '.$amount);
-
-                $oneUserBonusModel->$type += $amount;
-                if ($oneUserBonusModel->$type < 0) {
-                    RedisLock::instance()->unlock($lockKey);
-                    throw new Exception('金额不足');
-                }
-
-                if (isset($params['QY'])) {
-                    $paramData['QY_TOTAL'] = new Expression('QY_TOTAL + '.$params['QY']);
-                    //$oneUserBonusModel->QY_TOTAL += $params['QY'];
-                }
-                if (isset($params['FW'])) {
-                    $paramData['FW_TOTAL'] = new Expression('FW_TOTAL + '.$params['FW']);
-                }
-                if (isset($params['YC'])) {
-                    $paramData['YC_TOTAL'] = new Expression('YC_TOTAL + '.$params['YC']);
-                    //$oneUserBonusModel->YC_TOTAL += $params['YC'];
-                }
-                if (isset($params['VIP'])) {
-                    $paramData['VIP_TOTAL'] = new Expression('VIP_TOTAL + '.$params['VIP']);
-                }
-                if (isset($params['BD'])) {
-                    $paramData['BD_TOTAL'] = new Expression('BD_TOTAL + '.$params['BD']);
-                    //$oneUserBonusModel->BD_TOTAL += $params['BD'];
-                }
-                if (isset($params['TG'])) {
-                    $paramData['TG_TOTAL'] = new Expression('TG_TOTAL + '.$params['TG']);
-                    //$oneUserBonusModel->TG_TOTAL += $params['TG'];
-                }
-                if (isset($params['YJ'])) {
-                    $paramData['YJ_TOTAL'] = new Expression('YJ_TOTAL + '.$params['YJ']);
-                    //$oneUserBonusModel->YJ_TOTAL += $params['YJ'];
-                }
-                if (isset($params['GX'])) {
-                    $paramData['GX_TOTAL'] = new Expression('GX_TOTAL + '.$params['GX']);
-                    //$oneUserBonusModel->GX_TOTAL += $params['GX'];
-                }
-                if (isset($params['GL'])) {
-                    $paramData['GL_TOTAL'] = new Expression('GL_TOTAL + '.$params['GL']);
-                    //$oneUserBonusModel->GL_TOTAL += $params['GL'];
-                }
-                if (isset($params['BS'])) {
-                    $paramData['BS_TOTAL'] = new Expression('BS_TOTAL + '.$params['BS']);
-                    //$oneUserBonusModel->GL_TOTAL += $params['GL'];
-                }
-                if (isset($params['ST'])) {
-                    $paramData['STORE_TOTAL'] = new Expression('STORE_TOTAL + '.$params['ST']);
-                }
-                if (isset($params['RECONSUME_POINTS_TOTAL'])) {
-                    $paramData['RECONSUME_POINTS_TOTAL'] = new Expression('RECONSUME_POINTS_TOTAL + '.$params['RECONSUME_POINTS_TOTAL']);
-                    //$oneUserBonusModel->RECONSUME_POINTS_TOTAL += $params['RECONSUME_POINTS_TOTAL'];
-                }
-                if (isset($params['EXCHANGE_POINTS_TOTAL'])) {
-                    $paramData['EXCHANGE_POINTS_TOTAL'] = new Expression('EXCHANGE_POINTS_TOTAL + '.$params['EXCHANGE_POINTS_TOTAL']);
-                    //$oneUserBonusModel->RECONSUME_POINTS_TOTAL += $params['RECONSUME_POINTS_TOTAL'];
-                }
-                if (isset($params['MANAGE_TAX'])) {
-                    $paramData['MANAGE_TAX'] = new Expression('MANAGE_TAX + '.$params['MANAGE_TAX']);
-                    //$oneUserBonusModel->MANAGE_TAX += $params['MANAGE_TAX'];
-                }
-
-                if (isset($params['ORI_QY'])) {
-                    $paramData['ORI_QY_TOTAL'] = new Expression('ORI_QY_TOTAL + '.$params['ORI_QY']);
-                    //$oneUserBonusModel->ORI_QY_TOTAL += $params['ORI_QY'];
-                }
-//                if (isset($params['ORI_FW'])) {
-//                    $paramData['ORI_FW_TOTAL'] = new Expression('ORI_FW_TOTAL + '.$params['ORI_FW']);
-//                }
-                if (isset($params['ORI_YC'])) {
-                    $paramData['ORI_YC_TOTAL'] = new Expression('ORI_YC_TOTAL + '.$params['ORI_YC']);
-                    //$oneUserBonusModel->ORI_YC_TOTAL += $params['ORI_YC'];
-                }
-                if (isset($params['ORI_VIP'])) {
-                    $paramData['ORI_VIP_TOTAL'] = new Expression('ORI_VIP_TOTAL + '.$params['ORI_VIP']);
-                }
-                if (isset($params['ORI_VIP'])) {
-                    $paramData['ORI_VIP_TOTAL'] = new Expression('ORI_VIP_TOTAL + '.$params['ORI_VIP']);
-                }
-                if (isset($params['ORI_STANDARD'])) {
-                    $paramData['ORI_STANDARD_TOTAL'] = new Expression('ORI_STANDARD_TOTAL + '.$params['ORI_STANDARD']);
-                }
-                if (isset($params['ORI_TG'])) {
-                    $paramData['ORI_TG_TOTAL'] = new Expression('ORI_TG_TOTAL + '.$params['ORI_TG']);
-                    //$oneUserBonusModel->ORI_TG_TOTAL += $params['ORI_TG'];
-                }
-                if (isset($params['ORI_YJ'])) {
-                    $paramData['ORI_YJ_TOTAL'] = new Expression('ORI_YJ_TOTAL + '.$params['ORI_YJ']);
-                    //$oneUserBonusModel->ORI_YJ_TOTAL += $params['ORI_YJ'];
-                }
-                if (isset($params['ORI_GX'])) {
-                    $paramData['ORI_GX_TOTAL'] = new Expression('ORI_GX_TOTAL + '.$params['ORI_GX']);
-                    //$oneUserBonusModel->ORI_GX_TOTAL += $params['ORI_GX'];
-                }
-                if (isset($params['ORI_GL'])) {
-                    $paramData['ORI_GL_TOTAL'] = new Expression('ORI_GL_TOTAL + '.$params['ORI_GL']);
-                    //$oneUserBonusModel->ORI_GL_TOTAL += $params['ORI_GL'];
-                }
-                if (isset($params['ORI_BS'])) {
-                    $paramData['ORI_BS_TOTAL'] = new Expression('ORI_BS_TOTAL + '.$params['ORI_BS']);
-                    //$oneUserBonusModel->ORI_GL_TOTAL += $params['ORI_GL'];
-                }
-                if (isset($params['ORI_ST'])) {
-                    $paramData['ORI_STORE_TOTAL'] = new Expression('ORI_STORE_TOTAL + '.$params['ORI_ST']);
-                }
-
-                if (isset($params['BONUS_TOTAL'])) {
-                    $paramData['BONUS_TOTAL'] = new Expression('BONUS_TOTAL + '.$params['BONUS_TOTAL']);
-                    //$oneUserBonusModel->BONUS_TOTAL += $params['BONUS_TOTAL'];
-                }
-                UserBonus::updateAll($paramData, 'USER_ID=:USER_ID', [':USER_ID' => $userId]);
-
-            } else {
-                $paramData = [
-                    'USER_ID'=>$userId,
-                    $type=>$amount,
-                    'CREATED_AT'=>Date::nowTime()
-                ];
-                if (isset($params['QY'])) {
-//                    $paramData['QY_TOTAL'] = new Expression('QY_TOTAL + '.$params['QY']);
-                    $paramData['QY_TOTAL'] = $params['QY'];
-                }
-                if (isset($params['FW'])) {
-//                    $paramData['FW_TOTAL'] = new Expression('FW_TOTAL + '.$params['FW']);
-                    $paramData['FW_TOTAL'] = $params['FW'];
-                }
-                if (isset($params['YC'])) {
-//                    $paramData['YC_TOTAL'] = new Expression('YC_TOTAL + '.$params['YC']);
-                    $paramData['YC_TOTAL'] = $params['YC'];
-                }
-                if (isset($params['VIP'])) {
-//                    $paramData['VIP_TOTAL'] = new Expression('VIP_TOTAL + '.$params['VIP']);
-                    $paramData['VIP_TOTAL'] = $params['VIP'];
-                }
-
-                if (isset($params['BD'])) {
-//                    $paramData['BD_TOTAL'] = new Expression('BD_TOTAL + '.$params['BD']);
-                    $paramData['BD_TOTAL'] = $params['BD'];
-                    //$oneUserBonusModel->BD_TOTAL += $params['BD'];
-                }
-                if (isset($params['TG'])) {
-//                    $paramData['TG_TOTAL'] = new Expression('TG_TOTAL + '.$params['TG']);
-                    $paramData['TG_TOTAL'] = $params['TG'];
-                }
-                if (isset($params['YJ'])) {
-//                    $paramData['YJ_TOTAL'] = new Expression('YJ_TOTAL + '.$params['YJ']);
-                    $paramData['YJ_TOTAL'] = $params['YJ'];
-                }
-                if (isset($params['GX'])) {
-//                    $paramData['GX_TOTAL'] = new Expression('GX_TOTAL + '.$params['GX']);
-                    $paramData['GX_TOTAL'] = $params['GX'];
-                }
-                if (isset($params['GL'])) {
-//                    $paramData['GL_TOTAL'] = new Expression('GL_TOTAL + '.$params['GL']);
-                    $paramData['GL_TOTAL'] = $params['GL'];
-                }
-                if (isset($params['BS'])) {
-                    $paramData['BS_TOTAL'] = $params['BS'];
-                    //$oneUserBonusModel->GL_TOTAL += $params['GL'];
-                }
-                if (isset($params['RECONSUME_POINTS_TOTAL'])) {
-//                    $paramData['RECONSUME_POINTS_TOTAL'] = new Expression('RECONSUME_POINTS_TOTAL + '.$params['RECONSUME_POINTS_TOTAL']);
-                    $paramData['RECONSUME_POINTS_TOTAL'] = $params['RECONSUME_POINTS_TOTAL'];
-                }
-                if (isset($params['MANAGE_TAX'])) {
-//                    $paramData['MANAGE_TAX'] = new Expression('MANAGE_TAX + '.$params['MANAGE_TAX']);
-                    $paramData['MANAGE_TAX'] = $params['MANAGE_TAX'];
-                }
-
-                if (isset($params['ORI_QY'])) {
-//                    $paramData['ORI_QY_TOTAL'] = new Expression('ORI_QY_TOTAL + '.$params['ORI_QY']);
-                    $paramData['ORI_QY_TOTAL'] = $params['ORI_QY'];
-                }
-//                if (isset($params['ORI_FW'])) {
-////                    $paramData['ORI_FW_TOTAL'] = new Expression('ORI_FW_TOTAL + '.$params['ORI_FW']);
-//                    $paramData['ORI_FW_TOTAL'] = $params['ORI_FW'];
-//                }
-                if (isset($params['ORI_YC'])) {
-//                    $paramData['ORI_YC_TOTAL'] = new Expression('ORI_YC_TOTAL + '.$params['ORI_YC']);
-                    $paramData['ORI_YC_TOTAL'] = $params['ORI_YC'];
-                }
-                if (isset($params['ORI_VIP'])) {
-//                    $paramData['ORI_VIP_TOTAL'] = new Expression('ORI_VIP_TOTAL + '.$params['ORI_VIP']);
-                    $paramData['ORI_VIP_TOTAL'] = $params['ORI_VIP'];
-                }
-                if (isset($params['ORI_STANDARD'])) {
-                    $paramData['ORI_STANDARD_TOTAL'] = $params['ORI_STANDARD'];
-                }
-                if (isset($params['ORI_BD'])) {
-//                    $paramData['ORI_BD_TOTAL'] = new Expression('ORI_BD_TOTAL + '.$params['ORI_BD']);
-                    $paramData['ORI_BD_TOTAL'] = $params['ORI_BD'];
-                }
-                if (isset($params['ORI_TG'])) {
-//                    $paramData['ORI_TG_TOTAL'] = new Expression('ORI_TG_TOTAL + '.$params['ORI_TG']);
-                    $paramData['ORI_TG_TOTAL'] = $params['ORI_TG'];
-                }
-                if (isset($params['ORI_YJ'])) {
-//                    $paramData['ORI_YJ_TOTAL'] = new Expression('ORI_YJ_TOTAL + '.$params['ORI_YJ']);
-                    $paramData['ORI_YJ_TOTAL'] = $params['ORI_YJ'];
-                }
-                if (isset($params['ORI_GX'])) {
-//                    $paramData['ORI_GX_TOTAL'] = new Expression('ORI_GX_TOTAL + '.$params['ORI_GX']);
-                    $paramData['ORI_GX_TOTAL'] = $params['ORI_GX'];
-                }
-                if (isset($params['ORI_GL'])) {
-//                    $paramData['ORI_GL_TOTAL'] = new Expression('ORI_GL_TOTAL + '.$params['ORI_GL']);
-                    $paramData['ORI_GL_TOTAL'] = $params['ORI_GL'];
-                }
-                if (isset($params['ORI_BS'])) {
-                    $paramData['ORI_BS_TOTAL'] = $params['ORI_BS'];
-                    //$oneUserBonusModel->ORI_GL_TOTAL += $params['ORI_GL'];
-                }
-
-                if (isset($params['BONUS_TOTAL'])) {
-//                    $paramData['BONUS_TOTAL'] = new Expression('BONUS_TOTAL + '.$params['BONUS_TOTAL']);
-                    $paramData['BONUS_TOTAL'] = $params['BONUS_TOTAL'];
-                }
-                UserBonus::insertOne($paramData);
-            }
-
-            unset($oneUserBonusModel,$paramData);
-            // 获取发放完成的奖金信息
-            $oneUserBonus = UserBonus::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
-            $userInfo = Info::getLastInfo($userId);
-            // 记录流水
-            $flowInsertData = [
-                'USER_ID' => $userId,
-                'LAST_DEC_LV' => $userInfo['DEC_LV'],
-                'LAST_EMP_LV' => $userInfo['LAST_EMP_LV'],
-                'LAST_STATUS' => $userInfo['STATUS'],
-                'CALC_ID' => $params['CALC_ID'] ?? null,
-                'AMOUNT' => $amount,
-                'TOTAL' => $oneUserBonus[$type],
-                'IS_INCR' => $amount > 0 ? FlowBonus::INCR_ADD : FlowBonus::INCR_REDUCE,
-                'REMARK' => $params['REMARK'] ?? null,
-                'REMARK_IS_SHOW' => $params['REMARK_IS_SHOW'] ?? 1,
-                'PERIOD_NUM' => $params['PERIOD_NUM'] ?? $periodNum,
-                'CALC_MONTH' => $calcYearMonth,
-                'P_MONTH' => Date::ociToDate(),
-                'CREATED_AT' => $params['TIME'] ?? Date::nowTime(),
-                'ADMIN_NAME' => $params['ADMIN_NAME'] ?? 'system',
-                'DEAL_TYPE_ID' => $params['DEAL_TYPE_ID'] ?? '',
-                'DEAL_TYPE_IS_PRESET' => $params['DEAL_TYPE_IS_PRESET'] ?? 1,
-                'TRANSFER_SN' => $params['TRANSFER_SN'] ?? '',
-                'SORT' => $params['SORT'] ?? 0,
-            ];
-            unset($userInfo, $oneUserBonus);
-            if (strtolower($type) == 'reconsume_points' || strtolower($type) == 'cf' || strtolower($type) == 'lx' 
-                || strtolower($type) == 'exchange_points'
-            ) {
-                unset($flowInsertData['CALC_ID']);
-                unset($flowInsertData['TRANSFER_SN']);
-                unset($flowInsertData['SORT']);
-            }
-            if (strtolower($type) == 'bonus') {
-                FlowBonus::insertOne($flowInsertData);
-            } elseif (strtolower($type) == 'reconsume_points') {
-                //记录和扣除期数的积分
-                if( $amount > 0 ) {
-                    self::addPeriodReconsumePoints($userId, $periodNum, $amount);
-                }else {
-                    self::deductPeriodReconsumePoints($userId, abs($amount));
-                }
-                FlowReconsumePoints::insertOne($flowInsertData);
-            } elseif (strtolower($type) == 'exchange_points') {
-                //记录和扣除期数的积分
-                if( $amount > 0 ) {
-                    self::addPeriodExchangePoints($userId, $periodNum, $amount);
-                }else {
-                    self::deductPeriodExchangePoints($userId, abs($amount));
-                }
-                FlowExchangePoints::insertOne($flowInsertData);
-            } elseif (strtolower($type) == 'cf') {
-                FlowCF::insertOne($flowInsertData);
-            } elseif (strtolower($type) == 'lx') {
-                FlowLX::insertOne($flowInsertData);
-            }
-            unset($flowInsertData);
-            RedisLock::instance()->unlock($lockKey);
-        } else {
-            throw new Exception('流水产生错误');
-        }
-        return true;
-    }
-
-    /**
-     * 添加对应期数的复消积分
-     * @param $userId
-     * @param $periodNum
-     * @param $amount
-     * @throws \yii\db\Exception
-     * @return boolean
-     */
-    public static function addPeriodReconsumePoints($userId, $periodNum, $amount) {
-        if($amount <= 0) return false;
-        $exists = UserPeriodPoints::find()->where('USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', [
-            'USER_ID' => $userId,
-            'PERIOD_NUM' => $periodNum,
-        ])->asArray()->exists();
-        if( $exists ) {
-            UserPeriodPoints::updateAllCounters([
-                'RECONSUME_POINTS' => $amount,
-                'REMAINDER_POINTS' => $amount,
-            ], 'USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', [
-                'USER_ID' => $userId,
-                'PERIOD_NUM' => $periodNum,
-            ]);
-        }else {
-            UserPeriodPoints::insertOne([
-                'USER_ID' => $userId,
-                'PERIOD_NUM' => $periodNum,
-                'RECONSUME_POINTS' => $amount,
-                'REMAINDER_POINTS' => $amount,
-                'EXPIRED' => 0,
-                'CREATED_AT' => Date::nowTime()
-            ]);
-        }
-
-        return true;
-    }
-
-    /**
-     * 添加对应期数的兑换积分
-     * @param $userId
-     * @param $periodNum
-     * @param $amount
-     * @throws \yii\db\Exception
-     * @return boolean
-     */
-    public static function addPeriodExchangePoints($userId, $periodNum, $amount) {
-        if($amount <= 0) return false;
-        $exists = UserPeriodExchangePoints::find()->where('USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', [
-            'USER_ID' => $userId,
-            'PERIOD_NUM' => $periodNum,
-        ])->asArray()->exists();
-        if( $exists ) {
-            UserPeriodExchangePoints::updateAllCounters([
-                'EXCHANGE_POINTS' => $amount,
-                'REMAINDER_POINTS' => $amount,
-            ], 'USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', [
-                'USER_ID' => $userId,
-                'PERIOD_NUM' => $periodNum,
-            ]);
-        }else {
-            UserPeriodExchangePoints::insertOne([
-                'USER_ID' => $userId,
-                'PERIOD_NUM' => $periodNum,
-                'EXCHANGE_POINTS' => $amount,
-                'REMAINDER_POINTS' => $amount,
-                'EXPIRED' => 0,
-                'CREATED_AT' => Date::nowTime()
-            ]);
-        }
-
-        return true;
-    }
-
-
-    /**
-     * 减少
-     * @param $userId
-     * @param $amount
-     * @return bool
-     */
-    public static function deductPeriodReconsumePoints($userId, $amount) {
-        if( $amount <= 0 ) return false;
-        $avalidList = UserPeriodPoints::find()->where('USER_ID=:USER_ID AND EXPIRED=:EXPIRED AND REMAINDER_POINTS>0', [
-            'USER_ID' => $userId,
-            'EXPIRED'=>0
-        ])->orderBy('PERIOD_NUM ASC')->asArray()->all();
-        if( !$avalidList ) return false;
-
-        foreach ($avalidList as $everyData) {
-            if( $amount <= 0 ) break;
-
-            $remainderPoints = floatval($everyData['REMAINDER_POINTS']);
-            if( $amount >= $remainderPoints ) {
-                UserPeriodPoints::updateAllCounters([
-                    'REMAINDER_POINTS' => (-1) * $remainderPoints
-                ], 'ID=:ID', ['ID'=>$everyData['ID']]);
-
-                $amount -= $remainderPoints;
-            }else {
-                UserPeriodPoints::updateAllCounters([
-                    'REMAINDER_POINTS' => (-1) * $amount
-                ], 'ID=:ID', ['ID'=>$everyData['ID']]);
-
-                $amount = 0;
-            }
-
-            unset($everyData, $remainderPoints);
-        }
-        if( $amount > 0 ) return false;
-
-        return true;
-    }
-
-    /**
-     * 减少
-     * @param $userId
-     * @param $amount
-     * @return bool
-     */
-    public static function deductPeriodExchangePoints($userId, $amount) {
-        if( $amount <= 0 ) return false;
-        $avalidList = UserPeriodExchangePoints::find()->where('USER_ID=:USER_ID AND EXPIRED=:EXPIRED AND REMAINDER_POINTS>0', [
-            'USER_ID' => $userId,
-            'EXPIRED'=>0
-        ])->orderBy('PERIOD_NUM ASC')->asArray()->all();
-        if( !$avalidList ) return false;
-
-        foreach ($avalidList as $everyData) {
-            if( $amount <= 0 ) break;
-
-            $remainderPoints = floatval($everyData['REMAINDER_POINTS']);
-            if( $amount >= $remainderPoints ) {
-                UserPeriodExchangePoints::updateAllCounters([
-                    'REMAINDER_POINTS' => (-1) * $remainderPoints
-                ], 'ID=:ID', ['ID'=>$everyData['ID']]);
-
-                $amount -= $remainderPoints;
-            }else {
-                UserPeriodExchangePoints::updateAllCounters([
-                    'REMAINDER_POINTS' => (-1) * $amount
-                ], 'ID=:ID', ['ID'=>$everyData['ID']]);
-
-                $amount = 0;
-            }
-
-            unset($everyData, $remainderPoints);
-        }
-        if( $amount > 0 ) return false;
-
-        return true;
-    }
-
-    /**
-     * 冻结用户余额
-     * @param $userId
-     * @param $amount
-     * @param null $remark
-     * @param null $time
-     * @return bool
-     * @throws Exception
-     * @throws \yii\db\Exception
-     */
-    public static function freezeUserBonus($userId, $amount, $remark = null, $time = null) {
-        return self::changeFreezeUserBonus($userId, $amount, ['REMARK' => $remark, 'TIME' => $time]);
-    }
-
-    /**
-     * 解冻用户余额
-     * @param $userId
-     * @param $amount
-     * @param null $remark
-     * @param null $time
-     * @return bool
-     * @throws Exception
-     * @throws \yii\db\Exception
-     */
-    public static function unfreezeUserBonus($userId, $amount, $remark = null, $time = null) {
-        return self::changeFreezeUserBonus($userId, -$amount, ['REMARK' => $remark, 'TIME' => $time]);
-    }
-
-    /**
-     * @param $userId
-     * @param $amount
-     * @param $params
-     * [
-     *      'REMARK' => '备注',
-     *      'PERIOD_NUM' => 100,
-     * ]
-     * @return bool
-     * @throws Exception
-     * @throws \yii\db\Exception
-     */
-    public static function changeFreezeUserBonus($userId, $amount, $params) {
-        if ($amount == 0) return true;
-        $period = Period::instance();
-        if (!isset($params['PERIOD_NUM'])) {
-            $periodNum = $period->getNowPeriodNum();
-        } else {
-            $periodNum = $params['PERIOD_NUM'];
-        }
-        $calcYearMonth = $period->getYearMonth($periodNum);
-        // 改变冻结
-        $oneUserBonusModel = UserBonus::findOne(['USER_ID' => $userId]);
-        if ($oneUserBonusModel) {
-            $oneUserBonusModel->BONUS_FREEZE = $oneUserBonusModel->BONUS_FREEZE + $amount;
-        } else {
-            $oneUserBonusModel = new UserBonus();
-            $oneUserBonusModel->USER_ID = $userId;
-            $oneUserBonusModel->BONUS_FREEZE = $amount;
-        }
-        if (!$oneUserBonusModel->save()) {
-            throw new Exception(Form::formatErrorsForApi($oneUserBonusModel->getErrors()));
-        }
-        unset($oneUserBonusModel);
-        // 流水
-        // 获取发放完成的奖金信息
-        $oneUserBonus = UserBonus::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
-        // 记录流水
-        $flowInsertData = [
-            'USER_ID' => $userId,
-            'AMOUNT' => abs($amount),
-            'TOTAL' => $oneUserBonus['BONUS'],
-            'IS_INCR' => $amount > 0 ? FlowBonus::INCR_FREEZE : FlowBonus::INCR_UNFREEZE,
-            'REMARK' => $params['REMARK'] ?? null,
-            'PERIOD_NUM' => $params['PERIOD_NUM'] ?? $periodNum,
-            'CALC_MONTH' => $calcYearMonth,
-            'P_MONTH' => Date::ociToDate(),
-            'CREATED_AT' => $params['TIME'] ?? Date::nowTime(),
-        ];
-
-        FlowBonus::insertOne($flowInsertData);
-        unset($flowInsertData);
-        return true;
-    }
-
-    /**
-     * 清空会员奖金有流水
-     * @param $userId
-     * @param array $params
-     * @throws Exception
-     * @throws \yii\db\Exception
-     */
-    public static function clearAllBonus($userId, $params = []) {
-        // 先查找会员的全部余额
-        $userBonus = UserBonus::findOne(['USER_ID' => $userId]);
-        // 如果没有会员余额数据,新建余额数据
-        if (!$userBonus) {
-            UserBonus::insertOne(['USER_ID' => $userId, 'CREATED_AT' => Date::nowTime()]);
-        } else {
-            $period = Period::instance();
-            foreach (\Yii::$app->params['bonusWalletType'] as $type) {
-                $field = strtoupper($type['name']);
-                if ($userBonus[$field]<=0) continue;
-                $userInfo = Info::getLastInfo($userId);
-                $flowInsertData = [
-                    'USER_ID' => $userId,
-                    'LAST_DEC_LV' => $userInfo['DEC_LV'],
-                    'LAST_EMP_LV' => $userInfo['EMP_LV'],
-                    'LAST_STATUS' => $userInfo['STATUS'],
-                    'CALC_ID' => $params['CALC_ID'] ?? null,
-                    'AMOUNT' => -$userBonus[$field],
-                    'TOTAL' => 0,
-                    'IS_INCR' => FlowBonus::INCR_REDUCE,
-                    'REMARK' => $params['REMARK'] ?? null,
-                    'REMARK_IS_SHOW' => $params['REMARK_IS_SHOW'] ?? 1,
-                    'PERIOD_NUM' => $params['PERIOD_NUM'] ?? $period->getNowPeriodNum(),
-                    'CALC_MONTH' => $period->getNowYearMonth(),
-                    'P_MONTH' => Date::ociToDate(),
-                    'CREATED_AT' => $params['TIME'] ?? Date::nowTime(),
-                    'ADMIN_NAME' => $params['ADMIN_NAME'] ?? 'system',
-                    'DEAL_TYPE_ID' => $params['DEAL_TYPE_ID'] ?? '',
-                    'DEAL_TYPE_IS_PRESET' => $params['DEAL_TYPE_IS_PRESET'] ?? 1,
-                    'TRANSFER_SN' => $params['TRANSFER_SN'] ?? '',
-                    'SORT' => $params['SORT'] ?? 0,
-                ];
-
-                // 流水
-                if (strtolower($field) == 'bonus') FlowBonus::insertOne($flowInsertData);
-                elseif (strtolower($field) == 'cf') {
-                    unset($flowInsertData['CALC_ID']);
-                    unset($flowInsertData['SORT']);
-                    unset($flowInsertData['TRANSFER_SN']);
-                    FlowCF::insertOne($flowInsertData);
-                } elseif (strtolower($field) == 'lx') {
-                    unset($flowInsertData['CALC_ID']);
-                    unset($flowInsertData['SORT']);
-                    unset($flowInsertData['TRANSFER_SN']);
-                    FlowLX::insertOne($flowInsertData);
-                }
-            }
-            // 清空
-            $userBonus->BONUS = 0;
-            $userBonus->CF = 0;
-            $userBonus->LX = 0;
-            if (!$userBonus->save()) {
-                throw new Exception(Form::formatErrorsForApi($userBonus->getErrors()));
-            }
-        }
-        FlowBonus::updateAll(['DELETED' => 1, 'DELETED_AT' => Date::nowTime()], 'USER_ID=:USER_ID', [':USER_ID' => $userId]);
-        FlowCF::updateAll(['DELETED' => 1, 'DELETED_AT' => Date::nowTime()], 'USER_ID=:USER_ID', [':USER_ID' => $userId]);
-        FlowLX::updateAll(['DELETED' => 1, 'DELETED_AT' => Date::nowTime()], 'USER_ID=:USER_ID', [':USER_ID' => $userId]);
-    }
-
-    /**
-     * 是否存在奖金余额
-     * @param $userId
-     * @return bool
-     */
-    public static function hasBonus($userId) {
-        $userBonus = UserBonus::findOne(['USER_ID' => $userId]);
-        if (!$userBonus) {
-            return false;
-        }
-        foreach (\Yii::$app->params['bonusWalletType'] as $type) {
-            $field = strtoupper($type['name']);
-            if (isset($userBonus[$field]) && $userBonus[$field] > 0) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * 获取金额用于日志
-     * @param $userId
-     * @return array
-     */
-    public static function getLogData($userId){
-        $userWallet = UserWallet::findOne(['USER_ID' => $userId]);
-        $cash = !empty($userWallet) ? $userWallet['CASH'] : '';
-        $userName = Info::getUserNameByUserId($userId);
-        $data = [];
-        $data[$userId]['label'] = $userName.'余额';
-        $data[$userId]['value'] = '奖金'.self::getAvailableBalance($userId).',现金'.$cash;
-        return $data;
-    }
-}
+<?php
+/**
+ * Created by PhpStorm.
+ * User: leo
+ * Date: 2018/10/30
+ * Time: 下午3:19
+ */
+
+namespace common\helpers\user;
+
+use common\components\ActiveRecord;
+use common\helpers\Cache;
+use common\helpers\Date;
+use common\helpers\Form;
+use common\libs\lock\RedisLock;
+use common\models\FlowBonus;
+use common\models\FlowCF;
+use common\models\FlowLX;
+use common\models\FlowReconsumePoints;
+use common\models\InvoiceFlow;
+use common\models\Period;
+use common\models\DeclarationLevel;
+use common\models\DecRole;
+use common\models\FlowExchangePoints;
+use common\models\UserPeriodPoints;
+use common\models\UserWallet;
+use common\models\UserBonus;
+use common\models\UserInfo;
+use common\models\UserPeriodExchangePoints;
+use yii\base\Exception;
+use yii\db\Expression;
+
+class Balance {
+    const INCR_REDUCE = 0;      // 减少
+    const INCR_ADD = 1;         // 增加
+    const INCR_FREEZE = 2;      // 冻结
+    const INCR_UNFREEZE = 3;    // 解冻
+
+    const BONUS_BALANCE_LOCK_KEY = 'Bonus';
+    const RECONSUME_POINTS_BALANCE_LOCK_KEY = 'reconsumePoints';
+    const EXCHANGE_POINTS_BALANCE_LOCK_KEY = 'exchangePoints';
+    const CF_BALANCE_LOCK_KEY = 'CF';
+    const LX_BALANCE_LOCK_KEY = 'LX';
+    const INVOICE_BALANCE_LOCK_KEY = 'Invoice';
+
+    /**
+     * 发票流水
+     * @param $userId
+     * @param $amount
+     * @param $params
+     * @return bool
+     * @throws Exception
+     * @throws \yii\db\Exception
+     */
+    public static function changeInvoice($userId, $amount, $params) {
+        if ($amount == 0) return true;
+        $period = Period::instance();
+        if (!isset($params['PERIOD_NUM'])) {
+            $periodNum = $period->getNowPeriodNum();
+        } else {
+            $periodNum = $params['PERIOD_NUM'];
+        }
+        $calcYearMonth = $period->getYearMonth($periodNum);
+        // redis加锁(防止并发余额数值不准确出错)
+        $lockKey = self::INVOICE_BALANCE_LOCK_KEY . $userId;
+        if (RedisLock::instance()->lock($lockKey)) {
+            $userInfo = UserInfo::findOne(['USER_ID' => $userId]);
+            $totals = $userInfo->INVOICE_BALANCE + $amount;
+            $userInfo->INVOICE_BALANCE = $totals;
+            if (!$userInfo->save()) {
+                throw new \Exception(Form::formatErrorsForApi($userInfo->getErrors()));
+            }
+            //记录流水
+            $baseInfo = Info::baseInfoZh($userId);
+            $flowInsertData = [
+                'USER_ID' => $userId,
+                'REAL_NAME' => $baseInfo['REAL_NAME'],
+                'DEC_LV' => $baseInfo['DEC_LV'],
+                'EMP_LV' => $baseInfo['EMP_LV'],
+                'MOBILE' => $baseInfo['MOBILE'],
+                'REG_TYPE' => $userInfo['REG_TYPE'],
+                'REG_NAME' => $userInfo['REG_NAME'],
+                'CREDIT_CODE' => $userInfo['CREDIT_CODE'],
+                'SALE_NAME' => $params['SALE_NAME'] ?? null,
+                'TAXPAYER_NUMBER' => $params['TAXPAYER_NUMBER'] ?? null,
+                'INVOICE_SN' => $params['INVOICE_SN'] ?? null,
+                'INVOICE_ACCOUNT' => $params['INVOICE_ACCOUNT'] ?? null,
+                'TAX_ACCOUNT' => $params['TAX_ACCOUNT'] ?? null,
+                'OUTED_AT' => $params['OUTED_AT'] ?? 0,
+                'AMOUNT' => abs($amount),
+                'TOTAL' => $totals,
+                'WITHDRAW_SN' => $params['WITHDRAW_SN'] ?? null,
+                'IS_INCR' => $amount > 0 ? self::INCR_ADD : self::INCR_REDUCE,
+                'PERIOD_NUM' => $periodNum,
+                'CALC_MONTH' => $calcYearMonth,
+                'REMARK' => $params['REMARK'] ?? null,
+                'CREATE_ADMIN' => $params['CREATE_ADMIN'],
+                'CREATE_REMARK' => $params['CREATE_REMARK'] ?? null,
+                'CREATE_TIME' => $params['CREATE_TIME'],
+                'AUDIT_ADMIN' => $params['AUDIT_ADMIN'],
+                'AUDIT_REMARK' => $params['AUDIT_REMARK'] ?? null,
+                'AUDIT_TIME' => $params['AUDIT_TIME'],
+                'P_MONTH' => Date::ociToDate(),
+                'CREATED_AT' => $params['TIME'] ?? Date::nowTime(),
+            ];
+            InvoiceFlow::insertOne($flowInsertData);
+            unset($flowInsertData);
+            RedisLock::instance()->unlock($lockKey);
+        } else {
+            throw new Exception('流水产生错误');
+        }
+        return true;
+    }
+
+    /**
+     * 获取当前可用余额
+     * @param $userId
+     * @return int|mixed
+     */
+    public static function getAvailableBalance($userId) {
+        $oneData = UserBonus::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
+        if ($oneData) {
+            return $oneData['BONUS'] - $oneData['BONUS_FREEZE'];
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * 获取当前车房养老奖余额
+     * @param $userId
+     * @return int|mixed
+     */
+    public static function getBalanceCF($userId) {
+        $oneData = UserBonus::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
+        if ($oneData) {
+            return $oneData['CF'];
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * 获取当前复消积分余额
+     * @param $userId
+     * @return int|mixed
+     */
+    public static function getBalanceReconsumePoints($userId) {
+        $oneData = UserBonus::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
+        if ($oneData) {
+            return $oneData['RECONSUME_POINTS'];
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * 获取当前兑换积分余额
+     * @param $userId
+     * @return int|mixed
+     */
+    public static function getBalanceExchangePoints($userId) {
+        $oneData = UserBonus::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
+        if ($oneData) {
+            return $oneData['EXCHANGE_POINTS'];
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * 获取当前车房养老奖余额
+     * @param $userId
+     * @return int|mixed
+     */
+    public static function getBalanceLX($userId) {
+        $oneData = UserBonus::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
+        if ($oneData) {
+            return $oneData['LX'];
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * 改变会员的余额
+     * @param $userId
+     * @param $type
+     * @param $amount
+     * @param array $params
+     * @param bool $allowMinus
+     * @return bool
+     * @throws Exception
+     * @throws \yii\db\Exception
+     */
+    public static function changeUserBonus($userId, $type, $amount, $params = [], $allowMinus = false) {
+        if (array_key_exists($type, UserBonus::TYPE)) {
+            $type = strtoupper($type);
+        }
+        if ($amount == 0) return true;
+        $period = Period::instance();
+        if (!isset($params['PERIOD_NUM'])) {
+            $periodNum = $period->getNowPeriodNum();
+        } else {
+            $periodNum = $params['PERIOD_NUM'];
+        }
+        $calcYearMonth = $period->getYearMonth($periodNum);
+        // redis加锁(防止并发余额数值不准确出错)
+        switch ($type) {
+            case 'BONUS':
+                $lockKey = self::BONUS_BALANCE_LOCK_KEY . $userId;
+                break;
+            case 'RECONSUME_POINTS':
+                $lockKey = self::RECONSUME_POINTS_BALANCE_LOCK_KEY . $userId;
+                break;
+            case 'EXCHANGE_POINTS':
+                $lockKey = self::EXCHANGE_POINTS_BALANCE_LOCK_KEY . $userId;
+                break;
+            case 'CF':
+                $lockKey = self::CF_BALANCE_LOCK_KEY . $userId;
+                break;
+            case 'LX':
+                $lockKey = self::LX_BALANCE_LOCK_KEY . $userId;
+                break;
+            default:
+                throw new Exception('流水类型错误');
+        }
+        if (RedisLock::instance()->lock($lockKey)) {
+            // 改变发奖
+            $paramData = [];
+            $oneUserBonusModel = UserBonus::findOne(['USER_ID' => $userId]);
+            if ($oneUserBonusModel) {
+                $paramData[$type] = new Expression($type.' + '.$amount);
+
+                $oneUserBonusModel->$type += $amount;
+                if ($oneUserBonusModel->$type < 0) {
+                    RedisLock::instance()->unlock($lockKey);
+                    throw new Exception('金额不足');
+                }
+
+                if (isset($params['QY'])) {
+                    $paramData['QY_TOTAL'] = new Expression('QY_TOTAL + '.$params['QY']);
+                    //$oneUserBonusModel->QY_TOTAL += $params['QY'];
+                }
+                if (isset($params['FW'])) {
+                    $paramData['FW_TOTAL'] = new Expression('FW_TOTAL + '.$params['FW']);
+                }
+                if (isset($params['YC'])) {
+                    $paramData['YC_TOTAL'] = new Expression('YC_TOTAL + '.$params['YC']);
+                    //$oneUserBonusModel->YC_TOTAL += $params['YC'];
+                }
+                if (isset($params['VIP'])) {
+                    $paramData['VIP_TOTAL'] = new Expression('VIP_TOTAL + '.$params['VIP']);
+                }
+                if (isset($params['BD'])) {
+                    $paramData['BD_TOTAL'] = new Expression('BD_TOTAL + '.$params['BD']);
+                    //$oneUserBonusModel->BD_TOTAL += $params['BD'];
+                }
+                if (isset($params['TG'])) {
+                    $paramData['TG_TOTAL'] = new Expression('TG_TOTAL + '.$params['TG']);
+                    //$oneUserBonusModel->TG_TOTAL += $params['TG'];
+                }
+                if (isset($params['YJ'])) {
+                    $paramData['YJ_TOTAL'] = new Expression('YJ_TOTAL + '.$params['YJ']);
+                    //$oneUserBonusModel->YJ_TOTAL += $params['YJ'];
+                }
+                if (isset($params['GX'])) {
+                    $paramData['GX_TOTAL'] = new Expression('GX_TOTAL + '.$params['GX']);
+                    //$oneUserBonusModel->GX_TOTAL += $params['GX'];
+                }
+                if (isset($params['GL'])) {
+                    $paramData['GL_TOTAL'] = new Expression('GL_TOTAL + '.$params['GL']);
+                    //$oneUserBonusModel->GL_TOTAL += $params['GL'];
+                }
+                if (isset($params['BS'])) {
+                    $paramData['BS_TOTAL'] = new Expression('BS_TOTAL + '.$params['BS']);
+                    //$oneUserBonusModel->GL_TOTAL += $params['GL'];
+                }
+                if (isset($params['ST'])) {
+                    $paramData['STORE_TOTAL'] = new Expression('STORE_TOTAL + '.$params['ST']);
+                }
+                if (isset($params['RECONSUME_POINTS_TOTAL'])) {
+                    $paramData['RECONSUME_POINTS_TOTAL'] = new Expression('RECONSUME_POINTS_TOTAL + '.$params['RECONSUME_POINTS_TOTAL']);
+                    //$oneUserBonusModel->RECONSUME_POINTS_TOTAL += $params['RECONSUME_POINTS_TOTAL'];
+                }
+                if (isset($params['EXCHANGE_POINTS_TOTAL'])) {
+                    $paramData['EXCHANGE_POINTS_TOTAL'] = new Expression('EXCHANGE_POINTS_TOTAL + '.$params['EXCHANGE_POINTS_TOTAL']);
+                    //$oneUserBonusModel->RECONSUME_POINTS_TOTAL += $params['RECONSUME_POINTS_TOTAL'];
+                }
+                if (isset($params['MANAGE_TAX'])) {
+                    $paramData['MANAGE_TAX'] = new Expression('MANAGE_TAX + '.$params['MANAGE_TAX']);
+                    //$oneUserBonusModel->MANAGE_TAX += $params['MANAGE_TAX'];
+                }
+
+                if (isset($params['ORI_QY'])) {
+                    $paramData['ORI_QY_TOTAL'] = new Expression('ORI_QY_TOTAL + '.$params['ORI_QY']);
+                    //$oneUserBonusModel->ORI_QY_TOTAL += $params['ORI_QY'];
+                }
+//                if (isset($params['ORI_FW'])) {
+//                    $paramData['ORI_FW_TOTAL'] = new Expression('ORI_FW_TOTAL + '.$params['ORI_FW']);
+//                }
+                if (isset($params['ORI_YC'])) {
+                    $paramData['ORI_YC_TOTAL'] = new Expression('ORI_YC_TOTAL + '.$params['ORI_YC']);
+                    //$oneUserBonusModel->ORI_YC_TOTAL += $params['ORI_YC'];
+                }
+                if (isset($params['ORI_VIP'])) {
+                    $paramData['ORI_VIP_TOTAL'] = new Expression('ORI_VIP_TOTAL + '.$params['ORI_VIP']);
+                }
+                if (isset($params['ORI_VIP'])) {
+                    $paramData['ORI_VIP_TOTAL'] = new Expression('ORI_VIP_TOTAL + '.$params['ORI_VIP']);
+                }
+                if (isset($params['ORI_STANDARD'])) {
+                    $paramData['ORI_STANDARD_TOTAL'] = new Expression('ORI_STANDARD_TOTAL + '.$params['ORI_STANDARD']);
+                }
+                if (isset($params['ORI_TG'])) {
+                    $paramData['ORI_TG_TOTAL'] = new Expression('ORI_TG_TOTAL + '.$params['ORI_TG']);
+                    //$oneUserBonusModel->ORI_TG_TOTAL += $params['ORI_TG'];
+                }
+                if (isset($params['ORI_YJ'])) {
+                    $paramData['ORI_YJ_TOTAL'] = new Expression('ORI_YJ_TOTAL + '.$params['ORI_YJ']);
+                    //$oneUserBonusModel->ORI_YJ_TOTAL += $params['ORI_YJ'];
+                }
+                if (isset($params['ORI_GX'])) {
+                    $paramData['ORI_GX_TOTAL'] = new Expression('ORI_GX_TOTAL + '.$params['ORI_GX']);
+                    //$oneUserBonusModel->ORI_GX_TOTAL += $params['ORI_GX'];
+                }
+                if (isset($params['ORI_GL'])) {
+                    $paramData['ORI_GL_TOTAL'] = new Expression('ORI_GL_TOTAL + '.$params['ORI_GL']);
+                    //$oneUserBonusModel->ORI_GL_TOTAL += $params['ORI_GL'];
+                }
+                if (isset($params['ORI_BS'])) {
+                    $paramData['ORI_BS_TOTAL'] = new Expression('ORI_BS_TOTAL + '.$params['ORI_BS']);
+                    //$oneUserBonusModel->ORI_GL_TOTAL += $params['ORI_GL'];
+                }
+                if (isset($params['ORI_ST'])) {
+                    $paramData['ORI_STORE_TOTAL'] = new Expression('ORI_STORE_TOTAL + '.$params['ORI_ST']);
+                }
+
+                if (isset($params['BONUS_TOTAL'])) {
+                    $paramData['BONUS_TOTAL'] = new Expression('BONUS_TOTAL + '.$params['BONUS_TOTAL']);
+                    //$oneUserBonusModel->BONUS_TOTAL += $params['BONUS_TOTAL'];
+                }
+                UserBonus::updateAll($paramData, 'USER_ID=:USER_ID', [':USER_ID' => $userId]);
+
+            } else {
+                $paramData = [
+                    'USER_ID'=>$userId,
+                    $type=>$amount,
+                    'CREATED_AT'=>Date::nowTime()
+                ];
+                if (isset($params['QY'])) {
+//                    $paramData['QY_TOTAL'] = new Expression('QY_TOTAL + '.$params['QY']);
+                    $paramData['QY_TOTAL'] = $params['QY'];
+                }
+                if (isset($params['FW'])) {
+//                    $paramData['FW_TOTAL'] = new Expression('FW_TOTAL + '.$params['FW']);
+                    $paramData['FW_TOTAL'] = $params['FW'];
+                }
+                if (isset($params['YC'])) {
+//                    $paramData['YC_TOTAL'] = new Expression('YC_TOTAL + '.$params['YC']);
+                    $paramData['YC_TOTAL'] = $params['YC'];
+                }
+                if (isset($params['VIP'])) {
+//                    $paramData['VIP_TOTAL'] = new Expression('VIP_TOTAL + '.$params['VIP']);
+                    $paramData['VIP_TOTAL'] = $params['VIP'];
+                }
+
+                if (isset($params['BD'])) {
+//                    $paramData['BD_TOTAL'] = new Expression('BD_TOTAL + '.$params['BD']);
+                    $paramData['BD_TOTAL'] = $params['BD'];
+                    //$oneUserBonusModel->BD_TOTAL += $params['BD'];
+                }
+                if (isset($params['TG'])) {
+//                    $paramData['TG_TOTAL'] = new Expression('TG_TOTAL + '.$params['TG']);
+                    $paramData['TG_TOTAL'] = $params['TG'];
+                }
+                if (isset($params['YJ'])) {
+//                    $paramData['YJ_TOTAL'] = new Expression('YJ_TOTAL + '.$params['YJ']);
+                    $paramData['YJ_TOTAL'] = $params['YJ'];
+                }
+                if (isset($params['GX'])) {
+//                    $paramData['GX_TOTAL'] = new Expression('GX_TOTAL + '.$params['GX']);
+                    $paramData['GX_TOTAL'] = $params['GX'];
+                }
+                if (isset($params['GL'])) {
+//                    $paramData['GL_TOTAL'] = new Expression('GL_TOTAL + '.$params['GL']);
+                    $paramData['GL_TOTAL'] = $params['GL'];
+                }
+                if (isset($params['BS'])) {
+                    $paramData['BS_TOTAL'] = $params['BS'];
+                    //$oneUserBonusModel->GL_TOTAL += $params['GL'];
+                }
+                if (isset($params['RECONSUME_POINTS_TOTAL'])) {
+//                    $paramData['RECONSUME_POINTS_TOTAL'] = new Expression('RECONSUME_POINTS_TOTAL + '.$params['RECONSUME_POINTS_TOTAL']);
+                    $paramData['RECONSUME_POINTS_TOTAL'] = $params['RECONSUME_POINTS_TOTAL'];
+                }
+                if (isset($params['MANAGE_TAX'])) {
+//                    $paramData['MANAGE_TAX'] = new Expression('MANAGE_TAX + '.$params['MANAGE_TAX']);
+                    $paramData['MANAGE_TAX'] = $params['MANAGE_TAX'];
+                }
+
+                if (isset($params['ORI_QY'])) {
+//                    $paramData['ORI_QY_TOTAL'] = new Expression('ORI_QY_TOTAL + '.$params['ORI_QY']);
+                    $paramData['ORI_QY_TOTAL'] = $params['ORI_QY'];
+                }
+//                if (isset($params['ORI_FW'])) {
+////                    $paramData['ORI_FW_TOTAL'] = new Expression('ORI_FW_TOTAL + '.$params['ORI_FW']);
+//                    $paramData['ORI_FW_TOTAL'] = $params['ORI_FW'];
+//                }
+                if (isset($params['ORI_YC'])) {
+//                    $paramData['ORI_YC_TOTAL'] = new Expression('ORI_YC_TOTAL + '.$params['ORI_YC']);
+                    $paramData['ORI_YC_TOTAL'] = $params['ORI_YC'];
+                }
+                if (isset($params['ORI_VIP'])) {
+//                    $paramData['ORI_VIP_TOTAL'] = new Expression('ORI_VIP_TOTAL + '.$params['ORI_VIP']);
+                    $paramData['ORI_VIP_TOTAL'] = $params['ORI_VIP'];
+                }
+                if (isset($params['ORI_STANDARD'])) {
+                    $paramData['ORI_STANDARD_TOTAL'] = $params['ORI_STANDARD'];
+                }
+                if (isset($params['ORI_BD'])) {
+//                    $paramData['ORI_BD_TOTAL'] = new Expression('ORI_BD_TOTAL + '.$params['ORI_BD']);
+                    $paramData['ORI_BD_TOTAL'] = $params['ORI_BD'];
+                }
+                if (isset($params['ORI_TG'])) {
+//                    $paramData['ORI_TG_TOTAL'] = new Expression('ORI_TG_TOTAL + '.$params['ORI_TG']);
+                    $paramData['ORI_TG_TOTAL'] = $params['ORI_TG'];
+                }
+                if (isset($params['ORI_YJ'])) {
+//                    $paramData['ORI_YJ_TOTAL'] = new Expression('ORI_YJ_TOTAL + '.$params['ORI_YJ']);
+                    $paramData['ORI_YJ_TOTAL'] = $params['ORI_YJ'];
+                }
+                if (isset($params['ORI_GX'])) {
+//                    $paramData['ORI_GX_TOTAL'] = new Expression('ORI_GX_TOTAL + '.$params['ORI_GX']);
+                    $paramData['ORI_GX_TOTAL'] = $params['ORI_GX'];
+                }
+                if (isset($params['ORI_GL'])) {
+//                    $paramData['ORI_GL_TOTAL'] = new Expression('ORI_GL_TOTAL + '.$params['ORI_GL']);
+                    $paramData['ORI_GL_TOTAL'] = $params['ORI_GL'];
+                }
+                if (isset($params['ORI_BS'])) {
+                    $paramData['ORI_BS_TOTAL'] = $params['ORI_BS'];
+                    //$oneUserBonusModel->ORI_GL_TOTAL += $params['ORI_GL'];
+                }
+
+                if (isset($params['BONUS_TOTAL'])) {
+//                    $paramData['BONUS_TOTAL'] = new Expression('BONUS_TOTAL + '.$params['BONUS_TOTAL']);
+                    $paramData['BONUS_TOTAL'] = $params['BONUS_TOTAL'];
+                }
+                UserBonus::insertOne($paramData);
+            }
+
+            unset($oneUserBonusModel,$paramData);
+            // 获取发放完成的奖金信息
+            $oneUserBonus = UserBonus::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
+            $userInfo = Info::getLastInfo($userId);
+            // 记录流水
+            $flowInsertData = [
+                'USER_ID' => $userId,
+                'LAST_DEC_LV' => $userInfo['DEC_LV'],
+                'LAST_EMP_LV' => $userInfo['LAST_EMP_LV'],
+                'LAST_STATUS' => $userInfo['STATUS'],
+                'CALC_ID' => $params['CALC_ID'] ?? null,
+                'AMOUNT' => $amount,
+                'TOTAL' => $oneUserBonus[$type],
+                'IS_INCR' => $amount > 0 ? FlowBonus::INCR_ADD : FlowBonus::INCR_REDUCE,
+                'REMARK' => $params['REMARK'] ?? null,
+                'REMARK_IS_SHOW' => $params['REMARK_IS_SHOW'] ?? 1,
+                'PERIOD_NUM' => $params['PERIOD_NUM'] ?? $periodNum,
+                'CALC_MONTH' => $calcYearMonth,
+                'P_MONTH' => Date::ociToDate(),
+                'CREATED_AT' => $params['TIME'] ?? Date::nowTime(),
+                'ADMIN_NAME' => $params['ADMIN_NAME'] ?? 'system',
+                'DEAL_TYPE_ID' => $params['DEAL_TYPE_ID'] ?? '',
+                'DEAL_TYPE_IS_PRESET' => $params['DEAL_TYPE_IS_PRESET'] ?? 1,
+                'TRANSFER_SN' => $params['TRANSFER_SN'] ?? '',
+                'SORT' => $params['SORT'] ?? 0,
+                'ORDER_SN' => $params['ORDER_SN'] ?? '',
+            ];
+            unset($userInfo, $oneUserBonus);
+            if (strtolower($type) == 'reconsume_points' || strtolower($type) == 'cf' || strtolower($type) == 'lx'
+                || strtolower($type) == 'exchange_points'
+            ) {
+                unset($flowInsertData['CALC_ID']);
+                unset($flowInsertData['TRANSFER_SN']);
+                unset($flowInsertData['SORT']);
+            }
+            if (strtolower($type) == 'bonus') {
+                FlowBonus::insertOne($flowInsertData);
+            } elseif (strtolower($type) == 'reconsume_points') {
+                //记录和扣除期数的积分
+                if( $amount > 0 ) {
+                    self::addPeriodReconsumePoints($userId, $periodNum, $amount);
+                }else {
+                    self::deductPeriodReconsumePoints($userId, abs($amount));
+                }
+                FlowReconsumePoints::insertOne($flowInsertData);
+            } elseif (strtolower($type) == 'exchange_points') {
+                //记录和扣除期数的积分
+                if( $amount > 0 ) {
+                    self::addPeriodExchangePoints($userId, $periodNum, $amount);
+                }else {
+                    self::deductPeriodExchangePoints($userId, abs($amount));
+                }
+                FlowExchangePoints::insertOne($flowInsertData);
+            } elseif (strtolower($type) == 'cf') {
+                FlowCF::insertOne($flowInsertData);
+            } elseif (strtolower($type) == 'lx') {
+                FlowLX::insertOne($flowInsertData);
+            }
+            unset($flowInsertData);
+            RedisLock::instance()->unlock($lockKey);
+        } else {
+            throw new Exception('流水产生错误');
+        }
+        return true;
+    }
+
+    /**
+     * 添加对应期数的复消积分
+     * @param $userId
+     * @param $periodNum
+     * @param $amount
+     * @throws \yii\db\Exception
+     * @return boolean
+     */
+    public static function addPeriodReconsumePoints($userId, $periodNum, $amount) {
+        if($amount <= 0) return false;
+        $exists = UserPeriodPoints::find()->where('USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', [
+            'USER_ID' => $userId,
+            'PERIOD_NUM' => $periodNum,
+        ])->asArray()->exists();
+        if( $exists ) {
+            UserPeriodPoints::updateAllCounters([
+                'RECONSUME_POINTS' => $amount,
+                'REMAINDER_POINTS' => $amount,
+            ], 'USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', [
+                'USER_ID' => $userId,
+                'PERIOD_NUM' => $periodNum,
+            ]);
+        }else {
+            UserPeriodPoints::insertOne([
+                'USER_ID' => $userId,
+                'PERIOD_NUM' => $periodNum,
+                'RECONSUME_POINTS' => $amount,
+                'REMAINDER_POINTS' => $amount,
+                'EXPIRED' => 0,
+                'CREATED_AT' => Date::nowTime()
+            ]);
+        }
+
+        return true;
+    }
+
+    /**
+     * 添加对应期数的兑换积分
+     * @param $userId
+     * @param $periodNum
+     * @param $amount
+     * @throws \yii\db\Exception
+     * @return boolean
+     */
+    public static function addPeriodExchangePoints($userId, $periodNum, $amount) {
+        if($amount <= 0) return false;
+        $exists = UserPeriodExchangePoints::find()->where('USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', [
+            'USER_ID' => $userId,
+            'PERIOD_NUM' => $periodNum,
+        ])->asArray()->exists();
+        if( $exists ) {
+            UserPeriodExchangePoints::updateAllCounters([
+                'EXCHANGE_POINTS' => $amount,
+                'REMAINDER_POINTS' => $amount,
+            ], 'USER_ID=:USER_ID AND PERIOD_NUM=:PERIOD_NUM', [
+                'USER_ID' => $userId,
+                'PERIOD_NUM' => $periodNum,
+            ]);
+        }else {
+            UserPeriodExchangePoints::insertOne([
+                'USER_ID' => $userId,
+                'PERIOD_NUM' => $periodNum,
+                'EXCHANGE_POINTS' => $amount,
+                'REMAINDER_POINTS' => $amount,
+                'EXPIRED' => 0,
+                'CREATED_AT' => Date::nowTime()
+            ]);
+        }
+
+        return true;
+    }
+
+
+    /**
+     * 减少
+     * @param $userId
+     * @param $amount
+     * @return bool
+     */
+    public static function deductPeriodReconsumePoints($userId, $amount) {
+        if( $amount <= 0 ) return false;
+        $avalidList = UserPeriodPoints::find()->where('USER_ID=:USER_ID AND EXPIRED=:EXPIRED AND REMAINDER_POINTS>0', [
+            'USER_ID' => $userId,
+            'EXPIRED'=>0
+        ])->orderBy('PERIOD_NUM ASC')->asArray()->all();
+        if( !$avalidList ) return false;
+
+        foreach ($avalidList as $everyData) {
+            if( $amount <= 0 ) break;
+
+            $remainderPoints = floatval($everyData['REMAINDER_POINTS']);
+            if( $amount >= $remainderPoints ) {
+                UserPeriodPoints::updateAllCounters([
+                    'REMAINDER_POINTS' => (-1) * $remainderPoints
+                ], 'ID=:ID', ['ID'=>$everyData['ID']]);
+
+                $amount -= $remainderPoints;
+            }else {
+                UserPeriodPoints::updateAllCounters([
+                    'REMAINDER_POINTS' => (-1) * $amount
+                ], 'ID=:ID', ['ID'=>$everyData['ID']]);
+
+                $amount = 0;
+            }
+
+            unset($everyData, $remainderPoints);
+        }
+        if( $amount > 0 ) return false;
+
+        return true;
+    }
+
+    /**
+     * 减少
+     * @param $userId
+     * @param $amount
+     * @return bool
+     */
+    public static function deductPeriodExchangePoints($userId, $amount) {
+        if( $amount <= 0 ) return false;
+        $avalidList = UserPeriodExchangePoints::find()->where('USER_ID=:USER_ID AND EXPIRED=:EXPIRED AND REMAINDER_POINTS>0', [
+            'USER_ID' => $userId,
+            'EXPIRED'=>0
+        ])->orderBy('PERIOD_NUM ASC')->asArray()->all();
+        if( !$avalidList ) return false;
+
+        foreach ($avalidList as $everyData) {
+            if( $amount <= 0 ) break;
+
+            $remainderPoints = floatval($everyData['REMAINDER_POINTS']);
+            if( $amount >= $remainderPoints ) {
+                UserPeriodExchangePoints::updateAllCounters([
+                    'REMAINDER_POINTS' => (-1) * $remainderPoints
+                ], 'ID=:ID', ['ID'=>$everyData['ID']]);
+
+                $amount -= $remainderPoints;
+            }else {
+                UserPeriodExchangePoints::updateAllCounters([
+                    'REMAINDER_POINTS' => (-1) * $amount
+                ], 'ID=:ID', ['ID'=>$everyData['ID']]);
+
+                $amount = 0;
+            }
+
+            unset($everyData, $remainderPoints);
+        }
+        if( $amount > 0 ) return false;
+
+        return true;
+    }
+
+    /**
+     * 冻结用户余额
+     * @param $userId
+     * @param $amount
+     * @param null $remark
+     * @param null $time
+     * @return bool
+     * @throws Exception
+     * @throws \yii\db\Exception
+     */
+    public static function freezeUserBonus($userId, $amount, $remark = null, $time = null) {
+        return self::changeFreezeUserBonus($userId, $amount, ['REMARK' => $remark, 'TIME' => $time]);
+    }
+
+    /**
+     * 解冻用户余额
+     * @param $userId
+     * @param $amount
+     * @param null $remark
+     * @param null $time
+     * @return bool
+     * @throws Exception
+     * @throws \yii\db\Exception
+     */
+    public static function unfreezeUserBonus($userId, $amount, $remark = null, $time = null) {
+        return self::changeFreezeUserBonus($userId, -$amount, ['REMARK' => $remark, 'TIME' => $time]);
+    }
+
+    /**
+     * @param $userId
+     * @param $amount
+     * @param $params
+     * [
+     *      'REMARK' => '备注',
+     *      'PERIOD_NUM' => 100,
+     * ]
+     * @return bool
+     * @throws Exception
+     * @throws \yii\db\Exception
+     */
+    public static function changeFreezeUserBonus($userId, $amount, $params) {
+        if ($amount == 0) return true;
+        $period = Period::instance();
+        if (!isset($params['PERIOD_NUM'])) {
+            $periodNum = $period->getNowPeriodNum();
+        } else {
+            $periodNum = $params['PERIOD_NUM'];
+        }
+        $calcYearMonth = $period->getYearMonth($periodNum);
+        // 改变冻结
+        $oneUserBonusModel = UserBonus::findOne(['USER_ID' => $userId]);
+        if ($oneUserBonusModel) {
+            $oneUserBonusModel->BONUS_FREEZE = $oneUserBonusModel->BONUS_FREEZE + $amount;
+        } else {
+            $oneUserBonusModel = new UserBonus();
+            $oneUserBonusModel->USER_ID = $userId;
+            $oneUserBonusModel->BONUS_FREEZE = $amount;
+        }
+        if (!$oneUserBonusModel->save()) {
+            throw new Exception(Form::formatErrorsForApi($oneUserBonusModel->getErrors()));
+        }
+        unset($oneUserBonusModel);
+        // 流水
+        // 获取发放完成的奖金信息
+        $oneUserBonus = UserBonus::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
+        // 记录流水
+        $flowInsertData = [
+            'USER_ID' => $userId,
+            'AMOUNT' => abs($amount),
+            'TOTAL' => $oneUserBonus['BONUS'],
+            'IS_INCR' => $amount > 0 ? FlowBonus::INCR_FREEZE : FlowBonus::INCR_UNFREEZE,
+            'REMARK' => $params['REMARK'] ?? null,
+            'PERIOD_NUM' => $params['PERIOD_NUM'] ?? $periodNum,
+            'CALC_MONTH' => $calcYearMonth,
+            'P_MONTH' => Date::ociToDate(),
+            'CREATED_AT' => $params['TIME'] ?? Date::nowTime(),
+        ];
+
+        FlowBonus::insertOne($flowInsertData);
+        unset($flowInsertData);
+        return true;
+    }
+
+    /**
+     * 清空会员奖金有流水
+     * @param $userId
+     * @param array $params
+     * @throws Exception
+     * @throws \yii\db\Exception
+     */
+    public static function clearAllBonus($userId, $params = []) {
+        // 先查找会员的全部余额
+        $userBonus = UserBonus::findOne(['USER_ID' => $userId]);
+        // 如果没有会员余额数据,新建余额数据
+        if (!$userBonus) {
+            UserBonus::insertOne(['USER_ID' => $userId, 'CREATED_AT' => Date::nowTime()]);
+        } else {
+            $period = Period::instance();
+            foreach (\Yii::$app->params['bonusWalletType'] as $type) {
+                $field = strtoupper($type['name']);
+                if ($userBonus[$field]<=0) continue;
+                $userInfo = Info::getLastInfo($userId);
+                $flowInsertData = [
+                    'USER_ID' => $userId,
+                    'LAST_DEC_LV' => $userInfo['DEC_LV'],
+                    'LAST_EMP_LV' => $userInfo['EMP_LV'],
+                    'LAST_STATUS' => $userInfo['STATUS'],
+                    'CALC_ID' => $params['CALC_ID'] ?? null,
+                    'AMOUNT' => -$userBonus[$field],
+                    'TOTAL' => 0,
+                    'IS_INCR' => FlowBonus::INCR_REDUCE,
+                    'REMARK' => $params['REMARK'] ?? null,
+                    'REMARK_IS_SHOW' => $params['REMARK_IS_SHOW'] ?? 1,
+                    'PERIOD_NUM' => $params['PERIOD_NUM'] ?? $period->getNowPeriodNum(),
+                    'CALC_MONTH' => $period->getNowYearMonth(),
+                    'P_MONTH' => Date::ociToDate(),
+                    'CREATED_AT' => $params['TIME'] ?? Date::nowTime(),
+                    'ADMIN_NAME' => $params['ADMIN_NAME'] ?? 'system',
+                    'DEAL_TYPE_ID' => $params['DEAL_TYPE_ID'] ?? '',
+                    'DEAL_TYPE_IS_PRESET' => $params['DEAL_TYPE_IS_PRESET'] ?? 1,
+                    'TRANSFER_SN' => $params['TRANSFER_SN'] ?? '',
+                    'SORT' => $params['SORT'] ?? 0,
+                ];
+
+                // 流水
+                if (strtolower($field) == 'bonus') FlowBonus::insertOne($flowInsertData);
+                elseif (strtolower($field) == 'cf') {
+                    unset($flowInsertData['CALC_ID']);
+                    unset($flowInsertData['SORT']);
+                    unset($flowInsertData['TRANSFER_SN']);
+                    FlowCF::insertOne($flowInsertData);
+                } elseif (strtolower($field) == 'lx') {
+                    unset($flowInsertData['CALC_ID']);
+                    unset($flowInsertData['SORT']);
+                    unset($flowInsertData['TRANSFER_SN']);
+                    FlowLX::insertOne($flowInsertData);
+                }
+            }
+            // 清空
+            $userBonus->BONUS = 0;
+            $userBonus->CF = 0;
+            $userBonus->LX = 0;
+            if (!$userBonus->save()) {
+                throw new Exception(Form::formatErrorsForApi($userBonus->getErrors()));
+            }
+        }
+        FlowBonus::updateAll(['DELETED' => 1, 'DELETED_AT' => Date::nowTime()], 'USER_ID=:USER_ID', [':USER_ID' => $userId]);
+        FlowCF::updateAll(['DELETED' => 1, 'DELETED_AT' => Date::nowTime()], 'USER_ID=:USER_ID', [':USER_ID' => $userId]);
+        FlowLX::updateAll(['DELETED' => 1, 'DELETED_AT' => Date::nowTime()], 'USER_ID=:USER_ID', [':USER_ID' => $userId]);
+    }
+
+    /**
+     * 是否存在奖金余额
+     * @param $userId
+     * @return bool
+     */
+    public static function hasBonus($userId) {
+        $userBonus = UserBonus::findOne(['USER_ID' => $userId]);
+        if (!$userBonus) {
+            return false;
+        }
+        foreach (\Yii::$app->params['bonusWalletType'] as $type) {
+            $field = strtoupper($type['name']);
+            if (isset($userBonus[$field]) && $userBonus[$field] > 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 获取金额用于日志
+     * @param $userId
+     * @return array
+     */
+    public static function getLogData($userId){
+        $userWallet = UserWallet::findOne(['USER_ID' => $userId]);
+        $cash = !empty($userWallet) ? $userWallet['CASH'] : '';
+        $userName = Info::getUserNameByUserId($userId);
+        $data = [];
+        $data[$userId]['label'] = $userName.'余额';
+        $data[$userId]['value'] = '奖金'.self::getAvailableBalance($userId).',现金'.$cash;
+        return $data;
+    }
+}

+ 202 - 201
common/helpers/user/Cash.php

@@ -1,201 +1,202 @@
-<?php
-/**
- * Created by PhpStorm.
- * User: leo
- * Date: 2018/10/30
- * Time: 下午3:19
- */
-
-namespace common\helpers\user;
-
-use common\helpers\Date;
-use common\helpers\Form;
-use common\libs\lock\RedisLock;
-use common\models\FlowWallet;
-use common\models\Period;
-use common\models\UserWallet;
-use yii\base\Exception;
-use yii\db\Expression;
-
-class Cash {
-    const INCR_REDUCE = 0;      // 减少
-    const INCR_ADD = 1;         // 增加
-    const INCR_FREEZE = 2;      // 冻结
-    const INCR_UNFREEZE = 3;    // 解冻
-
-    const CASH_BALANCE_LOCK_KEY = 'Cash';
-
-    /**
-     * 获取当前可用余额
-     * @param $userId
-     * @return int|mixed
-     */
-    public static function getAvailableBalance($userId) {
-        $oneData = UserWallet::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
-        if ($oneData) {
-            return $oneData['CASH'];
-        } else {
-            return 0;
-        }
-    }
-
-    /**
-     * 改变会员的现金余额
-     * @param $userId
-     * @param $type
-     * @param $amount
-     * @param array $params
-     * @param bool $allowMinus
-     * @return bool
-     * @throws Exception
-     * @throws \yii\db\Exception
-     */
-    public static function changeUserCash($userId, $type='CASH', $amount, $params = [], $allowMinus = false) {
-        if ($amount == 0) return true;
-        $period = Period::instance();
-        if (!isset($params['PERIOD_NUM'])) {
-            $periodNum = $period->getNowPeriodNum();
-        } else {
-            $periodNum = $params['PERIOD_NUM'];
-        }
-        $calcYearMonth = $period->getYearMonth($periodNum);
-        // redis加锁(防止并发余额数值不准确出错)
-        switch ($type) {
-            case 'CASH':
-                $lockKey = self::CASH_BALANCE_LOCK_KEY . $userId;
-                break;
-            default:
-                throw new Exception('流水类型错误');
-        }
-        if (RedisLock::instance()->lock($lockKey)) {
-            // 改变发奖
-            $paramData = [];
-            $oneUserBonusModel = UserWallet::findOne(['USER_ID' => $userId]);
-            if ($oneUserBonusModel) {
-                $paramData[$type] = new Expression($type.' + '.$amount);
-
-                $oneUserBonusModel->$type += $amount;
-                if ($oneUserBonusModel->$type < 0) {
-                    RedisLock::instance()->unlock($lockKey);
-                    throw new Exception('金额不足');
-                }
-                UserWallet::updateAll($paramData, 'USER_ID=:USER_ID', [':USER_ID' => $userId]);
-
-            } else {
-                $paramData = [
-                    'USER_ID'=>$userId,
-                    $type=>$amount,
-                    'UPDATED_AT'=>Date::nowTime()
-                ];
-                UserWallet::insertOne($paramData);
-
-//                $oneUserBonusModel = new UserWallet();
-//                $oneUserBonusModel->USER_ID = $userId;
-//                $oneUserBonusModel->$type = $amount;
-//                $oneUserBonusModel->UPDATED_AT = Date::nowTime();
-//                if (!$oneUserBonusModel->save()) {
-//                    throw new \yii\db\Exception(Form::formatErrorsForApi($oneUserBonusModel->getErrors()));
-//                }
-            }
-
-            unset($oneUserBonusModel,$paramData);
-            // 获取发放完成的奖金信息
-            $oneUserBonus = UserWallet::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
-            // 记录流水
-            $flowInsertData = [
-                'USER_ID' => $userId,
-                'CALC_ID' => $params['CALC_ID'] ?? null,
-                'AMOUNT' => $amount,
-                'TOTAL' => $oneUserBonus[$type],
-                'IS_INCR' => $amount > 0 ? FlowWallet::INCR_ADD : FlowWallet::INCR_REDUCE,
-                'REMARK' => $params['REMARK'] ?? null,
-                'PERIOD_NUM' => $params['PERIOD_NUM'] ?? $periodNum,
-                'CALC_MONTH' => $calcYearMonth,
-                'P_MONTH' => Date::ociToDate(),
-                'CREATED_AT' => $params['TIME'] ?? Date::nowTime(),
-                'ADMIN_NAME' => $params['ADMIN_NAME'] ?? 'system',
-                'SORT' => $params['SORT'] ?? 0,
-                'TRANSFER_SN' => $params['TRANSFER_SN'] ?? '',
-            ];
-            if (strtolower($type) == 'cash') FlowWallet::insertOne($flowInsertData);
-            unset($flowInsertData);
-            RedisLock::instance()->unlock($lockKey);
-        } else {
-            throw new Exception('流水产生错误');
-        }
-        return true;
-    }
-
-    /**
-     * 清空会员现金所有流水
-     * @param $userId
-     * @param array $params
-     * @throws Exception
-     * @throws \yii\db\Exception
-     */
-    public static function clearAllCash($userId, $params = []) {
-        // 先查找会员的全部余额
-        $userWallet = UserWallet::findOne(['USER_ID' => $userId]);
-        // 如果没有会员余额数据,新建余额数据
-        if (!$userWallet) {
-            UserWallet::insertOne(['USER_ID' => $userId, 'CREATED_AT' => Date::nowTime()]);
-        } else {
-            $period = Period::instance();
-            $field = 'CASH';
-            if ($userWallet[$field]<=0) return;
-            $flowInsertData = [
-                'USER_ID' => $userId,
-                'CALC_ID' => $params['CALC_ID'] ?? null,
-                'AMOUNT' => -$userWallet[$field],
-                'TOTAL' => 0,
-                'IS_INCR' => FlowWallet::INCR_REDUCE,
-                'REMARK' => $params['REMARK'] ?? null,
-                'PERIOD_NUM' => $params['PERIOD_NUM'] ?? $period->getNowPeriodNum(),
-                'CALC_MONTH' => $period->getNowYearMonth(),
-                'P_MONTH' => Date::ociToDate(),
-                'CREATED_AT' => $params['TIME'] ?? Date::nowTime(),
-                'ADMIN_NAME' => $params['ADMIN_NAME'] ?? 'system',
-                'SORT' => $params['SORT'] ?? 0,
-                'TRANSFER_SN' => $params['TRANSFER_SN'] ?? '',
-            ];
-            // 流水
-            if (strtolower($field) == 'cash') FlowWallet::insertOne($flowInsertData);
-
-            // 清空
-            $userWallet->CASH = 0;
-            if (!$userWallet->save()) {
-                throw new Exception(Form::formatErrorsForApi($userWallet->getErrors()));
-            }
-        }
-        FlowWallet::updateAll(['DELETED' => 1, 'DELETED_AT' => Date::nowTime()], 'USER_ID=:USER_ID', [':USER_ID' => $userId]);
-    }
-
-    /**
-     * 是否存在现金余额
-     * @param $userId
-     * @return bool
-     */
-    public static function hasCash($userId) {
-        $userWallet = UserWallet::findOne(['USER_ID' => $userId]);
-        if (!$userWallet) {
-            return false;
-        }
-        if (isset($userWallet['CASH']) && $userWallet['CASH'] > 0) {
-            return true;
-        }
-    }
-
-    /**
-     * 获取金额用于日志
-     * @param $userId
-     * @return array
-     */
-    public static function getLogData($userId){
-        $userWallet = UserWallet::findOne(['USER_ID' => $userId]);
-        $userName = Info::getUserNameByUserId($userId);
-        $data = [];
-        $data[$userId]['label'] = $userName.'余额';
-        $data[$userId]['value'] = '奖金'.self::getAvailableBalance($userId).',现金'.$userWallet['CASH'];
-        return $data;
-    }
-}
+<?php
+/**
+ * Created by PhpStorm.
+ * User: leo
+ * Date: 2018/10/30
+ * Time: 下午3:19
+ */
+
+namespace common\helpers\user;
+
+use common\helpers\Date;
+use common\helpers\Form;
+use common\libs\lock\RedisLock;
+use common\models\FlowWallet;
+use common\models\Period;
+use common\models\UserWallet;
+use yii\base\Exception;
+use yii\db\Expression;
+
+class Cash {
+    const INCR_REDUCE = 0;      // 减少
+    const INCR_ADD = 1;         // 增加
+    const INCR_FREEZE = 2;      // 冻结
+    const INCR_UNFREEZE = 3;    // 解冻
+
+    const CASH_BALANCE_LOCK_KEY = 'Cash';
+
+    /**
+     * 获取当前可用余额
+     * @param $userId
+     * @return int|mixed
+     */
+    public static function getAvailableBalance($userId) {
+        $oneData = UserWallet::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
+        if ($oneData) {
+            return $oneData['CASH'];
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * 改变会员的现金余额
+     * @param $userId
+     * @param $type
+     * @param $amount
+     * @param array $params
+     * @param bool $allowMinus
+     * @return bool
+     * @throws Exception
+     * @throws \yii\db\Exception
+     */
+    public static function changeUserCash($userId, $type='CASH', $amount, $params = [], $allowMinus = false) {
+        if ($amount == 0) return true;
+        $period = Period::instance();
+        if (!isset($params['PERIOD_NUM'])) {
+            $periodNum = $period->getNowPeriodNum();
+        } else {
+            $periodNum = $params['PERIOD_NUM'];
+        }
+        $calcYearMonth = $period->getYearMonth($periodNum);
+        // redis加锁(防止并发余额数值不准确出错)
+        switch ($type) {
+            case 'CASH':
+                $lockKey = self::CASH_BALANCE_LOCK_KEY . $userId;
+                break;
+            default:
+                throw new Exception('流水类型错误');
+        }
+        if (RedisLock::instance()->lock($lockKey)) {
+            // 改变发奖
+            $paramData = [];
+            $oneUserBonusModel = UserWallet::findOne(['USER_ID' => $userId]);
+            if ($oneUserBonusModel) {
+                $paramData[$type] = new Expression($type.' + '.$amount);
+
+                $oneUserBonusModel->$type += $amount;
+                if ($oneUserBonusModel->$type < 0) {
+                    RedisLock::instance()->unlock($lockKey);
+                    throw new Exception('金额不足');
+                }
+                UserWallet::updateAll($paramData, 'USER_ID=:USER_ID', [':USER_ID' => $userId]);
+
+            } else {
+                $paramData = [
+                    'USER_ID'=>$userId,
+                    $type=>$amount,
+                    'UPDATED_AT'=>Date::nowTime()
+                ];
+                UserWallet::insertOne($paramData);
+
+//                $oneUserBonusModel = new UserWallet();
+//                $oneUserBonusModel->USER_ID = $userId;
+//                $oneUserBonusModel->$type = $amount;
+//                $oneUserBonusModel->UPDATED_AT = Date::nowTime();
+//                if (!$oneUserBonusModel->save()) {
+//                    throw new \yii\db\Exception(Form::formatErrorsForApi($oneUserBonusModel->getErrors()));
+//                }
+            }
+
+            unset($oneUserBonusModel,$paramData);
+            // 获取发放完成的奖金信息
+            $oneUserBonus = UserWallet::find()->where('USER_ID=:USER_ID', [':USER_ID' => $userId])->asArray()->one();
+            // 记录流水
+            $flowInsertData = [
+                'USER_ID' => $userId,
+                'CALC_ID' => $params['CALC_ID'] ?? null,
+                'AMOUNT' => $amount,
+                'TOTAL' => $oneUserBonus[$type],
+                'IS_INCR' => $amount > 0 ? FlowWallet::INCR_ADD : FlowWallet::INCR_REDUCE,
+                'REMARK' => $params['REMARK'] ?? null,
+                'PERIOD_NUM' => $params['PERIOD_NUM'] ?? $periodNum,
+                'CALC_MONTH' => $calcYearMonth,
+                'P_MONTH' => Date::ociToDate(),
+                'CREATED_AT' => $params['TIME'] ?? Date::nowTime(),
+                'ADMIN_NAME' => $params['ADMIN_NAME'] ?? 'system',
+                'SORT' => $params['SORT'] ?? 0,
+                'TRANSFER_SN' => $params['TRANSFER_SN'] ?? '',
+                'ORDER_SN' => $params['ORDER_SN'] ?? '',
+            ];
+            if (strtolower($type) == 'cash') FlowWallet::insertOne($flowInsertData);
+            unset($flowInsertData);
+            RedisLock::instance()->unlock($lockKey);
+        } else {
+            throw new Exception('流水产生错误');
+        }
+        return true;
+    }
+
+    /**
+     * 清空会员现金所有流水
+     * @param $userId
+     * @param array $params
+     * @throws Exception
+     * @throws \yii\db\Exception
+     */
+    public static function clearAllCash($userId, $params = []) {
+        // 先查找会员的全部余额
+        $userWallet = UserWallet::findOne(['USER_ID' => $userId]);
+        // 如果没有会员余额数据,新建余额数据
+        if (!$userWallet) {
+            UserWallet::insertOne(['USER_ID' => $userId, 'CREATED_AT' => Date::nowTime()]);
+        } else {
+            $period = Period::instance();
+            $field = 'CASH';
+            if ($userWallet[$field]<=0) return;
+            $flowInsertData = [
+                'USER_ID' => $userId,
+                'CALC_ID' => $params['CALC_ID'] ?? null,
+                'AMOUNT' => -$userWallet[$field],
+                'TOTAL' => 0,
+                'IS_INCR' => FlowWallet::INCR_REDUCE,
+                'REMARK' => $params['REMARK'] ?? null,
+                'PERIOD_NUM' => $params['PERIOD_NUM'] ?? $period->getNowPeriodNum(),
+                'CALC_MONTH' => $period->getNowYearMonth(),
+                'P_MONTH' => Date::ociToDate(),
+                'CREATED_AT' => $params['TIME'] ?? Date::nowTime(),
+                'ADMIN_NAME' => $params['ADMIN_NAME'] ?? 'system',
+                'SORT' => $params['SORT'] ?? 0,
+                'TRANSFER_SN' => $params['TRANSFER_SN'] ?? '',
+            ];
+            // 流水
+            if (strtolower($field) == 'cash') FlowWallet::insertOne($flowInsertData);
+
+            // 清空
+            $userWallet->CASH = 0;
+            if (!$userWallet->save()) {
+                throw new Exception(Form::formatErrorsForApi($userWallet->getErrors()));
+            }
+        }
+        FlowWallet::updateAll(['DELETED' => 1, 'DELETED_AT' => Date::nowTime()], 'USER_ID=:USER_ID', [':USER_ID' => $userId]);
+    }
+
+    /**
+     * 是否存在现金余额
+     * @param $userId
+     * @return bool
+     */
+    public static function hasCash($userId) {
+        $userWallet = UserWallet::findOne(['USER_ID' => $userId]);
+        if (!$userWallet) {
+            return false;
+        }
+        if (isset($userWallet['CASH']) && $userWallet['CASH'] > 0) {
+            return true;
+        }
+    }
+
+    /**
+     * 获取金额用于日志
+     * @param $userId
+     * @return array
+     */
+    public static function getLogData($userId){
+        $userWallet = UserWallet::findOne(['USER_ID' => $userId]);
+        $userName = Info::getUserNameByUserId($userId);
+        $data = [];
+        $data[$userId]['label'] = $userName.'余额';
+        $data[$userId]['value'] = '奖金'.self::getAvailableBalance($userId).',现金'.$userWallet['CASH'];
+        return $data;
+    }
+}

+ 10 - 0
common/helpers/user/Info.php

@@ -73,6 +73,16 @@ class Info {
         return $user ? $user['MOBILE'] : null;
     }
 
+    /**
+     * 获取会员邮箱通过ID
+     * @param $userId
+     * @return null
+     */
+    public static function getUserEmailByUserId($userId) {
+        $user = User::findOneAsArray('ID=:ID AND DELETED=0', [':ID' => $userId], 'EMAIL');
+        return $user ? $user['EMAIL'] : null;
+    }
+
     /**
      * 通过用户ID获取用户的编号和名称
      * @param $userId

+ 97 - 0
common/models/ApproachDecOrder.php

@@ -0,0 +1,97 @@
+<?php
+
+namespace common\models;
+
+use Yii;
+
+/**
+ * This is the model class for table "{{%APPROACH_DEC_ORDER}}".
+ *
+ * @property string $ID
+ * @property string $DEC_SN 报单编号
+ * @property string $ORDER_SN 订单编号
+ * @property string $USER_ID 会员ID
+ * @property string $TO_USER_ID 报单对象ID
+ * @property string $TYPE 报单类型
+ * @property int $IS_ADMIN 是否管理员操作
+ * @property string $DEC_AMOUNT 报单金额
+ * @property string $DEC_PV 报单PV
+ * @property string $PAID_WALLET 支付钱包
+ * @property int $IS_BATCH 是否批量报单
+ * @property string $REMARK 备注
+ * @property string $REC_USER_ID 推荐人ID
+ * @property string $CON_USER_ID 接点人ID
+ * @property string $DEC_ID 报单中心ID
+ * @property int $PERIOD_NUM 报单期数
+ * @property string $P_CALC_MONTH 分区结算月
+ * @property int $CALC_MONTH 结算月
+ * @property int $CREATED_AT 创建时间
+ * @property string $UPDATER 操作人
+ * @property string $UPDATED_AT 更新时间
+ * @property int $IS_DEL 是否删除
+ * @property int $DELETED_AT 删除时间
+ * @property int $DETAIL_TYPE 类型
+ * @property int $UPGRADE_TYPE 升级类型
+ * @property string $ORI_LV 升级前级别
+ * @property string $UPGRADE_LV 升级后级别
+ */
+class ApproachDecOrder extends \common\components\ActiveRecord
+{
+    /**
+     * {@inheritdoc}
+     */
+    public static function tableName()
+    {
+        return '{{%APPROACH_DEC_ORDER}}';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function rules()
+    {
+        return [
+            [['USER_ID', 'TO_USER_ID','REC_USER_ID',/*'CON_USER_ID','DEC_ID', */'TYPE', 'PAID_WALLET', 'PERIOD_NUM', 'P_CALC_MONTH', 'CREATED_AT'], 'required'],
+            [['IS_ADMIN', 'IS_BATCH', 'PERIOD_NUM', 'CALC_MONTH', 'CREATED_AT', 'IS_DEL', 'DELETED_AT'], 'integer'],
+            [['DEC_AMOUNT', 'DEC_PV'], 'number'],
+            [['ID', 'DEC_SN', 'ORDER_SN', 'USER_ID', 'TO_USER_ID','REC_USER_ID','CON_USER_ID','DEC_ID', 'TYPE', 'UPDATER', 'UPDATED_AT'], 'string', 'max' => 32],
+            [['PAID_WALLET'], 'string', 'max' => 48],
+            [['REMARK'], 'string', 'max' => 4000],
+            [['DEC_SN'], 'unique'],
+            [['ID'], 'unique'],
+        ];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function attributeLabels()
+    {
+        return [
+            'ID' => 'ID',
+            'DEC_SN' => '报单编号',
+            'ORDER_SN' => '订单编号',
+            'USER_ID' => '会员ID',
+            'TO_USER_ID' => '报单对象ID',
+            'TYPE' => '报单类型',
+            'IS_ADMIN' => '是否管理员操作',
+            'DEC_AMOUNT' => '报单金额',
+            'DEC_PV' => '报单PV',
+            'PAID_WALLET' => '支付钱包',
+            'STATUS' => '支付状态',
+            'IS_BATCH' => '是否批量报单',
+            'REMARK' => '备注',
+            'REC_USER_ID' => '开拓人编号',
+            'CON_USER_ID' => '上级编号',
+            'DEC_ID' => '上级编号',
+            'PERIOD_NUM' => '报单期数',
+            'P_CALC_MONTH' => '分区结算月',
+            'CALC_MONTH' => '结算月',
+            'CREATED_AT' => '创建时间',
+            'UPDATER' => '操作人',
+            'UPDATED_AT' => '更新时间',
+            'IS_DEL' => '是否删除',
+            'DELETED_AT' => '删除时间',
+        ];
+    }
+}

+ 141 - 0
common/models/ApproachOrder.php

@@ -0,0 +1,141 @@
+<?php
+
+namespace common\models;
+
+use Yii;
+
+/**
+ * This is the model class for table "{{%ORDER}}".
+ *
+ * @property string $ID
+ * @property string $SN 订单号
+ * @property string $DEC_SN 报单编号
+ * @property string $USER_ID 用户ID
+ * @property string $USER_NAME 会员编号
+ * @property string $ORDER_TYPE 订货类型
+ * @property string $ORDER_AMOUNT 订单总价格
+ * @property string $PV 订货PV
+ * @property string $PAY_AMOUNT 支付价格
+ * @property string $PAY_PV 实付PV
+ * @property int $PAY_AT 支付时间
+ * @property string $REMAIN_PV
+ * @property string $PAY_TYPE 支付方式
+ * @property string $FREIGHT 运费
+ * @property string $PAY_FREIGHT 实付运费金额
+ * @property int $DELIVERY_STATUS 发货状态
+ * @property int $DELIVERY_PERIOD 发货期数
+ * @property int $DELIVERY_AT 发货时间
+ * @property string $EXPRESS_COMPANY 快递公司
+ * @property string $ORDER_TRACK_NO 快递单号
+ * @property int $EXPRESS_TYPE 发货方式
+ * @property string $FRONT_REMARK 前台备注
+ * @property string $REMARK 后台备注
+ * @property int $PERIOD_NUM 期数
+ * @property int $STATUS 订单状态
+ * @property string $CONSIGNEE 收货人
+ * @property string $MOBILE 收货人手机
+ * @property string $TEL 固定电话
+ * @property int $PROVINCE 省份名称
+ * @property int $CITY 城市名称
+ * @property int $COUNTY 县区
+ * @property string $ADDRESS 详细地址
+ * @property string $P_CALC_MONTH 分区日期
+ * @property int $CREATED_AT 订单创建时间
+ * @property string $CREATE_USER 订单创建人
+ * @property int $UPDATED_AT 修改时间
+ * @property string $UPDATER 修改人
+ * @property int $IS_DELETE 是否删除
+ * @property int $DELETED_AT 删除时间
+ * @property int $WAREHOUSE 发货仓
+ * @property string $EMAIL 邮箱
+ * @property string $NOTE 备注说明
+ * @property string $CONSIGNEE_REAL_NAME 收件人真实姓名
+ * @property string $CONSIGNEE_ID_NO 收件人身份证号码
+ * @property string $ZIP_CODE 收件人邮编
+ */
+class ApproachOrder extends \common\components\ActiveRecord
+{
+    /**
+     * {@inheritdoc}
+     */
+    public static function tableName()
+    {
+        return '{{%APPROACH_ORDER}}';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function rules()
+    {
+        return [
+            [['USER_ID', 'USER_NAME', 'ORDER_TYPE', 'CREATE_USER'], 'required'],
+            [['ORDER_AMOUNT', 'PV', 'PAY_AMOUNT', 'PAY_PV', 'FREIGHT', 'PAY_FREIGHT'], 'number'],
+            [['PAY_AT', 'DELIVERY_STATUS', 'DELIVERY_PERIOD', 'DELIVERY_AT', 'EXPRESS_TYPE', 'PERIOD_NUM', 'STATUS', 'PROVINCE', 'CITY', 'COUNTY', 'CREATED_AT', 'UPDATED_AT', 'IS_DELETE', 'DELETED_AT'], 'integer'],
+            [['ID','SN', 'DEC_SN', 'USER_ID', 'ORDER_TRACK_NO','PAY_TYPE'], 'string', 'max' => 32],
+            [['USER_NAME', 'TEL', 'CREATE_USER', 'UPDATER', 'WAREHOUSE'], 'string', 'max' => 16],
+            [['ORDER_TYPE'], 'string', 'max' => 12],
+            [['EXPRESS_COMPANY'], 'string', 'max' => 128],
+            [['FRONT_REMARK'], 'string', 'max' => 1000],
+            [['REMARK', 'NOTE'], 'string', 'max' => 4000],
+            [['CONSIGNEE'], 'string', 'max' => 120],
+            [['MOBILE'], 'string', 'max' => 11],
+            [['ADDRESS'], 'string', 'max' => 255],
+            [['SN'], 'unique'],
+        ];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function attributeLabels()
+    {
+        return [
+            'ID' => 'ID',
+            'SN' => '订单号',
+            'DEC_SN' => '报单编号',
+            'USER_ID' => '用户ID',
+            'USER_NAME' => '会员编号',
+            'ORDER_TYPE' => '订货类型',
+            'ORDER_AMOUNT' => '订单总价格',
+            'PV' => '订货PV',
+            'PAY_AMOUNT' => '支付价格',
+            'PAY_PV' => '实付PV',
+            'PAY_AT' => '支付时间',
+            'PAY_TYPE' => '支付方式',
+            'FREIGHT' => '运费',
+            'PAY_FREIGHT' => '实付运费金额',
+            'DELIVERY_STATUS' => '发货状态',
+            'DELIVERY_PERIOD' => '发货期数',
+            'DELIVERY_AT' => '发货时间',
+            'EXPRESS_COMPANY' => '快递公司',
+            'ORDER_TRACK_NO' => '快递单号',
+            'EXPRESS_TYPE' => '发货方式',
+            'FRONT_REMARK' => '前台备注',
+            'REMARK' => '后台备注',
+            'PERIOD_NUM' => '期数',
+            'STATUS' => '订单状态',
+            'CONSIGNEE' => '收货人',
+            'MOBILE' => '收货人手机',
+            'TEL' => '固定电话',
+            'PROVINCE' => '省份名称',
+            'CITY' => '城市名称',
+            'COUNTY' => '县区',
+            'ADDRESS' => '详细地址',
+            'P_CALC_MONTH' => '分区日期',
+            'CREATED_AT' => '订单创建时间',
+            'CREATE_USER' => '订单创建人',
+            'UPDATED_AT' => '修改时间',
+            'UPDATER' => '修改人',
+            'IS_DELETE' => '是否删除',
+            'DELETED_AT' => '删除时间',
+            'WAREHOUSE' => '发货仓',
+            'EMAIL' => 'Email'
+        ];
+    }
+
+    public function getUserByUserId()
+    {
+        return $this->hasOne(User::class, ['ID' => 'USER_ID']);
+    }
+}

+ 71 - 0
common/models/ApproachOrderCall.php

@@ -0,0 +1,71 @@
+<?php
+
+namespace common\models;
+
+use common\components\MongoActiveRecord;
+use Yii;
+
+/**
+ * This is the model class for collection "ar_approach_order_call".
+ *
+ * @property \MongoDB\BSON\ObjectID|string $_id
+ * @property string $sn
+ * @property string $Signature
+ * @property string $TransId
+ * @property string $data
+ */
+class ApproachOrderCall extends MongoActiveRecord
+{
+    /**
+     * {@inheritdoc}
+     */
+    public static function collectionName()
+    {
+        return 'ar_approach_order_call';
+    }
+
+    /**
+     * @return \yii\mongodb\Connection the MongoDB connection used by this AR class.
+     * @throws \yii\base\InvalidConfigException
+     */
+    public static function getDb()
+    {
+        return Yii::$app->get('dbLog');
+    }
+
+    /**
+     * 获取id
+     * @return string
+     */
+    public function getId() {
+        return (string) $this->_id;
+    }
+    /**
+     * {@inheritdoc}
+     */
+    public function attributes()
+    {
+        return [
+            '_id',
+            'sn',
+            'Signature',
+            'TransId',
+            'data',
+        ];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function attributeLabels()
+    {
+        return [
+            '_id' => 'objectID',
+            'sn' => 'orderSn',
+            'Signature' => 'Signature',
+            'TransId' => 'TransId',
+            'data' => 'data',
+        ];
+    }
+
+}

+ 75 - 0
common/models/ApproachOrderGoods.php

@@ -0,0 +1,75 @@
+<?php
+
+namespace common\models;
+
+use Yii;
+
+/**
+ * This is the model class for table "{{%ORDER_GOODS}}".
+ *
+ * @property string $ID
+ * @property string $ORDER_SN 订单ID
+ * @property string $GOODS_ID 商品ID
+ * @property string $GOODS_TITLE 商品名称
+ * @property string $PRICE 价格
+ * @property string $REAL_PRICE 实际价格
+ * @property string $PV 订货PV
+ * @property string $REAL_PV 实际PV
+ * @property string $TAX_RATE 税率
+ * @property string $POINT 兑换积分
+ * @property string $SKU_CODE 商品编码
+ * @property int $BUY_NUMS 购买数量
+ * @property string $P_CALC_MONTH 分区日期
+ * @property int CATEGORY_TYPE 商品分类
+ * @property int PAY_TYPE 支付方式
+ */
+class ApproachOrderGoods extends \common\components\ActiveRecord
+{
+    /**
+     * {@inheritdoc}
+     */
+    public static function tableName()
+    {
+        return '{{%APPROACH_ORDER_GOODS}}';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function rules()
+    {
+        return [
+            [['ORDER_SN', 'GOODS_ID', 'GOODS_TITLE', 'SKU_CODE', 'CATEGORY_TYPE', 'PAY_TYPE'], 'required'],
+            [['PRICE', 'REAL_PRICE', 'PV', 'REAL_PV', 'POINT', 'CATEGORY_TYPE', 'PAY_TYPE', 'TAX_RATE'], 'number'],
+            [['BUY_NUMS'], 'integer'],
+            [['ID', 'ORDER_SN', 'GOODS_ID'], 'string', 'max' => 32],
+            [['GOODS_TITLE'], 'string', 'max' => 255],
+            [['SKU_CODE'], 'string', 'max' => 16],
+            [['ID'], 'unique'],
+        ];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function attributeLabels()
+    {
+        return [
+            'ID' => 'ID',
+            'ORDER_SN' => '订单ID',
+            'GOODS_ID' => '商品ID',
+            'GOODS_TITLE' => '商品名称',
+            'PRICE' => '价格',
+            'REAL_PRICE' => '实际价格',
+            'PV' => '订货BV',
+            'REAL_PV' => '实际BV',
+            'TAX_RATE' => '税率',
+            'POINT' => '兑换积分',
+            'SKU_CODE' => '商品编码',
+            'BUY_NUMS' => '购买数量',
+            'P_CALC_MONTH' => '分区日期',
+            'CATEGORY_TYPE' => '商品分类',
+            'PAY_TYPE' => '支付方式',
+        ];
+    }
+}

+ 62 - 0
common/models/HighestEmpLevelLog.php

@@ -0,0 +1,62 @@
+<?php
+
+namespace common\models;
+
+/**
+ * This is the model class for table "{{%HIGHEST_EMP_LEVEL_LOG}}".
+ *
+ * @property string $ID
+ * @property string $USER_ID 会员ID
+ * @property string $FROM_ID 变动前的级别
+ * @property string $TO_ID 变动后的级别
+ * @property string $ADMIN_ID admin id
+ * @property int $PERIOD_NUM 变动的期数
+ * @property string $CALC_MONTH 变动的结算月
+ * @property string $REMARK 备注
+ * @property int $STATUS 状态
+ * @property int $CREATED_AT 创建时间
+ * @property int $DEC_TYPE 变动类型: 1管理后台调整级别 2奖金计算调整
+ */
+class HighestEmpLevelLog extends \common\components\ActiveRecord
+{
+    /**
+     * {@inheritdoc}
+     */
+    public static function tableName()
+    {
+        return '{{%HIGHEST_EMP_LEVEL_LOG}}';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function rules()
+    {
+        return [
+            [['USER_ID', 'FROM_ID', 'TO_ID', 'PERIOD_NUM', 'CALC_MONTH', 'CREATED_AT'], 'required'],
+            [['PERIOD_NUM', 'CALC_MONTH', 'STATUS', 'CREATED_AT'], 'integer'],
+            [['ID', 'USER_ID', 'FROM_ID', 'TO_ID', 'ADMIN_ID'], 'string', 'max' => 32],
+            [['REMARK'], 'string', 'max' => 4000],
+            [['ID'], 'unique'],
+        ];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function attributeLabels()
+    {
+        return [
+            'ID' => 'ID',
+            'USER_ID' => '会员ID',
+            'FROM_ID' => '变动前的级别',
+            'TO_ID' => '变动后的级别',
+            'ADMIN_ID' => '管理员id',
+            'PERIOD_NUM' => '变动的期数',
+            'CALC_MONTH' => '变动的结算月',
+            'REMARK' => '备注',
+            'STATUS' => '状态',
+            'CREATED_AT' => '创建时间',
+        ];
+    }
+}

+ 49 - 0
common/models/OrderPeriodAdjust.php

@@ -0,0 +1,49 @@
+<?php
+
+namespace common\models;
+
+/**
+ * This is the model class for table "{{%ORDER_PERIOD_ADJUST}}".
+ *
+ * @property string $ID
+ * @property string $ORDER_SN 订单号
+ * @property int $ORIGIN_PERIOD 调整前期数
+ * @property int $MODERN_PERIOD 调整后期数
+ * @property string $ADMIN_ID 创建人
+ * @property int $CREATED_AT 创建时间
+ */
+class OrderPeriodAdjust extends \common\components\ActiveRecord
+{
+    /**
+     * {@inheritdoc}
+     */
+    public static function tableName()
+    {
+        return '{{%ORDER_PERIOD_ADJUST}}';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function rules()
+    {
+        return [
+            [['ORDER_SN', 'ORIGIN_PERIOD', 'MODERN_PERIOD'], 'required'],
+        ];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function attributeLabels()
+    {
+        return [
+            'ID' => 'ID',
+            'ORDER_SN' => '订单号',
+            'ORIGIN_PERIOD' => '调整前期数',
+            'MODERN_PERIOD' => '调整后期数',
+            'ADMIN_ID' => '创建人',
+            'CREATED_AT' => '创建时间',
+        ];
+    }
+}

+ 15 - 0
common/models/Period.php

@@ -856,4 +856,19 @@ class Period extends \common\components\ActiveRecord
 
         return $periods;
     }
+
+    /**
+     * 获取期数列表
+     * @param null $periodNum
+     * @param int $limit
+     * @return array|\yii\db\ActiveRecord[]
+     */
+    public static function getPeriodList($periodNum = null, $limit = 10) {
+        if ($periodNum) {
+            $periodList = static::find()->where('PERIOD_NUM >= :PERIOD_NUM', [':PERIOD_NUM' => $periodNum])->select('PERIOD_NUM,IS_SENT,IS_CLOSED')->limit($limit)->asArray()->all();
+        } else {
+            $periodList = static::find()->select('PERIOD_NUM,IS_SENT,IS_CLOSED')->limit($limit)->column();
+        }
+        return $periodList;
+    }
 }

+ 2 - 0
common/models/ReceiveAddress.php

@@ -16,6 +16,7 @@ use Yii;
  * @property int $CITY 城市名称
  * @property int $COUNTY 县区名称
  * @property string $ADDRESS 详细地址
+ * @property string $ZIP_CODE 邮政编码
  * @property int $IS_DEFAULT 是否默认
  * @property int $CREATED_AT 创建时间
  * @property string $UPDATER 修改人
@@ -64,6 +65,7 @@ class ReceiveAddress extends \common\components\ActiveRecord
             'CITY' => '城市名称',
             'COUNTY' => '县区名称',
             'ADDRESS' => '详细地址',
+            'ZIP_CODE' => '邮编',
             'IS_DEFAULT' => '是否默认',
             'CREATED_AT' => '创建时间',
             'UPDATER' => '修改人',

+ 7 - 1
common/models/ShopGoods.php

@@ -39,6 +39,9 @@ class ShopGoods extends \common\components\ActiveRecord
         ],
         3 => [
             'name' => '积分兑换'
+        ],
+        4 => [
+            'name' => '在线支付'
         ]
     ];
     const GOODS_TYPE = [
@@ -168,7 +171,10 @@ class ShopGoods extends \common\components\ActiveRecord
             ],
             'exchange' => [
                 'name' => '无业绩兑换点数'
-            ]
+            ],
+            'online' => [
+                'name' => '在线支付'
+            ],
         ];
     }
 

+ 27 - 21
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 => '提现已付款',
@@ -340,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;

+ 101 - 0
common/models/WstOrderCall.php

@@ -0,0 +1,101 @@
+<?php
+
+namespace common\models;
+
+use common\components\MongoActiveRecord;
+use Yii;
+
+/**
+ * This is the model class for collection "ar_wst_order_call".
+ *
+ * @property \MongoDB\BSON\ObjectID|string $_id
+ * @property string $order_id
+ * @property string $order_no
+ * @property string $warehouse_id
+ * @property string $delivery_method_name
+ * @property string $addon_service_name
+ * @property string $country
+ * @property string $state
+ * @property string $city
+ * @property string $post_code
+ * @property string $address
+ * @property string $consignee
+ * @property string $telephone
+ * @property string $comment
+ * @property string $products
+ */
+class WstOrderCall extends MongoActiveRecord
+{
+    /**
+     * {@inheritdoc}
+     */
+    public static function collectionName()
+    {
+        return 'ar_wst_order_call';
+    }
+
+    /**
+     * @return \yii\mongodb\Connection the MongoDB connection used by this AR class.
+     * @throws \yii\base\InvalidConfigException
+     */
+    public static function getDb()
+    {
+        return Yii::$app->get('dbLog');
+    }
+
+    /**
+     * 获取id
+     * @return string
+     */
+    public function getId() {
+        return (string) $this->_id;
+    }
+    /**
+     * {@inheritdoc}
+     */
+    public function attributes()
+    {
+        return [
+            '_id',
+            'order_id',
+            'order_no',
+            'warehouse_id',
+            'delivery_method_name',
+            'addon_service_name',
+            'country',
+            'state',
+            'city',
+            'post_code',
+            'address',
+            'consignee',
+            'telephone',
+            'comment',
+            'products',
+        ];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function attributeLabels()
+    {
+        return [
+            '_id' => 'objectID',
+            'order_id',
+            'order_no',
+            'warehouse_id',
+            'delivery_method_name',
+            'addon_service_name',
+            'country',
+            'state',
+            'city',
+            'post_code',
+            'address',
+            'consignee',
+            'telephone',
+            'comment',
+            'products',
+        ];
+    }
+
+}

+ 492 - 0
common/models/forms/ApproachOrderForm.php

@@ -0,0 +1,492 @@
+<?php
+namespace common\models\forms;
+
+use common\helpers\Cache;
+use common\helpers\Date;
+use common\components\Model;
+use common\helpers\Form;
+use common\helpers\IPay88;
+use common\helpers\LoggerTool;
+use common\helpers\PayStack;
+use common\helpers\user\Balance;
+use common\helpers\user\Cash;
+use common\helpers\user\Info;
+use common\libs\logging\operate\AdminOperate;
+use common\models\ApproachDecOrder;
+use common\models\ApproachOrder;
+use common\models\ApproachOrderGoods;
+use common\models\BaUser;
+use common\models\DealType;
+use common\models\DecLevelLog;
+use common\models\DecOrder;
+use common\models\Order;
+use common\models\OrderGoods;
+use common\models\Period;
+use common\models\ReceiveAddress;
+use common\models\Region;
+use common\models\ShopGoods;
+use common\models\User;
+use common\models\UserNetwork;
+use common\models\Instalment;
+use Yii;
+use yii\base\Exception;
+
+/**
+ * Login form
+ */
+class ApproachOrderForm extends Model
+{
+    public $sn;
+    public $expressCompany;
+    public $orderTrackNo;
+    public $status;
+    public $remark;
+    public $note;
+
+    public $type;
+    public $addressId;
+    public $payType;
+    public $goodsId;
+    public $goodsNum;
+    public $payPassword;
+
+    public $userName;
+    public $consignee;
+    public $acceptMobile;
+    public $province;
+    public $city;
+    public $county;
+    public $lgaName;
+    public $detailaddress;
+
+    public $consigneeIdNo;
+    public $consigneeRealName;
+
+    private $_address;
+    private $_decAmount;
+    private $_decPv;
+    private $_freight;
+    private $_payAmount;
+    private $_orderGoods;
+    private $_remainPv;
+    private $_realPv;
+
+    /**
+     * @var ApproachOrder
+     */
+    private $_model;
+
+    public function init() {
+        parent::init();
+        $this->adminOperateLogger = new AdminOperate([
+            'fetchClass' => ApproachOrder::class,
+        ]);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function rules()
+    {
+        return [
+            [['sn', 'expressCompany', 'orderTrackNo', 'status', 'remark','type','addressId','payType','goodsId','goodsNum', 'payPassword','userName','consignee','acceptMobile','province','city','county','cityName','detailaddress', 'consigneeIdNo', 'consigneeRealName'], 'trim'],
+            [['sn', 'expressCompany', 'orderTrackNo', 'status', 'remark','type','addressId','payType','goodsId','goodsNum', 'payPassword','userName','consignee','acceptMobile','province','city','county','detailaddress', 'consigneeIdNo', 'consigneeRealName'], 'required'],
+            [['status'], 'isStatus'],
+            [['addressId'], 'isAddress'],
+            [['payType'], 'isPayType'],
+        ];
+    }
+
+    public function attributeLabels()
+    {
+        return [
+            'sn' => '订单号',
+            'expressCompany' => '快递公司',
+            'orderTrackNo' => '快递单号',
+            'status' => '状态',
+            'remark' => '备注',
+            'type' => '订单类型',
+            'addressId' => '收货地址',
+            'payType' => '支付方式',
+            'goodsId' => '商品ID',
+            'goodsNum' => '商品数量',
+            'userName' => '复消会员编号',
+            'consignee' => '收货人',
+            'acceptMobile' => '收货电话',
+            'province' => '省',
+            'city' => '市',
+            'county' => '区',
+            'detailaddress' => '收货详细地址',
+        ];
+    }
+
+    /**
+     * 指定校验场景
+     * @return array
+     */
+    public function scenarios()
+    {
+        $parentScenarios =  parent::scenarios();
+        $customScenarios = [
+            // 管理员修改订单状态
+            'adminStatus' => ['sn', 'status'],
+            // 校验订单支付
+            'verifyPay' => ['sn', 'status', 'note'],
+            // 会员下单
+            'userOrder' => ['type','addressId', 'payType','goodsId','goodsNum', 'note', 'consigneeIdNo', 'consigneeRealName'],
+        ];
+        return array_merge($parentScenarios, $customScenarios);
+    }
+
+    /**
+     * 校验之前
+     * @return bool
+     */
+    public function beforeValidate()
+    {
+        $parentValidate = parent::beforeValidate();
+        if ($this->sn) {
+            $this->_model = ApproachOrder::findOne(['SN' => $this->sn]);
+            if (!$this->_model){
+                $this->addError('sn', '订单不存在');
+                return false;
+            }
+        }
+
+        if ($this->scenario == 'verifyIPay88'){
+            if ($this->_model->STATUS != \Yii::$app->params['orderStatus']['notPaid']['value']) {
+                $this->addError('sn', '支付方式错误');
+                return false;
+            }
+        }
+
+        return $parentValidate;
+    }
+
+    /**
+     * 判断收货地址是否存在
+     * @param $attribute
+     */
+    public function isAddress($attribute){
+        if (!$receiveAddress = ReceiveAddress::find()->where(' ID=:ID', [':ID' => $this->addressId])->asArray()->one()) {
+            $this->addError($attribute, '收货地址不存在');
+        } else {
+            $this->_address = $receiveAddress;
+        }
+    }
+
+    /**
+     * 判断支付方式
+     * @param $attribute
+     * @throws Exception
+     */
+    public function isPayType($attribute)
+    {
+        if ($this->payType != 'online'){
+            $this->addError('支付方式错误');
+        }
+
+        // 一个订单只能包含一类商品
+        $goods = ShopGoods::find()->select('ID,CATE_ID')->where(['in', 'ID', $this->goodsId])->andWhere(['STATUS' => 1])->asArray()->all();
+        if (!$goods) {
+            throw new Exception('商品已下架');
+        }
+        $goodsCategoryType = array_unique(array_column($goods, 'CATE_ID'));
+        if (count($goodsCategoryType) > 1) {
+            $this->addError($attribute, '订单不能包含多种商品分类');
+        }
+    }
+
+    /**
+     * 校验类型
+     * @param $attribute
+     */
+    public function isStatus($attribute){
+        if($this->type && !in_array($this->type, \Yii::$app->params['orderStatus'])){
+            $this->addError($attribute, '订单状态类型错误');
+            return ;
+        }
+    }
+
+    /**
+     * 校验iPay88支付,更新订单状态.同步到正式订单.
+     * @throws Exception
+     */
+    public function verifyPayOnline(): ?ApproachOrder
+    {
+        if (!$this->validate()) {
+            return null;
+        }
+
+        LoggerTool::info([$this->sn, $this->note]);
+
+        // 调用iPay88支付校验
+//        LoggerTool::info([$this->note['reference'], $this->note]);
+//        $payload = IPay88::transactionVerify($this->note['reference']);
+//        LoggerTool::info($payload);
+//        if ($payload['status'] !== true) {
+//            throw new Exception(Form::formatErrorsForApi($payload['message']));
+//        }
+//        if ($payload['data']['amount'] != $this->_model->PAY_AMOUNT * 100) {
+//            throw new Exception(Form::formatErrorsForApi('支付金额与订单金额不符'));
+//        }
+
+        $db = \Yii::$app->db;
+        $transaction = $db->beginTransaction();
+        try {
+            // 更新准订单状态为已支付
+            $this->_model->STATUS = $this->status;
+            $this->_model->NOTE = json_encode($this->note);
+            $this->_model->PAY_AT = time();
+//            $this->_model->PAY_AT = Date::utcToTime($this->note['TranDate']);
+            if (!$this->_model->save()) {
+                throw new Exception(Form::formatErrorsForApi($this->_model->getErrors()));
+            }
+
+            // 同步准订单到正式订单
+            Order::insertOne($this->_model->toArray());
+            // 同步准订单商品到正式订单商品
+            $approachOrderGoods = ApproachOrderGoods::findAllAsArray('ORDER_SN = :ORDER_SN', [':ORDER_SN' => $this->sn]);
+            OrderGoods::batchInsert($approachOrderGoods);
+
+            // 删除中间表
+            ApproachOrder::deleteAll('SN = :SN', [':SN' => $this->sn]);
+            ApproachOrderGoods::deleteAll('ORDER_SN = :ORDER_SN', [':ORDER_SN' => $this->sn]);
+
+            $transaction->commit();
+        } catch (Exception $e) {
+            $transaction->rollBack();
+            $this->addError('edit', $e->getFile() . '  ' . $e->getMessage());
+            return null;
+        }
+
+        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
+        ];
+    }
+
+
+    /**
+     * 复销
+     * @throws Exception
+     * @throws \yii\db\Exception
+     */
+    public function add() {
+        if(!$this->validate()){
+            return null;
+        }
+
+        $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);
+
+                    $this->_orderGoods[] = [
+                        'GOODS_ID' => $goods['ID'],
+                        'PRICE' => $goods['SELL_PRICE'],
+                        'PV' => $currentPv,
+                        'REAL_PRICE' => $realPrice,
+                        'REAL_PV' => $realPv,
+                        'REMAIN_PV' => $remainPv,
+                        'POINT' => $goods['POINT'],
+                        'BUY_NUMS' => intval($v),
+                        'SKU_CODE' => $goods['GOODS_NO'],
+                        'GOODS_TITLE' => $goods['GOODS_NAME']
+                    ];
+                }
+            }
+        }
+
+        $this->_decAmount = $totalAmount;
+        $this->_decPv = $totalPv;
+        $this->_realPv = $totalRealPv;
+        $this->_freight = ($totalAmount>=300) ? 0 : 15;
+        $this->_payAmount = $this->_decAmount + $this->_freight;
+
+        $db = \Yii::$app->db;
+        $transaction = $db->beginTransaction();
+
+        // 支付减库存
+        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'] >= $this->goodsNum[$k]) {
+                    $data = ShopGoods::find()->where(['ID' => $ids[$k]])->one();
+                    $goods_store_nums = $data->STORE_NUMS - $this->goodsNum[$k];
+                    $data->STORE_NUMS = $goods_store_nums;
+                    $data->update();
+                    //下单后库存小于等于0 商品下架
+                    if ($goods_store_nums <= 0) {
+                        $data->STATUS = 0;
+                        $data->UPDATED_AT = Date::nowTime();
+                        $data->update();
+                    }
+                } else {
+                    throw new Exception($goods['GOODS_NAME'].'库存不足,无法购买商品');
+                }
+            }
+        }
+
+        try {
+            // 写入订单
+            if (!$orderResult = $this->addOrder()) {
+                throw new Exception(Form::formatErrorsForApi($orderResult->getErrors()));
+            }
+
+            // TODO: 获取iPay88所需参数
+//            $orderSn = $orderResult->SN;
+
+            $transaction->commit();
+
+            return $orderResult;
+        }catch (\Exception $e){
+            $transaction->rollBack();
+            $this->addError('add', $e->getMessage());
+            return null;
+        }
+    }
+
+    /**
+     * 复销订单
+     * @throws Exception
+     */
+    public function addOrder()
+    {
+        $periodObj = Period::instance();
+        $nowPeriodNum = $periodObj->getNowPeriodNum();
+        $nowCalcMonth = $periodObj->getYearMonth($nowPeriodNum);
+
+        $userId = \Yii::$app->user->id;
+
+        $userName = Info::getUserNameByUserId($userId);
+        $userRealName = Info::getUserRealNameByUserId($userId);
+        $userMobile = Info::getUserMobileByUserId($userId);
+        $userEmail = Info::getUserEmailByUserId($userId);
+
+        // 加入订单信息
+        $warehouse = Region::getWarehouseByCode($this->_address['PROVINCE']);//仓库
+        if(!$warehouse){
+            throw new Exception('地区暂时不支持配送,具体联系客服');
+        }
+
+        $ordNo = $this->_generateSn();
+        $orderModel = new ApproachOrder();
+        $orderModel->SN = 'OS' . $ordNo;
+        $orderModel->DEC_SN = 'DS' . $ordNo;
+        $orderModel->ORDER_TYPE = $this->type;
+        $orderModel->USER_ID = $userId;
+        $orderModel->USER_NAME = $userName;
+        $orderModel->ORDER_AMOUNT = $this->_decAmount;
+        $orderModel->PV = $this->_decPv;
+        $orderModel->PAY_AMOUNT = $this->_payAmount;
+        $orderModel->PAY_PV = $this->_decPv;
+        $orderModel->REMAIN_PV = $this->_remainPv;
+        $orderModel->PAY_AT = 0;
+        $orderModel->PAY_TYPE = $this->payType;
+        $orderModel->PERIOD_NUM = $nowPeriodNum;
+        $orderModel->P_CALC_MONTH = Date::ociToDate($nowCalcMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH);
+        $orderModel->FREIGHT = $this->_freight;
+        $orderModel->PAY_FREIGHT = $this->_freight;
+        $orderModel->CONSIGNEE = $this->_address['CONSIGNEE'];
+        $orderModel->MOBILE = $this->_address['MOBILE'];
+        $orderModel->PROVINCE = $this->_address['PROVINCE'];
+        $orderModel->CITY = $this->_address['CITY'];
+        $orderModel->COUNTY = $this->_address['COUNTY'];
+        $orderModel->ADDRESS = $this->_address['ADDRESS'];
+        $orderModel->FRONT_REMARK = $this->remark;
+        $orderModel->WAREHOUSE = $warehouse;
+        $orderModel->STATUS = \Yii::$app->params['orderStatus']['notPaid']['value'];
+        $orderModel->CREATED_AT = Date::nowTime();
+        $orderModel->CREATE_USER = $userName;
+        $orderModel->EMAIL = $userEmail ?: $userName.'@elken.net';
+        $orderModel->CONSIGNEE_ID_NO = $this->consigneeIdNo;
+        $orderModel->CONSIGNEE_REAL_NAME = $this->consigneeRealName;
+        $orderModel->ZIP_CODE = $this->_address['ZIP_CODE'];
+        if(!$orderModel->save()){
+            $this->addErrors($orderModel->getErrors());
+            return false;
+        }
+
+        // 加入商品到订单商品表
+        foreach($this->_orderGoods as $key=>$value) {
+            $this->_orderGoods[$key]['ORDER_SN'] = $orderModel->SN;
+            $this->_orderGoods[$key]['P_CALC_MONTH'] = Date::ociToDate($nowCalcMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH);
+        }
+        ApproachOrderGoods::batchInsert($this->_orderGoods);
+
+        return $orderModel;
+    }
+
+    /**
+     * 生成流水号
+     * @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;
+    }
+}

+ 916 - 916
common/models/forms/DeclarationForm.php

@@ -1,916 +1,916 @@
-<?php
-namespace common\models\forms;
-
-use common\components\Model;
-use common\helpers\Cache;
-use common\helpers\Date;
-use common\helpers\Form;
-use common\helpers\user\Cash;
-use common\helpers\user\Reconsume;
-use common\helpers\user\Info;
-use common\models\DeclarationPackage;
-use common\models\DecOrder;
-use common\models\EmployLevel;
-use common\models\Order;
-use common\models\OrderGoods;
-use common\models\Period;
-use common\models\ReceiveAddress;
-use common\models\ReconsumePool;
-use common\models\ReconsumePoolFlow;
-use common\models\DeclarationLevel;
-use common\models\Region;
-use common\models\ShopGoods;
-use common\models\User;
-use common\models\UserInfo;
-use common\models\UserNetwork;
-use common\models\UserRelation;
-use yii\base\Exception;
-
-/**
- * Login form
- */
-class DeclarationForm extends Model
-{
-    public $type;
-    public $decLv;
-    public $decWay;
-    public $packageId;
-    public $goodsId;
-    public $goodsNum;
-    public $insertUserName;
-    public $password;
-    public $payPassword;
-    public $realName;
-    public $insertUserIdCard;
-    public $mobile;
-    public $address;
-    public $openBank;
-    public $bankAddress;
-    public $bankNo;
-    public $bankProvince;
-    public $bankCity;
-    public $bankCounty;
-    public $conUserName;
-    public $recUserName;
-    public $decUserName;
-    public $location;
-    public $consignee;
-    public $acceptMobile;
-    public $province;
-    public $city;
-    public $county;
-
-    // 传过来的全部数据
-    public $allData;
-    private $_decId;
-    public $_insertUserId;
-    private $_decAmount;
-    private $_decPv;
-    private $_orderGoods;
-
-    // 批量报单时添加会员的REDIS里面缓存的添加的会员资料
-    const REDIS_WAIT_ADD_USER = 'user:dec:waitAdd';
-
-    const TYPE_ZC = 'ZC';
-//    const TYPE_YH = 'YH';
-    const TYPE_ZG = 'ZG';
-    const TYPE_LS = 'LS';
-    const TYPE_FX = 'FX';
-
-//    private $_modelClass = null;
-    private $_oneOrder = null;
-    private $_userForm = null;
-    // 全部的上级(安置网和开拓网)
-    private $_tempParentUser = [];
-    // 全部的安置网上级
-    private $_tempNetworkParentUser = [];
-    // 全部的开拓网上级
-    private $_tempRelationParentUser = [];
-    private $_types = [
-        self::TYPE_ZC => [
-            'name' => '首购单',
-        ],
-//        self::TYPE_YH => [
-//            'class' => DeclarationYH::class,
-//            'table' => '{{%DECLARATION_YH}}',
-//            'name' => '优惠单',
-//        ],
-        self::TYPE_ZG => [
-            'name' => '升级增购单',
-        ],
-        self::TYPE_LS => [
-            'name' => '零售单',
-        ],
-        self::TYPE_FX => [
-            'name' => '复销单',
-        ],
-    ];
-
-
-    /**
-     * @inheritdoc
-     */
-    public function rules()
-    {
-        return [
-            [['password','payPassword','type','decLv','decWay','packageId', 'insertUserName', 'realName', 'insertUserIdCard', 'mobile', 'address', 'openBank', 'bankAddress', 'bankNo','bankProvince','bankCity','bankCounty','consignee','acceptMobile','province','city','county','decUserName', 'conUserName', 'recUserName', 'location'], 'trim'],
-            [['type','decLv','decWay','insertUserName', 'insertUserIdCard','decUserName'], 'required'],
-            [['type'], 'isType', 'on'=>['userDec', 'canDec']],
-            [['insertUserName'], 'isCanAddUser'],
-            [['decUserName'], 'issetDec'],
-            [['conUserName'], 'isConUserName'],
-            [['recUserName'], 'isRecUserName'],
-            [['location'], 'isLocation'],
-            [['insertUserIdCard'], 'isSameSystem'],
-        ];
-    }
-
-    public function attributeLabels()
-    {
-        return [
-            'type' => '报单类型',
-            'decLv' => '报单级别',
-            //'decPv' => '报单PV',
-            'decWay' => '报单方式',
-            'packageId' => '报单套餐',
-            'goodsId' => '商品ID',
-            'goodsNum' => '商品数量',
-            //'addType' => '新增会员方式',
-            'insertUserName' => '会员用户名',
-            'password' => '登陆密码',
-            'payPassword' => '支付密码',
-            'realName' => '会员姓名',
-            'insertUserIdCard' => '身份证号',
-            'mobile' => '手机号',
-            'address' => '地址',
-            'openBank' => '开户行',
-            'bankAddress' => '开户支行',
-            'bankNo' => '银行账号',
-            'bankProvince' => '银行省份',
-            'bankCity' => '银行城市',
-            'bankCounty' => '银行县区',
-            'conUserName' => '指导老师用户名',
-            'recUserName' => '开拓人用户名',
-            'decUserName' => '报单中心用户名',
-            'conUid' => '指导老师会员ID',
-            'recUid' => '开拓人会员ID',
-            'location' => '市场',
-            'consignee' => '收货人',
-            'acceptMobile' => '收货人手机',
-            'province' => '收货省',
-            'city' => '收货市',
-            'county' => '收货区县',
-            'address' => '收货详细地址',
-        ];
-    }
-
-    /**
-     * 指定场景
-     * @return array
-     */
-    public function scenarios()
-    {
-        $parentScenarios =  parent::scenarios();
-        $customScenarios = [
-            'userDec' => ['type','allData', 'decLv','decWay','insertUserName','password','payPassword', 'realName', 'insertUserIdCard', 'mobile', 'address', 'openBank', 'bankAddress', 'bankNo', 'bankProvince','bankCity','bankCounty', 'consignee','acceptMobile','province','city','county', 'conUserName', 'recUserName','decUserName', 'location'],
-            'canDec' => ['type', 'insertUserName', 'insertUserIdCard', 'conUserName', 'recUserName', 'location'],
-            'notFull' => ['type', 'insertUserName', 'conUserName', 'recUserName', 'location'],
-        ];
-        return array_merge($parentScenarios, $customScenarios);
-    }
-
-    /**
-     * 判断报单中心是否存在
-     * @param $attribute
-     */
-    public function issetDec($attribute){
-        if (!$decUser = User::find()->select('ID')->where('IS_DEC=1 AND USER_NAME=:USER_NAME', [':USER_NAME' => $this->decUserName])->asArray()->one()) {
-            $this->addError($attribute, '报单中心不存在');
-            return false;
-        } else {
-            // 判断报单中心是否在新加入会员的安置网上级中
-            $this->loopFindParentToNetwork($this->insertUserName);
-            //反转数组,in_array搜索错误
-            //in_array($this->decUserName, $this->_tempNetworkParentUser[$this->insertUserName]);
-            $flipParent = array_flip(array_filter($this->_tempNetworkParentUser[$this->insertUserName]));
-//            var_dump($flipParent);
-//            echo $this->insertUserName.'=='.$this->decUserName;
-//            exit;
-            if (!isset($flipParent[$this->decUserName])) {
-                $this->addError($attribute, '为' . $this->insertUserName . '报单,报单中心' . $this->decUserName . '不在' . $this->insertUserName . '的安置网上级中');
-                return ;
-            }
-            $this->_decId = $decUser['ID'];
-        }
-    }
-
-    /**
-     * 判断指导老师
-     * @param $attribute
-     */
-    public function isConUserName($attribute){
-        if($this->type == self::TYPE_ZC){
-            // 从数据库查看接点会员是否在
-            if(!isset($this->_tempParentUser[$this->conUserName])){
-                $conUserTemp = UserInfo::findOneAsArray('USER_NAME=:USER_NAME', [':USER_NAME' => $this->conUserName]);
-                if(!$conUserTemp){
-                    if($this->insertUserName){
-                        $this->addError($attribute, '为'.$this->insertUserName.'报单,指导老师'.$this->conUserName.'不存在');
-                    } else {
-                        $this->addError($attribute, '指导老师'.$this->conUserName.'不存在');
-                    }
-                    return ;
-                }
-                $conUserTemp['CON_NUM'] = UserNetwork::firstFloorChildNum($conUserTemp['USER_ID']);
-                $conUserTemp['REC_NUM'] = UserRelation::firstFloorChildNum($conUserTemp['USER_ID']);
-                $this->_tempParentUser[$this->conUserName] = [
-                    'USER_NAME' => $this->conUserName,
-                    'ZC_PV' => $conUserTemp['ZC_PV'],
-                    'CON_USER_NAME' => Info::getUserNameByUserId($conUserTemp['CON_UID']),
-                    'REC_USER_NAME' => Info::getUserNameByUserId($conUserTemp['REC_UID']),
-                    'CON_NUM' => $conUserTemp['CON_NUM'],
-                    'REC_NUM' => $conUserTemp['REC_NUM'],
-                    'SYSTEM_ID' => $conUserTemp['SYSTEM_ID'],
-                    'LOCATION' => UserNetwork::getLocation($conUserTemp['USER_ID'], $conUserTemp['CON_UID']),
-                ];
-                // 把该会员下面的5个区是否存在会员都付上
-                for($i=1;$i<=5;$i++){
-                    $this->_tempParentUser[$this->conUserName]["LOCATION$i"] = UserNetwork::issetUserInLocation($conUserTemp['USER_ID'], $i);
-                }
-            }
-            $conUser = $this->_tempParentUser[$this->conUserName];
-            // 判断接点会员的下级会员是否大于三个,如果大于三个则不允许
-            if($conUser['CON_NUM'] >= 3){
-                if($this->insertUserName){
-                    $this->addError($attribute, '为'.$this->insertUserName.'报单,指导老师'.$this->conUserName.'下级点位已满');
-                } else {
-                    $this->addError($attribute, '指导老师'.$this->conUserName.'下级点位已满');
-                }
-                return;
-            }
-            if($this->insertUserName){
-                // 把自己加入到临时上级会员数组中
-                $this->_tempParentUser[$this->insertUserName] = [
-                    'USER_NAME' => $this->insertUserName,
-                    //'ZC_PV' => $this->decPv,
-                    'CON_USER_NAME' => $this->conUserName,
-                    'REC_USER_NAME' => $this->recUserName,
-                    'CON_NUM' => 0,
-                    'REC_NUM' => 0,
-                    'SYSTEM_ID' => $conUser['SYSTEM_ID'],
-                    'LOCATION' => $this->location,
-                    'LOCATION1' => 0,
-                    'LOCATION2' => 0,
-                    'LOCATION3' => 0,
-                    'LOCATION4' => 0,
-                    'LOCATION5' => 0,
-                ];
-            }
-
-        }
-    }
-
-    /**
-     * 判断开拓人
-     * @param $attribute
-     */
-    public function isRecUserName($attribute){
-        if($this->type == self::TYPE_ZC){
-            // 开拓人
-            if(!isset($this->_tempParentUser[$this->recUserName])){
-                $recUserTemp = UserInfo::findOneAsArray('USER_NAME=:USER_NAME', [':USER_NAME' => $this->recUserName]);
-                if(!$recUserTemp){
-                    if($this->insertUserName){
-                        $this->addError($attribute, '为'.$this->insertUserName.'报单,开拓人'.$this->recUserName.'不存在');
-                    } else {
-                        $this->addError($attribute, '开拓人'.$this->recUserName.'不存在');
-                    }
-
-                    return ;
-                }
-                $recUserTemp['CON_NUM'] = UserNetwork::firstFloorChildNum($recUserTemp['USER_ID']);
-                $recUserTemp['REC_NUM'] = UserRelation::firstFloorChildNum($recUserTemp['USER_ID']);
-                $this->_tempParentUser[$this->recUserName] = [
-                    'USER_NAME' => $this->recUserName,
-                    'ZC_PV' => $recUserTemp['ZC_PV'],
-                    'CON_USER_NAME' => Info::getUserNameByUserId($recUserTemp['CON_UID']),
-                    'REC_USER_NAME' => Info::getUserNameByUserId($recUserTemp['REC_UID']),
-                    'CON_NUM' => $recUserTemp['CON_NUM'],
-                    'REC_NUM' => $recUserTemp['REC_NUM'],
-                    'SYSTEM_ID' => $recUserTemp['SYSTEM_ID'],
-                    'LOCATION' => UserNetwork::getLocation($recUserTemp['USER_ID'], $recUserTemp['CON_UID']),
-                ];
-                // 把该会员下面的5个区是否存在会员都付上
-                for($i=1;$i<=5;$i++){
-                    $this->_tempParentUser[$this->recUserName]["LOCATION$i"] = UserNetwork::issetUserInLocation($recUserTemp['USER_ID'], $i);
-                }
-            }
-            $recUser = $this->_tempParentUser[$this->recUserName];
-            $this->_tempParentUser[$this->recUserName]['REC_NUM'] += 1;
-
-            // 存在新加入会员时查看开拓人是否在新加入会员的安置网上级中
-            if($this->insertUserName) {
-                $this->loopFindParentToNetwork($this->insertUserName);
-                if (!$this->recUserIsInNetworkParent()) {
-                    $this->addError($attribute, '为' . $this->insertUserName . '报单,开拓人' . $this->recUserName . '不在' . $this->insertUserName . '的安置网上级中');
-                    return ;
-                }
-            }
-
-            // 把自己加入到临时上级会员数组中
-            $this->_tempParentUser[$this->insertUserName] = [
-                'USER_NAME' => $this->insertUserName,
-                //'ZC_PV' => $this->decPv,
-                'CON_USER_NAME' => $this->conUserName,
-                'REC_USER_NAME' => $this->recUserName,
-                'CON_NUM' => 0,
-                'REC_NUM' => 0,
-                'SYSTEM_ID' => $recUser['SYSTEM_ID'],
-                'LOCATION' => $this->location,
-                'LOCATION1' => 0,
-                'LOCATION2' => 0,
-                'LOCATION3' => 0,
-                'LOCATION4' => 0,
-                'LOCATION5' => 0,
-            ];
-        }
-
-    }
-
-    /**
-     * 循环把所有新加入的会员的上级加入到临时变量中
-     * @param null $conUserName
-     * @return bool
-     */
-    private function loopFindParentToNetwork($conUserName = null) {
-        if($conUserName == null ){
-            $conUserName = $this->insertUserName;
-        }
-        $findUserKey = array_search($conUserName, array_column($this->allData, 'insertUserName'));
-        // 如果有这个新加入的会员,则查找其上级接点
-        if($findUserKey !== false){
-            if(strtoupper($this->allData[$findUserKey]['type']) == 'ZC'){
-                $this->_tempNetworkParentUser[$this->insertUserName][] = $this->allData[$findUserKey]['conUserName'];
-                $this->loopFindParentToNetwork($this->allData[$findUserKey]['conUserName']);
-            }
-        }
-        // 如果没有这个新加入的接点,
-        else {
-            if($this->insertUserName == $conUserName){
-                $this->addError('recUserName', '新加入的会员不存在');
-                return false;
-            }
-            // 去数据库里查找这个会员的所有上级
-//            $allParentUser = UserNetwork::find()->select('PUI.USER_NAME')->where('UI.USER_NAME=:USER_NAME', [':USER_NAME'=>$conUserName])->from(UserNetwork::tableName().' AS UN')->join('LEFT JOIN', UserInfo::tableName().' AS UI', 'UN.USER_ID=UI.USER_ID')->join('LEFT JOIN', UserInfo::tableName().' AS PUI', 'UN.PARENT_UID=PUI.USER_ID')->orderBy('PUI.NETWORK_DEEP DESC')->asArray()->all();
-            $baseUser = Info::getBaseUserByUserName($conUserName);
-            $userNetworkInfo = UserNetwork::findOneAsArray('USER_ID=:USER_ID', [':USER_ID' => $baseUser['ID']]);
-            unset($baseUser);
-            $allParentUserIdsArr = explode(',', $userNetworkInfo['PARENT_UIDS']);
-            unset($userNetworkInfo);
-            $allParentUserIds = array_reverse($allParentUserIdsArr);
-            unset($allParentUserIdsArr);
-            if($allParentUserIds){
-                foreach($allParentUserIds as $parentUserId) {
-                    $parentBaseUser = Info::getBaseUserById($parentUserId);
-                    $this->_tempNetworkParentUser[$this->insertUserName][] = $parentBaseUser['USER_NAME'] ;
-
-                    unset($parentUserId, $parentBaseUser);
-                }
-            }
-            unset($allParentUserIds);
-        }
-        return true;
-    }
-
-    /**
-     * 开拓人是否在新加入会员的上级中
-     * @return bool
-     */
-    private function recUserIsInNetworkParent(){
-        return in_array($this->recUserName, $this->_tempNetworkParentUser[$this->insertUserName]);
-    }
-
-    /**
-     * 判断区域是否正确
-     * @param $attribute
-     */
-    public function isLocation($attribute){
-        if($this->type == self::TYPE_ZC){
-            if(!in_array($this->location, [1, 2, 3])){
-                $this->addError($attribute, '市场必须在第1市场、第2市场或第三3市场');
-            }
-            $conUser = $recUser = null;
-            if(isset($this->_tempParentUser[$this->conUserName])){
-                $conUser = $this->_tempParentUser[$this->conUserName];
-            }
-            if(isset($this->_tempParentUser[$this->recUserName])){
-                $recUser = $this->_tempParentUser[$this->recUserName];
-            }
-            if($conUser){
-                // 判断指导老师相应的区位是否已满
-                if($conUser['LOCATION'.$this->location]){
-                    if($this->insertUserName){
-                        $this->addError($attribute, '为'.$this->insertUserName.'报单,指导老师'.$this->conUserName.'的第'.$this->location.'市场已存在会员');
-                    } else {
-                        $this->addError($attribute, '指导老师'.$this->conUserName.'的第'.$this->location.'市场已存在会员');
-                    }
-                    return;
-                }
-                //市场顺序判断
-//                if($conUser['CON_NUM'] == 0 && $this->location != 1){
-//                    if($this->insertUserName){
-//                        $this->addError($attribute, '为'.$this->insertUserName.'报单,市场必须为指导老师'.$this->conUserName.'下第一市场');
-//                    } else {
-//                        $this->addError($attribute, '市场必须为指导老师'.$this->conUserName.'下第一市场');
-//                    }
-//                    return;
-//                }
-//                if($conUser['CON_NUM'] == 1 && $this->location == 3){
-//                    if($this->insertUserName){
-//                        $this->addError($attribute, '为'.$this->insertUserName.'报单,市场必须为指导老师'.$this->conUserName.'第二市场');
-//                    } else {
-//                        $this->addError($attribute, '市场必须为指导老师'.$this->conUserName.'第二市场');
-//                    }
-//                    return;
-//                }
-                $this->_tempParentUser[$this->conUserName]['CON_NUM'] += 1;
-                $this->_tempParentUser[$this->conUserName]['LOCATION'.$this->location] = true;
-            }
-        }
-    }
-
-    /**
-     * 判断会员是否可加入(通过redis结合数据库判断上级会员的情况)
-     * @param $attribute
-     */
-    public function isCanAddUser($attribute){
-        if($this->type == self::TYPE_ZC){
-            // 从数据库查看接点会员是否在
-            if(!isset($this->_tempParentUser[$this->conUserName])){
-                $conUserTemp = UserInfo::findOneAsArray('USER_NAME=:USER_NAME', [':USER_NAME' => $this->conUserName]);
-                if(!$conUserTemp){
-                    $this->addError($attribute, '为'.$this->insertUserName.'报单,指导老师'.$this->conUserName.'不存在');
-                    return ;
-                }
-                $conUserTemp['CON_NUM'] = UserNetwork::firstFloorChildNum($conUserTemp['USER_ID']);
-                $conUserTemp['REC_NUM'] = UserRelation::firstFloorChildNum($conUserTemp['USER_ID']);
-                $this->_tempParentUser[$this->conUserName] = [
-                    'USER_NAME' => $this->conUserName,
-                    //'ZC_PV' => $conUserTemp['ZC_PV'],
-                    'CON_USER_NAME' => Info::getUserNameByUserId($conUserTemp['CON_UID']),
-                    'REC_USER_NAME' => Info::getUserNameByUserId($conUserTemp['REC_UID']),
-                    'CON_NUM' => $conUserTemp['CON_NUM'],
-                    'REC_NUM' => $conUserTemp['REC_NUM'],
-                    'SYSTEM_ID' => $conUserTemp['SYSTEM_ID'],
-                    'LOCATION' => UserNetwork::getLocation($conUserTemp['USER_ID'], $conUserTemp['CON_UID']),
-                ];
-                // 把该会员下面的5个区是否存在会员都付上
-                for($i=1;$i<=5;$i++){
-                    $this->_tempParentUser[$this->conUserName]["LOCATION$i"] = UserNetwork::issetUserInLocation($conUserTemp['USER_ID'], $i);
-                }
-            }
-            $conUser = $this->_tempParentUser[$this->conUserName];
-
-            // 开拓人
-            if(!isset($this->_tempParentUser[$this->recUserName])){
-                $recUserTemp = UserInfo::findOneAsArray('USER_NAME=:USER_NAME', [':USER_NAME' => $this->recUserName]);
-                if(!$recUserTemp){
-                    $this->addError($attribute, '为'.$this->insertUserName.'报单,开拓人'.$this->recUserName.'不存在');
-                    return ;
-                }
-                $recUserTemp['CON_NUM'] = UserNetwork::firstFloorChildNum($recUserTemp['USER_ID']);
-                $recUserTemp['REC_NUM'] = UserRelation::firstFloorChildNum($recUserTemp['USER_ID']);
-                $this->_tempParentUser[$this->recUserName] = [
-                    'USER_NAME' => $this->recUserName,
-                    //'ZC_PV' => $recUserTemp['ZC_PV'],
-                    'CON_USER_NAME' => Info::getUserNameByUserId($recUserTemp['CON_UID']),
-                    'REC_USER_NAME' => Info::getUserNameByUserId($recUserTemp['REC_UID']),
-                    'CON_NUM' => $recUserTemp['CON_NUM'],
-                    'REC_NUM' => $recUserTemp['REC_NUM'],
-                    'SYSTEM_ID' => $recUserTemp['SYSTEM_ID'],
-                    'LOCATION' => UserNetwork::getLocation($recUserTemp['USER_ID'], $recUserTemp['CON_UID']),
-                ];
-                // 把该会员下面的5个区是否存在会员都付上
-                for($i=1;$i<=5;$i++){
-                    $this->_tempParentUser[$this->recUserName]["LOCATION$i"] = UserNetwork::issetUserInLocation($recUserTemp['USER_ID'], $i);
-                }
-            }
-            $recUser = $this->_tempParentUser[$this->recUserName];
-
-            // 判断接点会员的下级会员是否大于三个,如果大于三个则不允许
-            if($conUser['CON_NUM'] >= 3){
-                $this->addError($attribute, '为'.$this->insertUserName.'报单,指导老师'.$this->conUserName.'下级点位已满');
-                return;
-            }
-            // 判断指导老师相应的区位是否已满
-            if($conUser['LOCATION'.$this->location]){
-                $this->addError($attribute, '为'.$this->insertUserName.'报单,指导老师'.$this->conUserName.'该市场已存在会员');
-                return;
-            }
-//            if($conUser['CON_NUM'] == 0 && $this->location != 1){
-//                $this->addError($attribute, '为'.$this->insertUserName.'报单,市场必须为指导老师'.$this->conUserName.'下第一市场');
-//                return;
-//            }
-
-            // 把指导老师的变量的相关数量增加数量
-//            $this->_tempParentUser[$this->conUserName]['CON_NUM'] += 1;
-//            $this->_tempParentUser[$this->conUserName]['LOCATION'.$this->location] = true;
-//            $this->_tempParentUser[$this->recUserName]['REC_NUM'] += 1;
-
-            // 把自己加入到临时上级会员数组中
-            $this->_tempParentUser[$this->insertUserName] = [
-                'USER_NAME' => $this->insertUserName,
-                //'ZC_PV' => $this->decPv,
-                'CON_USER_NAME' => $this->conUserName,
-                'REC_USER_NAME' => $this->recUserName,
-                'CON_NUM' => 0,
-                'REC_NUM' => 0,
-                'SYSTEM_ID' => $recUser['SYSTEM_ID'],
-                'LOCATION' => $this->location,
-                'LOCATION1' => 0,
-                'LOCATION2' => 0,
-                'LOCATION3' => 0,
-                'LOCATION4' => 0,
-                'LOCATION5' => 0,
-            ];
-        }
-    }
-
-    /**
-     * 报单类型
-     * @param $attribute
-     * @param $params
-     */
-    public function isType($attribute, $params){
-        if(array_key_exists($this->type, $this->_types)){
-            if($this->type == self::TYPE_ZC){
-                if($this->scenario == 'userDec'){
-                    if(!$this->insertUserName) $this->addError($attribute, '首购必须填写加入会员编号');
-                }
-                if(!$this->insertUserName) $this->addError($attribute, '首购必须填写加入会员编号');
-                if(!$this->insertUserIdCard) $this->addError($attribute, '首购必须填写加入会员的身份证号');
-                if(!$this->conUserName) $this->addError($attribute, '首购必须填写加入会员的指导老师编号');
-                if(!$this->recUserName) $this->addError($attribute, '首购必须填写加入会员的开拓人编号');
-                if(!$this->location) $this->addError($attribute, '首购必须填写加入会员的市场');
-            }
-        } else {
-            $this->addError($attribute, '报单类型不正确');
-        }
-    }
-
-    /**
-     * 检验相同身份证 会员是否同一体系内(接点)
-     * @param $attribute
-     */
-    public function isSameSystem($attribute){
-        if(isset($this->_tempParentUser[$this->conUserName])){
-            // 新加入会员的身份证号对应网内的其他会员
-            $otherUser = User::findAllAsArray("ID_CARD=:ID_CARD AND IS_UNION=0 AND DELETED=0 AND (ID_CARD_PREFIX IS NULL OR ID_CARD_PREFIX='')", [':ID_CARD'=>$this->insertUserIdCard]);
-            if(count($otherUser)>=7){
-                $this->addError($attribute, '同一个身份证限制只能报7单');
-            }
-            if($otherUser){
-                $flipParent = array_flip(array_filter($this->_tempNetworkParentUser[$this->insertUserName]));
-                $isExsit = false;
-                foreach ($otherUser as $conUser){
-                    if(isset($flipParent[$conUser['USER_NAME']])){
-                        $isExsit = true;
-                        break;
-                    }
-                }
-                if (!$isExsit) {
-                    $this->addError($attribute, '为' . $this->insertUserName . '报单,身份证号码相同的会员'.$otherUser[0]['USER_NAME'].'不在' . $this->insertUserName . '的安置网上级中');
-                    return ;
-                }
-            }
-        } else {
-            $this->addError($attribute, '为'.$this->insertUserName.'报单,接点人'.$this->conUserName.'不存在');
-        }
-    }
-
-    /**
-     * 添加报单
-     * @param $allData
-     * @return bool|null
-     * @throws Exception
-     * @throws \yii\db\Exception
-     */
-    public function add($allData){
-        if(!$this->validate()){
-            return null;
-        }
-
-        // 首购单,需要添加会员操作
-        if($this->type == self::TYPE_ZC){
-            if (preg_match("/[\x7f-\xff]/", $this->insertUserName)) {  //判断字符串中是否有中文
-                throw new Exception('会员编号中不能含有汉字');
-            }
-            //报单商品及PV判断
-            $decLevelConfig = Cache::getDecLevelConfig();
-            $decLevel = $decLevelConfig[$this->decLv];
-            $toDecLevel = $this->decLv;
-            if(!$this->decLv){
-                throw new Exception('请选择报单级别');
-            }
-            if($this->decWay==1) {
-                $decPackage = DeclarationPackage::findOneAsArray('ID=:ID', [':ID'=>$this->packageId]);
-                $this->_decAmount = $decPackage['AMOUNT'];
-                $this->_decPv = $decPackage['PV'];
-                $this->_orderGoods[] = [
-                    'GOODS_ID' => $this->packageId,
-                    'PRICE' => $this->_decAmount,
-                    'REAL_PRICE' => $this->_decAmount,
-                    'PV' => $this->_decPv,
-                    'REAL_PV' => $this->_decPv,
-                    'BUY_NUMS' => 1,
-                    'SKU_CODE' => $decPackage['PACKAGE_NO'],
-                    'GOODS_TITLE' => $decPackage['PACKAGE_NAME']
-                ];
-                // 更改库存和状态
-                $data = DeclarationPackage::find()->where(['ID' => $decPackage['ID']])->one();
-                $data->STORE_NUMS = $data->STORE_NUMS - 1;
-                if($data->STORE_NUMS <= 0){
-                    $data->STATUS = 0;
-                    $data->UPDATED_AT = Date::nowTime();
-                }
-                $data->update();
-            }else{
-                $ids = $this->goodsId;
-                $totalAmount = 0;
-                $totalPv = 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('商品已下架');
-                            return;
-                        }
-                        if($goods['STORE_NUMS']>0){
-                            $totalAmount += $goods['SELL_PRICE'] * intval($v);
-                            $totalPv += $goods['PRICE_PV'] * intval($v);
-                            $this->_orderGoods[] = [
-                                'GOODS_ID' => $goods['ID'],
-                                'PRICE' => $goods['SELL_PRICE'],
-                                'REAL_PRICE' => $goods['SELL_PRICE'],
-                                'PV' => $goods['PRICE_PV'],
-                                'REAL_PV' => $goods['PRICE_PV'],
-                                'POINT' => $goods['POINT'],
-                                'BUY_NUMS' => intval($v),
-                                'SKU_CODE' => $goods['GOODS_NO'],
-                                'GOODS_TITLE' => $goods['GOODS_NAME']
-                            ];
-                            // 更改库存和状态
-                            $data = ShopGoods::find()->where(['ID' => $goods['ID']])->one();
-                            $data->STORE_NUMS = $data->STORE_NUMS - intval($v);
-                            if($data->STORE_NUMS <= 0){
-                                $data->STATUS = 0;
-                                $data->UPDATED_AT = Date::nowTime();
-                            }
-                            $data->update();
-                        }
-                    }
-                }
-                if($totalPv<$decLevel['PERF']){
-                    throw new Exception('自选商品总PV不能小于所选报单级别PV');
-                }
-                foreach ($decLevelConfig as $key=>$val){
-                    if($totalPv>=$val['PERF']){
-                        $toDecLevel = $key;
-                    }
-                }
-                if($this->decLv!=$toDecLevel){
-                    throw new Exception('自选商品总PV不能超过已选级别下一个级别的PV值');
-                }
-                $this->_decAmount = $totalAmount;
-                $this->_decPv = $totalPv;
-            }
-            //看现金余额是否充足
-            $loginUserId = \Yii::$app->user->id;
-            if (Cash::getAvailableBalance($loginUserId) < $this->_decAmount){
-                throw new Exception('报单人现金不足,无法完成报单');
-            }
-
-            if(!($zcResult = $this->addUser($allData))) {
-                throw new Exception(Form::formatErrorsForApi($this->_userForm->getErrors()));
-            }
-            if(!($decResult = $this->addDecOrder())) {
-                throw new Exception(Form::formatErrorsForApi($decResult->getErrors()));
-            }
-        }
-        return true;
-    }
-
-    /**
-     * 添加会员
-     * @param $allData
-     * @return bool|UserInfo|null
-     * @throws \yii\db\Exception
-     */
-    public function addUser($allData){
-        $period = Period::instance();
-        $userPasswd = $this->password;
-        $userPayPasswd = $this->payPassword;
-        // 如果身份证信息有误,或不足6位,并且没有手动填写密码,就用111111
-        if (Info::simpleIdCardCheck($this->insertUserIdCard)) {
-            if (empty($userPasswd)) {
-                $userPasswd = Info::passwordGenerator($this->insertUserIdCard,$this->insertUserName);
-            }
-            if (empty($userPayPasswd)) {
-                $userPayPasswd = Info::passwordGenerator($this->insertUserIdCard,$this->insertUserName);
-            }
-        } else {
-            if (empty($userPasswd)) {
-                $userPasswd = '111111';
-            }
-            if (empty($userPayPasswd)) {
-                $userPayPasswd = '111111';
-            }
-        }
-
-        // 增加会员
-        $user = new User();
-        $user->USER_NAME = $this->insertUserName;
-        $user->PASSWORD_HASH = \Yii::$app->security->generatePasswordHash($userPasswd);
-        $user->PAY_PASSWORD = \Yii::$app->security->generatePasswordHash($userPayPasswd);
-        $user->NATION = 0;
-        $user->REAL_NAME = $this->realName;
-        $user->ID_CARD = $this->insertUserIdCard;
-        $user->MOBILE = $this->mobile;
-        $user->ADDRESS = $this->address ? $this->address : '无';
-        $user->OPEN_BANK = $this->openBank;
-        $user->BANK_ADDRESS = $this->bankAddress;
-        $user->BANK_NO = $this->bankNo;
-        $user->BANK_PROVINCE = $this->bankProvince ?? 0;
-        $user->BANK_CITY = $this->bankCity ?? 0;
-        $user->BANK_COUNTY = $this->bankCounty ?? 0;
-        $user->CREATED_AT = Date::nowTime();
-        $user->STATUS = 1;
-        $user->DEC_LV = $this->decLv;
-        $user->LAST_DEC_LV = $this->decLv;
-        $user->EMP_LV = EmployLevel::getDefaultLevelId();
-        $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;
-        $user->DEC_ID = $this->_decId ?? null;
-        $user->DEC_ROLE_ID = $this->decRoleId ?? null;
-        $user->PERIOD_AT = $period->getNowPeriodNum();
-        $user->IS_DIRECT_SELLER = 0;
-        $user->VERIFIED = 1;
-        $user->VERIFIED_AT = Date::nowTime();
-
-        if (!$user->save()) {
-            throw new Exception(Form::formatErrorsForApi($user->getErrors()));
-        }
-
-        $this->_insertUserId = $user->ID;
-        $userForm = new UserForm();
-        $this->_userForm = $userForm;
-        $userForm->scenario = 'addWithUserName';
-        $userForm->userId = $this->_insertUserId;
-        $userForm->userName = $this->insertUserName;
-        $userForm->zcPv = $this->_decPv;
-        $userForm->zcAmount = $this->_decAmount;
-        $userForm->conUserName = $this->conUserName;
-        $userForm->recUserName = $this->recUserName;
-        $userForm->location = $this->location;
-        $userForm->idCard = $this->insertUserIdCard;
-        $userForm->allData = $allData;
-        if(!$userForm->validate()){
-            $this->addErrors($userForm->getErrors());
-            return false;
-        }
-        if($result = $userForm->add()){
-            return $result;
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * 添加报单订单
-     * @return bool|UserInfo|null
-     * @throws \yii\db\Exception
-     */
-    public function addDecOrder(){
-        $periodObj = Period::instance();
-        $nowPeriodNum = $periodObj->getNowPeriodNum();
-        $nowCalcMonth = $periodObj->getYearMonth($nowPeriodNum);
-
-        $ord = date('Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 10);
-        // 加入报单信息
-        $decOrderModel = new DecOrder();
-        $decOrderModel->DEC_SN = 'DS'.$ord;
-        $decOrderModel->ORDER_SN = 'OS'.$ord;
-        $decOrderModel->TYPE = $this->type;
-        $decOrderModel->USER_ID = \Yii::$app->user->id;
-        $decOrderModel->TO_USER_ID = $this->_insertUserId;
-        $decOrderModel->DEC_AMOUNT = $this->_decAmount;
-        $decOrderModel->DEC_PV = $this->_decPv;
-        $decOrderModel->PERIOD_NUM = $nowPeriodNum;
-        $decOrderModel->CALC_MONTH = $nowCalcMonth;
-        $decOrderModel->P_CALC_MONTH = Date::ociToDate($nowCalcMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH);
-        $decOrderModel->PAID_WALLET = 'cash';
-        $decOrderModel->CON_USER_ID = Info::getUserIdByUserName($this->conUserName);
-        $decOrderModel->REC_USER_ID = Info::getUserIdByUserName($this->recUserName);
-        $decOrderModel->DEC_ID = $this->_decId;
-        $decOrderModel->IS_DEL = 0;
-        $decOrderModel->CREATED_AT = Date::nowTime();
-        if(!$decOrderModel->save()){
-            throw new Exception(Form::formatErrorsForApi($decOrderModel->getErrors()));
-        }
-
-        // 加入订单信息
-        $warehouse = Region::getWarehouseByCode($this->province);//仓库
-        if(!$warehouse){
-            throw new Exception('地区暂时不支持配送,具体联系客服');
-        }
-        $orderModel = new Order();
-        $orderModel->SN = 'OS'.$ord;
-        $orderModel->DEC_SN = 'DS'.$ord;
-        $orderModel->ORDER_TYPE = $this->type;
-        $orderModel->USER_ID = $this->_insertUserId;
-        $orderModel->USER_NAME = $this->insertUserName;
-        $orderModel->ORDER_AMOUNT = $this->_decAmount;
-        $orderModel->PV = $this->_decPv;
-        $orderModel->PAY_AMOUNT = $this->_decAmount;
-        $orderModel->PAY_PV = $this->_decPv;
-        $orderModel->PAY_AT = Date::nowTime();
-        $orderModel->PAY_TYPE = 'cash';
-        $orderModel->PERIOD_NUM = $nowPeriodNum;
-        $orderModel->P_CALC_MONTH = Date::ociToDate($nowCalcMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH);
-        $orderModel->FREIGHT = 0;
-        $orderModel->PAY_FREIGHT = 0;
-        $orderModel->CONSIGNEE = $this->consignee;
-        $orderModel->MOBILE = $this->acceptMobile;
-        $orderModel->PROVINCE = $this->province;
-        $orderModel->CITY = $this->city;
-        $orderModel->COUNTY = intval($this->county) ?? 0;
-        $orderModel->ADDRESS = $this->address;
-        $orderModel->WAREHOUSE = $warehouse;
-        $orderModel->STATUS = 1;
-        $orderModel->CREATED_AT = Date::nowTime();
-        $orderModel->CREATE_USER = Info::getUserNameByUserId(\Yii::$app->user->id);
-        if(!$orderModel->save()){
-            throw new Exception(Form::formatErrorsForApi($orderModel->getErrors()));
-        }
-        // 加入商品到订单商品表
-        foreach($this->_orderGoods as $key=>$value){
-            $this->_orderGoods[$key]['ORDER_SN'] = $orderModel->SN;
-            $this->_orderGoods[$key]['P_CALC_MONTH'] = Date::ociToDate($nowCalcMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH);
-        }
-        OrderGoods::batchInsert($this->_orderGoods);
-
-        //写入收货地址信息
-        $addressModel = new ReceiveAddress();
-        $addressModel->USER_ID = $this->_insertUserId;
-        $addressModel->USER_NAME = $this->insertUserName;
-        $addressModel->CONSIGNEE = $this->consignee;
-        $addressModel->MOBILE = $this->acceptMobile;
-        $addressModel->PROVINCE = $this->province;
-        $addressModel->CITY = $this->city;
-        $addressModel->COUNTY = intval($this->county) ?? 0;
-        $addressModel->ADDRESS = $this->address;
-        $addressModel->IS_DEFAULT = 1;
-        if(!$addressModel->save()){
-            throw new Exception(Form::formatErrorsForApi($addressModel->getErrors()));
-        }
-        //扣报单人现金钱包
-        Cash::changeUserCash(\Yii::$app->user->id, 'CASH', -abs($this->_decAmount), ['REMARK' =>'为'.$this->insertUserName.'报单']);
-
-        return $addressModel;
-    }
-
-
-
-    /**
-     * 删单
-     * @return bool
-     * @throws \yii\db\Exception
-     */
-    public function delete(){
-        if(!$this->validate()){
-            return false;
-        }
-        $transaction = \Yii::$app->db->beginTransaction();
-        try {
-            $oneOrder = $this->_oneOrder;
-            // 首购单要删除会员
-            if($this->type == self::TYPE_ZC){
-                UserInfo::deleteUser($oneOrder['TO_USER_ID']);
-            }
-            // 如果是复销单的话,还需要考虑给会员的复销池减去金额
-            elseif($this->type == self::TYPE_FX){
-                Reconsume::changePoolPV($oneOrder['TO_USER_ID'], -abs($oneOrder['DEC_PV']), ['REMARK'=>'删单扣除', 'DEAL_TYPE'=>Reconsume::TYPE_AUDIT_PV]);
-            }
-            $transaction->commit();
-        } catch (Exception $e) {
-            $transaction->rollBack();
-            $this->addError('delete', $e->getMessage());
-            return false;
-        }
-        return true;
-    }
-
-}
+<?php
+namespace common\models\forms;
+
+use common\components\Model;
+use common\helpers\Cache;
+use common\helpers\Date;
+use common\helpers\Form;
+use common\helpers\user\Cash;
+use common\helpers\user\Reconsume;
+use common\helpers\user\Info;
+use common\models\DeclarationPackage;
+use common\models\DecOrder;
+use common\models\EmployLevel;
+use common\models\Order;
+use common\models\OrderGoods;
+use common\models\Period;
+use common\models\ReceiveAddress;
+use common\models\ReconsumePool;
+use common\models\ReconsumePoolFlow;
+use common\models\DeclarationLevel;
+use common\models\Region;
+use common\models\ShopGoods;
+use common\models\User;
+use common\models\UserInfo;
+use common\models\UserNetwork;
+use common\models\UserRelation;
+use yii\base\Exception;
+
+/**
+ * Login form
+ */
+class DeclarationForm extends Model
+{
+    public $type;
+    public $decLv;
+    public $decWay;
+    public $packageId;
+    public $goodsId;
+    public $goodsNum;
+    public $insertUserName;
+    public $password;
+    public $payPassword;
+    public $realName;
+    public $insertUserIdCard;
+    public $mobile;
+    public $address;
+    public $openBank;
+    public $bankAddress;
+    public $bankNo;
+    public $bankProvince;
+    public $bankCity;
+    public $bankCounty;
+    public $conUserName;
+    public $recUserName;
+    public $decUserName;
+    public $location;
+    public $consignee;
+    public $acceptMobile;
+    public $province;
+    public $city;
+    public $county;
+
+    // 传过来的全部数据
+    public $allData;
+    private $_decId;
+    public $_insertUserId;
+    private $_decAmount;
+    private $_decPv;
+    private $_orderGoods;
+
+    // 批量报单时添加会员的REDIS里面缓存的添加的会员资料
+    const REDIS_WAIT_ADD_USER = 'user:dec:waitAdd';
+
+    const TYPE_ZC = 'ZC';
+//    const TYPE_YH = 'YH';
+    const TYPE_ZG = 'ZG';
+    const TYPE_LS = 'LS';
+    const TYPE_FX = 'FX';
+
+//    private $_modelClass = null;
+    private $_oneOrder = null;
+    private $_userForm = null;
+    // 全部的上级(安置网和开拓网)
+    private $_tempParentUser = [];
+    // 全部的安置网上级
+    private $_tempNetworkParentUser = [];
+    // 全部的开拓网上级
+    private $_tempRelationParentUser = [];
+    private $_types = [
+        self::TYPE_ZC => [
+            'name' => '首购单',
+        ],
+//        self::TYPE_YH => [
+//            'class' => DeclarationYH::class,
+//            'table' => '{{%DECLARATION_YH}}',
+//            'name' => '优惠单',
+//        ],
+        self::TYPE_ZG => [
+            'name' => '升级增购单',
+        ],
+        self::TYPE_LS => [
+            'name' => '零售单',
+        ],
+        self::TYPE_FX => [
+            'name' => '复销单',
+        ],
+    ];
+
+
+    /**
+     * @inheritdoc
+     */
+    public function rules()
+    {
+        return [
+            [['password','payPassword','type','decLv','decWay','packageId', 'insertUserName', 'realName', 'insertUserIdCard', 'mobile', 'address', 'openBank', 'bankAddress', 'bankNo','bankProvince','bankCity','bankCounty','consignee','acceptMobile','province','city','county','decUserName', 'conUserName', 'recUserName', 'location'], 'trim'],
+            [['type','decLv','decWay','insertUserName', 'insertUserIdCard','decUserName'], 'required'],
+            [['type'], 'isType', 'on'=>['userDec', 'canDec']],
+            [['insertUserName'], 'isCanAddUser'],
+            [['decUserName'], 'issetDec'],
+            [['conUserName'], 'isConUserName'],
+            [['recUserName'], 'isRecUserName'],
+            [['location'], 'isLocation'],
+            [['insertUserIdCard'], 'isSameSystem'],
+        ];
+    }
+
+    public function attributeLabels()
+    {
+        return [
+            'type' => '报单类型',
+            'decLv' => '报单级别',
+            //'decPv' => '报单PV',
+            'decWay' => '报单方式',
+            'packageId' => '报单套餐',
+            'goodsId' => '商品ID',
+            'goodsNum' => '商品数量',
+            //'addType' => '新增会员方式',
+            'insertUserName' => '会员用户名',
+            'password' => '登陆密码',
+            'payPassword' => '支付密码',
+            'realName' => '会员姓名',
+            'insertUserIdCard' => '身份证号',
+            'mobile' => '手机号',
+            'address' => '地址',
+            'openBank' => '开户行',
+            'bankAddress' => '开户支行',
+            'bankNo' => '银行账号',
+            'bankProvince' => '银行省份',
+            'bankCity' => '银行城市',
+            'bankCounty' => '银行县区',
+            'conUserName' => '指导老师用户名',
+            'recUserName' => '开拓人用户名',
+            'decUserName' => '报单中心用户名',
+            'conUid' => '指导老师会员ID',
+            'recUid' => '开拓人会员ID',
+            'location' => '市场',
+            'consignee' => '收货人',
+            'acceptMobile' => '收货人手机',
+            'province' => '收货省',
+            'city' => '收货市',
+            'county' => '收货区县',
+            'address' => '收货详细地址',
+        ];
+    }
+
+    /**
+     * 指定场景
+     * @return array
+     */
+    public function scenarios()
+    {
+        $parentScenarios =  parent::scenarios();
+        $customScenarios = [
+            'userDec' => ['type','allData', 'decLv','decWay','insertUserName','password','payPassword', 'realName', 'insertUserIdCard', 'mobile', 'address', 'openBank', 'bankAddress', 'bankNo', 'bankProvince','bankCity','bankCounty', 'consignee','acceptMobile','province','city','county', 'conUserName', 'recUserName','decUserName', 'location'],
+            'canDec' => ['type', 'insertUserName', 'insertUserIdCard', 'conUserName', 'recUserName', 'location'],
+            'notFull' => ['type', 'insertUserName', 'conUserName', 'recUserName', 'location'],
+        ];
+        return array_merge($parentScenarios, $customScenarios);
+    }
+
+    /**
+     * 判断报单中心是否存在
+     * @param $attribute
+     */
+    public function issetDec($attribute){
+        if (!$decUser = User::find()->select('ID')->where('IS_DEC=1 AND USER_NAME=:USER_NAME', [':USER_NAME' => $this->decUserName])->asArray()->one()) {
+            $this->addError($attribute, '报单中心不存在');
+            return false;
+        } else {
+            // 判断报单中心是否在新加入会员的安置网上级中
+            $this->loopFindParentToNetwork($this->insertUserName);
+            //反转数组,in_array搜索错误
+            //in_array($this->decUserName, $this->_tempNetworkParentUser[$this->insertUserName]);
+            $flipParent = array_flip(array_filter($this->_tempNetworkParentUser[$this->insertUserName]));
+//            var_dump($flipParent);
+//            echo $this->insertUserName.'=='.$this->decUserName;
+//            exit;
+            if (!isset($flipParent[$this->decUserName])) {
+                $this->addError($attribute, '为' . $this->insertUserName . '报单,报单中心' . $this->decUserName . '不在' . $this->insertUserName . '的安置网上级中');
+                return ;
+            }
+            $this->_decId = $decUser['ID'];
+        }
+    }
+
+    /**
+     * 判断指导老师
+     * @param $attribute
+     */
+    public function isConUserName($attribute){
+        if($this->type == self::TYPE_ZC){
+            // 从数据库查看接点会员是否在
+            if(!isset($this->_tempParentUser[$this->conUserName])){
+                $conUserTemp = UserInfo::findOneAsArray('USER_NAME=:USER_NAME', [':USER_NAME' => $this->conUserName]);
+                if(!$conUserTemp){
+                    if($this->insertUserName){
+                        $this->addError($attribute, '为'.$this->insertUserName.'报单,指导老师'.$this->conUserName.'不存在');
+                    } else {
+                        $this->addError($attribute, '指导老师'.$this->conUserName.'不存在');
+                    }
+                    return ;
+                }
+                $conUserTemp['CON_NUM'] = UserNetwork::firstFloorChildNum($conUserTemp['USER_ID']);
+                $conUserTemp['REC_NUM'] = UserRelation::firstFloorChildNum($conUserTemp['USER_ID']);
+                $this->_tempParentUser[$this->conUserName] = [
+                    'USER_NAME' => $this->conUserName,
+                    'ZC_PV' => $conUserTemp['ZC_PV'],
+                    'CON_USER_NAME' => Info::getUserNameByUserId($conUserTemp['CON_UID']),
+                    'REC_USER_NAME' => Info::getUserNameByUserId($conUserTemp['REC_UID']),
+                    'CON_NUM' => $conUserTemp['CON_NUM'],
+                    'REC_NUM' => $conUserTemp['REC_NUM'],
+                    'SYSTEM_ID' => $conUserTemp['SYSTEM_ID'],
+                    'LOCATION' => UserNetwork::getLocation($conUserTemp['USER_ID'], $conUserTemp['CON_UID']),
+                ];
+                // 把该会员下面的5个区是否存在会员都付上
+                for($i=1;$i<=5;$i++){
+                    $this->_tempParentUser[$this->conUserName]["LOCATION$i"] = UserNetwork::issetUserInLocation($conUserTemp['USER_ID'], $i);
+                }
+            }
+            $conUser = $this->_tempParentUser[$this->conUserName];
+            // 判断接点会员的下级会员是否大于三个,如果大于三个则不允许
+            if($conUser['CON_NUM'] >= 3){
+                if($this->insertUserName){
+                    $this->addError($attribute, '为'.$this->insertUserName.'报单,指导老师'.$this->conUserName.'下级点位已满');
+                } else {
+                    $this->addError($attribute, '指导老师'.$this->conUserName.'下级点位已满');
+                }
+                return;
+            }
+            if($this->insertUserName){
+                // 把自己加入到临时上级会员数组中
+                $this->_tempParentUser[$this->insertUserName] = [
+                    'USER_NAME' => $this->insertUserName,
+                    //'ZC_PV' => $this->decPv,
+                    'CON_USER_NAME' => $this->conUserName,
+                    'REC_USER_NAME' => $this->recUserName,
+                    'CON_NUM' => 0,
+                    'REC_NUM' => 0,
+                    'SYSTEM_ID' => $conUser['SYSTEM_ID'],
+                    'LOCATION' => $this->location,
+                    'LOCATION1' => 0,
+                    'LOCATION2' => 0,
+                    'LOCATION3' => 0,
+                    'LOCATION4' => 0,
+                    'LOCATION5' => 0,
+                ];
+            }
+
+        }
+    }
+
+    /**
+     * 判断开拓人
+     * @param $attribute
+     */
+    public function isRecUserName($attribute){
+        if($this->type == self::TYPE_ZC){
+            // 开拓人
+            if(!isset($this->_tempParentUser[$this->recUserName])){
+                $recUserTemp = UserInfo::findOneAsArray('USER_NAME=:USER_NAME', [':USER_NAME' => $this->recUserName]);
+                if(!$recUserTemp){
+                    if($this->insertUserName){
+                        $this->addError($attribute, '为'.$this->insertUserName.'报单,开拓人'.$this->recUserName.'不存在');
+                    } else {
+                        $this->addError($attribute, '开拓人'.$this->recUserName.'不存在');
+                    }
+
+                    return ;
+                }
+                $recUserTemp['CON_NUM'] = UserNetwork::firstFloorChildNum($recUserTemp['USER_ID']);
+                $recUserTemp['REC_NUM'] = UserRelation::firstFloorChildNum($recUserTemp['USER_ID']);
+                $this->_tempParentUser[$this->recUserName] = [
+                    'USER_NAME' => $this->recUserName,
+                    'ZC_PV' => $recUserTemp['ZC_PV'],
+                    'CON_USER_NAME' => Info::getUserNameByUserId($recUserTemp['CON_UID']),
+                    'REC_USER_NAME' => Info::getUserNameByUserId($recUserTemp['REC_UID']),
+                    'CON_NUM' => $recUserTemp['CON_NUM'],
+                    'REC_NUM' => $recUserTemp['REC_NUM'],
+                    'SYSTEM_ID' => $recUserTemp['SYSTEM_ID'],
+                    'LOCATION' => UserNetwork::getLocation($recUserTemp['USER_ID'], $recUserTemp['CON_UID']),
+                ];
+                // 把该会员下面的5个区是否存在会员都付上
+                for($i=1;$i<=5;$i++){
+                    $this->_tempParentUser[$this->recUserName]["LOCATION$i"] = UserNetwork::issetUserInLocation($recUserTemp['USER_ID'], $i);
+                }
+            }
+            $recUser = $this->_tempParentUser[$this->recUserName];
+            $this->_tempParentUser[$this->recUserName]['REC_NUM'] += 1;
+
+            // 存在新加入会员时查看开拓人是否在新加入会员的安置网上级中
+            if($this->insertUserName) {
+                $this->loopFindParentToNetwork($this->insertUserName);
+                if (!$this->recUserIsInNetworkParent()) {
+                    $this->addError($attribute, '为' . $this->insertUserName . '报单,开拓人' . $this->recUserName . '不在' . $this->insertUserName . '的安置网上级中');
+                    return ;
+                }
+            }
+
+            // 把自己加入到临时上级会员数组中
+            $this->_tempParentUser[$this->insertUserName] = [
+                'USER_NAME' => $this->insertUserName,
+                //'ZC_PV' => $this->decPv,
+                'CON_USER_NAME' => $this->conUserName,
+                'REC_USER_NAME' => $this->recUserName,
+                'CON_NUM' => 0,
+                'REC_NUM' => 0,
+                'SYSTEM_ID' => $recUser['SYSTEM_ID'],
+                'LOCATION' => $this->location,
+                'LOCATION1' => 0,
+                'LOCATION2' => 0,
+                'LOCATION3' => 0,
+                'LOCATION4' => 0,
+                'LOCATION5' => 0,
+            ];
+        }
+
+    }
+
+    /**
+     * 循环把所有新加入的会员的上级加入到临时变量中
+     * @param null $conUserName
+     * @return bool
+     */
+    private function loopFindParentToNetwork($conUserName = null) {
+        if($conUserName == null ){
+            $conUserName = $this->insertUserName;
+        }
+        $findUserKey = array_search($conUserName, array_column($this->allData, 'insertUserName'));
+        // 如果有这个新加入的会员,则查找其上级接点
+        if($findUserKey !== false){
+            if(strtoupper($this->allData[$findUserKey]['type']) == 'ZC'){
+                $this->_tempNetworkParentUser[$this->insertUserName][] = $this->allData[$findUserKey]['conUserName'];
+                $this->loopFindParentToNetwork($this->allData[$findUserKey]['conUserName']);
+            }
+        }
+        // 如果没有这个新加入的接点,
+        else {
+            if($this->insertUserName == $conUserName){
+                $this->addError('recUserName', '新加入的会员不存在');
+                return false;
+            }
+            // 去数据库里查找这个会员的所有上级
+//            $allParentUser = UserNetwork::find()->select('PUI.USER_NAME')->where('UI.USER_NAME=:USER_NAME', [':USER_NAME'=>$conUserName])->from(UserNetwork::tableName().' AS UN')->join('LEFT JOIN', UserInfo::tableName().' AS UI', 'UN.USER_ID=UI.USER_ID')->join('LEFT JOIN', UserInfo::tableName().' AS PUI', 'UN.PARENT_UID=PUI.USER_ID')->orderBy('PUI.NETWORK_DEEP DESC')->asArray()->all();
+            $baseUser = Info::getBaseUserByUserName($conUserName);
+            $userNetworkInfo = UserNetwork::findOneAsArray('USER_ID=:USER_ID', [':USER_ID' => $baseUser['ID']]);
+            unset($baseUser);
+            $allParentUserIdsArr = explode(',', $userNetworkInfo['PARENT_UIDS']);
+            unset($userNetworkInfo);
+            $allParentUserIds = array_reverse($allParentUserIdsArr);
+            unset($allParentUserIdsArr);
+            if($allParentUserIds){
+                foreach($allParentUserIds as $parentUserId) {
+                    $parentBaseUser = Info::getBaseUserById($parentUserId);
+                    $this->_tempNetworkParentUser[$this->insertUserName][] = $parentBaseUser['USER_NAME'] ;
+
+                    unset($parentUserId, $parentBaseUser);
+                }
+            }
+            unset($allParentUserIds);
+        }
+        return true;
+    }
+
+    /**
+     * 开拓人是否在新加入会员的上级中
+     * @return bool
+     */
+    private function recUserIsInNetworkParent(){
+        return in_array($this->recUserName, $this->_tempNetworkParentUser[$this->insertUserName]);
+    }
+
+    /**
+     * 判断区域是否正确
+     * @param $attribute
+     */
+    public function isLocation($attribute){
+        if($this->type == self::TYPE_ZC){
+            if(!in_array($this->location, [1, 2, 3])){
+                $this->addError($attribute, '市场必须在第1市场、第2市场或第三3市场');
+            }
+            $conUser = $recUser = null;
+            if(isset($this->_tempParentUser[$this->conUserName])){
+                $conUser = $this->_tempParentUser[$this->conUserName];
+            }
+            if(isset($this->_tempParentUser[$this->recUserName])){
+                $recUser = $this->_tempParentUser[$this->recUserName];
+            }
+            if($conUser){
+                // 判断指导老师相应的区位是否已满
+                if($conUser['LOCATION'.$this->location]){
+                    if($this->insertUserName){
+                        $this->addError($attribute, '为'.$this->insertUserName.'报单,指导老师'.$this->conUserName.'的第'.$this->location.'市场已存在会员');
+                    } else {
+                        $this->addError($attribute, '指导老师'.$this->conUserName.'的第'.$this->location.'市场已存在会员');
+                    }
+                    return;
+                }
+                //市场顺序判断
+//                if($conUser['CON_NUM'] == 0 && $this->location != 1){
+//                    if($this->insertUserName){
+//                        $this->addError($attribute, '为'.$this->insertUserName.'报单,市场必须为指导老师'.$this->conUserName.'下第一市场');
+//                    } else {
+//                        $this->addError($attribute, '市场必须为指导老师'.$this->conUserName.'下第一市场');
+//                    }
+//                    return;
+//                }
+//                if($conUser['CON_NUM'] == 1 && $this->location == 3){
+//                    if($this->insertUserName){
+//                        $this->addError($attribute, '为'.$this->insertUserName.'报单,市场必须为指导老师'.$this->conUserName.'第二市场');
+//                    } else {
+//                        $this->addError($attribute, '市场必须为指导老师'.$this->conUserName.'第二市场');
+//                    }
+//                    return;
+//                }
+                $this->_tempParentUser[$this->conUserName]['CON_NUM'] += 1;
+                $this->_tempParentUser[$this->conUserName]['LOCATION'.$this->location] = true;
+            }
+        }
+    }
+
+    /**
+     * 判断会员是否可加入(通过redis结合数据库判断上级会员的情况)
+     * @param $attribute
+     */
+    public function isCanAddUser($attribute){
+        if($this->type == self::TYPE_ZC){
+            // 从数据库查看接点会员是否在
+            if(!isset($this->_tempParentUser[$this->conUserName])){
+                $conUserTemp = UserInfo::findOneAsArray('USER_NAME=:USER_NAME', [':USER_NAME' => $this->conUserName]);
+                if(!$conUserTemp){
+                    $this->addError($attribute, '为'.$this->insertUserName.'报单,指导老师'.$this->conUserName.'不存在');
+                    return ;
+                }
+                $conUserTemp['CON_NUM'] = UserNetwork::firstFloorChildNum($conUserTemp['USER_ID']);
+                $conUserTemp['REC_NUM'] = UserRelation::firstFloorChildNum($conUserTemp['USER_ID']);
+                $this->_tempParentUser[$this->conUserName] = [
+                    'USER_NAME' => $this->conUserName,
+                    //'ZC_PV' => $conUserTemp['ZC_PV'],
+                    'CON_USER_NAME' => Info::getUserNameByUserId($conUserTemp['CON_UID']),
+                    'REC_USER_NAME' => Info::getUserNameByUserId($conUserTemp['REC_UID']),
+                    'CON_NUM' => $conUserTemp['CON_NUM'],
+                    'REC_NUM' => $conUserTemp['REC_NUM'],
+                    'SYSTEM_ID' => $conUserTemp['SYSTEM_ID'],
+                    'LOCATION' => UserNetwork::getLocation($conUserTemp['USER_ID'], $conUserTemp['CON_UID']),
+                ];
+                // 把该会员下面的5个区是否存在会员都付上
+                for($i=1;$i<=5;$i++){
+                    $this->_tempParentUser[$this->conUserName]["LOCATION$i"] = UserNetwork::issetUserInLocation($conUserTemp['USER_ID'], $i);
+                }
+            }
+            $conUser = $this->_tempParentUser[$this->conUserName];
+
+            // 开拓人
+            if(!isset($this->_tempParentUser[$this->recUserName])){
+                $recUserTemp = UserInfo::findOneAsArray('USER_NAME=:USER_NAME', [':USER_NAME' => $this->recUserName]);
+                if(!$recUserTemp){
+                    $this->addError($attribute, '为'.$this->insertUserName.'报单,开拓人'.$this->recUserName.'不存在');
+                    return ;
+                }
+                $recUserTemp['CON_NUM'] = UserNetwork::firstFloorChildNum($recUserTemp['USER_ID']);
+                $recUserTemp['REC_NUM'] = UserRelation::firstFloorChildNum($recUserTemp['USER_ID']);
+                $this->_tempParentUser[$this->recUserName] = [
+                    'USER_NAME' => $this->recUserName,
+                    //'ZC_PV' => $recUserTemp['ZC_PV'],
+                    'CON_USER_NAME' => Info::getUserNameByUserId($recUserTemp['CON_UID']),
+                    'REC_USER_NAME' => Info::getUserNameByUserId($recUserTemp['REC_UID']),
+                    'CON_NUM' => $recUserTemp['CON_NUM'],
+                    'REC_NUM' => $recUserTemp['REC_NUM'],
+                    'SYSTEM_ID' => $recUserTemp['SYSTEM_ID'],
+                    'LOCATION' => UserNetwork::getLocation($recUserTemp['USER_ID'], $recUserTemp['CON_UID']),
+                ];
+                // 把该会员下面的5个区是否存在会员都付上
+                for($i=1;$i<=5;$i++){
+                    $this->_tempParentUser[$this->recUserName]["LOCATION$i"] = UserNetwork::issetUserInLocation($recUserTemp['USER_ID'], $i);
+                }
+            }
+            $recUser = $this->_tempParentUser[$this->recUserName];
+
+            // 判断接点会员的下级会员是否大于三个,如果大于三个则不允许
+            if($conUser['CON_NUM'] >= 3){
+                $this->addError($attribute, '为'.$this->insertUserName.'报单,指导老师'.$this->conUserName.'下级点位已满');
+                return;
+            }
+            // 判断指导老师相应的区位是否已满
+            if($conUser['LOCATION'.$this->location]){
+                $this->addError($attribute, '为'.$this->insertUserName.'报单,指导老师'.$this->conUserName.'该市场已存在会员');
+                return;
+            }
+//            if($conUser['CON_NUM'] == 0 && $this->location != 1){
+//                $this->addError($attribute, '为'.$this->insertUserName.'报单,市场必须为指导老师'.$this->conUserName.'下第一市场');
+//                return;
+//            }
+
+            // 把指导老师的变量的相关数量增加数量
+//            $this->_tempParentUser[$this->conUserName]['CON_NUM'] += 1;
+//            $this->_tempParentUser[$this->conUserName]['LOCATION'.$this->location] = true;
+//            $this->_tempParentUser[$this->recUserName]['REC_NUM'] += 1;
+
+            // 把自己加入到临时上级会员数组中
+            $this->_tempParentUser[$this->insertUserName] = [
+                'USER_NAME' => $this->insertUserName,
+                //'ZC_PV' => $this->decPv,
+                'CON_USER_NAME' => $this->conUserName,
+                'REC_USER_NAME' => $this->recUserName,
+                'CON_NUM' => 0,
+                'REC_NUM' => 0,
+                'SYSTEM_ID' => $recUser['SYSTEM_ID'],
+                'LOCATION' => $this->location,
+                'LOCATION1' => 0,
+                'LOCATION2' => 0,
+                'LOCATION3' => 0,
+                'LOCATION4' => 0,
+                'LOCATION5' => 0,
+            ];
+        }
+    }
+
+    /**
+     * 报单类型
+     * @param $attribute
+     * @param $params
+     */
+    public function isType($attribute, $params){
+        if(array_key_exists($this->type, $this->_types)){
+            if($this->type == self::TYPE_ZC){
+                if($this->scenario == 'userDec'){
+                    if(!$this->insertUserName) $this->addError($attribute, '首购必须填写加入会员编号');
+                }
+                if(!$this->insertUserName) $this->addError($attribute, '首购必须填写加入会员编号');
+                if(!$this->insertUserIdCard) $this->addError($attribute, '首购必须填写加入会员的身份证号');
+                if(!$this->conUserName) $this->addError($attribute, '首购必须填写加入会员的指导老师编号');
+                if(!$this->recUserName) $this->addError($attribute, '首购必须填写加入会员的开拓人编号');
+                if(!$this->location) $this->addError($attribute, '首购必须填写加入会员的市场');
+            }
+        } else {
+            $this->addError($attribute, '报单类型不正确');
+        }
+    }
+
+    /**
+     * 检验相同身份证 会员是否同一体系内(接点)
+     * @param $attribute
+     */
+    public function isSameSystem($attribute){
+        if(isset($this->_tempParentUser[$this->conUserName])){
+            // 新加入会员的身份证号对应网内的其他会员
+            $otherUser = User::findAllAsArray("ID_CARD=:ID_CARD AND IS_UNION=0 AND DELETED=0 AND (ID_CARD_PREFIX IS NULL OR ID_CARD_PREFIX='')", [':ID_CARD'=>$this->insertUserIdCard]);
+            if(count($otherUser)>=7){
+                $this->addError($attribute, '同一个身份证限制只能报7单');
+            }
+            if($otherUser){
+                $flipParent = array_flip(array_filter($this->_tempNetworkParentUser[$this->insertUserName]));
+                $isExsit = false;
+                foreach ($otherUser as $conUser){
+                    if(isset($flipParent[$conUser['USER_NAME']])){
+                        $isExsit = true;
+                        break;
+                    }
+                }
+                if (!$isExsit) {
+                    $this->addError($attribute, '为' . $this->insertUserName . '报单,身份证号码相同的会员'.$otherUser[0]['USER_NAME'].'不在' . $this->insertUserName . '的安置网上级中');
+                    return ;
+                }
+            }
+        } else {
+            $this->addError($attribute, '为'.$this->insertUserName.'报单,接点人'.$this->conUserName.'不存在');
+        }
+    }
+
+    /**
+     * 添加报单
+     * @param $allData
+     * @return bool|null
+     * @throws Exception
+     * @throws \yii\db\Exception
+     */
+    public function add($allData){
+        if(!$this->validate()){
+            return null;
+        }
+
+        // 首购单,需要添加会员操作
+        if($this->type == self::TYPE_ZC){
+            if (preg_match("/[\x7f-\xff]/", $this->insertUserName)) {  //判断字符串中是否有中文
+                throw new Exception('会员编号中不能含有汉字');
+            }
+            //报单商品及PV判断
+            $decLevelConfig = Cache::getDecLevelConfig();
+            $decLevel = $decLevelConfig[$this->decLv];
+            $toDecLevel = $this->decLv;
+            if(!$this->decLv){
+                throw new Exception('请选择报单级别');
+            }
+            if($this->decWay==1) {
+                $decPackage = DeclarationPackage::findOneAsArray('ID=:ID', [':ID'=>$this->packageId]);
+                $this->_decAmount = $decPackage['AMOUNT'];
+                $this->_decPv = $decPackage['PV'];
+                $this->_orderGoods[] = [
+                    'GOODS_ID' => $this->packageId,
+                    'PRICE' => $this->_decAmount,
+                    'REAL_PRICE' => $this->_decAmount,
+                    'PV' => $this->_decPv,
+                    'REAL_PV' => $this->_decPv,
+                    'BUY_NUMS' => 1,
+                    'SKU_CODE' => $decPackage['PACKAGE_NO'],
+                    'GOODS_TITLE' => $decPackage['PACKAGE_NAME']
+                ];
+                // 更改库存和状态
+                $data = DeclarationPackage::find()->where(['ID' => $decPackage['ID']])->one();
+                $data->STORE_NUMS = $data->STORE_NUMS - 1;
+                if($data->STORE_NUMS <= 0){
+                    $data->STATUS = 0;
+                    $data->UPDATED_AT = Date::nowTime();
+                }
+                $data->update();
+            }else{
+                $ids = $this->goodsId;
+                $totalAmount = 0;
+                $totalPv = 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('商品已下架');
+                            return;
+                        }
+                        if($goods['STORE_NUMS']>0){
+                            $totalAmount += $goods['SELL_PRICE'] * intval($v);
+                            $totalPv += $goods['PRICE_PV'] * intval($v);
+                            $this->_orderGoods[] = [
+                                'GOODS_ID' => $goods['ID'],
+                                'PRICE' => $goods['SELL_PRICE'],
+                                'REAL_PRICE' => $goods['SELL_PRICE'],
+                                'PV' => $goods['PRICE_PV'],
+                                'REAL_PV' => $goods['PRICE_PV'],
+                                'POINT' => $goods['POINT'],
+                                'BUY_NUMS' => intval($v),
+                                'SKU_CODE' => $goods['GOODS_NO'],
+                                'GOODS_TITLE' => $goods['GOODS_NAME']
+                            ];
+                            // 更改库存和状态
+                            $data = ShopGoods::find()->where(['ID' => $goods['ID']])->one();
+                            $data->STORE_NUMS = $data->STORE_NUMS - intval($v);
+                            if($data->STORE_NUMS <= 0){
+                                $data->STATUS = 0;
+                                $data->UPDATED_AT = Date::nowTime();
+                            }
+                            $data->update();
+                        }
+                    }
+                }
+                if($totalPv<$decLevel['PERF']){
+                    throw new Exception('自选商品总PV不能小于所选报单级别PV');
+                }
+                foreach ($decLevelConfig as $key=>$val){
+                    if($totalPv>=$val['PERF']){
+                        $toDecLevel = $key;
+                    }
+                }
+                if($this->decLv!=$toDecLevel){
+                    throw new Exception('自选商品总PV不能超过已选级别下一个级别的PV值');
+                }
+                $this->_decAmount = $totalAmount;
+                $this->_decPv = $totalPv;
+            }
+            //看现金余额是否充足
+            $loginUserId = \Yii::$app->user->id;
+            if (Cash::getAvailableBalance($loginUserId) < $this->_decAmount){
+                throw new Exception('报单人现金不足,无法完成报单');
+            }
+
+            if(!($zcResult = $this->addUser($allData))) {
+                throw new Exception(Form::formatErrorsForApi($this->_userForm->getErrors()));
+            }
+            if(!($decResult = $this->addDecOrder())) {
+                throw new Exception(Form::formatErrorsForApi($decResult->getErrors()));
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 添加会员
+     * @param $allData
+     * @return bool|UserInfo|null
+     * @throws \yii\db\Exception
+     */
+    public function addUser($allData){
+        $period = Period::instance();
+        $userPasswd = $this->password;
+        $userPayPasswd = $this->payPassword;
+        // 如果身份证信息有误,或不足6位,并且没有手动填写密码,就用111111
+        if (Info::simpleIdCardCheck($this->insertUserIdCard)) {
+            if (empty($userPasswd)) {
+                $userPasswd = Info::passwordGenerator($this->insertUserIdCard,$this->insertUserName);
+            }
+            if (empty($userPayPasswd)) {
+                $userPayPasswd = Info::passwordGenerator($this->insertUserIdCard,$this->insertUserName);
+            }
+        } else {
+            if (empty($userPasswd)) {
+                $userPasswd = '111111';
+            }
+            if (empty($userPayPasswd)) {
+                $userPayPasswd = '111111';
+            }
+        }
+
+        // 增加会员
+        $user = new User();
+        $user->USER_NAME = $this->insertUserName;
+        $user->PASSWORD_HASH = \Yii::$app->security->generatePasswordHash($userPasswd);
+        $user->PAY_PASSWORD = \Yii::$app->security->generatePasswordHash($userPayPasswd);
+        $user->NATION = 0;
+        $user->REAL_NAME = $this->realName;
+        $user->ID_CARD = $this->insertUserIdCard;
+        $user->MOBILE = $this->mobile;
+        $user->ADDRESS = $this->address ? $this->address : '无';
+        $user->OPEN_BANK = $this->openBank;
+        $user->BANK_ADDRESS = $this->bankAddress;
+        $user->BANK_NO = $this->bankNo;
+        $user->BANK_PROVINCE = $this->bankProvince ?? 0;
+        $user->BANK_CITY = $this->bankCity ?? 0;
+        $user->BANK_COUNTY = $this->bankCounty ?? 0;
+        $user->CREATED_AT = Date::nowTime();
+        $user->STATUS = 1;
+        $user->DEC_LV = $this->decLv;
+        $user->LAST_DEC_LV = $this->decLv;
+        $user->EMP_LV = EmployLevel::getDefaultLevelId();
+        $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;
+        $user->DEC_ID = $this->_decId ?? null;
+        $user->DEC_ROLE_ID = $this->decRoleId ?? null;
+        $user->PERIOD_AT = $period->getNowPeriodNum();
+        $user->IS_DIRECT_SELLER = 0;
+        $user->VERIFIED = 1;
+        $user->VERIFIED_AT = Date::nowTime();
+
+        if (!$user->save()) {
+            throw new Exception(Form::formatErrorsForApi($user->getErrors()));
+        }
+
+        $this->_insertUserId = $user->ID;
+        $userForm = new UserForm();
+        $this->_userForm = $userForm;
+        $userForm->scenario = 'addWithUserName';
+        $userForm->userId = $this->_insertUserId;
+        $userForm->userName = $this->insertUserName;
+        $userForm->zcPv = $this->_decPv;
+        $userForm->zcAmount = $this->_decAmount;
+        $userForm->conUserName = $this->conUserName;
+        $userForm->recUserName = $this->recUserName;
+        $userForm->location = $this->location;
+        $userForm->idCard = $this->insertUserIdCard;
+        $userForm->allData = $allData;
+        if(!$userForm->validate()){
+            $this->addErrors($userForm->getErrors());
+            return false;
+        }
+        if($result = $userForm->add()){
+            return $result;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * 添加报单订单
+     * @return bool|UserInfo|null
+     * @throws \yii\db\Exception
+     */
+    public function addDecOrder(){
+        $periodObj = Period::instance();
+        $nowPeriodNum = $periodObj->getNowPeriodNum();
+        $nowCalcMonth = $periodObj->getYearMonth($nowPeriodNum);
+
+        $ord = date('Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 10);
+        // 加入报单信息
+        $decOrderModel = new DecOrder();
+        $decOrderModel->DEC_SN = 'DS'.$ord;
+        $decOrderModel->ORDER_SN = 'OS'.$ord;
+        $decOrderModel->TYPE = $this->type;
+        $decOrderModel->USER_ID = \Yii::$app->user->id;
+        $decOrderModel->TO_USER_ID = $this->_insertUserId;
+        $decOrderModel->DEC_AMOUNT = $this->_decAmount;
+        $decOrderModel->DEC_PV = $this->_decPv;
+        $decOrderModel->PERIOD_NUM = $nowPeriodNum;
+        $decOrderModel->CALC_MONTH = $nowCalcMonth;
+        $decOrderModel->P_CALC_MONTH = Date::ociToDate($nowCalcMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH);
+        $decOrderModel->PAID_WALLET = 'cash';
+        $decOrderModel->CON_USER_ID = Info::getUserIdByUserName($this->conUserName);
+        $decOrderModel->REC_USER_ID = Info::getUserIdByUserName($this->recUserName);
+        $decOrderModel->DEC_ID = $this->_decId;
+        $decOrderModel->IS_DEL = 0;
+        $decOrderModel->CREATED_AT = Date::nowTime();
+        if(!$decOrderModel->save()){
+            throw new Exception(Form::formatErrorsForApi($decOrderModel->getErrors()));
+        }
+
+        // 加入订单信息
+        $warehouse = Region::getWarehouseByCode($this->province);//仓库
+        if(!$warehouse){
+            throw new Exception('地区暂时不支持配送,具体联系客服');
+        }
+        $orderModel = new Order();
+        $orderModel->SN = 'OS'.$ord;
+        $orderModel->DEC_SN = 'DS'.$ord;
+        $orderModel->ORDER_TYPE = $this->type;
+        $orderModel->USER_ID = $this->_insertUserId;
+        $orderModel->USER_NAME = $this->insertUserName;
+        $orderModel->ORDER_AMOUNT = $this->_decAmount;
+        $orderModel->PV = $this->_decPv;
+        $orderModel->PAY_AMOUNT = $this->_decAmount;
+        $orderModel->PAY_PV = $this->_decPv;
+        $orderModel->PAY_AT = Date::nowTime();
+        $orderModel->PAY_TYPE = 'cash';
+        $orderModel->PERIOD_NUM = $nowPeriodNum;
+        $orderModel->P_CALC_MONTH = Date::ociToDate($nowCalcMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH);
+        $orderModel->FREIGHT = 0;
+        $orderModel->PAY_FREIGHT = 0;
+        $orderModel->CONSIGNEE = $this->consignee;
+        $orderModel->MOBILE = $this->acceptMobile;
+        $orderModel->PROVINCE = $this->province;
+        $orderModel->CITY = $this->city;
+        $orderModel->COUNTY = intval($this->county) ?? 0;
+        $orderModel->ADDRESS = $this->address;
+        $orderModel->WAREHOUSE = $warehouse;
+        $orderModel->STATUS = 1;
+        $orderModel->CREATED_AT = Date::nowTime();
+        $orderModel->CREATE_USER = Info::getUserNameByUserId(\Yii::$app->user->id);
+        if(!$orderModel->save()){
+            throw new Exception(Form::formatErrorsForApi($orderModel->getErrors()));
+        }
+        // 加入商品到订单商品表
+        foreach($this->_orderGoods as $key=>$value){
+            $this->_orderGoods[$key]['ORDER_SN'] = $orderModel->SN;
+            $this->_orderGoods[$key]['P_CALC_MONTH'] = Date::ociToDate($nowCalcMonth, Date::OCI_TIME_FORMAT_SHORT_MONTH);
+        }
+        OrderGoods::batchInsert($this->_orderGoods);
+
+        //写入收货地址信息
+        $addressModel = new ReceiveAddress();
+        $addressModel->USER_ID = $this->_insertUserId;
+        $addressModel->USER_NAME = $this->insertUserName;
+        $addressModel->CONSIGNEE = $this->consignee;
+        $addressModel->MOBILE = $this->acceptMobile;
+        $addressModel->PROVINCE = $this->province;
+        $addressModel->CITY = $this->city;
+        $addressModel->COUNTY = intval($this->county) ?? 0;
+        $addressModel->ADDRESS = $this->address;
+        $addressModel->IS_DEFAULT = 1;
+        if(!$addressModel->save()){
+            throw new Exception(Form::formatErrorsForApi($addressModel->getErrors()));
+        }
+        //扣报单人现金钱包
+        Cash::changeUserCash(\Yii::$app->user->id, 'CASH', -abs($this->_decAmount), ['REMARK' =>'为'.$this->insertUserName.'报单', 'ORDER_SN' => $orderModel->SN]);
+
+        return $addressModel;
+    }
+
+
+
+    /**
+     * 删单
+     * @return bool
+     * @throws \yii\db\Exception
+     */
+    public function delete(){
+        if(!$this->validate()){
+            return false;
+        }
+        $transaction = \Yii::$app->db->beginTransaction();
+        try {
+            $oneOrder = $this->_oneOrder;
+            // 首购单要删除会员
+            if($this->type == self::TYPE_ZC){
+                UserInfo::deleteUser($oneOrder['TO_USER_ID']);
+            }
+            // 如果是复销单的话,还需要考虑给会员的复销池减去金额
+            elseif($this->type == self::TYPE_FX){
+                Reconsume::changePoolPV($oneOrder['TO_USER_ID'], -abs($oneOrder['DEC_PV']), ['REMARK'=>'删单扣除', 'DEAL_TYPE'=>Reconsume::TYPE_AUDIT_PV]);
+            }
+            $transaction->commit();
+        } catch (Exception $e) {
+            $transaction->rollBack();
+            $this->addError('delete', $e->getMessage());
+            return false;
+        }
+        return true;
+    }
+
+}

+ 9 - 9
common/models/forms/DeclarationUpgradeForm.php

@@ -209,7 +209,7 @@ class DeclarationUpgradeForm extends Model
         if(!$warehouse){
             throw new Exception('地区暂时不支持配送,具体联系客服');
         }
-        
+
         $upgradeType = $isObserve ? 1 : 2; // 1补差  2全额
         $periodObj = Period::instance();
         $nowPeriodNum = $periodObj->getNowPeriodNum();
@@ -329,7 +329,7 @@ class DeclarationUpgradeForm extends Model
                 throw new Exception(Form::formatErrorsForApi($addressModel->getErrors()));
             }
             // 扣报单人现金钱包
-            Cash::changeUserCash(\Yii::$app->user->id, 'CASH', -abs($this->_decAmount), ['REMARK' =>'为'.$this->insertUserName.'升级报单']);
+            Cash::changeUserCash(\Yii::$app->user->id, 'CASH', -abs($this->_decAmount), ['REMARK' =>'为'.$this->insertUserName.'升级报单', 'ORDER_SN' => $orderModel->SN]);
             // 为被升级人进行升级操作
             $decLevelLog = new DecLevelLog();
             $decLog = [
@@ -373,11 +373,11 @@ class DeclarationUpgradeForm extends Model
             $this->loopFindParentToNetwork($this->insertUserName);
             //反转数组,in_array搜索错误
             //in_array($this->decUserName, $this->_tempNetworkParentUser[$this->insertUserName]);
-            $flipParent = array_flip(array_filter($this->_tempNetworkParentUser[$this->insertUserName]));
-            if (!isset($flipParent[$this->decUserName])) {
-                $this->addError($attribute, '为' . $this->insertUserName . '升级报单,报单中心' . $this->decUserName . '不在' . $this->insertUserName . '的安置网上级中');
-                return ;
-            }
+//            $flipParent = array_flip(array_filter($this->_tempNetworkParentUser[$this->insertUserName]));
+//            if (!isset($flipParent[$this->decUserName])) {
+//                $this->addError($attribute, '为' . $this->insertUserName . '升级报单,报单中心' . $this->decUserName . '不在' . $this->insertUserName . '的安置网上级中');
+//                return ;
+//            }
             $this->_decId = $decUser['ID'];
         }
     }
@@ -401,7 +401,7 @@ class DeclarationUpgradeForm extends Model
     public function alreadyMaxDec($attribute) {
         $baseInfo = Info::baseInfoZhByUserName($this->insertUserName);
         $userDecId = $baseInfo['DEC_LV'];// 用户当前的级别
-        $maxPerfInfo = DeclarationLevel::getMaxDecPref(); 
+        $maxPerfInfo = DeclarationLevel::getMaxDecPref();
         $maxDecId = $maxPerfInfo['ID']; // 级别配置中最高级别ID
         if ($maxDecId == $userDecId) {
             $this->addError($attribute, '已是最高级别,无需升级');
@@ -436,7 +436,7 @@ class DeclarationUpgradeForm extends Model
             }
         }
         unset($allParentUserIds);
-        
+
         return true;
     }
 

+ 146 - 0
common/models/forms/HighestEmpLevelLogForm.php

@@ -0,0 +1,146 @@
+<?php
+namespace common\models\forms;
+
+use common\helpers\Date;
+use common\components\Model;
+use common\helpers\Form;
+use common\helpers\user\Info;
+use common\libs\logging\operate\AdminOperate;
+use common\models\EmployLevel;
+use common\models\HighestEmpLevelLog;
+use common\models\Period;
+use common\models\User;
+use yii\base\Exception;
+
+/**
+ * Login form
+ */
+class HighestEmpLevelLogForm extends Model
+{
+    public $userName;
+    public $levelId;
+    public $periodNum;
+    public $remark;
+    private $_userId;
+    private $_fromId;
+
+    public function init() {
+        parent::init();
+        $this->adminOperateLogger = new AdminOperate([
+            'fetchClass' => User::class,
+        ]);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function rules()
+    {
+        return [
+            [['userName', 'levelId', 'periodNum', 'remark'], 'trim'],
+            [['userName', 'levelId', 'periodNum'], 'required'],
+            [['userName'], 'exist', 'targetClass' => User::class, 'targetAttribute' => 'USER_NAME'],
+            [['levelId'], 'exist', 'targetClass' => EmployLevel::class, 'targetAttribute' => 'ID'],
+            [['userName'], 'isUser'],
+            [['levelId'], 'isLevel'],
+            [['periodNum'], 'integer'],
+        ];
+    }
+
+    public function attributeLabels()
+    {
+        return [
+            'userName' => '会员编号',
+            'levelId' => '级别',
+            'periodNum' => '期数',
+            'remark' => '备注',
+        ];
+    }
+
+    /**
+     * 指定校验场景
+     * @return array
+     */
+    public function scenarios()
+    {
+        $parentScenarios =  parent::scenarios();
+        $customScenarios = [
+            'adminChange' => ['userName', 'levelId', 'remark'],
+        ];
+        return array_merge($parentScenarios, $customScenarios);
+    }
+
+    /**
+     * 赋值UserId并校验会员是否存在
+     * @param $attribute
+     */
+    public function isUser($attribute){
+        $this->_userId = Info::getUserIdByUserName($this->userName);
+        if(!$this->_userId){
+            $this->addError($attribute, '会员不存在');
+        }
+    }
+
+    /**
+     * 查看级别是否有变化
+     * @param $attribute
+     * @throws \yii\db\Exception
+     */
+    public function isLevel($attribute){
+        $this->_fromId = Info::getEmpLv($this->_userId);
+        if ($this->levelId == $this->_fromId) {
+            $this->addError($attribute, '级别没有变化无需调整');
+        }
+    }
+
+    /**
+     * 更改最高聘级.
+     * @return HighestEmpLevelLog|null
+     */
+    public function adminChange()
+    {
+        if (!$this->validate()) {
+            return null;
+        }
+        $this->adminOperateLogger->beforeUpdate($this->_userId,'ID',['select'=>'ID,EMP_LV']);
+
+        $model = new HighestEmpLevelLog();
+
+        $db = \Yii::$app->db;
+        $transaction = $db->beginTransaction();
+        try {
+            $period = Period::instance();
+            // 新增数据
+            $model->USER_ID = $this->_userId;
+            $model->FROM_ID = $this->_fromId;
+            $model->TO_ID = $this->levelId;
+            $model->PERIOD_NUM = $period->getNowPeriodNum();
+            $model->CALC_MONTH = $period->getYearMonth($period->getNowPeriodNum());
+            $model->REMARK = $this->remark ?? '';
+            $model->STATUS = 1;
+            $model->ADMIN_ID = \Yii::$app->user->id;
+            $model->CREATED_AT = Date::nowTime();
+            if (!$model->save()) {
+                throw new Exception(Form::formatErrorsForApi($model->getErrors()));
+            }
+
+            // 修改最高聘级
+            User::updateAll(['EMP_LV' => $this->levelId], 'ID=:USER_ID', [':USER_ID' => $this->_userId]);
+
+            $transaction->commit();
+        } catch (Exception $e) {
+            $transaction->rollBack();
+            $this->addError('adminChange', $e->getMessage());
+            return null;
+        }
+
+        $this->adminOperateLogger->afterUpdate($this->_userId,'ID',['select'=>'ID,EMP_LV'])->clean()->save([
+            'optType' => '调整会员最高聘级',
+            'userId' => $this->_userId,
+            'userName' => Info::getUserNameByUserId($this->_userId),
+            'remark' => $this->remark
+        ]);
+
+        return $model;
+    }
+}

+ 22 - 14
common/models/forms/OrderDeleteForm.php

@@ -87,7 +87,7 @@ class OrderDeleteForm extends Model
         $sn = $this->orderSn;
         // 获取订单详情
         $orderInfo = Order::findUseDbCalc()
-        ->select('ID,DEC_SN,SN,USER_ID,ORDER_TYPE,IS_DELETE,PAY_AMOUNT,PAY_TYPE,ORDER_AMOUNT,USER_NAME,PV,PAY_PV,PERIOD_NUM,PROVINCE,CITY,COUNTY,ADDRESS')
+        ->select('ID,DEC_SN,SN,USER_ID,ORDER_TYPE,IS_DELETE,PAY_AMOUNT,PAY_TYPE,ORDER_AMOUNT,USER_NAME,PV,PAY_PV,PERIOD_NUM,PROVINCE,CITY,COUNTY,ADDRESS,CREATE_USER,ORDER_CATEGORY')
         ->where("SN=:SN", [':SN' => $sn])
         ->asArray()
         ->one();
@@ -106,11 +106,11 @@ class OrderDeleteForm extends Model
                 ->where("ORDER_SN=:ORDER_SN", [':ORDER_SN' => $sn])
                 ->asArray()
                 ->one();
-                $userId = $decInfo['USER_ID']; 
+                $userId = $decInfo['USER_ID'];
                 // 删除报单
                 $delDecOrder = DecOrder::updateAll(
-                    ['IS_DEL'=>1, 'DELETED_AT'=>Date::nowTime()], 
-                    'ORDER_SN=:ORDER_SN', 
+                    ['IS_DEL'=>1, 'DELETED_AT'=>Date::nowTime()],
+                    'ORDER_SN=:ORDER_SN',
                     ['ORDER_SN'=>$sn]
                 );
                 if (!$delDecOrder) {
@@ -138,18 +138,26 @@ class OrderDeleteForm extends Model
                     }
                     $isLock = 1;
                 }
-            } 
+            } else if ($orderInfo['ORDER_CATEGORY'] === 'STUDIO') {
+                // 工作室复消:退款给下单人
+                $createUser = User::findOneAsArray('USER_NAME=:USER_NAME', [':USER_NAME' => $orderInfo['CREATE_USER']]);
+                if (!$createUser) {
+                    $transaction->rollBack();
+                    throw new Exception('删除订单失败。查找下单人失败');
+                }
+                $userId = $createUser['ID'];
+            }
             // 公共的退钱,删除订单操作
             $delOrder = Order::updateAll(
-                ['IS_DELETE'=>1, 'DELETED_AT'=>Date::nowTime()], 
-                'SN=:SN', 
+                ['IS_DELETE'=>1, 'DELETED_AT'=>Date::nowTime()],
+                'SN=:SN',
                 ['SN'=>$sn]
             );
             if (!$delOrder) {
                 $transaction->rollBack();
                 throw new Exception('删除订单失败');
             }
-            
+
             // 记录退还前的账户原资金
             $cash = $point = $bonus = $exchange = 0;
             $userBonus = UserBonus::findUseSlaves()
@@ -172,11 +180,11 @@ class OrderDeleteForm extends Model
             //退还
             $amountResult = false;
             if($payType == 'cash') {
-                $amountResult = Cash::changeUserCash($userId, 'CASH', +abs($payAmount), ['REMARK' => '删单退回']);
+                $amountResult = Cash::changeUserCash($userId, 'CASH', +abs($payAmount), ['REMARK' => '删单退回', 'ORDER_SN' => $orderInfo['SN']]);
             } else if ($payType == 'exchange') {
-                $amountResult = Balance::changeUserBonus($userId,'exchange_points', +abs($payAmount),['DEAL_TYPE_ID' => DealType::EXCHANGE_POINTS_EXCHANGE,'REMARK' => '删单退回']);
+                $amountResult = Balance::changeUserBonus($userId,'exchange_points', +abs($payAmount),['DEAL_TYPE_ID' => DealType::EXCHANGE_POINTS_EXCHANGE,'REMARK' => '删单退回', 'ORDER_SN' => $orderInfo['SN']]);
             } else{
-                $amountResult = Balance::changeUserBonus($userId,'reconsume_points', +abs($payAmount),['DEAL_TYPE_ID' => DealType::RECONSUME_POINTS_EXCHANGE,'REMARK' => '删单退回']);
+                $amountResult = Balance::changeUserBonus($userId,'reconsume_points', +abs($payAmount),['DEAL_TYPE_ID' => DealType::RECONSUME_POINTS_EXCHANGE,'REMARK' => '删单退回', 'ORDER_SN' => $orderInfo['SN']]);
             }
             if ($amountResult !== true) {
                 $transaction->rollBack();
@@ -226,7 +234,7 @@ class OrderDeleteForm extends Model
                 $this->addErrors($returnOrderModel->getErrors());
                 return false;
             }
-            
+
             $transaction->commit();
         } catch(Exception $e) {
             $transaction->rollBack();
@@ -317,8 +325,8 @@ class OrderDeleteForm extends Model
                     $this->addError($attribute, '此注册报单,存在复消单,无法删除,订单编号为:'.$this->orderSn);
                     return ;
                 }
-            }   
+            }
         }
-        return true; 
+        return true;
     }
 }

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

@@ -484,20 +484,19 @@ class OrderForm extends Model
 
         //扣除会员余额/积分
         if($this->payType=='cash') {
-            Cash::changeUserCash(\Yii::$app->user->id, 'CASH', -abs($this->_payAmount), ['REMARK' => '会员复销余额支付']);
+            Cash::changeUserCash(\Yii::$app->user->id, 'CASH', -abs($this->_payAmount), ['REMARK' => '会员复销余额支付', 'ORDER_SN' => $orderModel->SN]);
         } else if ($this->payType=='exchange') {
-            Balance::changeUserBonus(\Yii::$app->user->id,'exchange_points', -abs($this->_payAmount),['DEAL_TYPE_ID' => DealType::EXCHANGE_POINTS_EXCHANGE,'REMARK' => '会员兑换积分兑换']);
+            Balance::changeUserBonus(\Yii::$app->user->id,'exchange_points', -abs($this->_payAmount),['DEAL_TYPE_ID' => DealType::EXCHANGE_POINTS_EXCHANGE,'REMARK' => '会员兑换积分兑换', 'ORDER_SN' => $orderModel->SN]);
         } else{
-            Balance::changeUserBonus(\Yii::$app->user->id,'reconsume_points', -abs($this->_payAmount),['DEAL_TYPE_ID' => DealType::RECONSUME_POINTS_EXCHANGE,'REMARK' => '会员复销点数兑换']);
+            Balance::changeUserBonus(\Yii::$app->user->id,'reconsume_points', -abs($this->_payAmount),['DEAL_TYPE_ID' => DealType::RECONSUME_POINTS_EXCHANGE,'REMARK' => '会员复销点数兑换', 'ORDER_SN' => $orderModel->SN]);
         }
         return $orderModel;
     }
 
     /**
      * 帮会员复销
-     * @return bool|null
      * @throws Exception
-     * @throws \yii\db\Exception
+     * @throws \yii\db\Exception|\Throwable
      */
     public function reconsumeAdd(){
         if(!$this->validate()){
@@ -590,10 +589,7 @@ class OrderForm extends Model
                         }
                     }else{
                         throw new Exception($goods['GOODS_NAME'].'库存不足,无法购买商品');
-
                     }
-
-
                 }
             }
 //                exit();
@@ -613,6 +609,7 @@ class OrderForm extends Model
 
     /**
      * 帮会员复消的订单
+     * @throws Exception
      */
     public function addUserOrder(){
         $periodObj = Period::instance();
@@ -659,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){
@@ -671,9 +669,9 @@ class OrderForm extends Model
 
         //扣除会员余额/积分
         if($this->payType=='cash') {
-            Cash::changeUserCash($loginUserId, 'CASH', -abs($this->_payAmount), ['REMARK' => '会员复销余额支付']);
+            Cash::changeUserCash($loginUserId, 'CASH', -abs($this->_payAmount), ['REMARK' => '会员复销余额支付', 'ORDER_SN' => $orderModel->SN]);
         }else{
-            Balance::changeUserBonus($loginUserId,'reconsume_points', -abs($this->_payAmount),['DEAL_TYPE_ID' => DealType::RECONSUME_POINTS_EXCHANGE, 'REMARK' => '会员复销点数兑换']);
+            Balance::changeUserBonus($loginUserId,'reconsume_points', -abs($this->_payAmount),['DEAL_TYPE_ID' => DealType::RECONSUME_POINTS_EXCHANGE, 'REMARK' => '会员复销点数兑换', 'ORDER_SN' => $orderModel->SN]);
         }
         return $orderModel;
     }

+ 152 - 0
common/models/forms/OrderPeriodAdjustForm.php

@@ -0,0 +1,152 @@
+<?php
+namespace common\models\forms;
+
+use backendApi\modules\v1\models\Admin;
+use common\helpers\Date;
+use common\components\Model;
+use common\helpers\LoggerTool;
+use common\libs\logging\operate\AdminOperate;
+use common\models\DecOrder;
+use common\models\FlowExchangePoints;
+use common\models\FlowReconsumePoints;
+use common\models\FlowWallet;
+use common\models\Order;
+use common\models\OrderPeriodAdjust;
+use common\models\Period;
+use common\models\User;
+use common\models\UserInfo;
+
+/**
+ * OrderPeriodAdjustForm form
+ */
+class OrderPeriodAdjustForm extends Model
+{
+    public $orderSn;
+    public $modernPeriod;
+
+    public $order;
+
+    public function init() {
+        parent::init();
+        $this->adminOperateLogger = new AdminOperate([
+            'fetchClass' => OrderPeriodAdjust::class,
+        ]);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function rules()
+    {
+        return [
+            [['orderSn', 'modernPeriod'], 'trim'],
+            [['orderSn', 'modernPeriod'], 'required'],
+        ];
+    }
+
+    public function attributeLabels()
+    {
+        return [
+            'orderSn' => '订单号',
+            'modernPeriod' => '调整后期数',
+        ];
+    }
+
+    /**
+     * 指定校验场景
+     * @return array
+     */
+    public function scenarios()
+    {
+        $parentScenarios =  parent::scenarios();
+        $customScenarios = [
+            'orderPeriodAdjust' => ['orderSn', 'modernPeriod'],
+        ];
+        return array_merge($parentScenarios, $customScenarios);
+    }
+
+    /**
+     * 校验之前
+     * @return bool
+     */
+    public function beforeValidate()
+    {
+        $parentValidate = parent::beforeValidate();
+        // 校验订单
+        $this->order = Order::findOne(['SN' => $this->orderSn, 'IS_DELETE' => 0]);
+        if (!$this->order) {
+            $this->addError('orderSn', '订单不存在');
+            return false;
+        }
+        // 目前期数:已封期、未挂网可调整
+        $period = Period::getInfoByPeriodNum($this->modernPeriod);
+        if (!$period) {
+            $this->addError('modernPeriod', '期数不存在');
+            return false;
+        }
+        if (!((+$period['IS_CLOSED'] == 1) && (+$period['IS_SENT'] == 0))) {
+            $this->addError('orderSn', '调整后的期数必须是已封期且未挂网');
+            return false;
+        }
+
+        return $parentValidate;
+    }
+
+    /**
+     * @return bool|null
+     */
+    public function periodAdjust()
+    {
+        if (!$this->validate()) {
+            return null;
+        }
+
+        $db = \Yii::$app->db;
+        $transaction = $db->beginTransaction();
+        try {
+            // 调整订单期数
+            Order::updateAll(['PERIOD_NUM' => $this->modernPeriod], 'SN = :SN', [':SN' => $this->orderSn]);
+
+            if ($this->order->ORDER_TYPE === 'ZC') {
+                // 调整报单期数
+                DecOrder::updateAll(['PERIOD_NUM' => $this->modernPeriod], 'ORDER_SN = :ORDER_SN', ['ORDER_SN' => $this->orderSn]);
+                // 调整会员的期数
+                User::updateAll(['PERIOD_AT' => $this->modernPeriod], 'ID = :USER_ID', ['USER_ID' => $this->order->USER_ID]);
+                UserInfo::updateAll(['HIGHEST_EMP_LV_PERIOD' => $this->modernPeriod], 'USER_ID = :USER_ID', ['USER_ID' => $this->order->USER_ID]);
+            }
+
+            // 调整流水的期数
+            switch ($this->order->PAY_TYPE){
+                case 'cash':
+                    FlowWallet::updateAll(['PERIOD_NUM' => $this->modernPeriod], 'ORDER_SN = :ORDER_SN', ['ORDER_SN' => $this->orderSn]);
+                    break;
+                case 'point':
+                    FlowReconsumePoints::updateAll(['PERIOD_NUM' => $this->modernPeriod], 'ORDER_SN = :ORDER_SN', ['ORDER_SN' => $this->orderSn]);
+                    break;
+                case 'exchange':
+                    FlowExchangePoints::updateAll(['PERIOD_NUM' => $this->modernPeriod], 'ORDER_SN = :ORDER_SN', ['ORDER_SN' => $this->orderSn]);
+                    break;
+                default:
+                    break;
+            }
+
+            // 写入调整记录
+            $orderModel = new OrderPeriodAdjust();
+            $orderModel->ORDER_SN = $this->orderSn;
+            $orderModel->ORIGIN_PERIOD = $this->order->PERIOD_NUM;
+            $orderModel->MODERN_PERIOD = $this->modernPeriod;
+            $orderModel->ADMIN_ID = Admin::getAdminNameById(\Yii::$app->user->id);
+            $orderModel->CREATED_AT = Date::nowTime();
+            if (!$orderModel->save()) {
+                $this->addErrors($orderModel->getErrors());
+                return false;
+            }
+            $transaction->commit();
+        } catch(\Exception $e) {
+            $transaction->rollBack();
+            $this->addError('periodAdjust', $e->getMessage());
+            return null;
+        }
+        return true;
+    }
+}

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

@@ -25,6 +25,7 @@ class ReceiveAddressForm extends Model
     public $city;
     public $county;
     public $address;
+    public $zipCode;
     public $isDefault;
 
     /**
@@ -46,7 +47,7 @@ class ReceiveAddressForm extends Model
     public function rules()
     {
         return [
-            [['id', 'consignee', 'mobile', 'province', 'city', 'county', 'address', 'isDefault'], 'trim'],
+            [['id', 'consignee', 'mobile', 'province', 'city', 'county', 'address', 'zipCode', 'isDefault'], 'trim'],
             [['id', 'consignee', 'mobile', 'province', 'city', 'county', 'address'], 'required'],
             [['mobile'], 'mobile'],
             [['province', 'city', 'county'], 'exist', 'targetClass' => Region::class, 'targetAttribute' => 'REGION_CODE'],
@@ -62,6 +63,7 @@ class ReceiveAddressForm extends Model
             'city' => '市/区',
             'county' => '区/县',
             'address' => '详细地址',
+            'zipCode' => '邮政编码',
         ];
     }
 
@@ -73,8 +75,8 @@ class ReceiveAddressForm extends Model
     {
         $parentScenarios =  parent::scenarios();
         $customScenarios = [
-            'userAdd' => ['consignee', 'mobile', 'province', 'city', 'county', 'address', 'isDefault'],
-            'userEdit' => ['id', 'consignee', 'mobile', 'province', 'city', 'county', 'address', 'isDefault'],
+            'userAdd' => ['consignee', 'mobile', 'province', 'city', 'county', 'address', 'zipCode', 'isDefault'],
+            'userEdit' => ['id', 'consignee', 'mobile', 'province', 'city', 'county', 'address', 'zipCode', 'isDefault'],
             'userIsDefault' => ['id', 'isDefault'],
         ];
         return array_merge($parentScenarios, $customScenarios);
@@ -138,6 +140,7 @@ class ReceiveAddressForm extends Model
                 $this->_model->CITY = $this->city;
                 $this->_model->COUNTY = $this->county;
                 $this->_model->ADDRESS = $this->address;
+                $this->_model->ZIP_CODE = $this->zipCode;
                 $this->_model->IS_DEFAULT = $this->isDefault ? 1 : 0;
                 $this->_model->CREATED_AT = Date::nowTime();
             } elseif($this->scenario == 'userEdit') {
@@ -147,6 +150,7 @@ class ReceiveAddressForm extends Model
                 $this->_model->CITY = $this->city;
                 $this->_model->COUNTY = $this->county;
                 $this->_model->ADDRESS = $this->address;
+                $this->_model->ZIP_CODE = $this->zipCode;
                 $this->_model->IS_DEFAULT = $this->isDefault ? 1 : 0;
                 $this->_model->UPDATED_AT = Date::nowTime();
             } elseif($this->scenario == 'userIsDefault') {

+ 18 - 7
common/models/forms/ShopGoodsForm.php

@@ -51,7 +51,7 @@ class ShopGoodsForm extends Model
     {
         return [
             [['id','sellDiscount','giftType','sellType','goodsNo', 'goodsName', 'unit', 'sellPrice', 'marketPrice', 'pricePv', 'storeNums', 'content', 'sort','status','cover'], 'trim'],
-            [['goodsName','sellDiscount','giftType','goodsNo', 'storeNums','sellPrice','marketPrice','pricePv', 'sort','status','cover'], 'required'],
+            [['goodsName','sellDiscount','giftType','goodsNo', 'storeNums','sellPrice','marketPrice','pricePv', 'sort','status', 'type'], 'required'],
             [['id'], 'required', 'on'=>'edit'],
             [['id'], 'exist', 'targetClass'=>ShopGoods::class, 'targetAttribute'=>'ID'],
             [['sellPrice','marketPrice','pricePv'], 'price'],
@@ -59,7 +59,8 @@ class ShopGoodsForm extends Model
             [['selectedIds'], 'isSelected'],
             [['sort'], 'isSort'],
             [['sellDiscount'], 'isDiscount'],
-            [['statusdate','goodsstatusdate'],'match','pattern'=>'/^[0-1]{1,1}$/']
+            [['statusdate','goodsstatusdate'],'match','pattern'=>'/^[0-1]{1,1}$/'],
+            [['type'], 'isType'],
         ];
     }
 
@@ -82,6 +83,7 @@ class ShopGoodsForm extends Model
             'storeNums' => '库存',
             'content' => '产品详情',
             'listOrder' => '排序',
+            'type' => '商品来源',
         ];
     }
 
@@ -93,8 +95,8 @@ class ShopGoodsForm extends Model
     {
         $parentScenarios =  parent::scenarios();
         $customScenarios = [
-            'add' => ['goodsName','sellDiscount','giftType', 'sellType','goodsNo','unit','sellPrice','marketPrice','pricePv','storeNums', 'content','sort','cover'],
-            'edit' => ['id','goodsName','sellDiscount','giftType', 'sellType','goodsNo','unit','sellPrice','marketPrice','pricePv', 'storeNums', 'content','sort','cover','statusdate','goodsstatusdate','goodsdate'],
+            'add' => ['goodsName','sellDiscount','giftType', 'sellType','goodsNo','unit','sellPrice','marketPrice','pricePv','storeNums', 'content','sort','cover', 'type'],
+            'edit' => ['id','goodsName','sellDiscount','giftType', 'sellType','goodsNo','unit','sellPrice','marketPrice','pricePv', 'storeNums', 'content','sort','cover','statusdate','goodsstatusdate','goodsdate', 'type'],
             'changeStatus' => ['selectedIds', 'status'],
         ];
         return array_merge($parentScenarios, $customScenarios);
@@ -139,6 +141,14 @@ class ShopGoodsForm extends Model
         }
     }
 
+    /**
+     * 根据商品类型处理支付类型
+     * @param $attributes
+     */
+    public function isType() {
+        $this->sellType = $this->type == '1' ? '1,2,3' : '4';
+    }
+
     /**
      * 添加
      * @return ShopGoods|null
@@ -157,7 +167,7 @@ class ShopGoodsForm extends Model
             $shopGoods->SELL_DISCOUNT = $this->sellDiscount;
             $shopGoods->GIFT_TYPE = implode(',',$this->giftType);
             // $shopGoods->SELL_TYPE = implode(',',$this->sellType);
-            $shopGoods->SELL_TYPE = '1,2,3';
+            $shopGoods->SELL_TYPE = $this->sellType;
             $shopGoods->GOODS_NO = $this->goodsNo;
             $shopGoods->UNIT = $this->unit ? $this->unit : '个';
             $shopGoods->COVER = $this->cover ? $this->cover : '';
@@ -168,7 +178,7 @@ class ShopGoodsForm extends Model
             $shopGoods->CONTENT = $this->content;
             $shopGoods->STORE_NUMS = $this->storeNums;
             $shopGoods->SORT = $this->sort;
-            $shopGoods->CATE_ID = '1';
+            $shopGoods->CATE_ID = $this->type;
             $shopGoods->CREATED_AT = Date::nowTime();
             if (!$shopGoods->save()) {
                 throw new Exception(Form::formatErrorsForApi($shopGoods->getErrors()));
@@ -198,10 +208,11 @@ class ShopGoodsForm extends Model
             $model = $this->_model;
             $model->GOODS_NAME = $this->goodsName;
             $model->TYPE = 0;
+            $model->CATE_ID = $this->type;
             $model->SELL_DISCOUNT = $this->sellDiscount;
             $model->GIFT_TYPE = implode(',',$this->giftType);
             // $model->SELL_TYPE = implode(',',$this->sellType);
-            $model->SELL_TYPE = '1,2,3';
+            $model->SELL_TYPE = $this->sellType;
             $model->GOODS_NO = $this->goodsNo;
             $model->UNIT = $this->unit ? $this->unit : '个';
             $model->COVER = $this->cover ? $this->cover : '';

+ 4 - 2
common/models/forms/TransferForm.php

@@ -264,9 +264,11 @@ class TransferForm extends Model {
      */
     public function validatePassword($attribute, $params) {
         $uid = \Yii::$app->user->id;
-        if(!$this->_fromUserInfo){
-            LoggerTool::info('transfer error, '.$uid.' '. $this->amount.' '. $this->toUserName);
+        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, '支付密码不正确');
         }

+ 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);
                     //记录付款信息

+ 2 - 1
composer.json

@@ -23,7 +23,8 @@
         "anlity/yii2-swoole-async-timer": "^0.9.1",
         "yiisoft/yii2-mongodb": "^2.1",
         "godruoyi/php-snowflake": "^1.0",
-        "yiisoft/yii2-redis": "^2.0"
+        "yiisoft/yii2-redis": "^2.0",
+	    "ext-curl": "*"
     },
     "require-dev": {
         "yiisoft/yii2-debug": "~2.0.0",

+ 62 - 19
console/controllers/ToolController.php

@@ -176,25 +176,68 @@ class ToolController extends BaseController
     }
 
     /**
-     * 自动送钉钉提醒
+     * 自动送钉钉提醒(会员端)
      */
-    public function actionAutoSendDingTalkTable() {
-//        $ip = 'http://16.163.228.151:8013';
-//        $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 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);
+        }
+    }
+
+    /**
+     * 自动推送跨境商品到wst
+     */
+    public function actionAutoLogistics() {
+        $ip = 'https://fapi.ekhkad.com';
+        $curl = curl_init();
+        curl_setopt($curl, CURLOPT_URL, $ip . '/v1/shop/logistics-auto');
+        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);
+        }
     }
 }

+ 22 - 2
frontendApi/config/params.php

@@ -1,6 +1,26 @@
 <?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', 'v1/site/send-notice',],
-    'noCheckPermissionActions' => [],
+    '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',
+        'v1/shop/verify-approach-order',
+        'v1/shop/logistics',
+        'v1/shop/logistics-auto',
+    ],
+    'noCheckPermissionActions' => [
+        'shop/logistics',
+        'shop/logistics-auto',
+    ],
 ];

+ 6 - 1
frontendApi/config/urlManagerRules.php

@@ -73,7 +73,12 @@ return [
             'GET pay-success' => 'pay-success',
             'GET order-list' => 'order-list',
             'GET dec-order-list' => 'dec-order-list',
-            'GET order-list' => 'order-list',
+            'POST sure-approach-order' => 'sure-approach-order',
+            'POST verify-approach-order' => 'verify-approach-order',
+            'POST delete-approach-order' => 'delete-approach-order',
+            'POST i-pay88' => 'i-pay88',
+            'GET logistics' => 'logistics',
+            'GET logistics-auto' => 'logistics-auto',
         ],
     ],
     [

+ 416 - 0
frontendApi/modules/v1/components/IPay88.php

@@ -0,0 +1,416 @@
+<?php
+
+namespace frontendApi\modules\v1\components;
+
+use common\helpers\LoggerTool;
+use Exception;
+use Yii;
+
+class IPay88 {
+
+    /**
+     * Normal iPay88 payment method
+     */
+    const TRANSACTION_TYPE_PAYMENT = 'payment';
+
+    /**
+     * Normal iPay88 recurring payment subscription
+     */
+    const TRANSACTION_TYPE_RECURRING_SUBSCRIPTION = 'recurring_subscription';
+
+    /**
+     * Normal iPay88 recurring payment termination
+     */
+    const TRANSACTION_TYPE_RECURRING_TERMINATION = 'recurring_termination';
+
+    /**
+     * Merchant code assigned by iPay88
+     */
+    public $merchantCode;
+
+    /**
+     * Merchant Key assigned by iPay88
+     */
+    public $merchantKey;
+
+    /**
+     * Currency Code max length 5
+     */
+    public $currencyCode;
+
+    /**
+     * Merchant code assigned by iPay88
+     */
+    public $responseUrl;
+
+    /*
+     * Response Url or Return Url after payment
+     */
+    public $paymentUrl;
+
+    /*
+     * Backend Url or Notify Url after payment (Send response by iPay88 server)
+     */
+    public $backendUrl;
+
+    /*
+     * Requery from iPay88 server regarding bill details
+     */
+    public $requeryUrl;
+
+    /*
+    * ipay88 Recurring Payment Url
+    */
+    public $recurringUrlSubscription;
+
+    /*
+    * ipay88 Recurring Payment Termination Url
+    */
+    public $recurringUrlTermination;
+
+
+    /*
+     * Details to be sent to IPay88 for payment request.
+     */
+    private $paymentRequest = array(
+        'MerchantCode', // Merchant code assigned by iPay88. (length 20)
+        'PaymentId', // (Optional) (int)
+        'RefNo', // Unique merchant transaction number / Order ID (Retry for same RefNo only valid for 30 mins). (length 20)
+        'Amount', // Payment amount with two decimals.
+        'Currency', // (length 5)
+        'ProdDesc', // Product description. (length 100)
+        'UserName', // Customer name. (length 100)
+        'UserEmail', // Customer email.  (length 100)
+        'UserContact', // Customer contact.  (length 20)
+        'Remark', // (Optional) Merchant remarks. (length 100)
+        'Lang', // (Optional) Encoding type:- ISO-8859-1 (English), UTF-8 (Unicode), GB2312 (Chinese Simplified), GD18030 (Chinese Simplified), BIG5 (Chinese Traditional)
+        'Signature',
+        'ResponseURL',
+        'BackendURL',
+    );
+
+
+    /*
+     * Details to be sent to iPay88 for recurring subscription payment request.
+     */
+    private $recurringSubscriptionRequest = array(
+        'MerchantCode', // Merchant code assigned by iPay88. (length 20)
+        'RefNo', // Unique merchant transaction number / Order ID. (length 20)
+        'FirstPaymentDate', // (ddmmyyyy)
+        'Currency', // MYR only. (length 5)
+        'Amount', // Payment amount with two decimals.
+        'NumberOfPayments', // (int)
+        'Frequency', // Frequency type; 1 - Monthly, 2 - Quarterly, 3 - Half-Yearly, 4 - Yearly. (int)
+        'Desc', // Product description. (length 100)
+        'CC_Name', // Name printed on credit card. (length 100)
+        'CC_PAN', // 16-digit credit card number (Visa/Mastercard). (length 16)
+        'CC_CVC', // 3-digit verification code behind credit card. (length 3)
+        'CC_ExpiryDate', // Credit card expiry date. (mmyyyy)
+        'CC_Country', // Credit card issuing country. (length 100)
+        'CC_Bank', // Credit card issuing bank. (length 100)
+        'CC_Ic', // Credit card holder IC / Passport number. (length 50)
+        'CC_Email', // Credit card holder email address. (length 255)
+        'CC_Phone', // Credit card phone number. (length 100)
+        'CC_Remark', // (Optional) Remarks. (varchar 100)
+        'P_Name', // Subscriber name as printed in IC / Passport. (length 100)
+        'P_Email', // Subscriber email address. (length 255)
+        'P_Phone', // Subscriber phone number. (length 100)
+        'P_Addrl1', // Subscriber address line 1. (length 100)
+        'P_Addrl2', // (Optional) Subscriber address line 2. (length 100)
+        'P_City', // Subscriber city. (length 100)
+        'P_State', // Subscriber state. (length 100)
+        'P_Zip', // Subscriber zip code. (length 100)
+        'P_Country', // Subscriber country. (varchar 100)
+        'BackendURL', // Payment backend response page. (length 255)
+        'Signature', // SHA1 signature. (length 100)
+    );
+
+
+    /*
+     * Get required payment fields
+     */
+    public function getPaymentFields($reqParams = null, $paymentType) {
+        $retnParams = array();
+        try {
+            if (isset($reqParams) && (count($reqParams) > 0)) {
+
+                if (isset($paymentType) && $paymentType != "") {
+                    $paymentType = strtolower(trim($paymentType));
+                    switch ($paymentType) {
+                        case 'payment':
+                            $retnParams = $this->__getPaymentField($reqParams, $paymentType);
+                            break;
+                        case 'recurring_subscription':
+                            $retnParams = $this->__getRecurringSubscriptionField($reqParams, $paymentType);
+                            break;
+                        case 'recurring_termination':
+                            $retnParams = $this->__getRecurringTerminationField($reqParams, $paymentType);
+                            break;
+                    }
+                } else {
+                    throw new Exception("Ipay: Payment method missing");
+                }
+            } else {
+                throw new Exception("Ipay: Required Parameters missing");
+            }
+        } catch (Exception $e) {
+            LoggerTool::error(['iPay88-getPaymentFields', $e->getLine(), $e->getMessage()]);
+        }
+        return $retnParams;
+    }
+
+    /*
+     * Code for hex2bin
+     */
+    public function _hex2bin($hexSource) {
+        $bin = '';
+        for ($i = 0; $i < strlen($hexSource); $i = $i + 2) {
+            $bin .= chr(hexdec(substr($hexSource, $i, 2)));
+        }
+        return $bin;
+    }
+
+    /*
+     * Get payment fields for normal payment fields
+     */
+    public function __getPaymentField($reqParams, $paymentType) {
+        $retnParams = array();
+        foreach ($this->paymentRequest as $pymtKey) {
+            if (isset($reqParams[$pymtKey])) {
+                $retnParams[$pymtKey] = $reqParams[$pymtKey];
+            } else {
+
+                switch ($pymtKey) {
+                    case 'MerchantCode':
+                        $retnParams[$pymtKey] = $this->merchantCode;
+                        break;
+                    case 'Currency':
+                        $retnParams[$pymtKey] = $this->currencyCode;
+                        break;
+                    case 'Lang':
+                        $retnParams[$pymtKey] = 'UTF-8'; //(Optional) Encoding type:- ISO-8859-1 (English), UTF-8 (Unicode), GB2312 (Chinese Simplified), GD18030 (Chinese Simplified), BIG5 (Chinese Traditional)
+                        break;
+                    case 'Signature':
+                        $retnParams[$pymtKey] = $this->__createSignature($retnParams, $paymentType); // SHA1 signature.
+                        break;
+                    case 'ResponseURL':
+                        $retnParams[$pymtKey] = $this->responseUrl; // (Optional) Payment response page.
+                        break;
+                    case 'BackendURL':
+                        $retnParams[$pymtKey] = $this->backendUrl; // (Optional) BackendURL but should security purpose
+                        break;
+                }
+            }
+        }
+
+        return $retnParams;
+    }
+
+    /*
+     * Get payment fields for recurring payment
+     */
+    public function __getRecurringSubscriptionField($reqParams, $paymentType) {
+        $retnParams = array();
+        foreach ($this->recurringSubscriptionRequest as $pymtKey) {
+            if (isset($reqParams[$pymtKey])) {
+                $retnParams[$pymtKey] = $reqParams[$pymtKey];
+            } else {
+
+                switch ($pymtKey) {
+                    case 'MerchantCode':
+                        $retnParams[$pymtKey] = $this->merchantCode;
+                        break;
+                    case 'Currency':
+                        $retnParams[$pymtKey] = $this->currencyCode;
+                        break;
+                    case 'Lang':
+                        $retnParams[$pymtKey] = 'UTF-8'; //(Optional) Encoding type:- ISO-8859-1 (English), UTF-8 (Unicode), GB2312 (Chinese Simplified), GD18030 (Chinese Simplified), BIG5 (Chinese Traditional)
+                        break;
+                    case 'Signature':
+                        $retnParams[$pymtKey] = $this->__createSignature($retnParams, $paymentType); // SHA1 signature.
+                        break;
+                    case 'ResponseURL':
+                        $retnParams[$pymtKey] = $this->responseUrl; // (Optional) Payment response page.
+                        break;
+                    case 'BackendURL':
+                        $retnParams[$pymtKey] = $this->backendUrl; // (Optional) BackendURL but should security purpose
+                        break;
+                }
+            }
+        }
+
+        return $retnParams;
+    }
+
+
+
+    /*
+     * Get payment fields for recurring payment termination
+     */
+    public function __getRecurringTerminationField($reqParams, $paymentType) {
+        $retnParams = array();
+        foreach ($this->recurringSubscriptionRequest as $pymtKey) {
+            if (isset($reqParams[$pymtKey])) {
+                $retnParams[$pymtKey] = $reqParams[$pymtKey];
+            } else {
+
+                switch ($pymtKey) {
+                    case 'MerchantCode':
+                        $retnParams[$pymtKey] = $this->merchantCode;
+                        break;
+                }
+            }
+        }
+
+        return $retnParams;
+    }
+
+    /*
+     * Create signature for payment
+     */
+    public function __createSignature($signatureParams, $paymentType) {
+        $signature = '';
+        if (isset($signatureParams)) {
+            $_signatureParams = array();
+            if ($paymentType == self::TRANSACTION_TYPE_PAYMENT) {
+                $_signatureParams = array('MerchantCode', 'RefNo', 'Amount', 'Currency');
+            } else if ($paymentType == self::TRANSACTION_TYPE_RECURRING_SUBSCRIPTION) {
+                $_signatureParams = array('MerchantCode', 'RefNo', 'FirstPaymentDate', 'Currency', 'Amount', 'NumberOfPayments', 'Frequency', 'CC_PAN');
+            } else if ($paymentType == self::TRANSACTION_TYPE_RECURRING_TERMINATION) {
+                $_signatureParams = array('MerchantCode', 'RefNo');
+            }
+
+
+            foreach ($_signatureParams as $val) {
+                if (!isset($signatureParams[$val])) {
+                    throw new Exception("Ipay: Missing required parameters for signature.");
+                    return false;
+                }
+            }
+        }
+
+        // Make sure the order is correct.
+        if ($paymentType == self::TRANSACTION_TYPE_PAYMENT) {
+            $signature .= $this->merchantKey;
+            $signature .= $signatureParams['MerchantCode'];
+            //$signature .= $signatureParams['PaymentId'];
+            $signature .= $signatureParams['RefNo'];
+            $signature .= preg_replace("/[^\d]+/", "", $signatureParams['Amount']);
+            $signature .= $signatureParams['Currency'];
+        } else if ($paymentType == self::TRANSACTION_TYPE_RECURRING_SUBSCRIPTION) {
+            $signature .= $signatureParams['MerchantCode'];
+            $signature .= $this->merchantKey;
+            $signature .= $signatureParams['RefNo'];
+            $signature .= $signatureParams['FirstPaymentDate'];
+            $signature .= $signatureParams['Currency'];
+            $signature .= $signatureParams['Amount'];
+            $signature .= $signatureParams['NumberOfPayments'];
+            $signature .= $signatureParams['Frequency'];
+            $signature .= $signatureParams['CC_PAN'];
+        } else if ($paymentType == self::TRANSACTION_TYPE_RECURRING_TERMINATION) {
+            $signature .= $signatureParams['MerchantCode'];
+            $signature .= $this->merchantKey;
+            $signature .= $signatureParams['RefNo'];
+        }
+        // Hash the signature.
+        //return $signature = base64_encode($this->_hex2bin(sha1($signature)));
+        return $signature = hash('sha256', $signature);
+    }
+
+    /*
+     * Get url for respective payment redirection url
+     */
+    public function getTransactionUrl($paymentType) {
+        if ($paymentType == self::TRANSACTION_TYPE_PAYMENT) {
+            return $this->paymentUrl;
+        } else if ($paymentType == self::TRANSACTION_TYPE_RECURRING_SUBSCRIPTION) {
+            return $this->recurringUrlSubscription;
+        } else if ($paymentType == self::TRANSACTION_TYPE_RECURRING_TERMINATION) {
+            return $this->recurringUrlTermination;
+        }
+    }
+
+
+    /*
+     * iPay88 payment signature validation
+     */
+    public function checkiPay88Signature($reqParams) {
+        $status = 'fail';
+        try {
+            if (isset($reqParams) && count($reqParams) > 0) {
+                $orginalKey = $this->merchantKey . $this->merchantCode;
+                if (isset($reqParams['RefNo'])) {
+                    $orginalKey .=$reqParams['RefNo'];
+                }
+
+                if (isset($reqParams['Amount'])) {
+                    $orginalKey .=preg_replace("/[^\d]+/", "", $reqParams['Amount']);
+                }
+                $orginalKey .= $this->currencyCode;
+                if (isset($reqParams['Status'])) {
+                    $orginalKey .=$reqParams['Status'];
+                }
+
+                $orginalKeyGen = base64_encode($this->_hex2bin(sha1($orginalKey)));
+                $returnKey = $this->merchantKey;
+                if (isset($reqParams['MerchantCode'])) {
+                    $returnKey .=$reqParams['MerchantCode'];
+                }
+
+
+                if (isset($reqParams['RefNo'])) {
+                    $returnKey .=$reqParams['RefNo'];
+                }
+                if (isset($reqParams['Amount'])) {
+                    $returnKey .=preg_replace("/[^\d]+/", "", $reqParams['Amount']);
+                }
+                if (isset($reqParams['Currency'])) {
+                    $returnKey .=$reqParams['Currency'];
+                }
+                if (isset($reqParams['Status'])) {
+                    $returnKey .=$reqParams['Status'];
+                }
+
+
+                $returnKeyGen = base64_encode($this->_hex2bin(sha1($returnKey)));
+                if ($orginalKeyGen === $returnKeyGen) {
+                    $status = 'success';
+                }
+            } else {
+                throw new Exception("Ipay::checkiPay88Signature: Params missing");
+            }
+        } catch (exception $e) {
+            LoggerTool::error(['iPay88-checkiPay88Signature', $e->getLine(), $e->getMessage()]);
+        }
+
+        return $status;
+    }
+
+    /*
+     * Curl hit to get bill deyails
+     */
+    public function requeryPayment($rawPostData) {
+        try {
+            $result = '';
+            if (is_callable('curl_init')) {
+                if (isset($rawPostData) && $rawPostData != "") {
+                    $ch = curl_init();
+                    $url = $this->requeryUrl . '?' . $rawPostData;
+                    curl_setopt($ch, CURLOPT_URL, $url);
+                    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+                    $result = curl_exec($ch);
+                    curl_close($ch);
+                } else {
+                    throw new Exception("Ipay::requeryPayment: No request string");
+                }
+            } else {
+                throw new Exception("Ipay::requeryPayment: Curl not enabled");
+            }
+        } catch (exception $e) {
+            LoggerTool::error(['iPay88-requeryPayment', $e->getLine(), $e->getMessage()]);
+        }
+
+        return $result;
+    }
+
+}

+ 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);
+    }
+}

+ 1 - 1
frontendApi/modules/v1/controllers/ConfigController.php

@@ -86,7 +86,7 @@ class ConfigController extends BaseController
         $condition = ' AND USER_ID=:USER_ID';
         $params[':USER_ID'] = \Yii::$app->user->id;
         $data = ReceiveAddress::lists($condition, $params, [
-            'SELECT' => 'ID,CONSIGNEE,MOBILE,PROVINCE,CITY,COUNTY,ADDRESS,IS_DEFAULT',
+            'SELECT' => 'ID,CONSIGNEE,MOBILE,PROVINCE,CITY,COUNTY,ADDRESS,ZIP_CODE,IS_DEFAULT',
             'orderBy' => 'IS_DEFAULT DESC,CREATED_AT DESC',
             'useSlaves' => true,
         ]);

+ 328 - 22
frontendApi/modules/v1/controllers/ShopController.php

@@ -8,10 +8,18 @@
 
 namespace frontendApi\modules\v1\controllers;
 
+use common\helpers\Cache;
 use common\helpers\Date;
+use common\helpers\DingTalk;
 use common\helpers\Form;
+use common\helpers\LoggerTool;
+use common\helpers\Logistics;
+use common\helpers\Tool;
 use common\helpers\user\Info;
+use common\models\ApproachOrder;
+use common\models\ApproachOrderGoods;
 use common\models\DecOrder;
+use common\models\forms\ApproachOrderForm;
 use common\models\forms\DeclarationForm;
 use common\models\forms\OrderForm;
 use common\models\Order;
@@ -22,10 +30,17 @@ use common\models\ShopGoods;
 use common\models\User;
 use common\models\UserBonus;
 use common\models\UserWallet;
+use Yii;
+use yii\data\Pagination;
+use yii\db\Query;
+use yii\web\HttpException;
 
 class ShopController extends BaseController {
+
     public $modelClass = DecOrder::class;
 
+    const TRANSACTION_TYPE_PAYMENT = 'payment';
+
     /**
      * 商品列表
      * @return mixed
@@ -45,6 +60,7 @@ class ShopController extends BaseController {
         ]);
         foreach ($data['list'] as $key => $value) {
             $data['list'][$key]['DISCOUNT'] = $value['SELL_DISCOUNT']*100;
+            $data['list'][$key]['CATE'] = ShopGoods::GOODS_TYPE[$value['CATE_ID']]['name'] ?? '';
         }
         return static::notice($data);
     }
@@ -146,6 +162,40 @@ class ShopController extends BaseController {
         return static::notice($data);
     }
 
+//    /**
+//     * 我的订单
+//     * @return mixed
+//     * @throws \yii\web\HttpException
+//     */
+//    public function actionOrderList() {
+//        $uname = Info::getUserNameByUserId(\Yii::$app->user->id);
+//        $condition = " AND IS_DELETE=0 AND ORDER_TYPE='FX' AND (USER_ID=:USER_ID OR CREATE_USER='$uname')";
+//        $params[':USER_ID'] = \Yii::$app->user->id;
+//        $data = Order::lists($condition, $params, [
+//            'select' => 'O.*,U.REAL_NAME,OG.*',
+//            'orderBy' => 'O.CREATED_AT DESC',
+//            'from' => Order::tableName() . ' AS O',
+//            'join' => [
+//                ['LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID'],
+//                ['LEFT JOIN', OrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN'],
+//            ],
+//        ]);
+//        foreach ($data['list'] as $key => $value) {
+//            if($value['ORDER_TYPE']=='ZC'){
+//                $data['list'][$key]['ORDER_TYPE'] = '首单';
+//            }else{
+////                $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);
+//    }
+
     /**
      * 我的订单
      * @return mixed
@@ -153,31 +203,51 @@ class ShopController extends BaseController {
      */
     public function actionOrderList() {
         $uname = Info::getUserNameByUserId(\Yii::$app->user->id);
-        $condition = " AND IS_DELETE=0 AND ORDER_TYPE='FX' AND (USER_ID=:USER_ID OR CREATE_USER='$uname')";
+        $condition = " O.IS_DELETE = 0 AND O.ORDER_TYPE='FX' AND (O.USER_ID=:USER_ID OR O.CREATE_USER='$uname')";
         $params[':USER_ID'] = \Yii::$app->user->id;
-        $data = Order::lists($condition, $params, [
-            'select' => 'O.*,U.REAL_NAME,OG.*',
-            'orderBy' => 'O.CREATED_AT DESC',
-            'from' => Order::tableName() . ' AS O',
-            'join' => [
-                ['LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID'],
-                ['LEFT JOIN', OrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN'],
-            ],
-        ]);
+        $orderQuery = Order::find()
+            ->alias('O')
+            ->where($condition, $params)
+            ->select('O.*,U.REAL_NAME,OG.REAL_PRICE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV,OG.ORDER_SN,OG.GOODS_ID')
+            ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID')
+            ->join('LEFT JOIN', OrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN')
+            ->orderBy('O.CREATED_AT DESC');
+
+        // 订单中间表只查询待支付和支付失败的订单
+        $params[':NOT_PAID'] = \Yii::$app->params['orderStatus']['notPaid']['value'];   // 待支付
+        $params[':FAIL_PAID'] = \Yii::$app->params['orderStatus']['failPaid']['value'];   // 支付失败
+        $orderStandardQuery = ApproachOrder::find()
+            ->alias('O')
+            ->where($condition . ' AND (O.STATUS = :NOT_PAID OR O.STATUS = :FAIL_PAID)', $params)
+            ->select('O.*,U.REAL_NAME,OG.REAL_PRICE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV,OG.ORDER_SN,OG.GOODS_ID')
+            ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID')
+            ->join('LEFT JOIN', ApproachOrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN')
+            ->orderBy('O.CREATED_AT DESC');
+
+        $queryAll = $orderQuery->union($orderStandardQuery, true);
+        $query = (new Query())->from(['Q' => $queryAll])->select('Q.*')->distinct()->orderBy(['CREATED_AT' => SORT_DESC]);
+
+        $totalCount = $query->count();
+        $pagination = new Pagination(['totalCount' => $totalCount, 'pageSize' => \Yii::$app->request->get('pageSize')]);
+        $lists = $query->offset($pagination->offset)->limit($pagination->limit)->all();
+
+        $data = [
+            'list' => $lists,
+            'currentPage'=>$pagination->page,
+            'totalPages'=>$pagination->pageCount,
+            'startNum' => $pagination->page * $pagination->pageSize + 1,
+            'totalCount' => $pagination->totalCount,
+            'pageSize' => $pagination->pageSize,
+        ];
+
         foreach ($data['list'] as $key => $value) {
-            if($value['ORDER_TYPE']=='ZC'){
-                $data['list'][$key]['ORDER_TYPE'] = '首单';
-            }else{
-//                $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' ? '兑换点数' : '复消点数');
+            $data['list'][$key]['ORDER_TYPE'] = $value['ORDER_TYPE'] == 'ZC' ? '首单' : '复消';
+            $data['list'][$key]['PAY_AT'] = $value['PAY_AT'] ? Date::convert($value['PAY_AT'],'Y-m-d H:i:s') : '';
+            $data['list'][$key]['PAY_TYPE'] = ShopGoods::payTypes()[$value['PAY_TYPE']]['name'] ?? '';
+            $data['list'][$key]['STATUS'] = \Yii::$app->params['orderStatus'][$value['STATUS']]['label'] ?? '';
         }
-        return static::notice($data);
+
+        return $data;
     }
 
     /**
@@ -237,6 +307,242 @@ class ShopController extends BaseController {
                 return static::notice(Form::formatErrorsForApi($formModel->getErrors()),400);
             }
         }
+
+        return static::notice('无效请求');
     }
 
+    /**
+     * 确认订单
+     */
+    public function actionSureApproachOrder(){
+        if (\Yii::$app->request->isPost) {
+            $formModel = new ApproachOrderForm();
+            $formModel->scenario = 'userOrder';
+            $formModel->remark = '复销备注';
+            $post = \Yii::$app->request->post();
+            $post['type'] = DeclarationForm::TYPE_FX;
+            if ($formModel->load($post, '') && $order = $formModel->add()) {
+                return static::notice($order);
+            } else {
+                return static::notice(Form::formatErrorsForApi($formModel->getErrors()),400);
+            }
+        }
+
+        return static::notice('无效请求');
+    }
+
+    /**
+     * iPay88支付成功的webhook.
+     * @throws HttpException
+     * @throws \Exception
+     */
+    public function actionVerifyApproachOrder() {
+        // iPay88支付成功的webhook.
+        $rawPostData = file_get_contents('php://input');
+        LoggerTool::notice(['actionVerifyApproachOrder', $rawPostData]);
+        $data = [];
+        if (strlen($rawPostData) > 0) {
+            $rawPostArray = explode('&', $rawPostData);
+            foreach ($rawPostArray as $raw) {
+                $raw = explode('=', $raw);
+                if (count($raw) == 2)
+                    $data[$raw[0]] = urldecode($raw[1]);
+            }
+        }
+
+        // 支付webhook回调日志
+        Tool::approachOrderCall($data);
+
+        try {
+            // 订单状态
+            $orderStatus = ($data['Status'] == '1') ? \Yii::$app->params['orderStatus']['paid']['value'] : \Yii::$app->params['orderStatus']['failPaid']['value'];
+
+            $oderSn = $data['RefNo'] ?? '';
+
+            $formModel =  new ApproachOrderForm();
+            $formModel->scenario = 'verifyPay';
+            $load = [
+                'sn' => $oderSn,
+                'scenario' => 'verifyPay',
+                'status' => $orderStatus,
+                'note' => [
+                    'MerchantCode' => $data['MerchantCode'],
+                    'PaymentId' => $data['PaymentId'],
+                    'status' => $data['Status'],
+                    'Signature' => $data['Signature'],
+                    'Currency' => $data['Currency'],
+                    'Amount' => $data['Amount'],
+                    'TransId' => $data['TransId'],
+                    'TranDate' => $data['TranDate'],
+                    'BankMID' => $data['BankMID'],
+                    'CCNo' => $data['CCNo'],
+
+                ],
+            ];
+
+            if ($formModel->load($load, '') && $result = $formModel->verifyPayOnline()) {
+                LoggerTool::info($result);
+
+                return http_response_code(200);
+            } else {
+                LoggerTool::error(Form::formatErrorsForApi($formModel->getErrors()));
+                return http_response_code(500);
+            }
+        } catch (\Exception $e) {
+            LoggerTool::error(sprintf('actionVerifyApproachOrderError: File[%s], Line:[%s], Message[%s]', $e->getFile(), $e->getLine(), $e->getMessage()));
+            return http_response_code(500);
+        }
+    }
+
+    /**
+     * 删除准订单
+     */
+    public function actionDeleteApproachOrder()
+    {
+        $orderSn = \Yii::$app->request->post('orderSn');
+        // 删除订单中间表
+        ApproachOrder::deleteAll('SN = :SN', [':SN' => $orderSn]);
+        // 删除订单商品中间表
+        ApproachOrderGoods::deleteAll('ORDER_SN = :ORDER_SN', [':ORDER_SN' => $orderSn]);
+
+        return static::notice('');
+    }
+
+    /**
+     * iPay88支付
+     * @return mixed
+     * @throws HttpException
+     */
+    public function actionIPay88()
+    {
+        // 订单ID
+        $paymentParams['RefNo'] = \Yii::$app->request->post('RefNo');
+        // 订单金额,元=>分
+        $money = \Yii::$app->request->post('Amount');
+        // 马来币汇率
+        $exchangeRateMYR = floatval(Cache::getSystemConfig()['exchangeRateMYR']['VALUE'] ?? 0);
+        // 计算马来币
+//        $amount = number_format(round($money * $exchangeRateMYR), 2, '.', '');
+        $amount = number_format(1, 2, '.', ''); // TODO: 测试
+        $paymentParams['Amount'] = str_replace('.', '', $amount);
+        // (Optional) (int)
+        $paymentParams['PaymentId'] = '';   // 2=信用卡 182=银联
+        // Product description. (length 100)
+        $paymentParams['ProdDesc'] = 'Pay for sales';
+        // Customer name. (length 100)
+        $paymentParams['UserName'] = 'MY32';
+        $paymentParams['SignatureType'] = 'SHA256';
+        // Customer email.  (length 100)
+        $paymentParams['UserEmail'] = 'ek_dummy25@elken.com';
+        // Customer contact.  (length 20)
+        $paymentParams['UserContact'] = '60172249692';
+
+        // (Optional) Merchant remarks. (length 100)
+        //$paymentParams['Remark'] = 'Here is the description';
+        //merchantkey + merchantcode+ reference Number + amount in cent + currency_code
+        $paymentFields = \Yii::$app->iPay88->getPaymentFields($paymentParams, self::TRANSACTION_TYPE_PAYMENT);
+
+        $transactionUrl = \Yii::$app->iPay88->getTransactionUrl(self::TRANSACTION_TYPE_PAYMENT);
+        $paymentFields['Amount'] = $amount;
+        $res = [
+            'paymentFields' => $paymentFields,
+            'transactionUrl' => $transactionUrl,
+        ];
+
+        return static::notice($res);
+    }
+
+    /**
+     * 推送订单到wst仓储系统
+     * @throws HttpException
+     * @throws \Exception
+     */
+    public function actionLogistics()
+    {
+        $orderSn = \Yii::$app->request->get('sn');
+        $order = Order::find()
+            ->where('SN=:ORDER_SN', [':ORDER_SN' => $orderSn])
+            ->asArray()
+            ->one();
+
+        if (!$order) {
+            return static::notice('订单【' . $orderSn . '】不存在');
+        }
+        if ($order['SEND_AT'] > 0) {
+            return static::notice('订单【' . $orderSn . '】不可重复推送');
+        }
+
+        $logistics = new Logistics();
+        $response = $logistics->createOrder($order);
+        LoggerTool::info(['actionLogistics', $response]);
+        if ($response['success'] == 1) {
+            // 更新db中订单推送成功状态
+            if (Order::updateAll(['SEND_AT' => time()], 'SN=:SN', [':SN' => $orderSn])) {
+                return static::notice($response);
+            } else {
+                return static::notice($orderSn . ' 推送wst系统成功, 更新状态失败');
+            }
+        }
+
+        return static::notice($orderSn . ' 推送wst系统失败');
+    }
+
+    /**
+     * @throws HttpException
+     * @throws \Exception
+     */
+    public function actionLogisticsAuto()
+    {
+        $createdAtStart = strtotime('yesterday');
+        $createdAtEnd = strtotime(date('Y-m-d')) - 1;
+        // 早0点推送,前一天0-24点的订单
+        $orderList = Order::find()
+            ->where(
+                '(CREATED_AT BETWEEN :CREATED_AT_START AND :CREATED_AT_END) AND STATUS=:STATUS AND SEND_AT=:SEND_AT AND PAY_TYPE=:PAY_TYPE',
+                [
+                    ':CREATED_AT_START' => $createdAtStart,
+                    ':CREATED_AT_END' => $createdAtEnd,
+                    ':STATUS' => \Yii::$app->params['orderStatus']['paid']['value'],
+                    ':SEND_AT' => 0,
+                    'PAY_TYPE' => 'online',
+                ]
+            )
+            ->asArray()
+            ->all();
+
+        if (!$orderList) {
+            LoggerTool::info(['推送wst系统终止,原因:无订单', $createdAtStart, $createdAtEnd]);
+            return static::notice('推送wst系统终止,原因:无订单');
+        }
+
+        $orderSnSuccess = [];
+        $orderSnFailed = [];
+        $logistics = new Logistics();
+        foreach ($orderList as $order) {
+            // 发送wst仓库系统
+            $response = $logistics->createOrder($order);
+            LoggerTool::warning($response);
+            if ($response['success'] == 1) {
+                // 写入mongo
+                Tool::wstOrderCall($response['data']);
+                $orderSnSuccess[] = $order['SN'];
+            } else {
+                $orderSnFailed[] = $order['SN'];
+            }
+
+            $orderSnSuccess[] = $response;
+        }
+
+
+        // 更新db中订单推送成功状态
+        if (count($orderSnSuccess) > 0) {
+            Order::updateAll(['SEND_AT' => time()], 'SN IN (:SN)', [':SN' => implode("', '", $orderSnSuccess)]);
+        }
+        if (count($orderSnFailed) > 0) {
+            // 发送预警通知
+            LoggerTool::error(['自动推送wst失败', $orderSnFailed]);
+        }
+
+        return static::notice(sprintf('wstLogisticsAutoSend success order count{%d}, orderSN[%s]; failed count{%d}, orderSN[%s]', count($orderSnSuccess), implode(', ', $orderSnSuccess), count($orderSnFailed), implode(', ', $orderSnFailed)));
+    }
 }

+ 1 - 1
frontendEle/.gitignore

@@ -8,7 +8,7 @@ yarn-error.log*
 /test/e2e/reports/
 selenium-debug.log
 src/utils/config_development.js
-src/utils/config_production.js
+src/utils/config.js
 config/index.js
 package-lock.json
 

+ 12 - 0
frontendEle/src/router/index.js

@@ -90,6 +90,18 @@ export const constantRouterMap = [
                     ],
                 },
             },
+            {
+              path: '/shop/order-overseas',
+              component: _import('shop/order-overseas'),
+              name: 'order-overseas',
+              meta: {
+                title: '海外商品结算',
+                breadcrumb: [
+                  {title: '首页', path: '/dashboard/index'},
+                  {title: '商城管理', path: '/shop/dec-order-list'}
+                ],
+              },
+            },
             {
                 path: '/shop/goods-detail/:id',
                 component: _import('shop/goods-detail'),

+ 10 - 0
frontendEle/src/views/config/receive-address-edit.vue

@@ -34,6 +34,12 @@
           </template>
           <el-input v-model="form.address"></el-input>
         </el-form-item>
+        <el-form-item>
+          <template slot="label">
+            邮政编码
+          </template>
+          <el-input v-model="form.zipCode"></el-input>
+        </el-form-item>
         <el-form-item>
           <template slot="label">
             是否默认
@@ -73,6 +79,7 @@
           mobile: '',
           areaSelected: [],
           address: '',
+          zipCode: '',
           isDefault: false,
         },
         loading: true,
@@ -90,6 +97,7 @@
           city: this.form.areaSelected[1] ? this.form.areaSelected[1] : '',
           county: this.form.areaSelected[2] ? this.form.areaSelected[2] : '',
           address: this.form.address,
+          zipCode: this.form.zipCode,
           isDefault: this.form.isDefault,
         }
         if (this.$route.name === 'config_receive-address-edit'){
@@ -102,6 +110,7 @@
             city: this.form.areaSelected[1] ? this.form.areaSelected[1] : '',
             county: this.form.areaSelected[2] ? this.form.areaSelected[2] : '',
             address: this.form.address,
+            zipCode: this.form.zipCode,
             isDefault: this.form.isDefault,
           }
         }
@@ -128,6 +137,7 @@
           this.form.areaSelected[1] = response.CITY
           this.form.areaSelected[2] = response.COUNTY
           this.form.address = response.ADDRESS
+          this.form.zipCode = response.ZIP_CODE
           this.form.isDefault = response.IS_DEFAULT === '1' ? true : false
           this.loading = false
         })

+ 2 - 1
frontendEle/src/views/config/receive-address-list.vue

@@ -4,10 +4,11 @@
       <el-table class="table-box" ref="multipleTable" :data="tableData" stripe style="width: 100%;">
         <el-table-column label="收货人" prop="CONSIGNEE" width="150"></el-table-column>
         <el-table-column label="手机号码" prop="MOBILE" width="150"></el-table-column>
+        <el-table-column label="邮编" prop="ZIP_CODE" width="120"></el-table-column>
         <el-table-column label="省/市" prop="PROVINCE_NAME" width="150"></el-table-column>
         <el-table-column label="市/区" prop="CITY_NAME" width="150"></el-table-column>
         <el-table-column label="区/县" prop="COUNTY_NAME" width="150"></el-table-column>
-        <el-table-column label="详细地址" prop="ADDRESS" ></el-table-column>
+        <el-table-column label="详细地址" prop="ADDRESS"></el-table-column>
         <el-table-column label="是否默认" width="100">
           <template slot-scope="scope">
             {{scope.row.IS_DEFAULT === '1' ? '是' : '否'}}

+ 56 - 58
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() {
+    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)
+    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'
+      this.submitButtonStat = true
+      let path = 'finance/transfer-add'
 
-        network.getData('finance/mult-point').then(response => {
-            this.form.transferCode = response.transferCode
+      network.getData('finance/mult-point').then(response => {
+        this.form.transferCode = response.transferCode
 
-            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();
-                    }
-                }
-            })
+        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>

+ 47 - 10
frontendEle/src/views/shop/index.vue

@@ -16,6 +16,9 @@
 
                 </el-table-column>
 
+
+                <el-table-column label="商品来源" prop="CATE"></el-table-column>
+
                 <el-table-column label="图片" >
                      <template slot-scope="scope">
                         <el-image style="width: 100px; height: 100px" :src="tool.getLocaleLink(scope.row.COVER, '/files/')" :preview-src-list="[tool.getLocaleLink(scope.row.COVER, '/files/')]"></el-image>
@@ -45,12 +48,11 @@
 </template>
 
 <script>
-    import network from '@/utils/network'
-    import baseInfo from '@/utils/baseInfo'
-    import store from '@/utils/vuexStore'
-    import tool from '@/utils/tool'
-    import Pagination from '@/components/Pagination'
-    export default {
+import network from '@/utils/network'
+import tool from '@/utils/tool'
+import Pagination from '@/components/Pagination'
+
+export default {
         name: "index",
         components: {Pagination},
         mounted() {
@@ -74,6 +76,7 @@
                 is_go_order:true,
                 numList: [],
                 selectLock:false,
+                cate: [],
             }
         },
         watch: {
@@ -81,11 +84,26 @@
                 this.getData()
             }
         },
+        created() {
+          // network.getData('shop/logistics').then(response => {
+          //   console.log(response);
+          // }).catch(err => {
+          //   console.log(err);
+          // })
+        },
         methods: {
             handleChange(val){
                 console.log(val);
             },
             goToAccounts() {
+                if (this.cate.length > 1) {
+                  this.$message({
+                    message: '海内商品、海外商品只能选择一种',
+                    type: 'warning'
+                  })
+                  return false
+                }
+
                 this.is_go_order=true;
                 // this.multipleSelection.map((item,index)=>{
                 //     item.chose_num = parseInt(item.chose_num);
@@ -97,11 +115,10 @@
                 //         this.is_go_order=false
                 //     }
                 // });
-                console.log('this.multipleSelection',this.multipleSelection);
                 setTimeout(()=>{
                     if(this.is_go_order){
                         sessionStorage.setItem('order_goods',JSON.stringify(this.multipleSelection))
-                        this.$router.push({path: `/shop/order`})
+                        this.$router.push(this.cate[0] == '1' ? {path: `/shop/order`} : {path: `/shop/order-overseas`})
                     }
                 },0)
 
@@ -116,18 +133,38 @@
             handleSelectionChange(val) {
                 if( this.selectLock ) return;
                 let idx = -1,num;
+                this.cate = []
+                let cateList = []
                 for(let i in this.tableData){
                     for(let v in val){
                         if(val[v].ID==this.tableData[i].ID){
                             idx = i;
                             num = this.numList[idx];
                             val[v]["chose_num"] = num;
+                            cateList.push(val[v].CATE_ID)
                             break;
                         }
                     }
                 }
-                this.multipleSelection[this.currentPage] = val;
-                console.log(this.multipleSelection);
+
+                for (let i = 0; i < cateList.length; i++) {
+                    if (cateList.indexOf(cateList[i]) === i) {
+                       this.cate.push(cateList[i])
+                    }
+                }
+
+                if ((this.cate.length > 1)) {
+                    // 海内/海外商品只能选择一种
+                    if (this.cate.length > 1) {
+                        this.$message({
+                          message: '海内商品、海外商品只能选择一种',
+                          type: 'warning'
+                        })
+                        return false
+                    }
+                }
+
+                this.multipleSelection[this.currentPage] = val
             },
             handleInputNumber(val, row){
                 let pageList = this.multipleSelection[this.currentPage];

File diff suppressed because it is too large
+ 207 - 103
frontendEle/src/views/shop/order-list.vue


+ 462 - 0
frontendEle/src/views/shop/order-overseas.vue

@@ -0,0 +1,462 @@
+<template>
+    <div v-loading="loading">
+        <div class="white-box">
+            <div class="table">
+                <el-table
+                    :data="goods"
+                    style="width: 100%"
+                    show-summary
+                    :summary-method="getSummaries">
+                     <el-table-column label="商品名称" prop="GOODS_NAME">
+                    </el-table-column>
+
+                  <el-table-column label="图片" >
+                    <template slot-scope="scope">
+                      <el-image style="width: 100px; height: 100px" :src="tool.getLocaleLink(scope.row.COVER, '/files/')" :preview-src-list="[tool.getLocaleLink(scope.row.COVER, '/files/')]"></el-image>
+                    </template>
+                  </el-table-column>
+
+                    <el-table-column label="会员价格" prop="member_price">
+                    </el-table-column>
+                    <el-table-column label="会员PV" prop="member_pv">
+                    </el-table-column>
+                    <el-table-column label="数量" prop="chose_num">
+
+                    </el-table-column>
+                    <el-table-column label="合计金额" prop="member_price_plus">
+
+                    </el-table-column>
+                    <el-table-column label="合计PV" prop="member_pv_plus"></el-table-column>
+                </el-table>
+            </div>
+
+            <div class="box address_box">
+                <div style="min-width: 65px;">收件人:</div>
+                <div class="sum" style="margin-top: 5px; margin-bottom: 5px;">
+                  <div class="sum_box">
+                    <div style="min-width: 70px; font-size: 14px; margin-right: 0;">真实姓名<span style="color: red;">*</span></div>
+                    <div><el-input size="small" v-model="consigneeRealName" style="min-width: 150px;"></el-input></div>
+                  </div>
+                  <div class="sum_box" style="margin-top: 5px;">
+                    <div style="min-width: 70px; font-size: 14px; margin-right: 0;">身份证号<span style="color: red;">*</span></div>
+                    <div><el-input size="small" v-model="consigneeIdNo" style="min-width: 150px;"></el-input></div>
+                  </div>
+                </div>
+            </div>
+            <div class="address_box">
+                请选择收货地址:
+                <el-radio-group v-model="addressId" @change='choseAddress'>
+                    <div v-for="(item , index) in all_address" :key='index' class="address">
+                        <el-radio :label="item.ID" >
+                            {{item.PROVINCE_NAME}}省{{item.CITY_NAME}}市{{item.COUNTY_NAME}}县&nbsp;&nbsp;&nbsp;&nbsp;
+                            详细地址:{{item.ADDRESS}}
+                            邮编:{{item.ZIP_CODE}}
+                            手机号码:{{item.MOBILE}}
+                        </el-radio>
+                    </div>
+                </el-radio-group>
+            </div>
+            <div class="address_box">
+                请选择支付方式:
+                <el-radio-group v-model="payType" @change='chosePayType'>
+                    <div v-for="(item , index) in payList" :key='index' class="address">
+                        <el-radio :label="item.type" >
+                            {{item.name}}
+                        </el-radio>
+                    </div>
+                </el-radio-group>
+            </div>
+            <div class="box address_box">
+                合计:
+                <div class="sum">
+                    <div class="sum_box">
+                        <div>实付金额</div>
+                        <div>¥{{ cashSum }}元</div>
+                    </div>
+                </div>
+            </div>
+            <div>
+                <el-button @click="goToAccounts()" :loading="submitButtonStat">去结算</el-button>
+            </div>
+        </div>
+
+      <el-dialog title="支付" v-if="visible" :visible.sync="visible" width="450px" :before-close="handleClose">
+        <div class="app-container">
+          <div v-loading="loading" class="white-box">
+            <form method="post" name="ePayment" :action="actionUrl">
+              <input type="hidden" name="MerchantCode" v-bind:value="form.MerchantCode"></input>
+              <input type="hidden" name="PaymentId" v-bind:value="form.PaymentId"></input>
+              <input type="hidden" name="RefNo" v-bind:value="form.RefNo"></input>
+              <input type="hidden" name="Amount"  v-bind:value="form.Amount"></input>
+              <input type="hidden" name="Currency"  v-bind:value="form.Currency"></input>
+              <input type="hidden" name="ProdDesc"  v-bind:value="form.ProdDesc"></input>
+              <input type="hidden" name="UserName"  v-bind:value="form.UserName"></input>
+              <input type="hidden" name="UserEmail" v-bind:value="form.UserEmail"></input>
+              <input type="hidden" name="UserContact" v-bind:value="form.UserContact"></input>
+              <!-- <input type="hidden" name="Remark"  value="gfdfgd"></input> -->
+              <input type="hidden" name="Lang"  v-bind:value="form.Lang"></input>
+              <input type="hidden" name="SignatureType" value="SHA256"></input>
+              <input type="hidden" name="Signature" v-bind:value="form.Signature"></input>
+              <input type="hidden" name="ResponseURL" v-bind:value="form.ResponseURL"></input>
+              <input type="hidden" name="BackendURL" v-bind:value="form.BackendURL"></input>
+              <span style="display: inline-block; margin: 0 auto;">因汇率波动,实际支付金额可能会有浮动</span><br /><br />
+              <input type="submit" value="支 付" name="Submit" class="payBtn"></input>
+            </form>
+          </div>
+        </div>
+      </el-dialog>
+
+      <el-dialog title="支付成功" :visible.sync="payDialog" :show-close="false" width="320px" :close="handleOrderList">
+        <el-result icon="success" title="支付成功">
+          <template slot="extra">
+            <span style="color: #008efa; font-size: 30px;">{{ countdown }}</span>
+          </template>
+        </el-result>
+      </el-dialog>
+
+      <el-dialog title="提示" :visible.sync="IDCardDialog" width="350px">
+        <el-result icon="warning" title="">
+          <template slot="extra">
+            <span style="font-size: 15px;">购买跨境商品必须上传<span style="color: red;">收件人身份信息</span>,如已上传请忽略</span><br /><br />
+            <el-button type="primary" size="medium" @click="uploadIDCard">去上传</el-button>
+          </template>
+        </el-result>
+      </el-dialog>
+    </div>
+</template>
+
+<script>
+ import network from '@/utils/network'
+ import tool from '@/utils/tool'
+  export default{
+      name: 'order-overseas',
+      data() {
+          return {
+              loading: true,
+              tool: tool,
+              goods:[],
+              payList:[],
+              all_address:[],
+              balance:{},
+              addressId:'',
+              payType:'',
+              pointsSum:'',
+              cashSum:'',
+              freight:'',
+              pointFreight:'',
+              goodsId:'',
+              goodsNum:'',
+              payPassword:'',
+              submitButtonStat: false,
+              visible: false,
+              payLoading: false,
+              payDialog: false,
+              countdown: 5,
+              actionUrl: '',
+              ePaymentShow: false,
+              form: {
+                MerchantCode: '',
+                PaymentId: 2,
+                RefNo: '',
+                Amount: '',
+                Currency: '',
+                ProdDesc: '',
+                UserName: '',
+                UserEmail: '',
+                UserContact: '',
+                Remark: '',
+                Lang: 'UTF-8',
+                SignatureType: 'SHA256',
+                Signature: '',
+                ResponseURL: '',
+                BackendURL: '',
+              },
+              consigneeRealName: '',
+              consigneeIdNo: '',
+              IDCardDialog: false,
+              IDCardWebsite: 'http://t.taoplus.cc/Home/UploadIDCard',
+          }
+      },
+      created() {
+          this.getShowCart();
+          let option= sessionStorage.getItem('order_goods');
+          if(option){
+              let pageGoodsList = JSON.parse(option);
+              let pageList;
+              for( let i in pageGoodsList ) {
+                  pageList =  pageGoodsList[i];
+                  if (!pageList) continue;
+
+                  pageList.map((pageData, index)=>{
+                      if( Number(pageData.chose_num) > 0 ) {
+                        let discount = pageData.DISCOUNT / 100;
+                        pageData.member_price = Math.round(pageData.SELL_PRICE * discount * 100) / 100;
+                        pageData.member_price_plus = Math.round(pageData.SELL_PRICE * Number(pageData.chose_num) * discount * 100) / 100;
+
+                        pageData.member_pv = Math.round(pageData.PRICE_PV * discount * 100) / 100;
+                        pageData.member_pv_plus = Math.round(pageData.PRICE_PV * Number(pageData.chose_num) * discount * 100) / 100;
+
+                        this.goods.push(pageData)
+                      }
+                  })
+              }
+
+              this.getSumMoney();
+          }
+          // 展示上传身份证页面
+          this.IDCardDialog  = true
+      },
+      methods:{
+          getSummaries(param) {
+            const { columns, data } = param;
+            const sums = [];
+            columns.forEach((column, index) => {
+              if (index === 0) {
+                sums[index] = '合计';
+                return;
+              }
+              const values = data.map(item => Number(item[column.property]));
+              if ((!values.every(value => isNaN(value))) && [4, 5, 6].includes(index)) {
+                sums[index] = values.reduce((prev, curr) => {
+                  const value = Number(curr);
+                  if (!isNaN(value)) {
+                    return prev + curr;
+                  } else {
+                    return prev;
+                  }
+                }, 0);
+              }
+            });
+
+            return sums;
+          },
+          goToAccounts(){
+              // 海外商品收货地址中必须包含邮编
+              let address = ''
+              this.all_address.map(item => {
+                if (item.ID === this.addressId) {
+                  address = item
+                }
+              })
+              // if (address.ZIP_CODE.length < 1) {
+              //   this.$message({
+              //     message: '收货地址中没有邮政编码',
+              //     type: 'error'
+              //   })
+              //   return false
+              // }
+
+              // 必须填写真实姓名和身份证号码
+              if (((this.consigneeIdNo.trim()).length <= 0) || ((this.consigneeRealName.trim()).length <= 0)) {
+                  this.$message({
+                    message: '收件人真实姓名和身份证号码必须填写',
+                    type: 'error'
+                  })
+                  return false
+              }
+
+              this.submitButtonStat = true
+              const data = {
+                addressId: this.addressId,
+                payType: this.payType,
+                goodsId: this.goodsId,
+                goodsNum: this.goodsNum,
+                consigneeIdNo: this.consigneeIdNo,
+                consigneeRealName: this.consigneeRealName,
+              }
+              this.$confirm(`确定要购买商品吗?`, '提示', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                type: 'warning',
+                customClass: 'msgbox',
+              }).then(() => {
+                network.postData(`shop/sure-approach-order`, data).then(response => {
+                  this.submitButtonStat = false
+                  // 唤起支付页面
+                  network.postData(`shop/i-pay88`, { Amount: response.ORDER_AMOUNT, RefNo: response.SN }).then(payment => {
+                    this.actionUrl = payment.transactionUrl
+                    this.form = payment.paymentFields
+
+                    this.visible = true
+                    this.payLoading = false
+                  }).catch(err => {
+                    this.$message({
+                      message: err,
+                      type: 'error'
+                    })
+                    this.submitButtonStat = false
+                  })
+                })
+              }).catch(err => {
+                this.$message({
+                  message: err,
+                  type: 'error'
+                })
+                this.submitButtonStat = false
+              })
+          },
+          getSumMoney(){
+              let cash_plus_sum=[];
+              let goodsId=[];
+              let goodsNum=[];
+              let choseNum = 0;
+              this.goods.map((item,index)=>{
+                  choseNum = Number(item.chose_num);
+                  if( choseNum > 0 ) {
+                      cash_plus_sum.push(item.SELL_PRICE * choseNum*(item.DISCOUNT/100));
+                      goodsId.push(item.ID);
+                      goodsNum.push(choseNum);
+                  }
+              })
+              this.goodsNum=goodsNum;
+              this.goodsId=goodsId;
+              //增加运费03-12yuan
+              let payAmount = tool.sum(cash_plus_sum);
+              this.pointFreight = 0
+              // if(payAmount>=300){
+              //   this.pointFreight = this.freight = 0;
+              // }else{
+              //   this.pointFreight = this.freight = 15;
+              // }
+
+            this.pointsSum = this.cashSum = tool.formatPrice(tool.sum(cash_plus_sum) + this.freight) ;
+          },
+          getShowCart(){
+              network.getData('shop/show-cart')
+              .then(response=>{
+                  this.loading=false;
+                  this.all_address=response.allAddress;
+                  this.all_address.map((item,index)=>{
+                      if(item.IS_DEFAULT==1){
+                          this.addressId=item.ID
+                      }
+                  })
+                  // 如果没有默认收货地址,则第一个地址默认选中
+                  if (this.all_address.length > 0 && this.addressId.length < 1) {
+                      this.addressId = this.all_address[0].ID
+                  }
+
+                  for(let key in response.payList){
+                    // 如果是海外商品,则只有在线支付
+                    if (key === 'online') {
+                      this.payList.push({type:key, name:response.payList[key].name})
+                      break;
+                    }
+                  }
+
+                //默认设置为第一项付款方式
+                  this.payType=this.payList[0].type;
+              })
+          },
+          chosePayType(type){
+
+          },
+          choseAddress(addressId){
+          },
+          // 关闭支付回调
+          handleClose () {
+           let _this = this
+           _this.$confirm('确认关闭?').then(() => {
+             return network.postData('shop/delete-approach-order', {orderSn: this.form.RefNo}).then(() => {
+               // 关闭支付模态框
+               _this.visible = false
+               // 关闭购物车页面,返回到订单列表页
+               sessionStorage.setItem('order_goods', null)
+               this.$router.push({path: `/shop/index`})
+             })
+           }).catch(() => {
+             // 关闭支付模态框
+             _this.visible = false
+             // 关闭购物车页面,返回到订单列表页
+             sessionStorage.setItem('order_goods', null)
+             this.$router.push({path: `/shop/index`})
+           })
+          },
+          // 关闭支付回调
+          processClose () {
+           // 关闭支付模态框
+           this.visible = false
+           // 关闭购物车页面,返回到订单列表页
+           sessionStorage.removeItem('order_goods')
+           this.$router.push({path: `/shop/index`})
+          },
+          handleOrderList () {
+           this.$router.push({path: `/shop/order-list`})
+          },
+          // 启动倒计时
+          handleCountdown () {
+           // 创建定时器
+           setInterval(() => {
+             // 每隔1秒把time的值减一,赋值给span标签
+             this.countdown--
+             if (this.countdown === 0) {
+               // 倒计时结束,跳转到订单列表
+               this.$router.push({path: `/shop/order-list`})
+             }
+           }, 1000)
+          },
+          // 上传身份证
+          uploadIDCard() {
+            // window.location.href = this.IDCardWebsite
+            window.open(this.IDCardWebsite, '_blank')
+          },
+      }
+  }
+</script>
+<style scoped>
+.address{
+    /* height: 3rem; */
+    line-height: 3.5rem;
+
+}
+.address_box{
+     border-bottom: 1px solid #e3e3e3;
+}
+.sum{
+    display: inline-block;
+}
+.box{
+    margin: 1rem 0;
+    display: flex;
+    justify-content: flex-start;
+    align-items: center;
+    padding-bottom: 1rem;
+}
+.sum_box{
+    display: flex;
+    margin-left: 1rem;
+}
+.sum_box > div{
+    line-height: 2rem;
+}
+.sum_box > div:nth-child(1){
+    margin-right: 1rem;
+}
+.payBtn {
+  display: inline-block;
+  line-height: 1;
+  white-space: nowrap;
+  cursor: pointer;
+  text-align: center;
+  padding: 10px 10px;
+  font-size: 14px;
+  border-radius: 4px;
+  color: #fff;
+  background-color: #409eff;
+  border: 1px solid #DCDFE6;
+  -webkit-appearance: none;
+  box-sizing: border-box;
+  margin-left: 150px;
+}
+@media (max-width: 720px) {
+  .msgbox{
+    width: 320px !important;
+    margin-top: 15px;
+  }
+}
+</style>
+<style>
+.myclass {
+    width:260px;
+}
+</style>

+ 3 - 0
frontendEle/src/views/shop/order.vue

@@ -245,6 +245,9 @@
                         }
                     })
                     for(let key in response.payList){
+                        if (key === 'online') {
+                          continue
+                        }
                         this.payList.push({type:key,name:response.payList[key].name})
                     }
                     // console.log(this.payList)

+ 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>

+ 15 - 2
vendor/autoload.php

@@ -3,8 +3,21 @@
 // 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);
+    if (!headers_sent()) {
+        header('HTTP/1.1 500 Internal Server Error');
+    }
+    $err = '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;
+    if (!ini_get('display_errors')) {
+        if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
+            fwrite(STDERR, $err);
+        } elseif (!headers_sent()) {
+            echo $err;
+        }
+    }
+    trigger_error(
+        $err,
+        E_USER_ERROR
+    );
 }
 
 require_once __DIR__ . '/composer/autoload_real.php';

+ 27 - 14
vendor/composer/ClassLoader.php

@@ -42,6 +42,9 @@ namespace Composer\Autoload;
  */
 class ClassLoader
 {
+    /** @var \Closure(string):void */
+    private static $includeFile;
+
     /** @var ?string */
     private $vendorDir;
 
@@ -106,6 +109,7 @@ class ClassLoader
     public function __construct($vendorDir = null)
     {
         $this->vendorDir = $vendorDir;
+        self::initializeIncludeClosure();
     }
 
     /**
@@ -425,7 +429,8 @@ class ClassLoader
     public function loadClass($class)
     {
         if ($file = $this->findFile($class)) {
-            includeFile($file);
+            $includeFile = self::$includeFile;
+            $includeFile($file);
 
             return true;
         }
@@ -555,18 +560,26 @@ class ClassLoader
 
         return false;
     }
-}
 
-/**
- * Scope isolated include.
- *
- * Prevents access to $this/self from included files.
- *
- * @param  string $file
- * @return void
- * @private
- */
-function includeFile($file)
-{
-    include $file;
+    /**
+     * @return void
+     */
+    private static function initializeIncludeClosure()
+    {
+        if (self::$includeFile !== null) {
+            return;
+        }
+
+        /**
+         * Scope isolated include.
+         *
+         * Prevents access to $this/self from included files.
+         *
+         * @param  string $file
+         * @return void
+         */
+        self::$includeFile = \Closure::bind(static function($file) {
+            include $file;
+        }, null, null);
+    }
 }

+ 19 - 12
vendor/composer/InstalledVersions.php

@@ -28,7 +28,7 @@ class InstalledVersions
 {
     /**
      * @var mixed[]|null
-     * @psalm-var array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}|array{}|null
+     * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
      */
     private static $installed;
 
@@ -39,7 +39,7 @@ class InstalledVersions
 
     /**
      * @var array[]
-     * @psalm-var array<string, array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
+     * @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
      */
     private static $installedByVendor = array();
 
@@ -98,7 +98,7 @@ class InstalledVersions
     {
         foreach (self::getInstalled() as $installed) {
             if (isset($installed['versions'][$packageName])) {
-                return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
+                return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
             }
         }
 
@@ -119,7 +119,7 @@ class InstalledVersions
      */
     public static function satisfies(VersionParser $parser, $packageName, $constraint)
     {
-        $constraint = $parser->parseConstraints($constraint);
+        $constraint = $parser->parseConstraints((string) $constraint);
         $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
 
         return $provided->matches($constraint);
@@ -243,7 +243,7 @@ class InstalledVersions
 
     /**
      * @return array
-     * @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}
+     * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
      */
     public static function getRootPackage()
     {
@@ -257,7 +257,7 @@ class InstalledVersions
      *
      * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
      * @return array[]
-     * @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}
+     * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
      */
     public static function getRawData()
     {
@@ -280,7 +280,7 @@ class InstalledVersions
      * Returns the raw data of all installed.php which are currently loaded for custom implementations
      *
      * @return array[]
-     * @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
+     * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
      */
     public static function getAllRawData()
     {
@@ -303,7 +303,7 @@ class InstalledVersions
      * @param  array[] $data A vendor/composer/installed.php data set
      * @return void
      *
-     * @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} $data
+     * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
      */
     public static function reload($data)
     {
@@ -313,7 +313,7 @@ class InstalledVersions
 
     /**
      * @return array[]
-     * @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
+     * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
      */
     private static function getInstalled()
     {
@@ -328,7 +328,9 @@ class InstalledVersions
                 if (isset(self::$installedByVendor[$vendorDir])) {
                     $installed[] = self::$installedByVendor[$vendorDir];
                 } elseif (is_file($vendorDir.'/composer/installed.php')) {
-                    $installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
+                    /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
+                    $required = require $vendorDir.'/composer/installed.php';
+                    $installed[] = self::$installedByVendor[$vendorDir] = $required;
                     if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
                         self::$installed = $installed[count($installed) - 1];
                     }
@@ -340,12 +342,17 @@ class InstalledVersions
             // only require the installed.php file if this file is loaded from its dumped location,
             // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
             if (substr(__DIR__, -8, 1) !== 'C') {
-                self::$installed = require __DIR__ . '/installed.php';
+                /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
+                $required = require __DIR__ . '/installed.php';
+                self::$installed = $required;
             } else {
                 self::$installed = array();
             }
         }
-        $installed[] = self::$installed;
+
+        if (self::$installed !== array()) {
+            $installed[] = self::$installed;
+        }
 
         return $installed;
     }

+ 10 - 17
vendor/composer/autoload_real.php

@@ -33,25 +33,18 @@ class ComposerAutoloaderInitfefd691d76b71aadb785cf30e72d29ac
 
         $loader->register(true);
 
-        $includeFiles = \Composer\Autoload\ComposerStaticInitfefd691d76b71aadb785cf30e72d29ac::$files;
-        foreach ($includeFiles as $fileIdentifier => $file) {
-            composerRequirefefd691d76b71aadb785cf30e72d29ac($fileIdentifier, $file);
+        $filesToLoad = \Composer\Autoload\ComposerStaticInitfefd691d76b71aadb785cf30e72d29ac::$files;
+        $requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
+            if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
+                $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
+
+                require $file;
+            }
+        }, null, null);
+        foreach ($filesToLoad as $fileIdentifier => $file) {
+            $requireFile($fileIdentifier, $file);
         }
 
         return $loader;
     }
 }
-
-/**
- * @param string $fileIdentifier
- * @param string $file
- * @return void
- */
-function composerRequirefefd691d76b71aadb785cf30e72d29ac($fileIdentifier, $file)
-{
-    if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
-        $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
-
-        require $file;
-    }
-}

+ 0 - 170
vendor/composer/installed.json

@@ -1290,117 +1290,6 @@
             ],
             "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"
-                }
-            },
-            "installation-source": "dist",
-            "autoload": {
-                "psr-4": {
-                    "Monolog\\": "src/Monolog"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Jordi Boggiano",
-                    "email": "j.boggiano@seld.be",
-                    "homepage": "https://seld.be"
-                }
-            ],
-            "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://tidelift.com/funding/github/packagist/monolog/monolog",
-                    "type": "tidelift"
-                }
-            ],
-            "install-path": "../monolog/monolog"
-        },
         {
             "name": "myclabs/deep-copy",
             "version": "1.10.2",
@@ -2746,65 +2635,6 @@
             ],
             "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",

+ 94 - 113
vendor/composer/installed.php

@@ -1,238 +1,229 @@
 <?php return array(
     'root' => array(
+        'name' => 'yiisoft/yii2-app-advanced',
         'pretty_version' => 'dev-master',
         'version' => 'dev-master',
+        'reference' => '02daf6795915d2a73148ee9628c654cda25624ac',
         'type' => 'project',
         'install_path' => __DIR__ . '/../../',
         'aliases' => array(),
-        'reference' => '0f13189868b03eac76766e36a2c19c88fba38db2',
-        'name' => 'yiisoft/yii2-app-advanced',
         'dev' => true,
     ),
     'versions' => array(
         'anlity/yii2-swoole-async-timer' => array(
             'pretty_version' => '0.9.2',
             'version' => '0.9.2.0',
+            'reference' => '60bb70e0e34951d5aa46b89fa224f471f68e666d',
             'type' => 'yii2-extension',
             'install_path' => __DIR__ . '/../anlity/yii2-swoole-async-timer',
             'aliases' => array(),
-            'reference' => '60bb70e0e34951d5aa46b89fa224f471f68e666d',
             'dev_requirement' => false,
         ),
         'behat/gherkin' => array(
             'pretty_version' => 'v4.9.0',
             'version' => '4.9.0.0',
+            'reference' => '0bc8d1e30e96183e4f36db9dc79caead300beff4',
             'type' => 'library',
             'install_path' => __DIR__ . '/../behat/gherkin',
             'aliases' => array(),
-            'reference' => '0bc8d1e30e96183e4f36db9dc79caead300beff4',
             'dev_requirement' => true,
         ),
         'bower-asset/bootstrap' => array(
             'pretty_version' => 'v3.3.7',
             'version' => '3.3.7.0',
+            'reference' => '0b9c4a4007c44201dce9a6cc1a38407005c26c86',
             'type' => 'bower-asset',
             'install_path' => __DIR__ . '/../bower-asset/bootstrap',
             'aliases' => array(),
-            'reference' => '0b9c4a4007c44201dce9a6cc1a38407005c26c86',
             'dev_requirement' => false,
         ),
         'bower-asset/inputmask' => array(
             'pretty_version' => '3.3.11',
             'version' => '3.3.11.0',
+            'reference' => '5e670ad62f50c738388d4dcec78d2888505ad77b',
             'type' => 'bower-asset',
             'install_path' => __DIR__ . '/../bower-asset/inputmask',
             'aliases' => array(),
-            'reference' => '5e670ad62f50c738388d4dcec78d2888505ad77b',
             'dev_requirement' => false,
         ),
         'bower-asset/jquery' => array(
             'pretty_version' => '3.2.1',
             'version' => '3.2.1.0',
+            'reference' => '77d2a51d0520d2ee44173afdf4e40a9201f5964e',
             'type' => 'bower-asset',
             'install_path' => __DIR__ . '/../bower-asset/jquery',
             'aliases' => array(),
-            'reference' => '77d2a51d0520d2ee44173afdf4e40a9201f5964e',
             'dev_requirement' => false,
         ),
         'bower-asset/punycode' => array(
             'pretty_version' => 'v1.3.2',
             'version' => '1.3.2.0',
+            'reference' => '38c8d3131a82567bfef18da09f7f4db68c84f8a3',
             'type' => 'bower-asset',
             'install_path' => __DIR__ . '/../bower-asset/punycode',
             'aliases' => array(),
-            'reference' => '38c8d3131a82567bfef18da09f7f4db68c84f8a3',
             'dev_requirement' => false,
         ),
         'bower-asset/typeahead.js' => array(
             'pretty_version' => 'v0.11.1',
             'version' => '0.11.1.0',
+            'reference' => '588440f66559714280628a4f9799f0c4eb880a4a',
             'type' => 'bower-asset',
             'install_path' => __DIR__ . '/../bower-asset/typeahead.js',
             'aliases' => array(),
-            'reference' => '588440f66559714280628a4f9799f0c4eb880a4a',
             'dev_requirement' => true,
         ),
         'bower-asset/yii2-pjax' => array(
             'pretty_version' => '2.0.7.1',
             'version' => '2.0.7.1',
+            'reference' => 'aef7b953107264f00234902a3880eb50dafc48be',
             'type' => 'bower-asset',
             'install_path' => __DIR__ . '/../bower-asset/yii2-pjax',
             'aliases' => array(),
-            'reference' => 'aef7b953107264f00234902a3880eb50dafc48be',
             'dev_requirement' => false,
         ),
         'cebe/markdown' => array(
             'pretty_version' => '1.2.1',
             'version' => '1.2.1.0',
+            'reference' => '9bac5e971dd391e2802dca5400bbeacbaea9eb86',
             'type' => 'library',
             'install_path' => __DIR__ . '/../cebe/markdown',
             'aliases' => array(),
-            'reference' => '9bac5e971dd391e2802dca5400bbeacbaea9eb86',
             'dev_requirement' => false,
         ),
         'codeception/base' => array(
             'pretty_version' => '2.5.6',
             'version' => '2.5.6.0',
+            'reference' => 'aace5bab5593c93d8473b620f70754135a1eb4f0',
             'type' => 'library',
             'install_path' => __DIR__ . '/../codeception/base',
             'aliases' => array(),
-            'reference' => 'aace5bab5593c93d8473b620f70754135a1eb4f0',
             'dev_requirement' => true,
         ),
         'codeception/phpunit-wrapper' => array(
             'pretty_version' => '7.8.2',
             'version' => '7.8.2.0',
+            'reference' => 'cafed18048826790c527843f9b85e8cc79b866f1',
             'type' => 'library',
             'install_path' => __DIR__ . '/../codeception/phpunit-wrapper',
             'aliases' => array(),
-            'reference' => 'cafed18048826790c527843f9b85e8cc79b866f1',
             'dev_requirement' => true,
         ),
         'codeception/stub' => array(
             'pretty_version' => '2.1.0',
             'version' => '2.1.0.0',
+            'reference' => '853657f988942f7afb69becf3fd0059f192c705a',
             'type' => 'library',
             'install_path' => __DIR__ . '/../codeception/stub',
             'aliases' => array(),
-            'reference' => '853657f988942f7afb69becf3fd0059f192c705a',
             'dev_requirement' => true,
         ),
         'codeception/verify' => array(
             'pretty_version' => '0.3.3',
             'version' => '0.3.3.0',
+            'reference' => '5d649dda453cd814dadc4bb053060cd2c6bb4b4c',
             'type' => 'library',
             'install_path' => __DIR__ . '/../codeception/verify',
             'aliases' => array(),
-            'reference' => '5d649dda453cd814dadc4bb053060cd2c6bb4b4c',
             'dev_requirement' => true,
         ),
         'doctrine/instantiator' => array(
             'pretty_version' => '1.4.0',
             'version' => '1.4.0.0',
+            'reference' => 'd56bf6102915de5702778fe20f2de3b2fe570b5b',
             'type' => 'library',
             'install_path' => __DIR__ . '/../doctrine/instantiator',
             'aliases' => array(),
-            'reference' => 'd56bf6102915de5702778fe20f2de3b2fe570b5b',
             'dev_requirement' => true,
         ),
         'doctrine/lexer' => array(
             'pretty_version' => '1.2.1',
             'version' => '1.2.1.0',
+            'reference' => 'e864bbf5904cb8f5bb334f99209b48018522f042',
             'type' => 'library',
             'install_path' => __DIR__ . '/../doctrine/lexer',
             'aliases' => array(),
-            'reference' => 'e864bbf5904cb8f5bb334f99209b48018522f042',
             'dev_requirement' => false,
         ),
         'egulias/email-validator' => array(
             'pretty_version' => '3.1.2',
             'version' => '3.1.2.0',
+            'reference' => 'ee0db30118f661fb166bcffbf5d82032df484697',
             'type' => 'library',
             'install_path' => __DIR__ . '/../egulias/email-validator',
             'aliases' => array(),
-            'reference' => 'ee0db30118f661fb166bcffbf5d82032df484697',
             'dev_requirement' => false,
         ),
         'ezyang/htmlpurifier' => array(
             'pretty_version' => 'v4.13.0',
             'version' => '4.13.0.0',
+            'reference' => '08e27c97e4c6ed02f37c5b2b20488046c8d90d75',
             'type' => 'library',
             'install_path' => __DIR__ . '/../ezyang/htmlpurifier',
             'aliases' => array(),
-            'reference' => '08e27c97e4c6ed02f37c5b2b20488046c8d90d75',
             'dev_requirement' => false,
         ),
         'fakerphp/faker' => array(
             'pretty_version' => 'v1.17.0',
             'version' => '1.17.0.0',
+            'reference' => 'b85e9d44eae8c52cca7aa0939483611f7232b669',
             'type' => 'library',
             'install_path' => __DIR__ . '/../fakerphp/faker',
             'aliases' => array(),
-            'reference' => 'b85e9d44eae8c52cca7aa0939483611f7232b669',
             'dev_requirement' => true,
         ),
         'godruoyi/php-snowflake' => array(
             'pretty_version' => '1.1.1',
             'version' => '1.1.1.0',
+            'reference' => 'd8cbe72ed375b45033b7042e3d03340ce4fa479f',
             'type' => 'library',
             'install_path' => __DIR__ . '/../godruoyi/php-snowflake',
             'aliases' => array(),
-            'reference' => 'd8cbe72ed375b45033b7042e3d03340ce4fa479f',
             'dev_requirement' => false,
         ),
         'guzzlehttp/psr7' => array(
             'pretty_version' => '1.8.3',
             'version' => '1.8.3.0',
+            'reference' => '1afdd860a2566ed3c2b0b4a3de6e23434a79ec85',
             'type' => 'library',
             'install_path' => __DIR__ . '/../guzzlehttp/psr7',
             'aliases' => array(),
-            'reference' => '1afdd860a2566ed3c2b0b4a3de6e23434a79ec85',
             'dev_requirement' => true,
         ),
         'maennchen/zipstream-php' => array(
             'pretty_version' => '2.1.0',
             'version' => '2.1.0.0',
+            'reference' => 'c4c5803cc1f93df3d2448478ef79394a5981cc58',
             'type' => 'library',
             'install_path' => __DIR__ . '/../maennchen/zipstream-php',
             'aliases' => array(),
-            'reference' => 'c4c5803cc1f93df3d2448478ef79394a5981cc58',
             'dev_requirement' => false,
         ),
         'markbaker/complex' => array(
             'pretty_version' => '3.0.1',
             'version' => '3.0.1.0',
+            'reference' => 'ab8bc271e404909db09ff2d5ffa1e538085c0f22',
             'type' => 'library',
             'install_path' => __DIR__ . '/../markbaker/complex',
             'aliases' => array(),
-            'reference' => 'ab8bc271e404909db09ff2d5ffa1e538085c0f22',
             'dev_requirement' => false,
         ),
         'markbaker/matrix' => array(
             'pretty_version' => '3.0.0',
             'version' => '3.0.0.0',
-            'type' => 'library',
-            'install_path' => __DIR__ . '/../markbaker/matrix',
-            'aliases' => array(),
             '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',
+            'install_path' => __DIR__ . '/../markbaker/matrix',
             'aliases' => array(),
-            'reference' => '720488632c590286b88b80e62aa3d3d551ad4a50',
             'dev_requirement' => false,
         ),
         'myclabs/deep-copy' => array(
             'pretty_version' => '1.10.2',
             'version' => '1.10.2.0',
+            'reference' => '776f831124e9c62e1a2c601ecc52e776d8bb7220',
             'type' => 'library',
             'install_path' => __DIR__ . '/../myclabs/deep-copy',
             'aliases' => array(),
-            'reference' => '776f831124e9c62e1a2c601ecc52e776d8bb7220',
             'dev_requirement' => true,
             'replaced' => array(
                 0 => '1.10.2',
@@ -241,154 +232,154 @@
         'myclabs/php-enum' => array(
             'pretty_version' => '1.8.3',
             'version' => '1.8.3.0',
+            'reference' => 'b942d263c641ddb5190929ff840c68f78713e937',
             'type' => 'library',
             'install_path' => __DIR__ . '/../myclabs/php-enum',
             'aliases' => array(),
-            'reference' => 'b942d263c641ddb5190929ff840c68f78713e937',
             'dev_requirement' => false,
         ),
         'paragonie/random_compat' => array(
             'pretty_version' => 'v9.99.100',
             'version' => '9.99.100.0',
+            'reference' => '996434e5492cb4c3edcb9168db6fbb1359ef965a',
             'type' => 'library',
             'install_path' => __DIR__ . '/../paragonie/random_compat',
             'aliases' => array(),
-            'reference' => '996434e5492cb4c3edcb9168db6fbb1359ef965a',
             'dev_requirement' => false,
         ),
         'phar-io/manifest' => array(
             'pretty_version' => '1.0.3',
             'version' => '1.0.3.0',
+            'reference' => '7761fcacf03b4d4f16e7ccb606d4879ca431fcf4',
             'type' => 'library',
             'install_path' => __DIR__ . '/../phar-io/manifest',
             'aliases' => array(),
-            'reference' => '7761fcacf03b4d4f16e7ccb606d4879ca431fcf4',
             'dev_requirement' => true,
         ),
         'phar-io/version' => array(
             'pretty_version' => '2.0.1',
             'version' => '2.0.1.0',
+            'reference' => '45a2ec53a73c70ce41d55cedef9063630abaf1b6',
             'type' => 'library',
             'install_path' => __DIR__ . '/../phar-io/version',
             'aliases' => array(),
-            'reference' => '45a2ec53a73c70ce41d55cedef9063630abaf1b6',
             'dev_requirement' => true,
         ),
         'phpdocumentor/reflection-common' => array(
             'pretty_version' => '2.2.0',
             'version' => '2.2.0.0',
+            'reference' => '1d01c49d4ed62f25aa84a747ad35d5a16924662b',
             'type' => 'library',
             'install_path' => __DIR__ . '/../phpdocumentor/reflection-common',
             'aliases' => array(),
-            'reference' => '1d01c49d4ed62f25aa84a747ad35d5a16924662b',
             'dev_requirement' => true,
         ),
         'phpdocumentor/reflection-docblock' => array(
             'pretty_version' => '5.3.0',
             'version' => '5.3.0.0',
+            'reference' => '622548b623e81ca6d78b721c5e029f4ce664f170',
             'type' => 'library',
             'install_path' => __DIR__ . '/../phpdocumentor/reflection-docblock',
             'aliases' => array(),
-            'reference' => '622548b623e81ca6d78b721c5e029f4ce664f170',
             'dev_requirement' => true,
         ),
         'phpdocumentor/type-resolver' => array(
             'pretty_version' => '1.5.1',
             'version' => '1.5.1.0',
+            'reference' => 'a12f7e301eb7258bb68acd89d4aefa05c2906cae',
             'type' => 'library',
             'install_path' => __DIR__ . '/../phpdocumentor/type-resolver',
             'aliases' => array(),
-            'reference' => 'a12f7e301eb7258bb68acd89d4aefa05c2906cae',
             'dev_requirement' => true,
         ),
         'phpoffice/phpspreadsheet' => array(
             'pretty_version' => '1.20.0',
             'version' => '1.20.0.0',
+            'reference' => '44436f270bb134b4a94670f3d020a85dfa0a3c02',
             'type' => 'library',
             'install_path' => __DIR__ . '/../phpoffice/phpspreadsheet',
             'aliases' => array(),
-            'reference' => '44436f270bb134b4a94670f3d020a85dfa0a3c02',
             'dev_requirement' => false,
         ),
         'phpspec/php-diff' => array(
             'pretty_version' => 'v1.1.3',
             'version' => '1.1.3.0',
+            'reference' => 'fc1156187f9f6c8395886fe85ed88a0a245d72e9',
             'type' => 'library',
             'install_path' => __DIR__ . '/../phpspec/php-diff',
             'aliases' => array(),
-            'reference' => 'fc1156187f9f6c8395886fe85ed88a0a245d72e9',
             'dev_requirement' => true,
         ),
         'phpspec/prophecy' => array(
             'pretty_version' => 'v1.15.0',
             'version' => '1.15.0.0',
+            'reference' => 'bbcd7380b0ebf3961ee21409db7b38bc31d69a13',
             'type' => 'library',
             'install_path' => __DIR__ . '/../phpspec/prophecy',
             'aliases' => array(),
-            'reference' => 'bbcd7380b0ebf3961ee21409db7b38bc31d69a13',
             'dev_requirement' => true,
         ),
         'phpunit/php-code-coverage' => array(
             'pretty_version' => '6.1.4',
             'version' => '6.1.4.0',
+            'reference' => '807e6013b00af69b6c5d9ceb4282d0393dbb9d8d',
             'type' => 'library',
             'install_path' => __DIR__ . '/../phpunit/php-code-coverage',
             'aliases' => array(),
-            'reference' => '807e6013b00af69b6c5d9ceb4282d0393dbb9d8d',
             'dev_requirement' => true,
         ),
         'phpunit/php-file-iterator' => array(
             'pretty_version' => '2.0.5',
             'version' => '2.0.5.0',
+            'reference' => '42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5',
             'type' => 'library',
             'install_path' => __DIR__ . '/../phpunit/php-file-iterator',
             'aliases' => array(),
-            'reference' => '42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5',
             'dev_requirement' => true,
         ),
         'phpunit/php-text-template' => array(
             'pretty_version' => '1.2.1',
             'version' => '1.2.1.0',
+            'reference' => '31f8b717e51d9a2afca6c9f046f5d69fc27c8686',
             'type' => 'library',
             'install_path' => __DIR__ . '/../phpunit/php-text-template',
             'aliases' => array(),
-            'reference' => '31f8b717e51d9a2afca6c9f046f5d69fc27c8686',
             'dev_requirement' => true,
         ),
         'phpunit/php-timer' => array(
             'pretty_version' => '2.1.3',
             'version' => '2.1.3.0',
+            'reference' => '2454ae1765516d20c4ffe103d85a58a9a3bd5662',
             'type' => 'library',
             'install_path' => __DIR__ . '/../phpunit/php-timer',
             'aliases' => array(),
-            'reference' => '2454ae1765516d20c4ffe103d85a58a9a3bd5662',
             'dev_requirement' => true,
         ),
         'phpunit/php-token-stream' => array(
             'pretty_version' => '3.1.3',
             'version' => '3.1.3.0',
+            'reference' => '9c1da83261628cb24b6a6df371b6e312b3954768',
             'type' => 'library',
             'install_path' => __DIR__ . '/../phpunit/php-token-stream',
             'aliases' => array(),
-            'reference' => '9c1da83261628cb24b6a6df371b6e312b3954768',
             'dev_requirement' => true,
         ),
         'phpunit/phpunit' => array(
             'pretty_version' => '7.5.20',
             'version' => '7.5.20.0',
+            'reference' => '9467db479d1b0487c99733bb1e7944d32deded2c',
             'type' => 'library',
             'install_path' => __DIR__ . '/../phpunit/phpunit',
             'aliases' => array(),
-            'reference' => '9467db479d1b0487c99733bb1e7944d32deded2c',
             'dev_requirement' => true,
         ),
         'psr/container' => array(
             'pretty_version' => '1.1.2',
             'version' => '1.1.2.0',
+            'reference' => '513e0666f7216c7459170d56df27dfcefe1689ea',
             'type' => 'library',
             'install_path' => __DIR__ . '/../psr/container',
             'aliases' => array(),
-            'reference' => '513e0666f7216c7459170d56df27dfcefe1689ea',
             'dev_requirement' => true,
         ),
         'psr/event-dispatcher-implementation' => array(
@@ -400,28 +391,28 @@
         'psr/http-client' => array(
             'pretty_version' => '1.0.1',
             'version' => '1.0.1.0',
+            'reference' => '2dfb5f6c5eff0e91e20e913f8c5452ed95b86621',
             'type' => 'library',
             'install_path' => __DIR__ . '/../psr/http-client',
             'aliases' => array(),
-            'reference' => '2dfb5f6c5eff0e91e20e913f8c5452ed95b86621',
             'dev_requirement' => false,
         ),
         'psr/http-factory' => array(
             'pretty_version' => '1.0.1',
             'version' => '1.0.1.0',
+            'reference' => '12ac7fcd07e5b077433f5f2bee95b3a771bf61be',
             'type' => 'library',
             'install_path' => __DIR__ . '/../psr/http-factory',
             'aliases' => array(),
-            'reference' => '12ac7fcd07e5b077433f5f2bee95b3a771bf61be',
             'dev_requirement' => false,
         ),
         'psr/http-message' => array(
             'pretty_version' => '1.0.1',
             'version' => '1.0.1.0',
+            'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363',
             'type' => 'library',
             'install_path' => __DIR__ . '/../psr/http-message',
             'aliases' => array(),
-            'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363',
             'dev_requirement' => false,
         ),
         'psr/http-message-implementation' => array(
@@ -430,218 +421,208 @@
                 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' => false,
+            'dev_requirement' => true,
             'provided' => array(
-                0 => '1.0.0 || 2.0.0 || 3.0.0',
-                1 => '1.0|2.0',
+                0 => '1.0|2.0',
             ),
         ),
         'psr/simple-cache' => array(
             'pretty_version' => '1.0.1',
             'version' => '1.0.1.0',
+            'reference' => '408d5eafb83c57f6365a3ca330ff23aa4a5fa39b',
             'type' => 'library',
             'install_path' => __DIR__ . '/../psr/simple-cache',
             'aliases' => array(),
-            'reference' => '408d5eafb83c57f6365a3ca330ff23aa4a5fa39b',
             'dev_requirement' => false,
         ),
         'ralouphie/getallheaders' => array(
             'pretty_version' => '3.0.3',
             'version' => '3.0.3.0',
+            'reference' => '120b605dfeb996808c31b6477290a714d356e822',
             'type' => 'library',
             'install_path' => __DIR__ . '/../ralouphie/getallheaders',
             'aliases' => array(),
-            'reference' => '120b605dfeb996808c31b6477290a714d356e822',
             'dev_requirement' => true,
         ),
         'sebastian/code-unit-reverse-lookup' => array(
             'pretty_version' => '1.0.2',
             'version' => '1.0.2.0',
+            'reference' => '1de8cd5c010cb153fcd68b8d0f64606f523f7619',
             'type' => 'library',
             'install_path' => __DIR__ . '/../sebastian/code-unit-reverse-lookup',
             'aliases' => array(),
-            'reference' => '1de8cd5c010cb153fcd68b8d0f64606f523f7619',
             'dev_requirement' => true,
         ),
         'sebastian/comparator' => array(
             'pretty_version' => '3.0.3',
             'version' => '3.0.3.0',
+            'reference' => '1071dfcef776a57013124ff35e1fc41ccd294758',
             'type' => 'library',
             'install_path' => __DIR__ . '/../sebastian/comparator',
             'aliases' => array(),
-            'reference' => '1071dfcef776a57013124ff35e1fc41ccd294758',
             'dev_requirement' => true,
         ),
         'sebastian/diff' => array(
             'pretty_version' => '3.0.3',
             'version' => '3.0.3.0',
+            'reference' => '14f72dd46eaf2f2293cbe79c93cc0bc43161a211',
             'type' => 'library',
             'install_path' => __DIR__ . '/../sebastian/diff',
             'aliases' => array(),
-            'reference' => '14f72dd46eaf2f2293cbe79c93cc0bc43161a211',
             'dev_requirement' => true,
         ),
         'sebastian/environment' => array(
             'pretty_version' => '4.2.4',
             'version' => '4.2.4.0',
+            'reference' => 'd47bbbad83711771f167c72d4e3f25f7fcc1f8b0',
             'type' => 'library',
             'install_path' => __DIR__ . '/../sebastian/environment',
             'aliases' => array(),
-            'reference' => 'd47bbbad83711771f167c72d4e3f25f7fcc1f8b0',
             'dev_requirement' => true,
         ),
         'sebastian/exporter' => array(
             'pretty_version' => '3.1.4',
             'version' => '3.1.4.0',
+            'reference' => '0c32ea2e40dbf59de29f3b49bf375176ce7dd8db',
             'type' => 'library',
             'install_path' => __DIR__ . '/../sebastian/exporter',
             'aliases' => array(),
-            'reference' => '0c32ea2e40dbf59de29f3b49bf375176ce7dd8db',
             'dev_requirement' => true,
         ),
         'sebastian/global-state' => array(
             'pretty_version' => '2.0.0',
             'version' => '2.0.0.0',
+            'reference' => 'e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4',
             'type' => 'library',
             'install_path' => __DIR__ . '/../sebastian/global-state',
             'aliases' => array(),
-            'reference' => 'e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4',
             'dev_requirement' => true,
         ),
         'sebastian/object-enumerator' => array(
             'pretty_version' => '3.0.4',
             'version' => '3.0.4.0',
+            'reference' => 'e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2',
             'type' => 'library',
             'install_path' => __DIR__ . '/../sebastian/object-enumerator',
             'aliases' => array(),
-            'reference' => 'e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2',
             'dev_requirement' => true,
         ),
         'sebastian/object-reflector' => array(
             'pretty_version' => '1.1.2',
             'version' => '1.1.2.0',
+            'reference' => '9b8772b9cbd456ab45d4a598d2dd1a1bced6363d',
             'type' => 'library',
             'install_path' => __DIR__ . '/../sebastian/object-reflector',
             'aliases' => array(),
-            'reference' => '9b8772b9cbd456ab45d4a598d2dd1a1bced6363d',
             'dev_requirement' => true,
         ),
         'sebastian/recursion-context' => array(
             'pretty_version' => '3.0.1',
             'version' => '3.0.1.0',
+            'reference' => '367dcba38d6e1977be014dc4b22f47a484dac7fb',
             'type' => 'library',
             'install_path' => __DIR__ . '/../sebastian/recursion-context',
             'aliases' => array(),
-            'reference' => '367dcba38d6e1977be014dc4b22f47a484dac7fb',
             'dev_requirement' => true,
         ),
         'sebastian/resource-operations' => array(
             'pretty_version' => '2.0.2',
             'version' => '2.0.2.0',
+            'reference' => '31d35ca87926450c44eae7e2611d45a7a65ea8b3',
             'type' => 'library',
             'install_path' => __DIR__ . '/../sebastian/resource-operations',
             'aliases' => array(),
-            'reference' => '31d35ca87926450c44eae7e2611d45a7a65ea8b3',
             'dev_requirement' => true,
         ),
         'sebastian/version' => array(
             'pretty_version' => '2.0.1',
             'version' => '2.0.1.0',
+            'reference' => '99732be0ddb3361e16ad77b68ba41efc8e979019',
             'type' => 'library',
             'install_path' => __DIR__ . '/../sebastian/version',
             'aliases' => array(),
-            'reference' => '99732be0ddb3361e16ad77b68ba41efc8e979019',
             'dev_requirement' => true,
         ),
         'sunmoon/yii2-phpspreadsheet' => array(
             'pretty_version' => '1.2.0',
             'version' => '1.2.0.0',
+            'reference' => '51fc4d0183eb81e654b3360ac18e631fc4b89c09',
             'type' => 'library',
             'install_path' => __DIR__ . '/../sunmoon/yii2-phpspreadsheet',
             'aliases' => array(),
-            'reference' => '51fc4d0183eb81e654b3360ac18e631fc4b89c09',
             'dev_requirement' => false,
         ),
         'swiftmailer/swiftmailer' => array(
             'pretty_version' => 'v6.3.0',
             'version' => '6.3.0.0',
+            'reference' => '8a5d5072dca8f48460fce2f4131fcc495eec654c',
             'type' => 'library',
             'install_path' => __DIR__ . '/../swiftmailer/swiftmailer',
             'aliases' => array(),
-            'reference' => '8a5d5072dca8f48460fce2f4131fcc495eec654c',
             'dev_requirement' => false,
         ),
         'symfony/browser-kit' => array(
             'pretty_version' => 'v4.4.27',
             'version' => '4.4.27.0',
+            'reference' => '9629d1524d8ced5a4ec3e94abdbd638b4ec8319b',
             'type' => 'library',
             'install_path' => __DIR__ . '/../symfony/browser-kit',
             'aliases' => array(),
-            'reference' => '9629d1524d8ced5a4ec3e94abdbd638b4ec8319b',
             'dev_requirement' => true,
         ),
         'symfony/console' => array(
             'pretty_version' => 'v4.4.34',
             'version' => '4.4.34.0',
+            'reference' => '329b3a75cc6b16d435ba1b1a41df54a53382a3f0',
             'type' => 'library',
             'install_path' => __DIR__ . '/../symfony/console',
             'aliases' => array(),
-            'reference' => '329b3a75cc6b16d435ba1b1a41df54a53382a3f0',
             'dev_requirement' => true,
         ),
         'symfony/css-selector' => array(
             'pretty_version' => 'v4.4.27',
             'version' => '4.4.27.0',
+            'reference' => '5194f18bd80d106f11efa8f7cd0fbdcc3af96ce6',
             'type' => 'library',
             'install_path' => __DIR__ . '/../symfony/css-selector',
             'aliases' => array(),
-            'reference' => '5194f18bd80d106f11efa8f7cd0fbdcc3af96ce6',
             'dev_requirement' => true,
         ),
         'symfony/deprecation-contracts' => array(
             'pretty_version' => 'v2.5.0',
             'version' => '2.5.0.0',
+            'reference' => '6f981ee24cf69ee7ce9736146d1c57c2780598a8',
             'type' => 'library',
             'install_path' => __DIR__ . '/../symfony/deprecation-contracts',
             'aliases' => array(),
-            'reference' => '6f981ee24cf69ee7ce9736146d1c57c2780598a8',
             'dev_requirement' => true,
         ),
         'symfony/dom-crawler' => array(
             'pretty_version' => 'v4.4.30',
             'version' => '4.4.30.0',
+            'reference' => '4632ae3567746c7e915c33c67a2fb6ab746090c4',
             'type' => 'library',
             'install_path' => __DIR__ . '/../symfony/dom-crawler',
             'aliases' => array(),
-            'reference' => '4632ae3567746c7e915c33c67a2fb6ab746090c4',
             'dev_requirement' => true,
         ),
         'symfony/event-dispatcher' => array(
             'pretty_version' => 'v4.4.34',
             'version' => '4.4.34.0',
+            'reference' => '1a024b45369c9d55d76b6b8a241bd20c9ea1cbd8',
             'type' => 'library',
             'install_path' => __DIR__ . '/../symfony/event-dispatcher',
             'aliases' => array(),
-            'reference' => '1a024b45369c9d55d76b6b8a241bd20c9ea1cbd8',
             'dev_requirement' => true,
         ),
         'symfony/event-dispatcher-contracts' => array(
             'pretty_version' => 'v1.1.11',
             'version' => '1.1.11.0',
+            'reference' => '01e9a4efac0ee33a05dfdf93b346f62e7d0e998c',
             'type' => 'library',
             'install_path' => __DIR__ . '/../symfony/event-dispatcher-contracts',
             'aliases' => array(),
-            'reference' => '01e9a4efac0ee33a05dfdf93b346f62e7d0e998c',
             'dev_requirement' => true,
         ),
         'symfony/event-dispatcher-implementation' => array(
@@ -653,217 +634,217 @@
         'symfony/finder' => array(
             'pretty_version' => 'v4.4.30',
             'version' => '4.4.30.0',
+            'reference' => '70362f1e112280d75b30087c7598b837c1b468b6',
             'type' => 'library',
             'install_path' => __DIR__ . '/../symfony/finder',
             'aliases' => array(),
-            'reference' => '70362f1e112280d75b30087c7598b837c1b468b6',
             'dev_requirement' => true,
         ),
         'symfony/polyfill-ctype' => array(
             'pretty_version' => 'v1.23.0',
             'version' => '1.23.0.0',
+            'reference' => '46cd95797e9df938fdd2b03693b5fca5e64b01ce',
             'type' => 'library',
             'install_path' => __DIR__ . '/../symfony/polyfill-ctype',
             'aliases' => array(),
-            'reference' => '46cd95797e9df938fdd2b03693b5fca5e64b01ce',
             'dev_requirement' => true,
         ),
         'symfony/polyfill-iconv' => array(
             'pretty_version' => 'v1.23.0',
             'version' => '1.23.0.0',
+            'reference' => '63b5bb7db83e5673936d6e3b8b3e022ff6474933',
             'type' => 'library',
             'install_path' => __DIR__ . '/../symfony/polyfill-iconv',
             'aliases' => array(),
-            'reference' => '63b5bb7db83e5673936d6e3b8b3e022ff6474933',
             'dev_requirement' => false,
         ),
         'symfony/polyfill-intl-idn' => array(
             'pretty_version' => 'v1.23.0',
             'version' => '1.23.0.0',
+            'reference' => '65bd267525e82759e7d8c4e8ceea44f398838e65',
             'type' => 'library',
             'install_path' => __DIR__ . '/../symfony/polyfill-intl-idn',
             'aliases' => array(),
-            'reference' => '65bd267525e82759e7d8c4e8ceea44f398838e65',
             'dev_requirement' => false,
         ),
         'symfony/polyfill-intl-normalizer' => array(
             'pretty_version' => 'v1.23.0',
             'version' => '1.23.0.0',
+            'reference' => '8590a5f561694770bdcd3f9b5c69dde6945028e8',
             'type' => 'library',
             'install_path' => __DIR__ . '/../symfony/polyfill-intl-normalizer',
             'aliases' => array(),
-            'reference' => '8590a5f561694770bdcd3f9b5c69dde6945028e8',
             'dev_requirement' => false,
         ),
         'symfony/polyfill-mbstring' => array(
             'pretty_version' => 'v1.23.1',
             'version' => '1.23.1.0',
+            'reference' => '9174a3d80210dca8daa7f31fec659150bbeabfc6',
             'type' => 'library',
             'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
             'aliases' => array(),
-            'reference' => '9174a3d80210dca8daa7f31fec659150bbeabfc6',
             'dev_requirement' => false,
         ),
         'symfony/polyfill-php72' => array(
             'pretty_version' => 'v1.23.0',
             'version' => '1.23.0.0',
+            'reference' => '9a142215a36a3888e30d0a9eeea9766764e96976',
             'type' => 'library',
             'install_path' => __DIR__ . '/../symfony/polyfill-php72',
             'aliases' => array(),
-            'reference' => '9a142215a36a3888e30d0a9eeea9766764e96976',
             'dev_requirement' => false,
         ),
         'symfony/polyfill-php73' => array(
             'pretty_version' => 'v1.23.0',
             'version' => '1.23.0.0',
+            'reference' => 'fba8933c384d6476ab14fb7b8526e5287ca7e010',
             'type' => 'library',
             'install_path' => __DIR__ . '/../symfony/polyfill-php73',
             'aliases' => array(),
-            'reference' => 'fba8933c384d6476ab14fb7b8526e5287ca7e010',
             'dev_requirement' => true,
         ),
         'symfony/polyfill-php80' => array(
             'pretty_version' => 'v1.23.1',
             'version' => '1.23.1.0',
+            'reference' => '1100343ed1a92e3a38f9ae122fc0eb21602547be',
             'type' => 'library',
             'install_path' => __DIR__ . '/../symfony/polyfill-php80',
             'aliases' => array(),
-            'reference' => '1100343ed1a92e3a38f9ae122fc0eb21602547be',
             'dev_requirement' => true,
         ),
         'symfony/service-contracts' => array(
             'pretty_version' => 'v2.5.0',
             'version' => '2.5.0.0',
+            'reference' => '1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc',
             'type' => 'library',
             'install_path' => __DIR__ . '/../symfony/service-contracts',
             'aliases' => array(),
-            'reference' => '1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc',
             'dev_requirement' => true,
         ),
         'symfony/yaml' => array(
             'pretty_version' => 'v4.4.34',
             'version' => '4.4.34.0',
+            'reference' => '2c309e258adeb9970229042be39b360d34986fad',
             'type' => 'library',
             'install_path' => __DIR__ . '/../symfony/yaml',
             'aliases' => array(),
-            'reference' => '2c309e258adeb9970229042be39b360d34986fad',
             'dev_requirement' => true,
         ),
         'theseer/tokenizer' => array(
             'pretty_version' => '1.2.1',
             'version' => '1.2.1.0',
+            'reference' => '34a41e998c2183e22995f158c581e7b5e755ab9e',
             'type' => 'library',
             'install_path' => __DIR__ . '/../theseer/tokenizer',
             'aliases' => array(),
-            'reference' => '34a41e998c2183e22995f158c581e7b5e755ab9e',
             'dev_requirement' => true,
         ),
         'webmozart/assert' => array(
             'pretty_version' => '1.10.0',
             'version' => '1.10.0.0',
+            'reference' => '6964c76c7804814a842473e0c8fd15bab0f18e25',
             'type' => 'library',
             'install_path' => __DIR__ . '/../webmozart/assert',
             'aliases' => array(),
-            'reference' => '6964c76c7804814a842473e0c8fd15bab0f18e25',
             'dev_requirement' => true,
         ),
         'yiisoft/yii2' => array(
             'pretty_version' => '2.0.43',
             'version' => '2.0.43.0',
+            'reference' => 'f370955faa3067d9b27879aaf14b0978a805cd59',
             'type' => 'library',
             'install_path' => __DIR__ . '/../yiisoft/yii2',
             'aliases' => array(),
-            'reference' => 'f370955faa3067d9b27879aaf14b0978a805cd59',
             'dev_requirement' => false,
         ),
         'yiisoft/yii2-app-advanced' => array(
             'pretty_version' => 'dev-master',
             'version' => 'dev-master',
+            'reference' => '02daf6795915d2a73148ee9628c654cda25624ac',
             'type' => 'project',
             'install_path' => __DIR__ . '/../../',
             'aliases' => array(),
-            'reference' => '0f13189868b03eac76766e36a2c19c88fba38db2',
             'dev_requirement' => false,
         ),
         'yiisoft/yii2-bootstrap' => array(
             'pretty_version' => '2.0.11',
             'version' => '2.0.11.0',
+            'reference' => '83d144f4089adaa7064ad60dc4c1436daa2eb30e',
             'type' => 'yii2-extension',
             'install_path' => __DIR__ . '/../yiisoft/yii2-bootstrap',
             'aliases' => array(),
-            'reference' => '83d144f4089adaa7064ad60dc4c1436daa2eb30e',
             'dev_requirement' => false,
         ),
         'yiisoft/yii2-composer' => array(
             'pretty_version' => '2.0.10',
             'version' => '2.0.10.0',
+            'reference' => '94bb3f66e779e2774f8776d6e1bdeab402940510',
             'type' => 'composer-plugin',
             'install_path' => __DIR__ . '/../yiisoft/yii2-composer',
             'aliases' => array(),
-            'reference' => '94bb3f66e779e2774f8776d6e1bdeab402940510',
             'dev_requirement' => false,
         ),
         'yiisoft/yii2-debug' => array(
             'pretty_version' => '2.0.14',
             'version' => '2.0.14.0',
+            'reference' => 'dc5a4a8529de1a41dbb037dbabf1f3f93002f21d',
             'type' => 'yii2-extension',
             'install_path' => __DIR__ . '/../yiisoft/yii2-debug',
             'aliases' => array(),
-            'reference' => 'dc5a4a8529de1a41dbb037dbabf1f3f93002f21d',
             'dev_requirement' => true,
         ),
         'yiisoft/yii2-faker' => array(
             'pretty_version' => '2.0.5',
             'version' => '2.0.5.0',
+            'reference' => '8c361657143bfaea58ff7dcc9bf51f1991a46f5d',
             'type' => 'yii2-extension',
             'install_path' => __DIR__ . '/../yiisoft/yii2-faker',
             'aliases' => array(),
-            'reference' => '8c361657143bfaea58ff7dcc9bf51f1991a46f5d',
             'dev_requirement' => true,
         ),
         'yiisoft/yii2-gii' => array(
             'pretty_version' => '2.0.8',
             'version' => '2.0.8.0',
+            'reference' => 'c02adc552bcf3a0ef6f3694a9dcbf209f4885ab1',
             'type' => 'yii2-extension',
             'install_path' => __DIR__ . '/../yiisoft/yii2-gii',
             'aliases' => array(),
-            'reference' => 'c02adc552bcf3a0ef6f3694a9dcbf209f4885ab1',
             'dev_requirement' => true,
         ),
         'yiisoft/yii2-httpclient' => array(
             'pretty_version' => '2.0.14',
             'version' => '2.0.14.0',
+            'reference' => '50d670d2e1a30a354c27aeebf806a2db16954836',
             'type' => 'yii2-extension',
             'install_path' => __DIR__ . '/../yiisoft/yii2-httpclient',
             'aliases' => array(),
-            'reference' => '50d670d2e1a30a354c27aeebf806a2db16954836',
             'dev_requirement' => false,
         ),
         'yiisoft/yii2-mongodb' => array(
             'pretty_version' => '2.1.12',
             'version' => '2.1.12.0',
+            'reference' => '4a74369a2b233f2def02579766e1eceadb8964be',
             'type' => 'yii2-extension',
             'install_path' => __DIR__ . '/../yiisoft/yii2-mongodb',
             'aliases' => array(),
-            'reference' => '4a74369a2b233f2def02579766e1eceadb8964be',
             'dev_requirement' => false,
         ),
         'yiisoft/yii2-redis' => array(
             'pretty_version' => '2.0.16',
             'version' => '2.0.16.0',
+            'reference' => '1b9efe97d8add594256b51089fbf7a56f31e3c9c',
             'type' => 'yii2-extension',
             'install_path' => __DIR__ . '/../yiisoft/yii2-redis',
             'aliases' => array(),
-            'reference' => '1b9efe97d8add594256b51089fbf7a56f31e3c9c',
             'dev_requirement' => false,
         ),
         'yiisoft/yii2-swiftmailer' => array(
             'pretty_version' => '2.1.2',
             'version' => '2.1.2.0',
+            'reference' => '09659a55959f9e64b8178d842b64a9ffae42b994',
             'type' => 'yii2-extension',
             'install_path' => __DIR__ . '/../yiisoft/yii2-swiftmailer',
             'aliases' => array(),
-            'reference' => '09659a55959f9e64b8178d842b64a9ffae42b994',
             'dev_requirement' => false,
         ),
     ),

+ 6 - 6
vendor/yiisoft/yii2/web/ErrorHandler.php

@@ -150,7 +150,7 @@ class ErrorHandler extends \yii\base\ErrorHandler
             $exception = new HttpException(500, Yii::t('yii', 'An internal server error occurred.'));
         }
 
-        $errorOutline = ['AR_', 'PHP', 'Undefined', 'Undefined index', 'SQLSTATE', 'Trying to access array offset on value of type null'];
+        $errorOutline = ['AR_', 'PHP', 'Undefined', 'Undefined index', 'SQLSTATE', 'Trying to access array offset on value of type null', 'Call to a member function', '转账时发生错误'];
         foreach ($errorOutline as $item) {
             if (false !== strpos($exception->getMessage(), $item)) {
                 $it = [
@@ -163,14 +163,14 @@ class ErrorHandler extends \yii\base\ErrorHandler
                 }
                 if (YII_DEBUG) {
                     $it['type'] = get_class($exception);
-                    if (!$exception instanceof UserException) {
-                        $it['file'] = $exception->getFile();
-                        $it['line'] = $exception->getLine();
+//                    if (!$exception instanceof UserException) {
+                        $it['file'] = $exception->getFile() ?? '';
+                        $it['line'] = $exception->getLine() ?? '';
                         $it['stack-trace'] = explode("\n", $exception->getTraceAsString());
                         if ($exception instanceof \yii\db\Exception) {
-                            $it['error-info'] = $exception->errorInfo;
+                            $it['error-info'] = $exception->errorInfo ?? '';
                         }
-                    }
+//                    }
                 }
                 if (($prev = $exception->getPrevious()) !== null) {
                     $it['previous'] = $this->convertExceptionToArray($prev);

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