Просмотр исходного кода

会员、商品加入多国家机制

kevin 1 год назад
Родитель
Сommit
eacb9001bd
59 измененных файлов с 2297 добавлено и 798 удалено
  1. 6 15
      backendApi/config/menu.php
  2. 17 6
      backendApi/config/urlManagerRules.php
  3. 0 25
      backendApi/modules/v1/controllers/ConfigController.php
  4. 52 0
      backendApi/modules/v1/controllers/CurrencyController.php
  5. 0 390
      backendApi/modules/v1/controllers/DemoController.php
  6. 3 3
      backendApi/modules/v1/controllers/ShopController.php
  7. 43 0
      backendApi/modules/v1/controllers/TransportationController.php
  8. 82 12
      backendApi/modules/v1/controllers/UserController.php
  9. 28 28
      backendApi/modules/v1/models/lists/shop/GoodsList.php
  10. 99 0
      backendApi/modules/v1/models/lists/user/ImmigrantList.php
  11. 14 41
      backendApi/modules/v1/models/lists/user/IndexList.php
  12. 10 9
      common/config/main.php
  13. 2 0
      common/config/params.php
  14. 7 0
      common/enum/StatusEnum.php
  15. 23 0
      common/helpers/Cache.php
  16. 15 0
      common/helpers/Tool.php
  17. 6 3
      common/helpers/user/Balance.php
  18. 42 0
      common/helpers/user/Info.php
  19. 4 0
      common/messages/en-US/app.php
  20. 60 0
      common/messages/en-US/ctx.php
  21. 4 1
      common/messages/zh-CN/app.php
  22. 62 0
      common/messages/zh-CN/ctx.php
  23. 15 1
      common/models/ApproachOrder.php
  24. 108 0
      common/models/Countries.php
  25. 98 0
      common/models/Currency.php
  26. 154 0
      common/models/CurrencyConversions.php
  27. 112 0
      common/models/FreeTemplate.php
  28. 114 0
      common/models/Language.php
  29. 15 1
      common/models/Order.php
  30. 2 0
      common/models/ReceiveAddress.php
  31. 15 0
      common/models/Region.php
  32. 2 11
      common/models/ShopGoods.php
  33. 53 0
      common/models/ShopGoodsNature.php
  34. 9 3
      common/models/User.php
  35. 72 0
      common/models/UserImmigrant.php
  36. 8 2
      common/models/forms/AdminAddUserForm.php
  37. 39 8
      common/models/forms/ApproachDeclarationForm.php
  38. 7 0
      common/models/forms/ApproachDeclarationLoopForm.php
  39. 34 8
      common/models/forms/ApproachDeclarationUpgradeForm.php
  40. 32 11
      common/models/forms/ApproachOrderForm.php
  41. 0 44
      common/models/forms/ConfigForm.php
  42. 123 0
      common/models/forms/CurrenciesConversionsForm.php
  43. 54 14
      common/models/forms/DeclarationForm.php
  44. 8 0
      common/models/forms/DeclarationLoopForm.php
  45. 42 14
      common/models/forms/DeclarationUpgradeForm.php
  46. 100 0
      common/models/forms/FreeTemplateForm.php
  47. 166 0
      common/models/forms/ImmigrantForm.php
  48. 32 52
      common/models/forms/OrderForm.php
  49. 71 48
      common/models/forms/ShopGoodsForm.php
  50. 9 0
      common/models/forms/TransferForm.php
  51. 1 1
      console/controllers/ConfigController.php
  52. 25 0
      console/controllers/ToolController.php
  53. 3 0
      frontendApi/config/params.php
  54. 5 1
      frontendApi/config/urlManagerRules.php
  55. 24 2
      frontendApi/modules/v1/controllers/ConfigController.php
  56. 16 2
      frontendApi/modules/v1/controllers/FinanceController.php
  57. 50 33
      frontendApi/modules/v1/controllers/ShopController.php
  58. 26 0
      frontendApi/modules/v1/controllers/SiteController.php
  59. 74 9
      frontendApi/modules/v1/controllers/UserController.php

+ 6 - 15
backendApi/config/menu.php

@@ -148,6 +148,8 @@ return [
             //['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, 'wiki' => 'memberHighestEmpLevelAdjustment'],
             ['name'=>'修改会员最高聘级', 'class'=>'', 'icon'=>'', 'controller'=>'user', 'action'=>'change-user-dec-level', 'routePath'=>'user/change-highest-emp-level', 'show'=>0,],
+            ['name'=>'会员国家调整列表', 'class'=>'', 'icon'=>'', 'controller'=>'user', 'action'=>'immigrant-list', 'routePath'=>'user/immigrant-list', 'show'=>1, 'wiki' => 'memberCountryAdjustment'],
+            ['name'=>'会员国家调整', 'class'=>'', 'icon'=>'', 'controller'=>'user', 'action'=>'immigrant', 'routePath'=>'user/immigrant', 'show'=>0,],
         ]
     ],
     'atlas'=>[
@@ -398,20 +400,6 @@ return [
             ['name'=>'显示文章', 'class'=>'', 'icon'=>'', 'controller'=>'article', 'action'=>'article-un-hide', 'routePath'=>'article/article-un-hide', 'show'=>0,],
         ]
     ],
-//    'demo'=>[
-//        'name'=>'Demo Management',
-//        'class' => '',
-//        'icon'=>'el-icon-picture-outline',
-//        'controller'=>'demo',
-//        'action'=>'',
-//        'routePath'=>'demo',
-//        'show'=>1,
-//        'wiki' => 'demoManagement',
-//        'child'=>[
-//            ['name'=>'Demo Pay', 'class'=>'', 'icon'=>'', 'controller'=>'demo', 'action'=>'pay', 'routePath'=>'demo/pay', 'show'=>1, 'wiki' => 'demoPay'],
-//            ['name'=>'Demo Ipay', 'class'=>'', 'icon'=>'', 'controller'=>'demo', 'action'=>'ipay', 'routePath'=>'demo/ipay', 'show'=>1, 'wiki' => 'demoIpay'],
-//        ]
-//    ],
     'ad'=>[
         'name'=>'Ad Management',
         'class' => '',
@@ -532,7 +520,6 @@ return [
 //            ['name'=>'短信管理', 'class'=>'', 'icon'=>'', 'controller'=>'config', 'action'=>'sms', 'routePath'=>'config/sms', 'show'=>1,],
 //            ['name'=>'积分配置', 'class'=>'', 'icon'=>'', 'controller'=>'config', 'action'=>'score', 'routePath'=>'config/score', 'show'=>1, 'wiki' => 'scoreConfig'],
             ['name'=>'转账配置', 'class'=>'', 'icon'=>'', 'controller'=>'config', 'action'=>'transfer', 'routePath'=>'config/transfer', 'show'=>1, 'wiki' => 'transferConfig'],
-            ['name'=>'汇率配置', 'class'=>'', 'icon'=>'', 'controller'=>'config', 'action'=>'exchange-rate', 'routePath'=>'config/exchange-rate', 'show'=>1,  'wiki' => 'exchangeRateConfig'],
             ['name'=>'其他配置', 'class'=>'', 'icon'=>'', 'controller'=>'config', 'action'=>'other', 'routePath'=>'config/other', 'show'=>1, 'wiki' => 'otherConfig'],
             ['name'=>'会员级别配置', 'class'=>'', 'icon'=>'', 'controller'=>'config', 'action'=>'dec-level', 'routePath'=>'config/dec-level', 'show'=>1, 'wiki' => 'decLevelConfig'],
             ['name'=>'添加会员级别', 'class'=>'', 'icon'=>'', 'controller'=>'config', 'action'=>'dec-level-add', 'routePath'=>'config/dec-level-add', 'show'=>0,],
@@ -542,6 +529,10 @@ 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, 'wiki' => 'decRoleConfig'],
             ['name'=>'编辑报单中心级别', 'class'=>'', 'icon'=>'', 'controller'=>'config', 'action'=>'dec-role-edit', 'routePath'=>'config/dec-role-edit', 'show'=>0,],
+            ['name'=>'汇率列表', 'class'=>'', 'icon'=>'', 'controller'=>'currency', 'action'=>'currencies', 'routePath'=>'currency/currencies', 'show'=>1,  'wiki' => 'exchangeRateConfig'],
+            ['name'=>'汇率配置', 'class'=>'', 'icon'=>'', 'controller'=>'currency', 'action'=>'set-currency', 'routePath'=>'currency/set-currency', 'show'=>0],
+            ['name'=>'运费模板列表', 'class'=>'', 'icon'=>'', 'controller'=>'transportation', 'action'=>'transportation', 'routePath'=>'transportation/transportation-list', 'show'=>1,  'wiki' => 'transportationConfig'],
+            ['name'=>'运费模板设置', 'class'=>'', 'icon'=>'', 'controller'=>'transportation', 'action'=>'set-transportation', 'routePath'=>'transportation/set-transportation', 'show'=>0],
         ],
     ],
 ];

+ 17 - 6
backendApi/config/urlManagerRules.php

@@ -186,6 +186,8 @@ return [
             'POST ba-is-modify-password-status' => 'ba-is-modify-password-status',
             'GET change-highest-emp-level-list' => 'change-highest-emp-level-list',
             'POST change-highest-emp-level' => 'change-highest-emp-level',
+            'GET immigrant-list' => 'immigrant-list',
+            'POST,GET immigrant' => 'immigrant',
         ],
     ],
     [
@@ -317,7 +319,8 @@ return [
             'POST,GET sms' => 'sms',
             'POST,GET transfer' => 'transfer',
             'POST,GET score' => 'score',
-            'POST,GET exchange-rate' => 'exchange-rate',
+            'GET immigrant-list' => 'immigrant-list',
+            'POST,GET immigrant' => 'immigrant',
         ],
     ],
     [
@@ -592,12 +595,20 @@ return [
     [
         'class' => 'yii\rest\UrlRule',
         'pluralize' => false,
-        'controller' => 'v1/demo',
+        'controller' => 'v1/currency',
         'extraPatterns' => [
-            'POST pay' => 'pay',
-            'GET,POST payments' => 'payments',
-            'POST ipay' => 'ipay',
-            'GET,POST ipayments' => 'ipayments',
+            'GET currencies' => 'currencies',
+            'GET currency-conversions' => 'currency-conversions',
+            'POST set-currency-conversions' => 'set-currency-conversions',
+        ],
+    ],
+    [
+        'class' => 'yii\rest\UrlRule',
+        'pluralize' => false,
+        'controller' => 'v1/transportation',
+        'extraPatterns' => [
+            'GET transportation' => 'transportation',
+            'POST set-transportation' => 'set-transportation',
         ],
     ],
 ];

+ 0 - 25
backendApi/modules/v1/controllers/ConfigController.php

@@ -849,29 +849,4 @@ class ConfigController extends BaseController {
         file_put_contents($path, $content, LOCK_EX);
         return static::notice(Yii::t('ctx', 'successfully'));
     }
-
-    /**
-     * 汇率配置.
-     * @return mixed
-     * @throws \yii\db\Exception
-     * @throws \yii\web\HttpException
-     */
-    public function actionExchangeRate() {
-        $post = Yii::$app->request->post();
-        unset($post['synchronize']);
-
-        $form = new ConfigForm();
-        if (\Yii::$app->request->isPost && $form->load($post, '')) {
-            if ($form->updateExchangeRate()) {
-                Config::updateToCache();
-                return static::notice(Yii::t('ctx', 'successfully'));
-            } else {
-                return static::notice(Form::formatErrorsForApi($form->getErrors()), 422);
-            }
-        }
-
-        $oneData = Config::find()->where('CONFIG_NAME=:CONFIG_NAME', [':CONFIG_NAME' => 'exchangeRate'])->asArray()->one();
-        $oneData['TITLE'] = Yii::t('ctx', $oneData['LANGUAGE_KEY']);
-        return static::notice($oneData);
-    }
 }

+ 52 - 0
backendApi/modules/v1/controllers/CurrencyController.php

@@ -0,0 +1,52 @@
+<?php
+
+namespace backendApi\modules\v1\controllers;
+
+use common\helpers\Form;
+use common\models\Currency;
+use common\models\CurrencyConversions;
+use common\models\forms\CurrenciesConversionsForm;
+use yii\db\Exception;
+use yii\web\HttpException;
+
+class CurrencyController extends BaseController
+{
+    public $modelClass = Currency::class;
+
+    public $currencyConversionsModelClass = CurrencyConversions::class;
+
+    public function actionCurrencies()
+    {
+        $data = $this->modelClass::getFromCache();
+        return static::notice(['data' => $data]);
+    }
+
+    public function actionCurrenciesConversions()
+    {
+        $data = $this->currencyConversionsModelClass::getFromCache();
+        return static::notice(['data' => $data]);
+    }
+
+    /**
+     * @throws Exception
+     * @throws HttpException
+     */
+    public function actionSetCurrenciesConversions()
+    {
+        if (\Yii::$app->request->isPost) {
+            $formModel = new CurrenciesConversionsForm();
+            $formModel->scenario = 'setCurrenciesConversions';
+            if ($formModel->load(\Yii::$app->request->post(), '') && $formModel->setCurrenciesConversions()) {
+                // 更新缓存
+                $this->currencyConversionsModelClass::updateToCache();
+
+                return static::notice(\Yii::t('ctx', 'successfully'));
+            } else {
+                return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
+
+            }
+        }
+
+        return static::notice(\Yii::t('ctx', 'illegalRequest'));
+    }
+}

+ 0 - 390
backendApi/modules/v1/controllers/DemoController.php

@@ -1,390 +0,0 @@
-<?php
-/**
- * Created by PhpStorm.
- * User: leo
- * Date: 2018/2/24
- * Time: 下午12:48
- */
-namespace backendApi\modules\v1\controllers;
-
-use backendApi\modules\v1\models\Admin;
-use backendApi\modules\v1\models\lists\user\IndexList;
-use common\models\AdLocation;
-use common\models\FlowBonus;
-use common\models\User;
-
-class DemoController extends BaseController
-{
-
-    public $modelClass = User::class;
-
-    public function actions()
-    {
-        return parent::actions(); // TODO: Change the autogenerated stub
-    }
-
-    /**
-     * 支付demo
-     * @return mixed
-     * @throws \yii\web\HttpException
-     */
-    public function actionPay()
-    {
-        $money = \Yii::$app->request->post('money');
-
-        $data['vpc_Currency']    = 'VND';
-        $data['vpc_Version']     = 2;
-        $data['vpc_Command']     = 'pay';
-        $data['vpc_AccessCode']  = '6BEB2546';
-        $data['vpc_Merchant']    = 'TESTONEPAY';
-        $data['vpc_Locale']      = 'en';
-        $data['vpc_ReturnURL']   = 'http://16.163.228.151:8040/v1/demo/payments';
-        $data['vpc_MerchTxnRef'] = rand(10000, 99999);
-        $data['vpc_OrderInfo']   = '123456';
-        $data['vpc_Amount']      = $money*100;
-        $data['vpc_TicketNo']    = $_SERVER ['REMOTE_ADDR'];
-        $data['AgainLink']       = 'http://16.163.228.151:8040/v1/demo/payments';    //跳转回当前页面地址
-        $data['Title']           = 'pay';
-        ksort($data);
-        $url         = "https://mtf.onepay.vn/paygate/vpcpay.op?";
-        $md5HashData = '';
-        foreach ($data as $key => $value) {
-
-            $url .= urlencode($key) . '=' . urlencode($value) . '&';
-
-            if ((strlen($value) > 0) && ((substr($key, 0, 4) == "vpc_") || (substr($key, 0, 5) == "user_"))) {
-                $md5HashData .= $key . "=" . $value . "&";
-            }
-        }
-        $SECURE_SECRET = "6D0870CDE5F24F34F3915FB0045120DB";
-        $md5HashData   = rtrim($md5HashData, "&");
-
-        $url     .= "vpc_SecureHash=" . strtoupper(hash_hmac('SHA256', $md5HashData, pack('H*', $SECURE_SECRET)));
-//        $listObj = new IndexList();
-//        $res     = $listObj->curl_get($url);
-//        print_r($res);
-//        die;
-        return static::notice($url);
-    }
-
-
-    public function actionPayments($vpc_MerchTxnRef){
-        file_put_contents('./text.txt',$vpc_MerchTxnRef);
-        $params = array(
-            'vpc_Version' => '1',
-            'vpc_Command' => 'queryDR',
-            'vpc_MerchTxnRef' => $vpc_MerchTxnRef,
-            'vpc_User' => 'op01',
-            'vpc_Password' => 'op123456',
-        );
-
-        //if($this->gateway === 'Inland'){
-        $vpcURL = 'https://mtf.onepay.vn/onecomm-pay/Vpcdps.op';
-        $params['vpc_AccessCode'] = '6BEB2546';
-        $params['vpc_Merchant'] = 'TESTONEPAY';
-//        }else
-//        {
-//            $vpcURL = 'https://mtf.onepay.vn/vpcpay/Vpcdps.op';
-//            $params['vpc_AccessCode'] = '6BEB2546';
-//            $params['vpc_Merchant'] = 'TESTONEPAY';
-//        }
-
-        $postData = "";
-        $ampersand = "";
-
-        foreach ($params as $key => $value) {
-            if (strlen($value) > 0) {
-                $postData .= $ampersand . urlencode($key) . '=' . urlencode($value);
-                $ampersand = "&";
-            }
-        }
-
-        ob_start();
-
-        $ch = curl_init();
-
-        curl_setopt($ch, CURLOPT_URL, $vpcURL);
-        curl_setopt($ch, CURLOPT_POST, 1);
-        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
-
-        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
-
-
-        curl_exec($ch);
-
-        $response = ob_get_contents();
-
-
-        ob_end_clean();
-
-        $message = "";
-
-        if (strchr($response, "<html>") || strchr($response, "<html>")) {
-            $message = $response;
-        } else {
-
-            if (curl_error($ch))
-                $message = "%s: s" . curl_errno($ch) . "<br/>" . curl_error($ch);
-        }
-
-
-        curl_close($ch);
-
-        $map = array();
-
-        if (strlen($message) == 0) {
-            $pairArray = explode("&", $response);
-            foreach ($pairArray as $pair) {
-                $param = explode("=", $pair);
-                $map[urldecode($param[0])] = urldecode($param[1]);
-            }
-            $message = $this->null2unknown($map, "vpc_Message");
-        }
-
-        $amount = $this->null2unknown($map, "vpc_Amount");
-        $locale = $this->null2unknown($map, "vpc_Locale");
-        $batchNo = $this->null2unknown($map, "vpc_BatchNo");
-        $command = $this->null2unknown($map, "vpc_Command");
-        $version = $this->null2unknown($map, "vpc_Version");
-        $cardType = $this->null2unknown($map, "vpc_Card");
-        $orderInfo = $this->null2unknown($map, "vpc_OrderInfo");
-        $receiptNo = $this->null2unknown($map, "vpc_ReceiptNo");
-        $merchantID = $this->null2unknown($map, "vpc_Merchant");
-        $authorizeID = $this->null2unknown($map, "vpc_AuthorizeId");
-        $transactionNo = $this->null2unknown($map, "vpc_TransactionNo");
-        $acqResponseCode = $this->null2unknown($map, "vpc_AcqResponseCode");
-        $txnResponseCode = $this->null2unknown($map, "vpc_TxnResponseCode");
-
-        $drExists = $this->null2unknown($map, "vpc_DRExists");
-        $multipleDRs = $this->null2unknown($map, "vpc_FoundMultipleDRs");
-
-        $verType = $this->null2unknown($map, "vpc_VerType");
-        $verStatus = $this->null2unknown($map, "vpc_VerStatus");
-        $token = $this->null2unknown($map, "vpc_VerToken");
-        $verSecurLevel = $this->null2unknown($map, "vpc_VerSecurityLevel");
-        $enrolled = $this->null2unknown($map, "vpc_3DSenrolled");
-        $xid = $this->null2unknown($map, "vpc_3DSXID");
-        $acqECI = $this->null2unknown($map, "vpc_3DSECI");
-        $authStatus = $this->null2unknown($map, "vpc_3DSstatus");
-
-        $shopTransNo = $this->null2unknown($map, "vpc_ShopTransactionNo");
-        $authorisedAmount = $this->null2unknown($map, "vpc_AuthorisedAmount");
-        $capturedAmount = $this->null2unknown($map, "vpc_CapturedAmount");
-        $refundedAmount = $this->null2unknown($map, "vpc_RefundedAmount");
-        $ticketNumber = $this->null2unknown($map, "vpc_TicketNo");
-
-        $errorTxt = "";
-        if ($txnResponseCode == "7" || $txnResponseCode == "No Value Returned") {
-            $errorTxt = "Error";
-        }
-
-        $transStatus = "";
-        if ($txnResponseCode == "0") {
-            $transStatus = "Giao dịch thành công";
-        } elseif ($txnResponseCode != "0") {
-            $transStatus = "Giao dịch thất bại";
-        }
-
-
-        $result = array(
-            'OnePay'	=> array(
-                'errorTxt'          => $errorTxt,
-                'resCode'			=> $txnResponseCode,
-                'resDescription'	=> $this->getResponseDescription($txnResponseCode)
-            )
-        );
-
-        return json_encode($result);
-    }
-
-    private function getResponseDescription($responseCode)
-    {
-        switch ($responseCode) {
-            case "0" :
-                $result = "Transaction Successful";
-                break;
-            case "?" :
-                $result = "Transaction status is unknown";
-                break;
-            case "1" :
-                $result = "Bank system reject";
-                break;
-            case "2" :
-                $result = "Bank Declined Transaction";
-                break;
-            case "3" :
-                $result = "No Reply from Bank";
-                break;
-            case "4" :
-                $result = "Expired Card";
-                break;
-            case "5" :
-                $result = "Insufficient funds";
-                break;
-            case "6" :
-                $result = "Error Communicating with Bank";
-                break;
-            case "7" :
-                $result = "Payment Server System Error";
-                break;
-            case "8" :
-                $result = "Transaction Type Not Supported";
-                break;
-            case "9" :
-                $result = "Bank declined transaction (Do not contact Bank)";
-                break;
-            case "A" :
-                $result = "Transaction Aborted";
-                break;
-            case "C" :
-                $result = "Transaction Cancelled";
-                break;
-            case "D" :
-                $result = "Deferred transaction has been received and is awaiting processing";
-                break;
-            case "F" :
-                $result = "3D Secure Authentication failed";
-                break;
-            case "I" :
-                $result = "Card Security Code verification failed";
-                break;
-            case "L" :
-                $result = "Shopping Transaction Locked (Please try the transaction again later)";
-                break;
-            case "N" :
-                $result = "Cardholder is not enrolled in Authentication scheme";
-                break;
-            case "P" :
-                $result = "Transaction has been received by the Payment Adaptor and is being processed";
-                break;
-            case "R" :
-                $result = "Transaction was not processed - Reached limit of retry attempts allowed";
-                break;
-            case "S" :
-                $result = "Duplicate SessionID (OrderInfo)";
-                break;
-            case "T" :
-                $result = "Address Verification Failed";
-                break;
-            case "U" :
-                $result = "Card Security Code Failed";
-                break;
-            case "V" :
-                $result = "Address Verification and Card Security Code Failed";
-                break;
-            default  :
-                $result = "Unable to be determined";
-        }
-        return $result;
-    }
-
-    private function null2unknown($map, $key)
-    {
-        if (array_key_exists($key, $map)) {
-            if (!is_null($map[$key])) {
-                return $map[$key];
-            }
-        }
-        return "No Value Returned";
-    }
-
-    public function actionIpay(){
-        $data = array(
-            'ApiVersion' => '2.0',
-            'MerchantCode' => 'ID00001',
-            'PaymentId' => '71',
-            'Currency' => 'IDR',
-            'RefNo' => 'A00000001',
-            'Amount' => '3000',
-            'ProdDesc' => 'test',
-            'UserName' => 'Thoriq',
-            'UserEmail' => 'thoriq@ipay88.co.id',
-            'UserContact' => '08123123123',
-            'Lang' => 'UTF-8',
-            'ResponseURL' => 'http://16.163.228.151:8040/v1/demo/ipayments',
-            'BackendURL' => 'http://16.163.228.151:8040/v1/demo/ipay',
-            'ItemTransactions' => array(
-                "Id" => "00001",
-                "Name" => "Smartphone Wireless Charger",
-                "Quantity" => "1",
-                "Amount" =>  "3000",
-                "ParentType" => "SELLER",
-                "ParentId" => "SELLER123",
-            ),
-            'ShippingAddress' => array(
-                "FirstName" =>  "Techsupp",
-                "LastName" => "Alpha",
-                "Address" =>  "Jl. Test BlokRNo.1",
-                "City" => "Jakarta",
-                "State" => "DKI Jakarta",
-                "PostalCode" => "18800",
-                "Phone" => "08123456789",
-                "CountryCode" => "1",
-            ),
-            'BillingAddress' => array(
-                "FirstName" => 'test',
-                "LastName" => "test",
-                "Address" => "test",
-                "City" => "test",
-                "State" => "test",
-                "PostalCode" => "11480",
-                "Phone" => "08788888888",
-                "CountryCode" => "2222",
-            ),
-            'Sellers' => array(
-                "Id" => "SELLER123",
-                "Name" => "Sellername",
-                "LegalId" => "3274011001900001",
-                "SellerIdNumber" => null,
-                "Email" => "sellername@gmail.com",
-                "Url" => "www.sunrise.com",
-                "address" => array(
-                    "FirstName" => 'test',
-                    "LastName" => "test",
-                    "Address" => "test",
-                    "City" => "test",
-                    "State" => "test",
-                    "PostalCode" => "11480",
-                    "Phone" => "08788888888",
-                    "CountryCode" => "2222",
-                ),
-            ),
-            "SettingField" => array(
-                "Name" => 'TenorInstallment',
-                "Value" => '3',
-            ),
-        );
-        $MerchantKey = 'apple';
-        $url = "https://sandbox.ipay88.co.id/ePayment/WebService/PaymentAPI/Checkout";
-        $str = "||" . $MerchantKey . "||" . $data['MerchantCode'] . "||" . $data['RefNo'] . "||" . $data['Amount'] . "||" . $data['Currency'] . "||";
-        $data['Signature'] = hash('sha256', $str);
-        $res = $this->curl_post($url,json_encode($data));
-        print_r($res);die;
-        //return static::notice($res);
-    }
-
-
-    private function curl_post($url,$param){
-        if (empty($url) || empty($param)) {
-            return false;
-        }
-
-        $postUrl = $url;
-        $curlPost = $param;
-        $ch = curl_init();//初始化curl
-        curl_setopt($ch, CURLOPT_URL,$postUrl);//抓取指定网页
-        curl_setopt($ch, CURLOPT_HEADER, 0);//设置header
-        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//要求结果为字符串且输出到屏幕上
-        curl_setopt($ch, CURLOPT_POST, 1);//post提交方式
-        curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
-        $data = curl_exec($ch);//运行curl
-        curl_close($ch);
-        print_r($data);die;
-        return $data;
-    }
-
-    public function actionIpayments(){
-        $data = file_get_contents('php://input');
-        file_put_contents('./text1.txt',$data);
-    }
-}

+ 3 - 3
backendApi/modules/v1/controllers/ShopController.php

@@ -123,8 +123,8 @@ class ShopController extends BaseController {
         return static::notice([
             'sellType' => ShopGoods::getSaleType(),
             'goodsType' => ShopGoods::getGoodType(),
-            'giftType' => ShopGoods::getGiftType(),//ShopGoods::GIFT_TYPE,
-            'categoryType' => ShopGoods::getCategoryType(),//ShopGoods::CATEGORY_TYPE,
+            'giftType' => ShopGoods::getGiftType(),
+            'categoryType' => ShopGoods::getCategoryType(),
         ]);
     }
 
@@ -253,7 +253,7 @@ class ShopController extends BaseController {
                 // Log::adminHandle('添加报单套餐', 1);
             });
         }
-        return static::notice('非请求', 405);
+        return static::notice('非请求', 405);
     }
 
     /**

+ 43 - 0
backendApi/modules/v1/controllers/TransportationController.php

@@ -0,0 +1,43 @@
+<?php
+
+namespace backendApi\modules\v1\controllers;
+
+use common\helpers\Form;
+use common\models\Currency;
+use common\models\CurrencyConversions;
+use common\models\forms\CurrenciesConversionsForm;
+use common\models\forms\FreeTemplateForm;
+use common\models\FreeTemplate;
+use yii\db\Exception;
+use yii\web\HttpException;
+
+class TransportationController extends BaseController
+{
+    public $modelClass = FreeTemplate::class;
+
+    public function actionTransportationList()
+    {
+        $data = $this->modelClass::getFromCache();
+
+        return static::notice(['data' => $data]);
+    }
+
+    public function actionSetTransportation()
+    {
+        if (\Yii::$app->request->isPost) {
+            $formModel = new FreeTemplateForm();
+            $formModel->scenario = 'setTransportation';
+            if ($formModel->load(\Yii::$app->request->post(), '') && $formModel->setTransportation()) {
+                // 更新缓存
+                $this->modelClass::updateToCache();
+
+                return static::notice(\Yii::t('ctx', 'successfully'));
+            } else {
+                return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
+
+            }
+        }
+
+        return static::notice(\Yii::t('ctx', 'illegalRequest'));
+    }
+}

+ 82 - 12
backendApi/modules/v1/controllers/UserController.php

@@ -35,6 +35,8 @@ use common\helpers\user\Info;
 use common\helpers\user\Status;
 use common\models\BaUser;
 use common\models\CompanyBank;
+use common\models\Countries;
+use common\models\CurrencyConversions;
 use common\models\FlowBonus;
 use common\models\forms\AdminAddUserForm;
 use common\models\forms\BaUserBasicForm;
@@ -44,6 +46,7 @@ use common\models\forms\CloseLoginForm;
 use common\models\forms\DecLevelLogForm;
 use common\models\forms\DecRoleLogForm;
 use common\models\forms\HighestEmpLevelLogForm;
+use common\models\forms\ImmigrantForm;
 use common\models\forms\NetMoveForm;
 use common\models\forms\RechargeForm;
 use common\models\forms\ReconsumeForm;
@@ -59,10 +62,12 @@ use common\models\forms\UserStatusForm;
 use common\models\forms\UserSystemForm;
 use common\models\forms\UserTeamworkForm;
 use common\models\forms\UserTransferPropForm;
+use common\models\Instalment;
 use common\models\Period;
 use common\models\ReconsumeAudit;
 use common\models\ReconsumePool;
 use common\models\RegInfoAudit;
+use common\models\Region;
 use common\models\RegType;
 use common\models\DecOrder;
 use common\models\DecRole;
@@ -70,6 +75,7 @@ use common\models\EmployLevel;
 use common\models\OpenBank;
 use common\models\UserBind;
 use common\models\UserClose;
+use common\models\UserImmigrant;
 use common\models\UserMove;
 use common\models\UserNetwork;
 use common\models\UserRelation;
@@ -114,6 +120,7 @@ class UserController extends BaseController
             'CREATED_AT' => 'U.CREATED_AT',
             'PERIOD_AT' => 'U.PERIOD_AT',
             'DEC_LV_NAME' => 'U.DEC_LV',
+            'COUNTRY_NAME' => 'U.COUNTRY_ID',
             'DEC_LV_UPDATED_AT' => 'U.DEC_LV_UPDATED_AT',
             'LAST_DEC_LV_NAME' => 'U.LAST_DEC_LV',
             'EMP_LV_NAME' => 'U.EMP_LV',
@@ -146,12 +153,8 @@ class UserController extends BaseController
                 'BIND' => ['PROVINCE', 'CITY', 'COUNTY'],
             ],
             'ADDRESS' => 'U.ADDRESS',
-//            'IS_AUTO_WITHDRAW' => 'UI.IS_AUTO_WITHDRAW',
             'VERIFIED' => 'U.VERIFIED',
             'VERIFIED_AT' => 'U.VERIFIED_AT',
-//            'IS_DIRECT_SELLER' => 'U.IS_DIRECT_SELLER',
-//            'IS_SYSTEM_LEADER' => 'UI.IS_SYSTEM_LEADER',
-//            'IS_GROUP_LEADER' => 'UI.IS_GROUP_LEADER',
             'ALLOW_TRANSFER' => 'UI.ALLOW_TRANSFER',
         ]);
         $condition = $filter['condition'];
@@ -1084,16 +1087,29 @@ class UserController extends BaseController
                 // Log::adminHandle('后台添加会员:' . $result['USER_NAME'], 1, $result['ID'], $result['USER_NAME']);
             });
         }
+
+        $countryId = \Yii::$app->request->get('countryId');
+
         // 获取所有报单中心级别
         $allDecRole = DecRole::getAllData();
         // 所有民族
         $allNation = Yii::$app->params['nation'];
-        // 所有开户行
-        $allOpenBank = OpenBank::findAllAsArray('STATUS=1');
-        if (!$userName = Info::generateUserName('NG')) {
+        // 行政区划
+        $regions = Region::getByCountryId($countryId);
+        // 银行开户行
+        $allOpenBank = OpenBank::findAllAsArray('STATUS=:STATUS AND COUNTRY_ID=:COUNTRY_ID', [':STATUS' => 1, ':COUNTRY_ID' => $countryId]);
+        // 生成用户名
+        if (!$userName = Info::generateWebName($countryId)) {
             return static::notice('Failed to generate member number', 400);//会员编号生成失败
         }
-        return static::notice(['allDecRole' => $allDecRole, 'allNation' => $allNation, 'allOpenBank' => $allOpenBank, 'userName' => $userName]);
+        return static::notice(
+            [
+                'allDecRole' => $allDecRole,
+                'allNation' => $allNation,
+                'allOpenBank' => $allOpenBank,
+                'userName' => $userName,
+                'region' => $regions,
+            ]);
     }
 
     /**
@@ -1149,10 +1165,11 @@ class UserController extends BaseController
         if (!$userInfo) {
             return static::notice('Data does not exist', 400);//数据不存在
         }
-        $allNation = \Yii::$app->params['nation'];
-        $allOpenBank = OpenBank::findAllAsArray('STATUS=1');
-        $data['allNation'] = $allNation;
-        $data['allOpenBank'] = $allOpenBank;
+
+        $data['allNation'] = \Yii::$app->params['nation'];
+        $data['allOpenBank'] = OpenBank::findAllAsArray('STATUS=1 AND COUNTRY_ID=:COUNTRY_ID', [':COUNTRY_ID' => $userInfo['COUNTRY_ID']]);
+        $data['region'] = Region::getByCountryId($userInfo['COUNTRY_ID']);
+
         $data['userInfo'] = [
             'userId' => $userInfo['ID'],
             'nation' => \Yii::$app->params['nation'][$userInfo['NATION']]['name']??'',
@@ -2408,4 +2425,57 @@ class UserController extends BaseController
         }
         return static::notice('无效请求', 400);
     }
+
+    /**
+     * 移民记录.
+     * @return mixed
+     * @throws \yii\base\Exception
+     * @throws \yii\web\HttpException
+     */
+    public function actionImmigrantList()
+    {
+        $filter = $this->filterCondition([
+            'USER_NAME' => 'CU.USER_NAME',
+            'CREATED_AT' => 'UU.CREATED_AT',
+            'ADMIN_NAME' => 'ADM.ADMIN_NAME',
+        ]);
+        $condition = $filter['condition'];
+        $params = $filter['params'];
+        $listObj = new UserImmigrant();
+        $data = $listObj->getList(['condition' => $condition, 'params' => $params]);
+
+        return static::notice($data);
+    }
+
+    /**
+     * 移民.
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionImmigrant()
+    {
+        // 移民条件检查
+        if (Yii::$app->request->isGet) {
+            // 会员
+            $userId = Info::getUserIdByUserName(Yii::$app->request->get('userName'));
+            // 1.是否有进行中的分期订单
+            $instalmentOrder = Instalment::findOne(['USER_ID' => $userId]);
+            // 订单分期总期数配置
+            if ($instalmentOrder) {
+                // 分期的总期数
+                $instalment = intval(Cache::getSystemConfig()['instalment']['VALUE'] ?? 3);
+                // 分期商品的期数不能大于总分期数限制
+                if (intval($instalmentOrder['STAGE']) < $instalment) {
+                    return static::notice(Yii::t('app', 'instalmentOrderInProcess'), 400);
+                }
+            }
+        }
+
+        // 移民
+        if (Yii::$app->request->isPost) {
+            return parent::edit(ImmigrantForm::class, Yii::t('ctx', 'successfully'), 'userImmigrant', ['userImmigrant'], null, function ($form, $result) {});
+        }
+
+        return static::notice(Yii::t('app', 'illegalRequest'), 400);
+    }
 }

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

@@ -138,34 +138,34 @@ class GoodsList extends \common\libs\dataList\DataList implements DataListInterf
                         ];
                     },
                 ],
-                'TAX_RATE' => [
-                    'header' => \Yii::t('ctx', 'shopListTaxRate'), // 税率
-                    'headerOther' => [
-                        'width' => '150',
-                    ],
-                    'value' => function ($row) {
-                        return Tool::formatPrice($row['TAX_RATE']);
-                    },
-                    'valueOther' => function ($row) {
-                        return [
-                            'tag' => ['type' => 'danger', 'size' => 'small', 'class' => 'no-border']
-                        ];
-                    },
-                ],
-                'TAX' => [
-                    'header' => \Yii::t('ctx', 'shopListTax'), // 税额
-                    'headerOther' => [
-                        'width' => '150',
-                    ],
-                    'value' => function ($row) {
-                        return Tool::formatPrice($row['SELL_PRICE'] - $row['SELL_PRICE'] / (1 + $row['TAX_RATE'] / 100));
-                    },
-                    'valueOther' => function ($row) {
-                        return [
-                            'tag' => ['type' => 'danger', 'size' => 'small', 'class' => 'no-border']
-                        ];
-                    },
-                ],
+//                'TAX_RATE' => [
+//                    'header' => \Yii::t('ctx', 'shopListTaxRate'), // 税率
+//                    'headerOther' => [
+//                        'width' => '150',
+//                    ],
+//                    'value' => function ($row) {
+//                        return Tool::formatPrice($row['TAX_RATE']);
+//                    },
+//                    'valueOther' => function ($row) {
+//                        return [
+//                            'tag' => ['type' => 'danger', 'size' => 'small', 'class' => 'no-border']
+//                        ];
+//                    },
+//                ],
+//                'TAX' => [
+//                    'header' => \Yii::t('ctx', 'shopListTax'), // 税额
+//                    'headerOther' => [
+//                        'width' => '150',
+//                    ],
+//                    'value' => function ($row) {
+//                        return Tool::formatPrice($row['SELL_PRICE'] - $row['SELL_PRICE'] / (1 + $row['TAX_RATE'] / 100));
+//                    },
+//                    'valueOther' => function ($row) {
+//                        return [
+//                            'tag' => ['type' => 'danger', 'size' => 'small', 'class' => 'no-border']
+//                        ];
+//                    },
+//                ],
                 'STORE_NUMS' => [
                     'header' => \Yii::t('ctx', 'shopListInventory'), // 库存
                     'headerOther' => [

+ 99 - 0
backendApi/modules/v1/models/lists/user/ImmigrantList.php

@@ -0,0 +1,99 @@
+<?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\Countries;
+use common\models\HighestEmpLevelLog;
+use common\models\User;
+use common\libs\dataList\column\DateTime;
+use common\models\UserImmigrant;
+use Yii;
+
+class ImmigrantList extends \common\libs\dataList\DataList implements DataListInterface
+{
+    /**
+     * 列表名称
+     * @return string
+     */
+    public function getListName(){
+        return '会员移民列表';
+    }
+
+    /**
+     * 列表筛选到的数据
+     */
+    public function dataHandle()
+    {
+        $this->listData = UserImmigrant::lists($this->condition, $this->params, [
+            'select' => 'UI.*, CU.USER_NAME, ADM.ADMIN_NAME, BC.NAME AS before_country, AC.NAME AS after_country',
+            'orderBy' => 'UI.CREATED_AT DESC, UI.id DESC',
+            'from' => UserImmigrant::tableName() . ' AS UI',
+            'join' => [
+                ['INNER JOIN', Admin::tableName() . ' AS ADM', 'UI.created_by=ADM.ID'],
+                ['INNER JOIN', User::tableName() . ' AS CU', 'UI.user_id=CU.ID'],
+                ['INNER JOIN', Countries::tableName() . ' AS BC', 'UI.before_country_id=CU.ID'],
+                ['INNER JOIN', Countries::tableName() . ' AS AC', 'UI.after_country_id=CU.ID'],
+            ],
+            'page' => $this->page,
+            'pageSize' => $this->pageSize,
+        ]);
+    }
+
+    /**
+     * 要展示和导出的所有字段
+     * @return array
+     */
+    public function getColumn() {
+        if (!$this->columns) {
+            $this->columns = [
+                'id' => null,
+                'user_id' => null,
+                'USER_NAME' => [
+                    'header' => Yii::t('ctx', 'memberCode'),
+                ],
+                'before_country' => [
+                    'header' => Yii::t('ctx', 'beforeCountry'),
+                    'valueOther' => [
+                        'tag'=>['type'=>'warning', 'size' => 'small', 'class'=>'no-border']
+                    ],
+                ],
+                'after_country' => [
+                    'header' => Yii::t('ctx', 'afterCountry'),
+                    'valueOther' => [
+                        'tag'=>['type'=>'warning', 'size' => 'small', 'class'=>'no-border']
+                    ],
+                ],
+                'ADMIN_NAME' => [
+                    'header' => Yii::t('ctx', 'operationAdministrator'),
+                ],
+                'CREATED_AT' => [
+                    'header' => Yii::t('ctx', 'createAt'),
+                    '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'=> Yii::t('ctx', 'memberCode')],
+                'CREATED_AT' => ['isUserTable' => false, 'name' => Yii::t('ctx', 'createAt'), 'other' => 'date'],
+                'ADMIN_NAME' => ['isUserTable' => false, 'name' => Yii::t('ctx', 'operationAdministrator')],
+            ];
+        }
+        return $this->filterTypes;
+    }
+}

+ 14 - 41
backendApi/modules/v1/models/lists/user/IndexList.php

@@ -5,8 +5,10 @@ use common\helpers\Cache;
 use common\helpers\http\BackendToFrontendApi;
 use common\helpers\user\Info;
 use common\libs\dataList\DataListInterface;
+use common\models\Countries;
 use common\models\DecRole;
 use common\models\EmployLevel;
+use common\models\Language;
 use common\models\OpenBank;
 use common\models\Region;
 use common\models\StarCrownLevel;
@@ -46,7 +48,9 @@ class IndexList extends \common\libs\dataList\DataList implements DataListInterf
                 UI.LAST_LOGIN_AT, UI.SHOW_EMP_LV,UN.RELATIVE_LOCATION,
                 CU.USER_NAME CON_USER_NAME,CU.REAL_NAME CON_REAL_NAME,
                 RU.USER_NAME REC_USER_NAME,RU.REAL_NAME REC_REAL_NAME,
-                DU.USER_NAME DEC_USER_NAME
+                DU.USER_NAME DEC_USER_NAME,
+                CS.NAME COUNTRY_NAME,
+                LG.NAME LANGUAGE_NAME
                 ',
             'orderBy' => 'UI.CREATED_AT DESC, UI.ID DESC',
             'from' => User::tableName() . ' AS U',
@@ -56,6 +60,8 @@ class IndexList extends \common\libs\dataList\DataList implements DataListInterf
                 ['LEFT JOIN', User::tableName() . ' AS CU', 'UI.CON_UID=CU.ID'],
                 ['LEFT JOIN', User::tableName() . ' AS RU', 'UI.REC_UID=RU.ID'],
                 ['LEFT JOIN', User::tableName() . ' AS DU', 'U.DEC_ID=DU.ID'],
+                ['LEFT JOIN', Countries::tableName() . ' AS CS', 'U.COUNTRY_ID=CS.ID'],
+                ['LEFT JOIN', Language::tableName() . ' AS LG', 'U.LANGUAGE_ID=LG.ID'],
             ],
             'page' => $this->page,
             'pageSize' => $this->pageSize,
@@ -119,12 +125,12 @@ class IndexList extends \common\libs\dataList\DataList implements DataListInterf
                     },
                     'headerOther' => ['width' => '110'],
                 ],
-                'ALLOW_LOGIN' => [
-                    'header' => Yii::t('ctx', 'filterAllowLogin'),
-                    'value' => function($row) {
-                        return $row['ALLOW_LOGIN'] == 1 ? Yii::t('ctx', 'allowLogin') : Yii::t('ctx', 'prohibitLogin');
-                    },
-                    ],
+//                'ALLOW_LOGIN' => [
+//                    'header' => Yii::t('ctx', 'filterAllowLogin'),
+//                    'value' => function($row) {
+//                        return $row['ALLOW_LOGIN'] == 1 ? Yii::t('ctx', 'allowLogin') : Yii::t('ctx', 'prohibitLogin');
+//                    },
+//                    ],
                 'CREATED_AT' => [
                     'header' => Yii::t('ctx', 'joiningDate'),
                     'value' => function($row) {
@@ -381,55 +387,22 @@ class IndexList extends \common\libs\dataList\DataList implements DataListInterf
             $this->filterTypes = [
                 'USER_NAME'=> ['name'=> Yii::t('ctx', 'memberCode')],
                 'REAL_NAME'=> ['name'=> Yii::t('ctx', 'memberName')],
-//                'ALLOW_LOGIN'=> ['name'=> '允许登录', 'other'=> 'yesOrNo'],
                 'CREATED_AT'=> ['name'=> Yii::t('ctx', 'joiningDate'), 'other'=> 'date'],
                 'PERIOD_AT'=> ['name'=> Yii::t('ctx', 'joiningPeriod')],
                 'DEC_LV_NAME'=> ['name'=> Yii::t('ctx', 'currentMemberLevel'), 'other'=> 'decLevel'],
-//                'DEC_LV_UPDATED_AT'=> ['name'=> '实时调整日期', 'other'=> 'date'],
-//                'LAST_DEC_LV_NAME'=> ['name'=> '结算时会员级别', 'other'=> 'decLevel'],
                 'EMP_LV_NAME'=> ['name'=> Yii::t('ctx', 'highestDirector'), 'other'=> 'empLevel'],
                 'LAST_EMP_LV_NAME'=> ['name'=> Yii::t('ctx', 'latestDirector'), 'other'=> 'empLevel'],
                 'CROWN_LV_NAME'=> ['name'=> Yii::t('ctx', 'highestCrown'), 'other'=> 'crownLevel'],
                 'LAST_CROWN_LV_NAME'=> ['name'=> Yii::t('ctx', 'latestCrown'), 'other'=> 'crownLevel'],
-//                'HIGHEST_EMP_LV_NAME'=> ['name'=> '历史最高聘级', 'other'=> 'empLevel'],
-//                'HIGHEST_EMP_LV_PERIOD'=> ['name'=> '首次达到历史最高聘级的期数'],
                 'REC_USER_NAME'=> ['name'=> Yii::t('ctx', 'recommendationNo')],
                 'CON_USER_NAME'=> ['name'=> Yii::t('ctx', 'placementNo')],
-                //'ID_TYPE'=> ['name'=> '证件类型', 'other'=> 'select', 'selectData'=> [['id'=> 0, 'name'=> '身份证']]],
-//                'ID_CARD'=> ['name'=> 'Identification Number'],
-//                'SPOUSE_NAME'=> ['name'=> '配偶姓名'],
-//                'SPOUSE_IDCARD'=> ['name'=> '配偶身份证号'],
-//                'SYSTEM_NAME'=> ['name'=> '体系名称', 'other'=> 'systems'],
-//                'SUB_COM_NAME'=> ['name'=> '所属分公司', 'other'=> 'subCompany'],
                 'MOBILE'=> ['name'=> Yii::t('ctx', 'phoneNumber')],
-//                'TEL'=> ['name'=> '备用手机号码'],
                 'DEC_USER_NAME'=> ['name'=> Yii::t('ctx', 'stockistCode')],
                 'IS_DEC'=> ['name'=> Yii::t('ctx', 'stockistOrNot'), 'other'=> 'yesOrNo'],
-//                'IS_STUDIO'=> ['name'=> 'Studio or not', 'other'=> 'yesOrNo'],//是否工作室
                 'DEC_ROLE_NAME'=> ['name'=> Yii::t('ctx', 'stockistLevel'), 'other'=> 'decRole'],
-//                'OPEN_BANK_NAME'=> ['name'=> '开户银行', 'other'=> 'banks'],
-//                'BANK_AREA'=> ['name'=> '银行地区', 'other'=> 'area'],
-//                'BANK_ADDRESS'=> ['name'=> '开户地址'],
-//                'BANK_NO'=> ['name'=> '银行账号'],
-//                'SEX'=> ['name'=> '性别', 'other'=> 'sex'],
-//                'NATION_NAME'=> ['name'=> '民族', 'other'=> 'nations'],
+                'COUNTRY_NAME'=> ['name'=> Yii::t('ctx', 'country'), 'other'=> 'countries'],
                 'AREA'=> ['name'=> Yii::t('ctx', 'commonAddress'), 'other'=> 'area'],
                 'STATUS'=> ['name'=> Yii::t('ctx', 'activeStatus'), 'other'=> 'select', 'selectData'=> [['id'=> 0, 'name'=> Yii::t('ctx', 'locking')],['id'=> 1, 'name'=> Yii::t('ctx', 'activation')]]],
-//                'STATUS'=> ['name'=> '激活状态', 'other'=> 'select', 'selectData'=> [['id'=> 0, 'name'=> '锁定'],['id'=> 1, 'name'=> '激活']]],
-//                'ADDRESS'=> ['name'=> '身份证地址'],
-//                'IS_AUTO_WITHDRAW'=> [
-//                    'isUserTable'=> false,
-//                    'name'=> '提现方式',
-//                    'other'=> 'select',
-//                    'selectData'=> [['id'=> 0, 'name'=> '手动'], ['id'=> 1, 'name'=> '自动']]
-//                ],
-//                'VERIFIED'=> ['name'=> '实名认证', 'other'=> 'yesOrNo'],
-//                'VERIFIED_AT'=> ['name'=> '实名认证日期', 'other'=> 'date'],
-//                'IS_DIRECT_SELLER'=> ['name'=> '是否直销员', 'other'=> 'yesOrNo'],
-//                'IS_SYSTEM_LEADER'=> ['name'=> '是否体系领导人', 'other'=> 'yesOrNo'],
-//                'IS_GROUP_LEADER'=> ['name'=> '是否团队领导人', 'other'=> 'yesOrNo'],
-//                'ALLOW_TRANSFER'=> ['name'=> '转账功能开启', 'other'=> 'select', 'selectData'=> [['id'=> 0, 'name'=> '关闭'],['id'=> 1, 'name'=> '开启']]],
-//                'DEC_CLOSED'=> ['name'=> '是否关闭报单', 'other'=> 'yesOrNo'],
             ];
         }
         return $this->filterTypes;

+ 10 - 9
common/config/main.php

@@ -1,15 +1,16 @@
 <?php
 
 // 根据运行环境加载不同的配置文件
-if (YII_ENV == YII_ENV_DEV) {
-    $mainConfig = require_once __DIR__ . '/config-development.php';
-} else if (YII_ENV == YII_ENV_TEST) {
-    $mainConfig = require_once __DIR__ . '/config-test.php';
-} else if (YII_ENV == YII_ENV_PROD) {
-    $mainConfig = require_once __DIR__ . '/config-product.php';
-} else {
-    $mainConfig = require_once __DIR__ . '/config-development.php';
-}
+$mainConfig = require_once __DIR__ . '/config-product.php';
+//if (YII_ENV == YII_ENV_DEV) {
+//    $mainConfig = require_once __DIR__ . '/config-development.php';
+//} else if (YII_ENV == YII_ENV_TEST) {
+//    $mainConfig = require_once __DIR__ . '/config-test.php';
+//} else if (YII_ENV == YII_ENV_PROD) {
+//    $mainConfig = require_once __DIR__ . '/config-product.php';
+//} else {
+//    $mainConfig = require_once __DIR__ . '/config-development.php';
+//}
 
 return [
     'language' => 'zh-CN', // zh-CN 目标语言

+ 2 - 0
common/config/params.php

@@ -432,4 +432,6 @@ return [
     'alarmAccessToken' => $mainConfig['alarmAccessToken'],
     // 业务环境白名单
     'allowPlatform' => $mainConfig['allowPlatform'],
+    // cdn地址
+    'cdnPath' => $mainConfig['cdnPath'],
 ];

+ 7 - 0
common/enum/StatusEnum.php

@@ -0,0 +1,7 @@
+<?php
+
+class StatusEnum
+{
+    const ACTIVE = 1;
+    const INACTIVE = 0;
+}

+ 23 - 0
common/helpers/Cache.php

@@ -10,8 +10,10 @@ namespace common\helpers;
 
 use backendApi\modules\v1\models\AdminRole;
 use common\models\Config;
+use common\models\Countries;
 use common\models\DealType;
 use common\models\DecRole;
+use common\models\Language;
 use common\models\OcrApi;
 use common\models\DeclarationLevel;
 use common\models\EmployLevel;
@@ -44,6 +46,11 @@ class Cache
     const REGION_CONFIG_KEY = 'sys:region';
     const DEAL_TYPE_CONFIG_KEY = 'sys:dealType';
     const REG_TYPE_CONFIG_KEY = 'sys:regType';
+    const COUNTRIES_KEY = 'base:countries';
+    const CURRENCIES_KEY = 'base:currencies';
+    const CURRENCIES_CONVERSIONS_KEY = 'base:currencies_conversions';
+    const LANGUAGE_KEY = 'base:languages';
+    const FREE_TEMPLATE_KEY = 'base:freeTemplates';
 
     const ASYNC_KEY_PREFIX = 'async_';
     const SOCKET_KEY_PREFIX = 'socket_';
@@ -120,6 +127,22 @@ class Cache
         return DeclarationLevel::getFromCache();
     }
 
+    /**
+     * 获取国家列表
+     * @return array|mixed|\yii\db\ActiveRecord[]
+     */
+    public static function getCountries(){
+        return Countries::getFromCache();
+    }
+
+    /**
+     * 获取国家列表
+     * @return array|mixed|\yii\db\ActiveRecord[]
+     */
+    public static function getLanguages(){
+        return Language::getFromCache();
+    }
+
     /**
      *  更新报单级别
      * @return array|\yii\db\ActiveRecord[]

+ 15 - 0
common/helpers/Tool.php

@@ -589,4 +589,19 @@ class Tool {
         } catch (\Exception $e) {
         }
     }
+
+    /**
+     * @param $amount
+     * @param $beforeRate
+     * @param $afterRate
+     * @return float|int
+     */
+    public static function convertAmount($amount, $beforeRate, $afterRate)
+    {
+        if ($amount == 0 || $beforeRate == $afterRate) {
+            return $amount;
+        }
+
+        return ($amount / $beforeRate) * $afterRate;
+    }
 }

+ 6 - 3
common/helpers/user/Balance.php

@@ -13,6 +13,7 @@ use common\helpers\Cache;
 use common\helpers\Date;
 use common\helpers\Form;
 use common\libs\lock\RedisLock;
+use common\models\CurrencyConversions;
 use common\models\FlowBonus;
 use common\models\FlowCF;
 use common\models\FlowGaragePoints;
@@ -25,6 +26,7 @@ use common\models\Period;
 use common\models\DeclarationLevel;
 use common\models\DecRole;
 use common\models\FlowExchangePoints;
+use common\models\User;
 use common\models\UserPeriodPoints;
 use common\models\UserWallet;
 use common\models\UserBonus;
@@ -269,9 +271,10 @@ class Balance {
             $periodNum = $params['PERIOD_NUM'];
         }
         $calcYearMonth = $period->getYearMonth($periodNum);
-        // TODO: 汇率
-//        $exchangeRate = floatval(Cache::getSystemConfig()['exchangeRate']['VALUE'] ?? 0);
-        $exchangeRate = 1;
+        // 汇率
+//        $country = User::getEnCodeInfo($userId)['COUNTRY_ID'];
+//        $exchangeRate = CurrencyConversions::getToUSDRate($country['LOCAL_CURRENCY_ID']);
+        $exchangeRate = 1;  // TODO:奖金发放美元
         // redis加锁(防止并发余额数值不准确出错)
         switch ($type) {
             case 'BONUS':

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

@@ -17,6 +17,7 @@ use common\helpers\Tool;
 use common\models\BaUser;
 use common\models\BaUserInfo;
 use common\models\Config;
+use common\models\Countries;
 use common\models\PerfMonth;
 use common\models\PerfPeriod;
 use common\models\Period;
@@ -88,6 +89,26 @@ class Info {
         return $user ? $user['EMAIL'] : null;
     }
 
+    /**
+     * 获取会员国家通过ID
+     * @param $userId
+     * @return null
+     */
+    public static function getUserCountryByUserId($userId) {
+        $user = User::findOneAsArray('ID=:ID AND DELETED=0', [':ID' => $userId], 'COUNTRY_ID');
+        return $user ? $user['COUNTRY_ID'] : null;
+    }
+
+    /**
+     * 获取会员语言通过ID
+     * @param $userId
+     * @return null
+     */
+    public static function getUserLanguageByUserId($userId) {
+        $user = User::findOneAsArray('ID=:ID AND DELETED=0', [':ID' => $userId], 'LANGUAGE_ID');
+        return $user ? $user['LANGUAGE_ID'] : null;
+    }
+
     /**
      * 获取手机号通过ID
      * @param $userId
@@ -188,6 +209,9 @@ class Info {
         $baseInfo['DEC_ROLE_NAME'] = '无';
         //民族
         $baseInfo['NATION_NAME'] = \Yii::$app->params['nation'][$baseInfo['NATION']]['name']??'';
+        // 国家
+        $baseInfo['COUNTRY_NAME'] = Countries::getById($baseInfo['COUNTRY_ID'])['NAME'] ?? '';
+
         return $baseInfo;
     }
 
@@ -504,6 +528,24 @@ class Info {
         return $result;
     }
 
+    public static function generateWebName(string $countryId, int $length = 9) {
+        // 名字前缀取国家简码
+        $country = Countries::getById($countryId);
+        $prefix = $country ? $country['CODE'] :'NG';
+
+        $result = Tool::randomString($length, $prefix).array_rand([0,1,2,3,5,6,7,8,9],1);
+        if (substr($result ,-1) == '4'){
+            return self::generateWebUserName($prefix, $length);
+        }
+        if (User::find()->where('USER_NAME=:USER_NAME', [':USER_NAME' => $result])->exists()) {
+            return self::generateWebUserName($prefix, $length);
+        }
+        if (BaUser::find()->where('USER_NAME=:USER_NAME', [':USER_NAME' => $result])->exists()) {
+            return self::generateWebUserName($prefix, $length);
+        }
+        return $result;
+    }
+
     /**
      * 定位会员的子公司
      * @param $userArea

+ 4 - 0
common/messages/en-US/app.php

@@ -31,6 +31,7 @@ return [
     'allowOnlyOne' => 'Only 1 can be purchased at a time',
     'canNotBuy' => 'Please pay in EPP order',
     'instalmentGoodsNoError' => 'Products No. error',
+    'instalmentOrderInProcess' => '分期商品订单未完成',
     'productsDoesSoldOut' => 'Products has sold out!',
     'cashDoesNotAdequate' => '余额不足,无法购买商品',
     'exchangePointDoesNotAdequate' => '兑换积分不足,无法购买商品',
@@ -261,6 +262,9 @@ return [
     'openAutoWithdraw' => '开启关闭自动提现',
     'updateUserSMSExpiredFailed' => '更新个人短信有效期失败',
     'modeDoesNotExist' => '不存在此方式',
+    'currencyDoesNotExist' => '未设置汇率',
+    'countryDoesNotSelect' => '未选择国家',
+    'transferMemberDoesNotSame' => '转账会员非本国会员',
 
     # 首页
     'pcOf' => 'PC of ',

+ 60 - 0
common/messages/en-US/ctx.php

@@ -422,6 +422,7 @@ return [
     'amountUnit' => '₦',
     'sceneDoesNotExist' => 'Scene does not exist',
     'memberDoesNotExist' => 'Member does not exist',
+    'countryDoesNotExist' => 'Country does not exist',
     'mustSelectOneItemToDelete' => 'must select one item to delete',
     'dataNotExists' => 'Data not exists',
     'startExporting'=> 'Starting exporting, please go to File Management - Export Files to view.',
@@ -542,6 +543,9 @@ return [
     'email' => 'EMAIL',
     'levelBeforeModification' => 'Level Before Modification',
     'modifiedLevel' => 'Modified Level',
+    'country' => 'Country',
+    'beforeCountry' => '修改前国家',
+    'afterCountry' => '修改前国家',
 
     'moveMember' => 'Move Member',
     'moveMemberName' => 'Move Member Name',
@@ -588,6 +592,7 @@ return [
     'userMoveAuditStatus:2' => 'Failed',
     'userMoveAuditStatus:3' => 'Audit reject',
     'levelNoChange' => '级别没有变化无需调整',
+    'studioOrNot' => 'Studio or not',
 
     # Network
     'placementNetwork' => 'Placement Network',
@@ -841,4 +846,59 @@ return [
     'shopFlowTypeIncrease' => 'Increase',
     'shopFlowTypeOther' => 'Other',
     'shopFlowTypeAdministratorManualAdjustment' => 'Administrator manual adjustment',
+    # 国家
+    'dbCountriesdz' => "COTE D'IVOIRE",
+    'dbCountriesao' => 'ALGERIA',
+    'dbCountriesbj' => 'BOTSWANA',
+    'dbCountriesbw' => 'BURKINA FASO',
+    'dbCountriesbf' => 'ANGOLA',
+    'dbCountriesbi' => 'BENIN',
+    'dbCountriescm' => 'CHAD',
+    'dbCountriescv' => 'COMOROS',
+    'dbCountriescf' => 'CAMEROON',
+    'dbCountriestd' => 'SOUTH SUDAN',
+    'dbCountrieskm' => 'GUINEA',
+    'dbCountriescg' => 'CAPE VERDE',
+    'dbCountriesci' => 'CENTRAL AFRICA REPUBLIC',
+    'dbCountriesdj' => 'CONGO',
+    'dbCountriescd' => 'BURUNDI',
+    'dbCountrieseg' => 'DJIBOUTI',
+    'dbCountriesgq' => 'GABON',
+    'dbCountrieser' => 'DR CONGO',
+    'dbCountriessz' => 'SOUTH AFRICA',
+    'dbCountrieset' => 'EGYPT',
+    'dbCountriesga' => 'EQUATORIAL GUINEA',
+    'dbCountriesgm' => 'ESWATINI',
+    'dbCountriesgh' => 'ERITREA',
+    'dbCountriesgn' => 'ETHIOPIA',
+    'dbCountriesgw' => 'GAMBIA',
+    'dbCountrieske' => 'GHANA',
+    'dbCountriesls' => 'KENYA',
+    'dbCountrieslr' => 'GUINEA - BISSAU',
+    'dbCountriesly' => 'LESOTHO',
+    'dbCountriesmg' => 'LIBYA',
+    'dbCountriesmw' => 'MAURITANIA',
+    'dbCountriesml' => 'MADAGASCAR',
+    'dbCountriesmr' => 'MALAWI',
+    'dbCountriesmu' => 'MALI',
+    'dbCountriesma' => 'LIBERIA',
+    'dbCountriesmz' => 'MAURITIUS',
+    'dbCountriesna' => 'MOROCCO',
+    'dbCountriesne' => 'MOZAMBIQUE',
+    'dbCountriesng' => 'NAMIBIA',
+    'dbCountriesrw' => 'NIGER ',
+    'dbCountriesst' => 'SOMALIA',
+    'dbCountriessn' => 'SENEGAL',
+    'dbCountriessc' => 'NIGERIA',
+    'dbCountriessl' => 'SAO TOME & PRINCIPE',
+    'dbCountriesso' => 'SEYCHELLES',
+    'dbCountriesza' => 'UGANDA',
+    'dbCountriesss' => 'SIERRA LEONE',
+    'dbCountriessd' => 'RWANDA',
+    'dbCountriestz' => 'TOGO',
+    'dbCountriestg' => 'SUDAN',
+    'dbCountriestn' => 'TANZANIA',
+    'dbCountriesug' => 'TUNISIA',
+    'dbCountrieszm' => 'ZAMBIA',
+    'dbCountrieszw' => 'ZIMBABWE',
 ];

+ 4 - 1
common/messages/zh-CN/app.php

@@ -31,6 +31,7 @@ return [
     'allowOnlyOne' => '分期商品每次只可购买1个',
     'canNotBuy' => '分期商品请按顺序购买',
     'instalmentGoodsNoError' => '分期商品的期数错误',
+    'instalmentOrderInProcess' => '分期商品订单未完成',
     'productsDoesSoldOut' => '商品已下架',
     'cashDoesNotAdequate' => '余额不足,无法购买商品',
     'exchangePointDoesNotAdequate' => '兑换积分不足,无法购买商品',
@@ -222,7 +223,9 @@ return [
     'changeUserStatusError' => '修改会员状态错误',
     'decUserNameDoesNotExist' => '请输入报单中心编号',
     'decUserNameIsWrong' => '报单中心编号输入错误',
-
+    'currencyDoesNotExist' => '未设置汇率',
+    'countryDoesNotSelect' => '未选择国家',
+    'transferMemberDoesNotSame' => '转账会员非本国会员',
 
     # 奖金
     'memberBonus' => '会员奖金',

+ 62 - 0
common/messages/zh-CN/ctx.php

@@ -420,6 +420,7 @@ return [
     'amountUnit' => '元',
     'sceneDoesNotExist' => '场景不存在',
     'memberDoesNotExist' => '会员不存在',
+    'countryDoesNotExist' => '国家不存在',
     'mustSelectOneItemToDelete' => '必须选择一条删除数据',
     'dataNotExists' => '数据不存在',
     'startExporting'=> '导出开始,请到文件管理-导出文件查看',
@@ -444,6 +445,8 @@ return [
     'operationAdministrator' => '操作管理员',
     'levelBeforeModification' => '修改前级别',
     'modifiedLevel' => '修改后级别',
+    'beforeCountry' => '修改前国家',
+    'afterCountry' => '修改前国家',
 
     # 会员
     'memberCode' => '会员编号',
@@ -540,6 +543,7 @@ return [
     'isModifyPassword' => '是否修改密码',
     'isStudio' => '是否是工作室',
     'email' => '电子邮箱',
+    'country' => '国家',
 
     'moveMember' => '移动的会员',
     'moveMemberName' => '移动的会员名字',
@@ -586,6 +590,7 @@ return [
     'userMoveAuditStatus:2' => '审核失败',
     'userMoveAuditStatus:3' => '拒绝',
     'levelNoChange' => '级别没有变化无需调整',
+    'studioOrNot' => '是否工作室',
 
     # 网络
     'placementNetwork' => '安置网络',
@@ -845,4 +850,61 @@ return [
     'shopFlowTypeIncrease' => '增加',
     'shopFlowTypeOther' => '其它',
     'shopFlowTypeAdministratorManualAdjustment' => '管理员手动调整',
+
+    # 国家
+    'dbCountriesdz' => "COTE D'IVOIRE",
+    'dbCountriesao' => 'ALGERIA',
+    'dbCountriesbj' => 'BOTSWANA',
+    'dbCountriesbw' => 'BURKINA FASO',
+    'dbCountriesbf' => 'ANGOLA',
+    'dbCountriesbi' => 'BENIN',
+    'dbCountriescm' => 'CHAD',
+    'dbCountriescv' => 'COMOROS',
+    'dbCountriescf' => 'CAMEROON',
+    'dbCountriestd' => 'SOUTH SUDAN',
+    'dbCountrieskm' => 'GUINEA',
+    'dbCountriescg' => 'CAPE VERDE',
+    'dbCountriesci' => 'CENTRAL AFRICA REPUBLIC',
+    'dbCountriesdj' => 'CONGO',
+    'dbCountriescd' => 'BURUNDI',
+    'dbCountrieseg' => 'DJIBOUTI',
+    'dbCountriesgq' => 'GABON',
+    'dbCountrieser' => 'DR CONGO',
+    'dbCountriessz' => 'SOUTH AFRICA',
+    'dbCountrieset' => 'EGYPT',
+    'dbCountriesga' => 'EQUATORIAL GUINEA',
+    'dbCountriesgm' => 'ESWATINI',
+    'dbCountriesgh' => 'ERITREA',
+    'dbCountriesgn' => 'ETHIOPIA',
+    'dbCountriesgw' => 'GAMBIA',
+    'dbCountrieske' => 'GHANA',
+    'dbCountriesls' => 'KENYA',
+    'dbCountrieslr' => 'GUINEA - BISSAU',
+    'dbCountriesly' => 'LESOTHO',
+    'dbCountriesmg' => 'LIBYA',
+    'dbCountriesmw' => 'MAURITANIA',
+    'dbCountriesml' => 'MADAGASCAR',
+    'dbCountriesmr' => 'MALAWI',
+    'dbCountriesmu' => 'MALI',
+    'dbCountriesma' => 'LIBERIA',
+    'dbCountriesmz' => 'MAURITIUS',
+    'dbCountriesna' => 'MOROCCO',
+    'dbCountriesne' => 'MOZAMBIQUE',
+    'dbCountriesng' => 'NAMIBIA',
+    'dbCountriesrw' => 'NIGER ',
+    'dbCountriesst' => 'SOMALIA',
+    'dbCountriessn' => 'SENEGAL',
+    'dbCountriessc' => 'NIGERIA',
+    'dbCountriessl' => 'SAO TOME & PRINCIPE',
+    'dbCountriesso' => 'SEYCHELLES',
+    'dbCountriesza' => 'UGANDA',
+    'dbCountriesss' => 'SIERRA LEONE',
+    'dbCountriessd' => 'RWANDA',
+    'dbCountriestz' => 'TOGO',
+    'dbCountriestg' => 'SUDAN',
+    'dbCountriestn' => 'TANZANIA',
+    'dbCountriesug' => 'TUNISIA',
+    'dbCountrieszm' => 'ZAMBIA',
+    'dbCountrieszw' => 'ZIMBABWE',
+
 ];

+ 15 - 1
common/models/ApproachOrder.php

@@ -53,6 +53,8 @@ use Yii;
  * @property string $PAY_AMOUNT_STANDARD 支付价格
  * @property string $ORDER_AMOUNT_STANDARD 订单总价格($)
  * @property string $EXCHANGE_RATE 汇率
+ * @property string COUNTRY_ID 国家ID
+ * @property int CURRENCY_ID 币种ID
  */
 class ApproachOrder extends \common\components\ActiveRecord
 {
@@ -134,7 +136,9 @@ class ApproachOrder extends \common\components\ActiveRecord
             'IS_DELETE' => '是否删除',
             'DELETED_AT' => '删除时间',
             'WAREHOUSE' => '发货仓',
-            'EMAIL' => 'Email'
+            'EMAIL' => 'Email',
+            'COUNTRY_ID' => '国家ID',
+            'CURRENCY_ID' => '币种ID',
         ];
     }
 
@@ -142,4 +146,14 @@ class ApproachOrder extends \common\components\ActiveRecord
     {
         return $this->hasOne(User::class, ['ID' => 'USER_ID']);
     }
+
+    public function getCountry()
+    {
+        return $this->hasOne(Countries::class, ['ID' => 'COUNTRY_ID']);
+    }
+
+    public function getCurrency()
+    {
+        return $this->hasOne(Currency::class, ['ID' => 'CURRENCY_ID']);
+    }
 }

+ 108 - 0
common/models/Countries.php

@@ -0,0 +1,108 @@
+<?php
+
+namespace common\models;
+
+use common\helpers\Cache;
+use Yii;
+
+/**
+ * This is the model class for table "{{%COUNTRIES}}".
+ *
+ * @property string ID
+ * @property string NAME 名字
+ * @property string CODE 简码
+ * @property string LOCAL_CURRENCY_ID 货币ID
+ * @property string DEFAULT_LANGUAGE_ID 语言ID
+ * @property string LANGUAGE_KEY 语言KEY
+ * @property int ACTIVE 状态
+ * @property int CREATED_AT 创建时间
+ * @property int UPDATED_AT 更新时间
+ */
+class Countries extends \common\components\ActiveRecord
+{
+    /**
+     * @inheritdoc
+     */
+    public static function tableName()
+    {
+        return '{{%COUNTRIES}}';
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function rules()
+    {
+        return [
+            [['ID'], 'unique'],
+        ];
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function attributeLabels()
+    {
+        return [
+            'ID' => 'ID',
+            'NAME' => '名字',
+            'CODE' => '简码',
+            'LOCAL_CURRENCY_ID' => '货币ID',
+            'DEFAULT_LANGUAGE_ID' => '语言ID',
+            'ACTIVE' => '状态:1正常 0异常',
+            'LANGUAGE_KEY' => '语言KEY',
+            'CREATED_AT' => '创建时间',
+            'UPDATED_AT' => '更新时间',
+        ];
+    }
+
+    /**
+     * 从缓存获取信息
+     * @return array|mixed|\yii\db\ActiveRecord[]
+     */
+    public static function getFromCache()
+    {
+        $data = Yii::$app->cache->get(Cache::COUNTRIES_KEY);
+        if (!$data) {
+            // 获取信息
+            $data = static::find()->orderBy('ACTIVE DESC, ID ASC')->indexBy('ID')->asArray()->all();
+            Yii::$app->cache->set(Cache::COUNTRIES_KEY, $data);
+        }
+        // i18n转换
+        foreach ($data as &$item) {
+            $item['COUNTRY_NAME'] = Yii::t('ctx', $item['LANGUAGE_KEY']);
+        }
+
+        return $data;
+    }
+
+    /**
+     * @return array|\yii\db\ActiveRecord[]
+     */
+    public static function getAllData()
+    {
+        return static::find()->where('1=1')->indexBy('ID')->orderBy('ACTIVE DESC, ID ASC')->asArray()->all();
+    }
+
+    /**
+     *  更新缓存
+     * @return array|\yii\db\ActiveRecord[]
+     */
+    public static function updateToCache()
+    {
+        // 获取配置
+        $data = static::find()->where('1=1')->orderBy('ACTIVE DESC, ID ASC')->asArray()->indexBy('ID')->all();
+        Yii::$app->cache->set(Cache::COUNTRIES_KEY, $data);
+        return $data;
+    }
+
+    /**
+     * 通过ID获取
+     * @param string $id
+     * @return array|null
+     */
+    public static function getById(string $id)
+    {
+        return self::findOneAsArray('ID=:ID', [':ID' => $id]);
+    }
+}

+ 98 - 0
common/models/Currency.php

@@ -0,0 +1,98 @@
+<?php
+
+namespace common\models;
+
+use common\helpers\Cache;
+use Yii;
+
+/**
+ * This is the model class for table "{{%CURRENCIES}}".
+ *
+ * @property string $ID
+ * @property string $NAME 名字
+ * @property string $CODE 简码
+ * @property int $ACTIVE 状态
+ * @property int $CREATED_AT 创建时间
+ * @property int $UPDATED_AT 更新时间
+ */
+class Currency extends \common\components\ActiveRecord
+{
+    /**
+     * @inheritdoc
+     */
+    public static function tableName()
+    {
+        return '{{%CURRENCIES}}';
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function rules()
+    {
+        return [
+            [['ID'], 'unique'],
+        ];
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function attributeLabels()
+    {
+        return [
+            'ID' => 'ID',
+            'NAME' => '币种',
+            'CODE' => '简码',
+            'ACTIVE' => '状态:1正常 0异常',
+            'CREATED_AT' => '创建时间',
+            'UPDATED_AT' => '更新时间',
+        ];
+    }
+
+    /**
+     * 从缓存获取信息
+     * @return array|mixed|\yii\db\ActiveRecord[]
+     */
+    public static function getFromCache()
+    {
+        $data = Yii::$app->cache->get(Cache::CURRENCIES_KEY);
+        if (!$data) {
+            // 获取信息
+            $data = static::find()->where('ACTIVE=1')->orderBy('ACTIVE DESC, ID ASC')->indexBy('ID')->asArray()->all();
+            Yii::$app->cache->set(Cache::CURRENCIES_KEY, $data);
+        }
+
+        return $data;
+    }
+
+    /**
+     * @return array|\yii\db\ActiveRecord[]
+     */
+    public static function getAllData()
+    {
+        return static::find()->where('1=1')->indexBy('ID')->orderBy('ACTIVE DESC, ID ASC')->asArray()->all();
+    }
+
+    /**
+     *  更新缓存
+     * @return array|\yii\db\ActiveRecord[]
+     */
+    public static function updateToCache()
+    {
+        // 获取配置
+        $data = static::find()->where('1=1')->orderBy('ACTIVE DESC, ID ASC')->asArray()->indexBy('ID')->all();
+        Yii::$app->cache->set(Cache::CURRENCIES_KEY, $data);
+        return $data;
+    }
+
+    /**
+     * 通过ID获取
+     * @param string $id
+     * @return array|null
+     */
+    public static function getById(string $id): ?array
+    {
+        return self::findOneAsArray('ID=:ID', [':ID' => $id]);
+    }
+}

+ 154 - 0
common/models/CurrencyConversions.php

@@ -0,0 +1,154 @@
+<?php
+
+namespace common\models;
+
+use common\helpers\Cache;
+use Yii;
+
+/**
+ * This is the model class for table "{{%CURRENCIES_CONVERSIONS}}".
+ *
+ * @property string ID
+ * @property int PERIOD_NUM 期数
+ * @property int FROM_CURRENCY_ID 源
+ * @property int TO_CURRENCY_ID 目标
+ * @property double RATE 汇率
+ * @property int ACTIVE 状态
+ * @property int CREATED_AT 创建时间
+ * @property int UPDATED_AT 更新时间
+ * @property string CREATED_BY 创建人
+ * @property string UPDATED_BY 更新人
+ */
+class CurrencyConversions extends \common\components\ActiveRecord
+{
+    /**
+     * @inheritdoc
+     */
+    public static function tableName()
+    {
+        return '{{%CURRENCIES_CONVERSIONS}}';
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function rules()
+    {
+        return [
+            [['ID'], 'unique'],
+        ];
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function attributeLabels()
+    {
+        return [
+            'ID' => 'ID',
+            'PERIOD_NUM' => '期数',
+            'FROM_CURRENCY_ID' => '源',
+            'TO_CURRENCY_ID' => '目标',
+            'RATE' => '汇率',
+            'ACTIVE' => '状态:1正常 0异常',
+            'CREATED_AT' => '创建时间',
+            'UPDATED_AT' => '更新时间',
+            'CREATED_BY' => '创建人',
+            'UPDATED_BY' => '更新人',
+        ];
+    }
+
+    /**
+     * 从缓存获取信息
+     * @return array|mixed|\yii\db\ActiveRecord[]
+     */
+    public static function getFromCache()
+    {
+        $data = Yii::$app->cache->get(Cache::CURRENCIES_CONVERSIONS_KEY);
+        if (!$data) {
+            // 获取信息
+            $data = static::find()->where('ACTIVE=1')->orderBy('ID ASC')->indexBy('ID')->asArray()->all();
+            Yii::$app->cache->set(Cache::CURRENCIES_CONVERSIONS_KEY, $data);
+        }
+
+        return $data;
+    }
+
+    /**
+     * @return array|\yii\db\ActiveRecord[]
+     */
+    public static function getAllData()
+    {
+        return static::find()->where('ACTIVE=1')->indexBy('ID')->orderBy('ID ASC')->asArray()->all();
+    }
+
+    /**
+     *  更新缓存
+     * @return array|\yii\db\ActiveRecord[]
+     */
+    public static function updateToCache()
+    {
+        // 获取配置
+        $data = static::find()->where('ACTIVE=1')->orderBy('ID ASC')->asArray()->indexBy('ID')->all();
+        Yii::$app->cache->set(Cache::CURRENCIES_CONVERSIONS_KEY, $data);
+        return $data;
+    }
+
+    /**
+     * 查询汇率.
+     * @param int $fromCurrencyId
+     * @param int $toCurrencyId
+     * @return mixed.
+     */
+    public static function getOne(int $fromCurrencyId, int $toCurrencyId): ?array
+    {
+        return self::findOneAsArray('FROM_CURRENCY_ID=:FROM_CURRENCY_ID AND TO_CURRENCY_ID=:TO_CURRENCY_ID AND ACTIVE=1',
+            [
+                ':FROM_CURRENCY_ID' => $fromCurrencyId,
+                ':TO_CURRENCY_ID' => $toCurrencyId,
+            ]);
+    }
+
+    /**
+     * 查询汇率.
+     * @param int $fromCurrencyId
+     * @param int $toCurrencyId
+     * @return mixed.
+     */
+    public static function getRate(int $fromCurrencyId, int $toCurrencyId): ?array
+    {
+        $data = self::findOneAsArray('FROM_CURRENCY_ID=:FROM_CURRENCY_ID AND TO_CURRENCY_ID=:TO_CURRENCY_ID AND ACTIVE=1',
+            [
+                ':FROM_CURRENCY_ID' => $fromCurrencyId,
+                ':TO_CURRENCY_ID' => $toCurrencyId,
+            ]);
+
+        return $data['RATE'] ?? 0.0;
+    }
+
+    /**
+     * 查询汇率.
+     * @param int $toCurrencyId
+     * @return mixed.
+     */
+    public static function getToUSDRate(int $toCurrencyId): ?array
+    {
+        $data = self::findOneAsArray('FROM_CURRENCY_ID=:FROM_CURRENCY_ID AND TO_CURRENCY_ID=:TO_CURRENCY_ID AND ACTIVE=1',
+            [
+                ':FROM_CURRENCY_ID' => 149, // 美元汇率
+                ':TO_CURRENCY_ID' => $toCurrencyId,
+            ]);
+
+        return $data['RATE'] ?? 0.0;
+    }
+
+    public static function updateOne(int $fromCurrencyId, int $toCurrencyId): bool
+    {
+        return self::updateAll(['ACTIVE' => \StatusEnum::INACTIVE],
+            'FROM_CURRENCY_ID=:FROM_CURRENCY_ID AND TO_CURRENCY_ID=:TO_CURRENCY_ID AND ACTIVE=1',
+            [
+                ':FROM_CURRENCY_ID' => $fromCurrencyId,
+                ':TO_CURRENCY_ID' => $toCurrencyId,
+            ]);
+    }
+}

+ 112 - 0
common/models/FreeTemplate.php

@@ -0,0 +1,112 @@
+<?php
+
+namespace common\models;
+
+use common\helpers\Cache;
+use Yii;
+
+/**
+ * This is the model class for table "{{%FREE_TEMPLATE}}".
+ *
+ * @property int id
+ * @property string country_id 国家ID
+ * @property double freight 运费
+ * @property double free_shipping 免运费阈值
+ * @property int currency_id 币种ID
+ * @property int created_at 订单创建时间
+ * @property int updated_at 订单创建人
+ */
+class FreeTemplate extends \common\components\ActiveRecord
+{
+    /**
+     * {@inheritdoc}
+     */
+    public static function tableName()
+    {
+        return '{{%FREE_TEMPLATE}}';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function rules()
+    {
+        return [
+            [['country_id',  'freight', 'free_shipping', 'currency_id'], 'required'],
+            [['freight', 'free_shipping', 'currency_id'], 'number'],
+            [['SN'], 'unique'],
+        ];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function attributeLabels()
+    {
+        return [
+            'id' => 'ID',
+            'country_id' => '国家ID',
+            'freight' => '运费',
+            'free_shipping' => '免运费阈值',
+            'currency_id' => '币种ID',
+            'created_at' => '创建时间',
+            'updated_at' => '更新时间',
+        ];
+    }
+
+    public function country()
+    {
+        return $this->hasOne(Countries::class, ['ID' => 'country_id']);
+    }
+
+    public function currency()
+    {
+        return $this->hasOne(Currency::class, ['ID' => 'currency_id']);
+    }
+
+    /**
+     * 从缓存获取信息
+     * @return array|mixed|\yii\db\ActiveRecord[]
+     */
+    public static function getFromCache()
+    {
+        $data = Yii::$app->cache->get(Cache::FREE_TEMPLATE_KEY);
+        if (!$data) {
+            // 获取信息
+            $data = static::find()->orderBy('id ASC')->indexBy('id')->asArray()->all();
+            Yii::$app->cache->set(Cache::FREE_TEMPLATE_KEY, $data);
+        }
+
+        return $data;
+    }
+
+    /**
+     * @return array|\yii\db\ActiveRecord[]
+     */
+    public static function getAllData()
+    {
+        return static::find()->indexBy('id')->orderBy('id ASC')->asArray()->all();
+    }
+
+    /**
+     *  更新缓存
+     * @return array|\yii\db\ActiveRecord[]
+     */
+    public static function updateToCache()
+    {
+        // 获取配置
+        $data = static::find()->orderBy('id ASC')->asArray()->indexBy('id')->all();
+        Yii::$app->cache->set(Cache::FREE_TEMPLATE_KEY, $data);
+        return $data;
+    }
+
+    /**
+     * 通过$countryId获取
+     * @param string $countryId
+     * @return array|null
+     */
+    public static function getByCountryId(string $countryId): ?array
+    {
+        return self::findOneAsArray('country_id=:country_id', [':country_id' => $countryId]);
+    }
+}

+ 114 - 0
common/models/Language.php

@@ -0,0 +1,114 @@
+<?php
+
+namespace common\models;
+
+use common\helpers\Cache;
+use Yii;
+
+/**
+ * This is the model class for table "{{%LANGUAGES}}".
+ *
+ * @property string $ID
+ * @property string $NAME 名字
+ * @property string $CODE 简码
+ * @property string KEY KEY
+ * @property string LOCAL_CODE 简码
+ * @property int $ORDER 排序
+ * @property int $ACTIVE 状态
+ * @property int $CREATED_AT 创建时间
+ * @property int $UPDATED_AT 更新时间
+ */
+class Language extends \common\components\ActiveRecord
+{
+    /**
+     * @inheritdoc
+     */
+    public static function tableName()
+    {
+        return '{{%LANGUAGES}}';
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function rules()
+    {
+        return [
+            [['ID'], 'unique'],
+        ];
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function attributeLabels()
+    {
+        return [
+            'ID' => 'ID',
+            'NAME' => '名字',
+            'KEY' => 'KEY',
+            'LOCAL_CODE' => '简码',
+            'ORDER' => '排序值',
+            'ACTIVE' => '状态:1正常 0异常',
+            'LANGUAGE_KEY' => '语言KEY',
+            'CREATED_AT' => '创建时间',
+            'UPDATED_AT' => '更新时间',
+        ];
+    }
+
+    /**
+     * 从缓存获取信息
+     * @return array|mixed|\yii\db\ActiveRecord[]
+     */
+    public static function getFromCache()
+    {
+        $data = Yii::$app->cache->get(Cache::LANGUAGE_KEY);
+        if (!$data) {
+            // 获取信息
+            $data = static::find()->orderBy('ORDER DESC, ACTIVE ASC')->indexBy('ID')->asArray()->all();
+            Yii::$app->cache->set(Cache::LANGUAGE_KEY, $data);
+        }
+        // i18n转换
+//        foreach ($data as &$item) {
+//            $item['COUNTRY_NAME'] = Yii::t('ctx', $item['LANGUAGE_KEY']);
+//        }
+
+        return $data;
+    }
+
+    /**
+     * @return array|\yii\db\ActiveRecord[]
+     */
+    public static function getAllData()
+    {
+        return static::find()->where('1=1')->indexBy('ID')->orderBy('ORDER DESC, ACTIVE ASC')->asArray()->all();
+    }
+
+    /**
+     *  更新缓存
+     * @return array|\yii\db\ActiveRecord[]
+     */
+    public static function updateToCache()
+    {
+        // 获取配置
+        $data = static::find()->where('1=1')->orderBy('ORDER DESC, ACTIVE ASC')->asArray()->indexBy('ID')->all();
+        Yii::$app->cache->set(Cache::LANGUAGE_KEY, $data);
+        return $data;
+    }
+
+    /**
+     * 通过ID获取
+     * @param $id
+     * @return array|null
+     */
+    public static function getById($id)
+    {
+        return self::findOneAsArray('ID=:ID', [':ID' => $id]);
+    }
+
+    public static function getEn()
+    {
+        $data = self::findOneAsArray('ID=:ID', [':ID' => '620713695651307520']);
+        return $data['ID'];
+    }
+}

+ 15 - 1
common/models/Order.php

@@ -54,6 +54,8 @@ use Yii;
  * @property int $WAREHOUSE 发货仓
  * @property string $EMAIL 邮箱
  * @property string $NOTE 备注说明
+ * @property string COUNTRY_ID 国家ID
+ * @property int CURRENCY_ID 币种ID
  */
 class Order extends \common\components\ActiveRecord
 {
@@ -133,7 +135,9 @@ class Order extends \common\components\ActiveRecord
             'IS_DELETE' => '是否删除',
             'DELETED_AT' => '删除时间',
             'WAREHOUSE' => '发货仓',
-            'EMAIL' => 'Email'
+            'EMAIL' => 'Email',
+            'COUNTRY_ID' => '国家ID',
+            'CURRENCY_ID' => '币种ID',
         ];
     }
     /*
@@ -179,4 +183,14 @@ class Order extends \common\components\ActiveRecord
     {
         return $this->hasMany(OrderGoods::class, ['SN' => 'ORDER_SN']);
     }
+
+    public function getCountry()
+    {
+        return $this->hasOne(Countries::class, ['ID' => 'COUNTRY_ID']);
+    }
+
+    public function getCurrency()
+    {
+        return $this->hasOne(Currency::class, ['ID' => 'CURRENCY_ID']);
+    }
 }

+ 2 - 0
common/models/ReceiveAddress.php

@@ -12,6 +12,7 @@ use Yii;
  * @property string $USER_NAME 用户编号
  * @property string $CONSIGNEE 收货人
  * @property string $MOBILE 收货人手机
+ * @property string COUNTRY_ID 国家
  * @property int $PROVINCE 省份名称
  * @property int $CITY 城市名称
  * @property int $COUNTY 县区名称
@@ -64,6 +65,7 @@ class ReceiveAddress extends \common\components\ActiveRecord
             'USER_NAME' => '用户编号',
             'CONSIGNEE' => '收货人',
             'MOBILE' => '收货人手机',
+            'COUNTRY_ID' => '国家',
             'PROVINCE' => '省份名称',
             'CITY' => '城市名称',
             'COUNTY' => '县区名称',

+ 15 - 0
common/models/Region.php

@@ -13,6 +13,7 @@ use Yii;
  * @property int $DEEP 深度
  * @property string $REGION_NAME 名称
  * @property int $PID 父级id
+ * @property string COUNTRY_ID 国家
  * @property string $AREA_CODE 区号
  * @property int $CREATED_AT 创建时间
  * @property int $UPDATED_AT 更新时间
@@ -56,6 +57,7 @@ class Region extends \common\components\ActiveRecord
             'DEEP' => '深度',
             'REGION_NAME' => '名称',
             'PID' => '父级id',
+            'COUNTRY_ID' => '国家',
             'AREA_CODE' => '区号',
             'CREATED_AT' => '创建时间',
             'UPDATED_AT' => '更新时间',
@@ -98,6 +100,19 @@ class Region extends \common\components\ActiveRecord
         return $data;
     }
 
+    public static function getByCountryId($countyId)
+    {
+        $result = [];
+        $regions = self::getFromCache();
+        foreach ($regions as $region) {
+            if ($region['COUNTRY_ID'] == $countyId) {
+                $result[$region['REGION_CODE']] = $region['REGION_NAME'];
+            }
+        }
+
+        return $result;
+    }
+
     /**
      *  更新缓存
      * @return array|\yii\db\ActiveRecord[]

+ 2 - 11
common/models/ShopGoods.php

@@ -17,11 +17,8 @@ namespace common\models;
  * @property string $COVER 商品封面
  * @property int $IMAGES 商品图片
  * @property string $CONTENT 商品内容
- * @property string $SELL_PRICE 销售价格
  * @property string $SELL_PRICE_STANDARD 标准价格
- * @property string $MARKET_PRICE 市场价格
  * @property int $PRICE_PV 价格PV
- * @property string $TAX_RATE 税率
  * @property int $POINT 兑换积分
  * @property int $STORE_NUMS 库存
  * @property int $IS_DEL 是否删除
@@ -151,9 +148,9 @@ class ShopGoods extends \common\components\ActiveRecord
     public function rules()
     {
         return [
-            [['SELL_DISCOUNT','GOODS_NAME', 'CATE_ID','GIFT_TYPE', 'GOODS_NO', 'SELL_PRICE','MARKET_PRICE','PRICE_PV','STORE_NUMS', 'SELL_TYPE', 'CATEGORY_TYPE', 'SELL_PRICE_STANDARD', 'TAX_RATE'], 'required'],
+            [['SELL_DISCOUNT','GOODS_NAME', 'CATE_ID','GIFT_TYPE', 'GOODS_NO', 'PRICE_PV','STORE_NUMS', 'SELL_TYPE', 'CATEGORY_TYPE', 'SELL_PRICE_STANDARD'], 'required'],
             [['STORE_NUMS'], 'integer'],
-            [['SELL_PRICE','MARKET_PRICE','PRICE_PV','POINT',/* 'SELL_TYPE',*/ 'CATEGORY_TYPE' ,'SELL_PRICE_STANDARD', 'TAX_RATE'], 'number'],
+            [['PRICE_PV','POINT', 'CATEGORY_TYPE' ,'SELL_PRICE_STANDARD'], 'number'],
             [['ID','CATE_ID', 'GOODS_NO','GIFT_TYPE'], 'string', 'max' => 32],
             [['UNIT'], 'string', 'max' => 16],
             [['COVER', 'GOODS_NAME'], 'string', 'max' => 255],
@@ -172,7 +169,6 @@ class ShopGoods extends \common\components\ActiveRecord
             'ID' => 'ID',
             'GOODS_NAME' => '商品名称',
             'CATE_ID' => '所属分类ID',
-            // 'TYPE' => '商品来源',
             'SELL_DISCOUNT' => '会员折扣',
             'GIFT_TYPE' => '商品类型',
             'CATEGORY_TYPE' => '商品分类',
@@ -182,13 +178,8 @@ class ShopGoods extends \common\components\ActiveRecord
             'COVER' => '商品封面',
             'IMAGES' => '商品图片',
             'CONTENT' => '商品内容',
-            'SELL_PRICE' => '销售价格',
             'SELL_PRICE_STANDARD' => 'US price($)',
-            'MARKET_PRICE' => '市场价格',
             'PRICE_PV' => '价格PV',
-            'TAX_RATE' => '税率',
-            'TAX_AMOUNT' => '税额',
-//            'POINT' => '兑换积分',
             'STORE_NUMS' => '库存',
             'STATUS' => '是否上架',
             'IS_DEL' => '是否删除',

+ 53 - 0
common/models/ShopGoodsNature.php

@@ -0,0 +1,53 @@
+<?php
+
+namespace common\models;
+
+/**
+ * This is the model class for table "{{%SHOP_GOODS_NATURE}}".
+ *
+ * @property string ID
+ * @property string GOODS_ID 商品ID
+ * @property string COUNTRY_ID 国家ID
+ * @property int    LOCAL_CURRENCY_ID 汇率ID
+ * @property double MARKET_PRICE 市场价格
+ * @property double SELL_PRICE 销售价格
+ * @property double TAX_RATE 税率
+ */
+class ShopGoodsNature extends \common\components\ActiveRecord
+{
+    /**
+     * @inheritdoc
+     */
+    public static function tableName()
+    {
+        return '{{%SHOP_GOODS_NATURE}}';
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function rules()
+    {
+        return [
+            [['GOODS_ID', 'COUNTRY_ID', 'LOCAL_CURRENCY_ID', 'MARKET_PRICE', 'SELL_PRICE', 'TAX_RATE'], 'required'],
+            [['TAX_RATE', 'MARKET_PRICE', 'SELL_PRICE', 'LOCAL_CURRENCY_ID'], 'number'],
+            [['ID'], 'unique'],
+        ];
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function attributeLabels()
+    {
+        return [
+            'ID' => 'ID',
+            'GOODS_ID' => '商品ID',
+            'COUNTRY_ID' => '国家ID',
+            'LOCAL_CURRENCY_ID' => '汇率ID',
+            'MARKET_PRICE' => '市场价格',
+            'SELL_PRICE' => '销售价格',
+            'TAX_RATE' => '税率',
+        ];
+    }
+}

+ 9 - 3
common/models/User.php

@@ -94,6 +94,8 @@ use common\libs\logging\operate\valueType\Config as ValueTypeConfig;
  * @property int $IS_MODIFY_PASSWORD 是否修改密码
  * @property int $IS_STUDIO 是否是工作室
  * @property string $EMAIL 邮箱
+ * @property string COUNTRY_ID 国家
+ * @property string LANGUAGE_ID
  */
 class User extends \common\components\ActiveRecord
 {
@@ -111,7 +113,7 @@ class User extends \common\components\ActiveRecord
     public function rules()
     {
         return [
-            [['USER_NAME', 'PASSWORD_HASH', 'PAY_PASSWORD', 'REAL_NAME',/* 'ID_CARD',*/ 'AVATAR'], 'required'],
+            [['USER_NAME', 'PASSWORD_HASH', 'PAY_PASSWORD', 'REAL_NAME',/* 'ID_CARD',*/ 'AVATAR', 'COUNTRY_ID'], 'required'],
             [['NATION', 'ID_TYPE', 'BANK_PROVINCE', 'BANK_CITY', 'BANK_COUNTY', 'CREATED_AT', 'UPDATED_AT', 'STATUS', 'DEC_CLOSED', 'DEC_CLOSED_AT', 'PROVINCE', 'CITY', 'COUNTY', 'DELETED', 'DELETED_AT', 'IS_DEC', 'IS_ATLAS', 'IS_RECHARGE','IS_STUDIO',  'PERIOD_AT', 'DEC_PROVINCE', 'DEC_CITY', 'DEC_COUNTY', 'IS_UNION', 'STATUS_AT', 'VERIFIED', 'VERIFIED_AT', 'ALLOW_LOGIN', 'NOT_OPERATING', 'REG_FROM', 'BANK_UPDATED_AT', 'IS_DIRECT_SELLER', 'DEC_LV_UPDATED_AT', 'DEC_LV_UPDATED_PERIOD', 'PART_FUNC_CLOSED', 'LAST_DEC_LV_UPDATED_PERIOD', 'LAST_DEC_LV_UPDATED_AT', 'DEC_CREATED_AT', 'DEC_CREATED_PERIOD', 'PASSWORD_CHANGED', 'SUB_COM_LEADER', 'READ_AGREEMENT', 'IS_FIRST_OPEN', 'IS_MODIFY_PASSWORD'], 'integer'],
             [['ZG_UPGRADE_PV'], 'number'],
             [['ID', 'OPEN_BANK', 'BANK_NO', 'DEC_LV', 'EMP_LV', 'CROWN_LV', 'SUB_COM_ID', 'DEC_ID', 'DEC_ROLE_ID', 'ID_CARD_PREFIX', 'SEX', 'DEC_PHONE', 'GUARANTOR', 'USER_CREATOR', 'USER_UPDATER', 'LAST_DEC_LV', 'EMAIL'], 'string', 'max' => 32],
@@ -216,6 +218,7 @@ class User extends \common\components\ActiveRecord
             'IS_MODIFY_PASSWORD' => Yii::t('app', 'isModifyPassword'),
             'IS_STUDIO' => Yii::t('app', 'isStudio'),
             'EMAIL' => Yii::t('app', 'email'),
+            'COUNTRY_ID' => Yii::t('app', 'country'),
         ];
     }
 
@@ -241,7 +244,7 @@ class User extends \common\components\ActiveRecord
     public static function getBaseInfoFromRedis($userId){
         $userInfo = Yii::$app->redis->hget(Cache::USER_INFO_KEY, $userId);
         if(!$userInfo){
-            $userInfo = static::find()->select('ID,USER_NAME,NATION,REAL_NAME,ID_CARD,ID_TYPE,MOBILE,ADDRESS,STATUS,DEC_LV,LAST_DEC_LV,EMP_LV,CROWN_LV,DEC_CLOSED,AVATAR,OPEN_BANK,BANK_ADDRESS,BANK_NO,VERIFIED,IS_UNION,IS_DEC,IS_ATLAS,IS_RECHARGE,IS_STUDIO,DEC_ROLE_ID,PROVINCE,CITY,COUNTY,EMAIL')->where('ID=:ID', [':ID'=>$userId])->asArray()->one();
+            $userInfo = static::find()->select('ID,USER_NAME,NATION,COUNTRY_ID,LANGUAGE_ID,REAL_NAME,ID_CARD,ID_TYPE,MOBILE,ADDRESS,STATUS,DEC_LV,LAST_DEC_LV,EMP_LV,CROWN_LV,DEC_CLOSED,AVATAR,OPEN_BANK,BANK_ADDRESS,BANK_NO,VERIFIED,IS_UNION,IS_DEC,IS_ATLAS,IS_RECHARGE,IS_STUDIO,DEC_ROLE_ID,PROVINCE,CITY,COUNTY,EMAIL')->where('ID=:ID', [':ID'=>$userId])->asArray()->one();
             Yii::$app->redis->hset(Cache::USER_INFO_KEY, $userId, Json::encode($userInfo));
         } else {
             $userInfo = Json::decode($userInfo);
@@ -255,7 +258,7 @@ class User extends \common\components\ActiveRecord
      * @return mixed
      */
     public static function updateBaseInfoToRedis($userId){
-        $userInfo = static::find()->select('ID,USER_NAME,NATION,REAL_NAME,ID_CARD,ID_TYPE,MOBILE,ADDRESS,STATUS,DEC_LV,LAST_DEC_LV,EMP_LV,CROWN_LV,DEC_CLOSED,AVATAR,OPEN_BANK,BANK_ADDRESS,BANK_NO,VERIFIED,IS_UNION,IS_DEC,IS_ATLAS,IS_RECHARGE,IS_STUDIO,DEC_ROLE_ID,PROVINCE,CITY,COUNTY,EMAIL')->where('ID=:ID', [':ID'=>$userId])->asArray()->one();
+        $userInfo = static::find()->select('ID,USER_NAME,NATION,COUNTRY_ID,LANGUAGE_ID,REAL_NAME,ID_CARD,ID_TYPE,MOBILE,ADDRESS,STATUS,DEC_LV,LAST_DEC_LV,EMP_LV,CROWN_LV,DEC_CLOSED,AVATAR,OPEN_BANK,BANK_ADDRESS,BANK_NO,VERIFIED,IS_UNION,IS_DEC,IS_ATLAS,IS_RECHARGE,IS_STUDIO,DEC_ROLE_ID,PROVINCE,CITY,COUNTY,EMAIL')->where('ID=:ID', [':ID'=>$userId])->asArray()->one();
         return Yii::$app->redis->hset(Cache::USER_INFO_KEY, $userId, Json::encode($userInfo));
     }
 
@@ -369,6 +372,8 @@ class User extends \common\components\ActiveRecord
             'BANK_NO' => $userInfo['BANK_NO'],
 //            'BANK_NO' => Tool::hideBankNo($userInfo['BANK_NO']),
             'EMAIL' => $userInfo['EMAIL'] ?? '',
+            'COUNTRY_ID' => $userInfo['COUNTRY_ID'],
+            'LANGUAGE_ID' => $userInfo['LANGUAGE_ID'],
         ];
     }
 
@@ -438,6 +443,7 @@ class User extends \common\components\ActiveRecord
             'OPEN_BANK' => '开户行',
             'BANK_ADDRESS' => '银行地址',
             'BANK_NO' => '银行卡号',
+            'COUNTRY' => '国家',
             'BANK_PROVINCE' => [
                 'label' => '银行省份',
                 'type' => ValueTypeConfig::REGION_TYPE

+ 72 - 0
common/models/UserImmigrant.php

@@ -0,0 +1,72 @@
+<?php
+
+namespace common\models;
+
+/**
+ * This is the model class for table "{{%USER_IMMIGRANT}}".
+ *
+ * @property int id
+ * @property int user_id 用户ID
+ * @property string before_country_id 移民前国家ID
+ * @property string after_country_id 移民后国家ID
+ * @property int period_num 期数
+ * @property int created_at 创建时间
+ * @property int created_by 创建人
+ */
+class UserImmigrant extends \common\components\ActiveRecord
+{
+    /**
+     * {@inheritdoc}
+     */
+    public static function tableName()
+    {
+        return '{{%USER_IMMIGRANT}}';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function rules()
+    {
+        return [
+            [['user_id', 'before_country_id', 'after_country_id', 'period_num'], 'required'],
+            [['period_num'], 'number'],
+        ];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function attributeLabels()
+    {
+        return [
+            'id' => 'ID',
+            'user_id' => '用户ID',
+            'before_country_id' => '移民前国家ID',
+            'after_country_id' => '移民后国家ID',
+            'period_num' => '期数',
+            'created_at' => '创建时间',
+            'created_by' => '创建人',
+        ];
+    }
+
+    public function beforeCountry()
+    {
+        return $this->hasOne(Countries::class, ['ID' => 'before_country_id']);
+    }
+
+    public function afterCountry()
+    {
+        return $this->hasOne(Countries::class, ['ID' => 'after_country_id']);
+    }
+
+    public function member()
+    {
+        return $this->hasOne(User::class, ['ID' => 'user_id']);
+    }
+
+    public function creater()
+    {
+        return $this->hasOne(User::class, ['ID' => 'created_by']);
+    }
+}

+ 8 - 2
common/models/forms/AdminAddUserForm.php

@@ -52,6 +52,8 @@ class AdminAddUserForm extends Model {
     public $recUserName;
     public $location;
     public $delUserName;
+    public $countryId;
+    public $languageId;
 
     private $_decId;
     private $_delUserId;
@@ -69,7 +71,7 @@ class AdminAddUserForm extends Model {
     public function rules() {
         return [
             [['userName', 'nation', 'realName', /*'idCard',*/ 'mobile', 'address', 'openBank', 'bankAddress', 'bankNo', 'bankAreaSelected', 'decLv', 'areaSelected', 'tel', 'isDec', 'decUserName', 'birthday', 'decRoleId', 'conUserName', 'recUserName', 'location', 'delUserName'], 'trim'],
-            [['userName', 'realName', /*'idCard',*/ 'decLv', 'decUserName', 'conUserName', 'recUserName', 'location'], 'required'],
+            [['userName', 'realName', /*'idCard',*/ 'decLv', 'decUserName', 'conUserName', 'recUserName', 'location', 'countryId', 'languageId'], 'required'],
             [['userName'], 'unique', 'targetClass' => UserInfo::class, 'targetAttribute' => 'USER_NAME'],
             [['conUserName'], 'exist', 'targetClass' => UserInfo::class, 'targetAttribute' => 'USER_NAME'],
             [['recUserName'], 'exist', 'targetClass' => UserInfo::class, 'targetAttribute' => 'USER_NAME'],
@@ -93,7 +95,7 @@ class AdminAddUserForm extends Model {
     public function scenarios() {
         $parentScenarios = parent::scenarios();
         $customScenarios = [
-            'add' => ['userName', 'nation', 'realName', /*'idCard',*/ 'mobile', 'address', 'openBank', 'bankAddress', 'bankNo', 'bankAreaSelected', 'decLv', 'areaSelected', 'tel', 'isDec', 'decUserName', 'birthday', 'decRoleId', 'conUserName', 'recUserName', 'location'],
+            'add' => ['userName', 'nation', 'realName', /*'idCard',*/ 'mobile', 'address', 'openBank', 'bankAddress', 'bankNo', 'bankAreaSelected', 'decLv', 'areaSelected', 'tel', 'isDec', 'decUserName', 'birthday', 'decRoleId', 'conUserName', 'recUserName', 'location', 'countryId', 'languageId'],
             'userDel' => ['delUserName'],
         ];
         return array_merge($parentScenarios, $customScenarios);
@@ -121,6 +123,8 @@ class AdminAddUserForm extends Model {
             'conUserName' => 'Contact person Member No',//接点人会员编号
             'recUserName' => 'Sponsor Member No',
             'location' => 'Resettlement area',//安置区域
+            'countryId' => 'Country',//安置区域
+            'languageId' => 'Language',//安置区域
         ];
     }
 
@@ -253,6 +257,8 @@ class AdminAddUserForm extends Model {
             $user->VERIFIED_AT = Date::nowTime();
             $user->USER_CREATOR = Admin::getAdminNameById(\Yii::$app->user->id);
             $user->IS_RECHARGE = 1;
+            $user->COUNTRY_ID = $this->countryId;
+            $user->LANGUAGE_ID = $this->languageId;
             if (!$user->save()) {
                 throw new Exception(Form::formatErrorsForApi($user->getErrors()));
             }

+ 39 - 8
common/models/forms/ApproachDeclarationForm.php

@@ -12,9 +12,12 @@ use common\helpers\user\Info;
 use common\models\ApproachDecOrder;
 use common\models\ApproachOrder;
 use common\models\ApproachOrderGoods;
+use common\models\Countries;
+use common\models\CurrencyConversions;
 use common\models\DeclarationPackage;
 use common\models\DecOrder;
 use common\models\EmployLevel;
+use common\models\Language;
 use common\models\Order;
 use common\models\OrderGoods;
 use common\models\Period;
@@ -24,6 +27,7 @@ use common\models\ReconsumePoolFlow;
 use common\models\DeclarationLevel;
 use common\models\Region;
 use common\models\ShopGoods;
+use common\models\ShopGoodsNature;
 use common\models\User;
 use common\models\UserInfo;
 use common\models\UserNetwork;
@@ -63,6 +67,7 @@ class ApproachDeclarationForm extends Model
     public $location;
     public $consignee;
     public $acceptMobile;
+    public $countryId;
     public $province;
     public $city;
     public $county;
@@ -70,6 +75,7 @@ class ApproachDeclarationForm extends Model
     public $lgaName;
     public $payType;
     public $decType;
+    public $languageId;
 
     // 传过来的全部数据
     public $allData;
@@ -634,6 +640,13 @@ class ApproachDeclarationForm extends Model
                     throw new Exception(Yii::t('app', 'pleaseSelectTheEntryLevel'));
                 }
 
+                // 报单中心汇率
+                $decCountry = User::getEnCodeInfo(\Yii::$app->user->id)['COUNTRY_ID'];
+                $decUserCurrencyRate = CurrencyConversions::getToUSDRate($decCountry['LOCAL_CURRENCY_ID']);
+                // 升级会员汇率
+                $country = Countries::getById($this->countryId);
+                $currencyRate = CurrencyConversions::getToUSDRate($country['LOCAL_CURRENCY_ID']);
+
                 if ($this->decWay == 1) {
                     $decPackage = DeclarationPackage::findOneAsArray('ID=:ID', [':ID' => $this->packageId]);
                     $this->_decAmount = $decPackage['AMOUNT'];
@@ -654,19 +667,25 @@ class ApproachDeclarationForm extends Model
                     $totalAmount = 0;
                     $totalAmountStandard = 0;
                     $totalPv = 0;
-                    $exchangeRate = floatval(Cache::getSystemConfig()['exchangeRate']['VALUE'] ?? 0); // 汇率
+
                     foreach ($this->goodsNum as $k => $v) {
                         if ($v) {
                             $goods = ShopGoods::findOneAsArray('ID=:ID AND STATUS=1', [':ID' => $ids[$k]]);
                             if ($goods['STORE_NUMS'] > 0) {
-                                $totalAmount += $goods['SELL_PRICE'] * intval($v);
+                                $goodsNature = ShopGoodsNature::findOneAsArray('GOODS_ID=:GOODS_ID AND COUNTRY_ID=:COUNTRY_ID',
+                                    [':GOODS_ID' => $ids[$k], ':COUNTRY_ID' => $this->countryId]);
+                                if (!$goodsNature) {
+                                    throw new Exception(Yii::t('app', 'productsDoesSoldOut'));
+                                }
+
+                                $totalAmount += $goodsNature['SELL_PRICE'] * intval($v);
                                 $totalAmountStandard += $goods['SELL_PRICE_STANDARD'] * intval($v);
                                 $realPriceStandard = $goods['SELL_PRICE_STANDARD'];
                                 $totalPv += $goods['PRICE_PV'] * intval($v);
                                 $this->_orderGoods[] = [
                                     'GOODS_ID' => $goods['ID'],
-                                    'PRICE' => $goods['SELL_PRICE'],
-                                    'REAL_PRICE' => $goods['SELL_PRICE'],
+                                    'PRICE' => $goodsNature['SELL_PRICE'],
+                                    'REAL_PRICE' => $goodsNature['SELL_PRICE'],
                                     'PV' => $goods['PRICE_PV'],
                                     'REAL_PV' => $goods['PRICE_PV'],
                                     'POINT' => $goods['POINT'],
@@ -676,8 +695,8 @@ class ApproachDeclarationForm extends Model
                                     'EMAIL' => $this->email,
                                     'STANDARD_PRICE' => $goods['SELL_PRICE_STANDARD'],
                                     'REAL_STANDARD_PRICE' => $realPriceStandard,
-                                    'EXCHANGE_RATE' => $exchangeRate,
-                                    'TAX_RATE' => $goods['TAX_RATE'],
+                                    'EXCHANGE_RATE' => $currencyRate,
+                                    'TAX_RATE' => $goodsNature['TAX_RATE'],
                                 ];
                             }
                             if($goods['INSTALMENT']>0){
@@ -777,6 +796,8 @@ class ApproachDeclarationForm extends Model
         $user->VERIFIED = 1;
         $user->VERIFIED_AT = Date::nowTime();
         $user->IS_RECHARGE = 1;
+        $user->COUNTRY_ID = $this->countryId;
+        $user->LANGUAGE_ID = $this->languageId ?? Language::getEn();
         if (!$user->save()) {
             throw new Exception(Form::formatErrorsForApi($user->getErrors()));
         }
@@ -847,7 +868,14 @@ class ApproachDeclarationForm extends Model
         } else {
             $warehouse = '01';
         }
-        $exchangeRate = floatval(Cache::getSystemConfig()['exchangeRate']['VALUE'] ?? 0);
+
+        // 升级会员
+        $userCountry = User::getEnCodeInfo($this->_insertUserId);
+        $userCurrencyRate = CurrencyConversions::getToUSDRate($userCountry['LOCAL_CURRENCY_ID']);
+        // 报单中心汇率
+        $decCountry = User::getEnCodeInfo(\Yii::$app->user->id)['COUNTRY_ID'];
+        $decUserCurrencyRate = CurrencyConversions::getToUSDRate($decCountry['LOCAL_CURRENCY_ID']);
+
         $orderModel = new ApproachOrder();
         $orderModel->SN = 'OS' . $ord;
         $orderModel->DEC_SN = 'DS' . $ord;
@@ -878,7 +906,9 @@ class ApproachDeclarationForm extends Model
         $orderModel->CREATE_USER = Info::getUserNameByUserId(\Yii::$app->user->id);
         $orderModel->ORDER_AMOUNT_STANDARD = $this->_decAmountStandard;
         $orderModel->PAY_AMOUNT_STANDARD = $this->_standardAmount;
-        $orderModel->EXCHANGE_RATE = $exchangeRate;
+        $orderModel->EXCHANGE_RATE = $userCurrencyRate;
+        $orderModel->COUNTRY_ID = $userCountry['COUNTRY_ID'];
+        $orderModel->CURRENCY_ID = $userCountry['LOCAL_CURRENCY_ID'] ?? 0;
         if ($this->province==1) {
             $orderModel->EXPRESS_TYPE = 1;
         }
@@ -900,6 +930,7 @@ class ApproachDeclarationForm extends Model
             $addressModel->USER_NAME = $this->insertUserName;
             $addressModel->CONSIGNEE = $this->consignee;
             $addressModel->MOBILE = $this->acceptMobile;
+            $addressModel->COUNTRY_ID = $userCountry['COUNTRY_ID'];
             $addressModel->PROVINCE = $this->province;
             $addressModel->CITY_NAME = $this->cityName;
             $addressModel->LGA_NAME = $this->lgaName;

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

@@ -4,6 +4,7 @@ namespace common\models\forms;
 use common\components\Model;
 use common\helpers\Cache;
 use common\helpers\Form;
+use common\models\ShopGoodsNature;
 use common\models\UserBind;
 use Yii;
 use yii\base\Exception;
@@ -147,6 +148,12 @@ class ApproachDeclarationLoopForm extends Model
                         if (!$goods) {
                             throw new Exception(Yii::t('app', 'productsDoesSoldOut'));
                         }
+                        $goodsNature = ShopGoodsNature::findOneAsArray('GOODS_ID=:GOODS_ID AND COUNTRY_ID=:COUNTRY_ID',
+                            [':GOODS_ID' => $value['goodsId'][$i], ':COUNTRY_ID' => $value['countryId']]);
+                        if (!$goodsNature) {
+                            throw new Exception(Yii::t('app', 'productsDoesSoldOut'));
+                        }
+
                         if($goods['INSTALMENT']>0){ // 分期的商品
                             if($value['goodsNum'][$i]>1){ // 只能购买一个
                                 throw new Exception(Yii::t('app', 'allowOnlyOne'));

+ 34 - 8
common/models/forms/ApproachDeclarationUpgradeForm.php

@@ -11,6 +11,8 @@ use common\models\ApproachDecOrder;
 use common\models\ApproachOrder;
 use common\models\ApproachOrderGoods;
 use common\models\Config;
+use common\models\Countries;
+use common\models\CurrencyConversions;
 use common\models\DeclarationLevel;
 use common\models\DeclarationPackage;
 use common\models\DecLevelLog;
@@ -23,6 +25,7 @@ use common\models\Period;
 use common\models\ReceiveAddress;
 use common\models\Region;
 use common\models\ShopGoods;
+use common\models\ShopGoodsNature;
 use common\models\User;
 use common\models\UserInfo;
 use common\models\UserNetwork;
@@ -138,6 +141,14 @@ class ApproachDeclarationUpgradeForm extends Model
             if ($this->decWay != 2) {
                 throw new Exception(Yii::t('app', 'upgradeMethodIncorrect'), 400);
             }
+
+            // 报单中心汇率
+            $decCountry = User::getEnCodeInfo(\Yii::$app->user->id)['COUNTRY_ID'];
+            $decUserCurrencyRate = CurrencyConversions::getToUSDRate($decCountry['LOCAL_CURRENCY_ID']);
+            // 升级会员汇率
+            $country = Countries::getById($baseInfo['COUNTRY_ID']);
+            $currencyRate = CurrencyConversions::getToUSDRate($country['LOCAL_CURRENCY_ID']);
+
             if($this->decWay==1) {
                 // 先不加套餐升级方式
                 // $decPackage = DeclarationPackage::findOneAsArray('ID=:ID', [':ID'=>$this->packageId]);
@@ -158,22 +169,28 @@ class ApproachDeclarationUpgradeForm extends Model
                 $totalAmount = 0;
                 $totalAmountStandard = 0;
                 $totalPv = 0;
-                $exchangeRate = floatval(Cache::getSystemConfig()['exchangeRate']['VALUE'] ?? 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('Products does not exists!');
                         }
+                        $goodsNature = ShopGoodsNature::findOneAsArray('GOODS_ID=:GOODS_ID AND COUNTRY_ID=:COUNTRY_ID',
+                            [':GOODS_ID' => $ids[$k], ':COUNTRY_ID' => $baseInfo['COUNTRY_ID']]);
+                        if (!$goodsNature) {
+                            throw new Exception(Yii::t('app', 'productsDoesSoldOut'));
+                        }
+
                         if($goods['STORE_NUMS']>0){
-                            $totalAmount += $goods['SELL_PRICE'] * intval($v);
+                            $totalAmount += $goodsNature['SELL_PRICE'] * intval($v);
                             $totalAmountStandard += $goods['SELL_PRICE_STANDARD'] * intval($v);
                             $realPriceStandard = $goods['SELL_PRICE_STANDARD'];
                             $totalPv += $goods['PRICE_PV'] * intval($v);
                             $this->_orderGoods[] = [
                                 'GOODS_ID' => $goods['ID'],
-                                'PRICE' => $goods['SELL_PRICE'],
-                                'REAL_PRICE' => $goods['SELL_PRICE'],
+                                'PRICE' => $goodsNature['SELL_PRICE'],
+                                'REAL_PRICE' => $goodsNature['SELL_PRICE'],
                                 'PV' => $goods['PRICE_PV'],
                                 'REAL_PV' => $goods['PRICE_PV'],
                                 'POINT' => $goods['POINT'],
@@ -183,8 +200,8 @@ class ApproachDeclarationUpgradeForm extends Model
                                 'EMAIL' => Info::getUserEmailByUserId(\Yii::$app->user->id) ?? '',
                                 'STANDARD_PRICE' => $goods['SELL_PRICE_STANDARD'],
                                 'REAL_STANDARD_PRICE' => $realPriceStandard,
-                                'EXCHANGE_RATE' => $exchangeRate,
-                                'TAX_RATE' => $goods['TAX_RATE'],
+                                'EXCHANGE_RATE' => $currencyRate,
+                                'TAX_RATE' => $goodsNature['TAX_RATE'],
                             ];
                         }
                         if($goods['INSTALMENT']>0){ // 如果有分期付款商品,检查用户的分期付款状态
@@ -310,7 +327,13 @@ class ApproachDeclarationUpgradeForm extends Model
                 throw new Exception(Form::formatErrorsForApi($decOrderModel->getErrors()));
             }
 
-            $exchangeRate = floatval(Cache::getSystemConfig()['exchangeRate']['VALUE'] ?? 0);
+            // 升级会员
+            $userCountry = User::getEnCodeInfo($this->_insertUserId);
+            $userCurrencyRate = CurrencyConversions::getToUSDRate($userCountry['LOCAL_CURRENCY_ID']);
+            // 报单中心汇率
+            $decCountry = User::getEnCodeInfo(\Yii::$app->user->id)['COUNTRY_ID'];
+            $decUserCurrencyRate = CurrencyConversions::getToUSDRate($decCountry['LOCAL_CURRENCY_ID']);
+
             $orderModel = new ApproachOrder();
             $orderModel->SN = 'OS' . $ord;
             $orderModel->DEC_SN = 'DS' . $ord;
@@ -340,7 +363,9 @@ class ApproachDeclarationUpgradeForm extends Model
             $orderModel->EMAIL = Info::getUserEmailByUserId(\Yii::$app->user->id) ?? '';
             $orderModel->ORDER_AMOUNT_STANDARD = $this->_decAmountStandard;
             $orderModel->PAY_AMOUNT_STANDARD = $this->_standardAmount;
-            $orderModel->EXCHANGE_RATE = $exchangeRate;
+            $orderModel->EXCHANGE_RATE = $userCurrencyRate;
+            $orderModel->COUNTRY_ID = $userCountry['COUNTRY_ID'];
+            $orderModel->CURRENCY_ID = $userCountry['LOCAL_CURRENCY_ID'] ?? 0;
             if(!$orderModel->save()){
                 $transaction->rollBack();
                 throw new Exception(Form::formatErrorsForApi($orderModel->getErrors()));
@@ -383,6 +408,7 @@ class ApproachDeclarationUpgradeForm extends Model
             $addressModel->USER_NAME = $this->insertUserName;
             $addressModel->CONSIGNEE = $this->consignee;
             $addressModel->MOBILE = $this->acceptMobile;
+            $addressModel->COUNTRY_ID = $userCountry['COUNTRY_ID'];
             $addressModel->PROVINCE = $this->province;
             $addressModel->LGA_NAME = $this->lgaName;
             $addressModel->CITY_NAME = $this->cityName;

+ 32 - 11
common/models/forms/ApproachOrderForm.php

@@ -16,15 +16,19 @@ use common\models\ApproachDecOrder;
 use common\models\ApproachOrder;
 use common\models\ApproachOrderGoods;
 use common\models\BaUser;
+use common\models\Countries;
+use common\models\CurrencyConversions;
 use common\models\DealType;
 use common\models\DecLevelLog;
 use common\models\DecOrder;
+use common\models\FreeTemplate;
 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\ShopGoodsNature;
 use common\models\User;
 use common\models\UserNetwork;
 use common\models\Instalment;
@@ -50,6 +54,7 @@ class ApproachOrderForm extends Model
     public $goodsNum;
     public $payPassword;
     public $email;
+    public $exchangeRate;
 
     public $userName;
     public $decUserName;
@@ -415,22 +420,31 @@ class ApproachOrderForm extends Model
         $goodsType = ShopGoods::getGoodType();
         $hasInstalment = 0;
         $loginUserId = \Yii::$app->user->id;
-        $exchangeRate = floatval(Cache::getSystemConfig()['exchangeRate']['VALUE'] ?? 0); // 汇率
+        $user = User::getEnCodeInfo(\Yii::$app->user->id);
+
         foreach ($this->goodsNum as $k => $v) {
             if ($v) {
                 $goods = ShopGoods::findOneAsArray('ID=:ID AND STATUS=1',[':ID'=> $ids[$k]]);
                 if (!$goods) {
                     throw new Exception(Yii::t('app', 'productsDoesSoldOut'));
                 }
+                $goodsNature = ShopGoodsNature::findOneAsArray('GOODS_ID=:GOODS_ID AND COUNTRY_ID=:COUNTRY_ID',
+                    [':GOODS_ID' => $ids[$k], ':COUNTRY_ID' => $user['COUNTRY_ID']]);
+                if (!$goodsNature) {
+                    throw new Exception(Yii::t('app', 'productsDoesSoldOut'));
+                }
+                // 汇率
+                $this->exchangeRate = CurrencyConversions::getToUSDRate($goodsNature['LOCAL_CURRENCY_ID']);
+
                 if($goods['STORE_NUMS']>0){
                     if ($goods['TYPE'] == 1 || $goods['TYPE'] == 2) {
                         $discount = $goodsType[$goods['TYPE']]['discount'];
-                        $realPrice = $goods['SELL_PRICE'] * $discount/100;
+                        $realPrice = $goodsNature['SELL_PRICE'] * $discount/100;
                         $realPv = $goods['PRICE_PV'] * $discount/100;
                         $realPriceStandard = $goods['SELL_PRICE_STANDARD'] * $discount/100;
                     } else {
                         $discount = $goods['SELL_DISCOUNT'];
-                        $realPrice = $goods['SELL_PRICE'] * $discount;
+                        $realPrice = $goodsNature['SELL_PRICE'] * $discount;
                         $realPv = $goods['PRICE_PV'] * $discount;
                         $realPriceStandard = $goods['SELL_PRICE_STANDARD'] * $discount;
                     }
@@ -440,13 +454,13 @@ class ApproachOrderForm extends Model
 
                     $this->_orderGoods[] = [
                         'GOODS_ID' => $goods['ID'],
-                        'PRICE' => $goods['SELL_PRICE'],
+                        'PRICE' => $goodsNature['SELL_PRICE'],
                         'PV' => $goods['PRICE_PV'],
                         'REAL_PRICE' => $realPrice,
                         'REAL_PV' => $realPv,
                         'POINT' => $goods['POINT'],
                         'BUY_NUMS' => intval($v),
-                        'TAX_RATE' => $goods['TAX_RATE'],
+                        'TAX_RATE' => $goodsNature['TAX_RATE'],
                         'SKU_CODE' => $goods['GOODS_NO'],
                         'GOODS_TITLE' => $goods['GOODS_NAME'],
                         'CATEGORY_TYPE' => $goods['CATEGORY_TYPE'],
@@ -454,7 +468,7 @@ class ApproachOrderForm extends Model
                         'EMAIL' => $this->email,
                         'STANDARD_PRICE' => $goods['SELL_PRICE_STANDARD'],
                         'REAL_STANDARD_PRICE' => $realPriceStandard,
-                        'EXCHANGE_RATE' => $exchangeRate,
+                        'EXCHANGE_RATE' => $goodsNature['TAX_RATE'],
                     ];
                 }
                 if($goods['INSTALMENT']>0){ // 如果有分期付款商品,检查用户的分期付款状态
@@ -488,10 +502,12 @@ class ApproachOrderForm extends Model
             }
         }
 
-        // 运费.奈拉
-        $freight = floatval(Cache::getSystemConfig()['freight']['VALUE'] ?? 0);
-        // 普通商品免运费阈值.奈拉
-        $freeShipping = floatval(Cache::getSystemConfig()['freeShipping']['VALUE'] ?? 0);
+        // 运费模板
+        $freeTemplate = FreeTemplate::getByCountryId($user['COUNTRY_ID']);
+        // 运费
+        $freight = $freeTemplate['freight'] ?? 0;
+        // 普通商品免运费阈值
+        $freeShipping = $freeTemplate['free_shipping'] ?? 0;
 
         $this->_decAmount = $totalAmount;
         $this->_decPv = $totalPv;
@@ -542,11 +558,14 @@ class ApproachOrderForm extends Model
         $nowCalcMonth = $periodObj->getYearMonth($nowPeriodNum);
 
         $userId = \Yii::$app->user->id;
+        $user = User::getEnCodeInfo(\Yii::$app->user->id);
 
         $userName = Info::getUserNameByUserId($userId);
         $userRealName = Info::getUserRealNameByUserId($userId);
         $userMobile = Info::getUserMobileByUserId($userId);
         $userEmail = Info::getUserEmailByUserId($userId);
+        $country = Countries::getById($user['COUNTRY_ID']);
+
         $exchangeRate = floatval(Cache::getSystemConfig()['exchangeRate']['VALUE'] ?? 0);
         // 加入订单信息
         if ($this->_address['PROVINCE'] != 1) {
@@ -593,7 +612,9 @@ class ApproachOrderForm extends Model
         $orderModel->EMAIL = $userEmail?$userEmail:$userName.'@elken.net';
         $orderModel->ORDER_AMOUNT_STANDARD = $this->_decAmountStandard;
         $orderModel->PAY_AMOUNT_STANDARD = $this->_standardAmount;
-        $orderModel->EXCHANGE_RATE = $exchangeRate;
+        $orderModel->EXCHANGE_RATE = $this->exchangeRate;
+        $orderModel->COUNTRY_ID = $user['COUNTRY_ID'];
+        $orderModel->CURRENCY_ID = $country['LOCAL_CURRENCY_ID'] ?? 0;
         if($this->_address['PROVINCE']==1){
             $orderModel->EXPRESS_TYPE = 1;
             $orderModel->CONSIGNEE = $userRealName;

+ 0 - 44
common/models/forms/ConfigForm.php

@@ -309,48 +309,4 @@ class ConfigForm extends Model
         ]);
         return true;
     }
-
-    /**
-     * 更新汇率配置
-     * @return bool|null
-     */
-    public function updateExchangeRate(): ?bool
-    {
-        if(!$this->validate()){
-            return null;
-        }
-
-        $beforeData = Config::getConfigByType('exchangeRate');
-        $this->adminOperateLogger->saveBeforeContent = $beforeData;
-
-        $postData = \Yii::$app->request->post();
-        $transaction = \Yii::$app->db->beginTransaction();
-        try{
-            Config::updateAll(['VALUE' => $postData['VALUE'], 'UPDATED_AT' => Date::nowTime()], "CONFIG_NAME=:CONFIG_NAME", [':CONFIG_NAME' => 'exchangeRate']);
-
-            if ($postData['synchronize']) {
-                unset($postData['synchronize']);
-                // 异步属性商品价格
-                $taskKey = \Yii::$app->swooleAsyncTimer->asyncHandle('config/update-exchange-rate', $postData);
-                if($taskKey === false){
-                    throw new Exception('请求异步服务器失败');
-                }
-            }
-
-            $transaction->commit();
-        } catch (Exception $e){
-            $transaction->rollBack();
-            $this->addError('updateExchangeRate', $e->getMessage());
-            return null;
-        }
-
-        $afterData = Config::getConfigByType('exchangeRate');
-        $this->adminOperateLogger->saveAfterContent = $afterData;
-        unset($beforeData,$afterData);
-        $this->adminOperateLogger->clean()->save([
-            'optType' => '更新汇率配置',
-        ]);
-
-        return true;
-    }
 }

+ 123 - 0
common/models/forms/CurrenciesConversionsForm.php

@@ -0,0 +1,123 @@
+<?php
+namespace common\models\forms;
+
+use common\components\Model;
+use common\helpers\Cache;
+use common\helpers\Date;
+use common\helpers\Form;
+use common\helpers\LoggerTool;
+use common\helpers\snowflake\PageSnowFake;
+use common\libs\logging\operate\AdminOperate;
+use common\models\CurrencyConversions;
+use common\models\Period;
+use common\models\ShopGoods;
+use StatusEnum;
+use yii\base\Exception;
+
+/**
+ * Login form
+ */
+class CurrenciesConversionsForm extends Model
+{
+    public $modelClass = CurrencyConversions::class;
+
+    public $from_currency_id;
+    public $to_currency_id;
+    public $rate;
+    public $synchronize;
+
+    private $period;
+
+    public function init() {
+        parent::init();
+        $this->adminOperateLogger = new AdminOperate([
+            'fetchClass' => CurrencyConversions::class,
+        ]);
+
+        $this->period = Period::instance();
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function rules()
+    {
+        return [
+            [['from_currency_id', 'to_currency_id', 'rate'], 'required'],
+        ];
+    }
+
+    public function attributeLabels()
+    {
+        return [
+            'from_currency_id' => 'From Currency Name', // 源汇率
+            'to_currency_id' => 'To Currency Name', // 目标汇率
+            'rate' => 'Rate', // 汇率
+        ];
+    }
+
+    /**
+     * 指定场景
+     * @return array
+     */
+    public function scenarios()
+    {
+        $parentScenarios =  parent::scenarios();
+        $customScenarios = [
+            'setCurrenciesConversions' => ['from_currency_id', 'to_currency_id', 'rate'],
+        ];
+
+        return array_merge($parentScenarios, $customScenarios);
+    }
+
+
+    /**
+     * 设置汇率.
+     * @return true
+     * @throws \yii\db\Exception
+     */
+    public function setCurrenciesConversions(): ?bool
+    {
+        if (!$this->validate()) {
+            return null;
+        }
+
+        $postData = \Yii::$app->request->post();
+
+        $transaction = \Yii::$app->db->beginTransaction();
+        try {
+            // 删除原记录
+            $this->modelClass::updateOne($this->from_currency_id, $this->to_currency_id);
+            // 添加新数据
+            $model = new CurrencyConversions();
+            $model->ID = PageSnowFake::instance()->generateId();
+            $model->PERIOD_NUM = $this->period->getNowPeriodNum();
+            $model->FROM_CURRENCY_ID = $this->from_currency_id;
+            $model->TO_CURRENCY_ID = $this->to_currency_id;
+            $model->RATE = $this->rate;
+            $model->ACTIVE = StatusEnum::ACTIVE;
+            $model->CREATED_AT = Date::nowTime();
+            $model->CREATED_BY = $this->goodsNo;
+            if (!$model->save()) {
+                throw new Exception(Form::formatErrorsForApi($model->getErrors()));
+            }
+
+            // 选择商品汇率同步,并且美元汇率变化时,更新商品属性
+            if ($postData['synchronize'] && (($this->from_currency_id == 104) || ($this->to_currency_id == 104))) {
+                // 异步属性商品价格
+                $taskKey = \Yii::$app->swooleAsyncTimer->asyncHandle('config/update-exchange-rate', $model->ID);
+                if($taskKey === false){
+                    throw new \yii\db\Exception('请求异步服务器失败');
+                }
+            }
+
+            $transaction->commit();
+        } catch (Exception $e) {
+            $transaction->rollBack();
+            $this->addError('edit', $e->getMessage());
+            return null;
+        }
+
+        return true;
+    }
+}

+ 54 - 14
common/models/forms/DeclarationForm.php

@@ -5,13 +5,17 @@ use common\components\Model;
 use common\helpers\Cache;
 use common\helpers\Date;
 use common\helpers\Form;
+use common\helpers\Tool;
 use common\helpers\user\Cash;
 use common\helpers\user\Reconsume;
 use common\helpers\user\Info;
 use common\models\BaUser;
+use common\models\Countries;
+use common\models\CurrencyConversions;
 use common\models\DeclarationPackage;
 use common\models\DecOrder;
 use common\models\EmployLevel;
+use common\models\Language;
 use common\models\Order;
 use common\models\OrderGoods;
 use common\models\Period;
@@ -21,6 +25,7 @@ use common\models\ReconsumePoolFlow;
 use common\models\DeclarationLevel;
 use common\models\Region;
 use common\models\ShopGoods;
+use common\models\ShopGoodsNature;
 use common\models\User;
 use common\models\UserInfo;
 use common\models\UserNetwork;
@@ -60,12 +65,14 @@ class DeclarationForm extends Model
     public $location;
     public $consignee;
     public $acceptMobile;
+    public $countryId;
     public $province;
     public $city;
     public $county;
     public $cityName;
     public $lgaName;
     public $decType;
+    public $languageId;
 
     // 传过来的全部数据
     public $allData;
@@ -165,6 +172,7 @@ class DeclarationForm extends Model
             'location' => 'market', // 市场
             'consignee' => 'Recipient', // 收货人
             'acceptMobile' => 'Recipient Phone Number', // 收货人手机
+            'countryId' => 'Country',
             'province' => 'Receiving Province',//收货省
             'city' => 'Receiving City',//收货市
             'county' => 'Receiving area / county',//收货区县
@@ -180,7 +188,7 @@ class DeclarationForm extends Model
     {
         $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', 'email'],
+            'userDec' => ['type','allData', 'decLv','decWay','insertUserName','password','payPassword', 'realName',/* 'insertUserIdCard',*/ 'mobile', 'address', 'openBank', 'bankAddress', 'bankNo', 'bankProvince','bankCity','bankCounty', 'consignee','acceptMobile','countryId', 'province',/*'city','county',*/ 'conUserName', 'recUserName','decUserName', 'location', 'email'],
             'canDec' => ['type', 'insertUserName',/* 'insertUserIdCard',*/ 'conUserName', 'recUserName', 'location'],
             'notFull' => ['type', 'insertUserName', 'conUserName', 'recUserName', 'location'],
         ];
@@ -649,6 +657,14 @@ class DeclarationForm extends Model
             if(!$this->decLv){
                 throw new Exception(Yii::t('app', 'pleaseSelectTheEntryLevel'));
             }
+
+            // 报单中心汇率
+            $decCountry = User::getEnCodeInfo(\Yii::$app->user->id)['COUNTRY_ID'];
+            $decUserCurrencyRate = CurrencyConversions::getToUSDRate($decCountry['LOCAL_CURRENCY_ID']);
+            // 升级会员汇率
+            $country = Countries::getById($this->countryId);
+            $currencyRate = CurrencyConversions::getToUSDRate($country['LOCAL_CURRENCY_ID']);
+
             if($this->decWay==1) {
                 $decPackage = DeclarationPackage::findOneAsArray('ID=:ID', [':ID'=>$this->packageId]);
                 $this->_decAmount = $decPackage['AMOUNT'];
@@ -677,19 +693,25 @@ class DeclarationForm extends Model
                 $totalAmount = 0;
                 $totalAmountStandard = 0;
                 $totalPv = 0;
-                $exchangeRate = floatval(Cache::getSystemConfig()['exchangeRate']['VALUE'] ?? 0); // 汇率
+
                 foreach ($this->goodsNum as $k => $v) {
                     if ($v) {
                         $goods = ShopGoods::findOneAsArray('ID=:ID AND STATUS=1',[':ID'=> $ids[$k]]);
                         if($goods['STORE_NUMS']>0){
-                            $totalAmount += $goods['SELL_PRICE'] * intval($v);
+                            $goodsNature = ShopGoodsNature::findOneAsArray('GOODS_ID=:GOODS_ID AND COUNTRY_ID=:COUNTRY_ID',
+                                [':GOODS_ID' => $ids[$k], ':COUNTRY_ID' => $this->countryId]);
+                            if (!$goodsNature) {
+                                throw new Exception(Yii::t('app', 'productsDoesSoldOut'));
+                            }
+
+                            $totalAmount += $goodsNature['SELL_PRICE'] * intval($v);
                             $totalAmountStandard += $goods['SELL_PRICE_STANDARD'] * intval($v);
                             $realPriceStandard = $goods['SELL_PRICE_STANDARD'];
                             $totalPv += $goods['PRICE_PV'] * intval($v);
                             $this->_orderGoods[] = [
                                 'GOODS_ID' => $goods['ID'],
-                                'PRICE' => $goods['SELL_PRICE'],
-                                'REAL_PRICE' => $goods['SELL_PRICE'],
+                                'PRICE' => $goodsNature['SELL_PRICE'],
+                                'REAL_PRICE' => $goodsNature['SELL_PRICE'],
                                 'PV' => $goods['PRICE_PV'],
                                 'REAL_PV' => $goods['PRICE_PV'],
                                 'POINT' => $goods['POINT'],
@@ -697,11 +719,12 @@ class DeclarationForm extends Model
                                 'SKU_CODE' => $goods['GOODS_NO'],
                                 'GOODS_TITLE' => $goods['GOODS_NAME'],
                                 'EMAIL' => $this->email,
-                                'TAX_RATE' => $goods['TAX_RATE'],
+                                'TAX_RATE' => $goodsNature['TAX_RATE'],
                                 'STANDARD_PRICE' => $goods['SELL_PRICE_STANDARD'],
                                 'REAL_STANDARD_PRICE' => $realPriceStandard,
-                                'EXCHANGE_RATE' => $exchangeRate,
+                                'EXCHANGE_RATE' => $currencyRate,
                             ];
+
                             // 更改库存和状态
                             $data = ShopGoods::find()->where(['ID' => $goods['ID']])->one();
                             $data->STORE_NUMS = $data->STORE_NUMS - intval($v);
@@ -743,10 +766,14 @@ class DeclarationForm extends Model
                 $this->_decAmountStandard = $totalAmountStandard;
                 $this->_standardAmount = $this->_decAmountStandard;
             }
+
             //看现金余额是否充足
             $loginUserId = \Yii::$app->user->id;
-            if (Cash::getAvailableBalance($loginUserId) < $this->_decAmount){
-                throw new Exception(Yii::t('app', 'applicantCashShort'));
+            $decCash = Cash::getAvailableBalance($loginUserId);
+            // 转换后的余额
+            $localCash = Tool::convertAmount($decCash, $decUserCurrencyRate, $currencyRate);
+            if ($localCash < $this->_decAmount){
+                throw new Exception(Yii::t('app', 'applicantCashShort'), 400);
             }
 
             if(!($zcResult = $this->addUser($allData))) {
@@ -808,6 +835,8 @@ class DeclarationForm extends Model
         $user->VERIFIED = 1;
         $user->VERIFIED_AT = Date::nowTime();
         $user->IS_RECHARGE = 1;
+        $user->COUNTRY_ID = $this->countryId;
+        $user->LANGUAGE_ID = $this->languageId ?? Language::getEn();
 
         if (!$user->save()) {
             throw new Exception(Form::formatErrorsForApi($user->getErrors()));
@@ -879,7 +908,14 @@ class DeclarationForm extends Model
         }else{
             $warehouse = '01';
         }
-        $exchangeRate = floatval(Cache::getSystemConfig()['exchangeRate']['VALUE'] ?? 0);
+
+        // 升级会员
+        $userCountry = User::getEnCodeInfo($this->_insertUserId);
+        $userCurrencyRate = CurrencyConversions::getToUSDRate($userCountry['LOCAL_CURRENCY_ID']);
+        // 报单中心汇率
+        $decCountry = User::getEnCodeInfo(\Yii::$app->user->id)['COUNTRY_ID'];
+        $decUserCurrencyRate = CurrencyConversions::getToUSDRate($decCountry['LOCAL_CURRENCY_ID']);
+
         $orderModel = new Order();
         $orderModel->SN = 'OS'.$ord;
         $orderModel->DEC_SN = 'DS'.$ord;
@@ -911,7 +947,9 @@ class DeclarationForm extends Model
         $orderModel->CREATE_USER = Info::getUserNameByUserId(\Yii::$app->user->id);
         $orderModel->ORDER_AMOUNT_STANDARD = $this->_decAmountStandard;
         $orderModel->PAY_AMOUNT_STANDARD = $this->_standardAmount;
-        $orderModel->EXCHANGE_RATE = $exchangeRate;
+        $orderModel->EXCHANGE_RATE = $userCurrencyRate;
+        $orderModel->COUNTRY_ID = $userCountry['COUNTRY_ID'];
+        $orderModel->CURRENCY_ID = $userCountry['LOCAL_CURRENCY_ID'] ?? 0;
         if($this->province==1){
             $orderModel->EXPRESS_TYPE = 1;
         }
@@ -925,6 +963,8 @@ class DeclarationForm extends Model
         }
         OrderGoods::batchInsert($this->_orderGoods);
 
+        // 支付金额
+        $decAmount = Tool::convertAmount($this->_decAmount, $userCurrencyRate, $decUserCurrencyRate);
         //写入收货地址信息,判断province字段,当不为1时,插入收货地址信息
         if($this->province!=1){
             $addressModel = new ReceiveAddress();
@@ -932,6 +972,7 @@ class DeclarationForm extends Model
             $addressModel->USER_NAME = $this->insertUserName;
             $addressModel->CONSIGNEE = $this->consignee;
             $addressModel->MOBILE = $this->acceptMobile;
+            $addressModel->COUNTRY_ID = $userCountry['COUNTRY_ID'];
             $addressModel->PROVINCE = $this->province;
 //            $addressModel->CITY = $this->city;
 //            $addressModel->COUNTY = intval($this->county) ?? 0;
@@ -943,12 +984,11 @@ class DeclarationForm extends Model
                 throw new Exception(Form::formatErrorsForApi($addressModel->getErrors()));
             }
             //扣报单人现金钱包
-//            Cash::changeUserCash(\Yii::$app->user->id, 'CASH', -abs($this->_decAmount), ['REMARK' =>'为'.$this->insertUserName.'报单', 'ORDER_SN' => $orderModel->SN]);
-            Cash::changeUserCash(\Yii::$app->user->id, 'CASH', -abs($this->_decAmount), ['REMARK' =>'To'.$this->insertUserName.'Entry', 'ORDER_SN' => $orderModel->SN]);
+            Cash::changeUserCash(\Yii::$app->user->id, 'CASH', -abs($decAmount), ['REMARK' =>'To'.$this->insertUserName.'Entry', 'ORDER_SN' => $orderModel->SN]);
             return $addressModel;
         }else{
             $addressModel = new ReceiveAddress();
-            Cash::changeUserCash(\Yii::$app->user->id, 'CASH', -abs($this->_decAmount), ['REMARK' =>'To'.$this->insertUserName.'Entry', 'ORDER_SN' => $orderModel->SN]);
+            Cash::changeUserCash(\Yii::$app->user->id, 'CASH', -abs($decAmount), ['REMARK' =>'To'.$this->insertUserName.'Entry', 'ORDER_SN' => $orderModel->SN]);
             return $addressModel;
         }
     }

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

@@ -4,6 +4,7 @@ namespace common\models\forms;
 use common\components\Model;
 use common\helpers\Cache;
 use common\helpers\Form;
+use common\models\ShopGoodsNature;
 use common\models\UserBind;
 use Yii;
 use yii\base\Exception;
@@ -141,6 +142,13 @@ class DeclarationLoopForm extends Model
                         if (!$goods) {
                             throw new Exception(Yii::t('app', 'productsDoesSoldOut'));
                         }
+                        $goodsNature = ShopGoodsNature::findOneAsArray('GOODS_ID=:GOODS_ID AND COUNTRY_ID=:COUNTRY_ID',
+                            [':GOODS_ID' => $value['goodsId'][$i], ':COUNTRY_ID' => $value['countryId']]);
+                        if (!$goodsNature) {
+                            throw new Exception(Yii::t('app', 'productsDoesSoldOut'));
+                        }
+
+
                         if($goods['INSTALMENT']>0){ // 分期的商品
                             if($value['goodsNum'][$i]>1){ // 只能购买一个
                                 throw new Exception(Yii::t('app', 'allowOnlyOne'));

+ 42 - 14
common/models/forms/DeclarationUpgradeForm.php

@@ -6,9 +6,12 @@ use common\helpers\Cache;
 use common\helpers\Date;
 use common\helpers\Form;
 use common\helpers\LoggerTool;
+use common\helpers\Tool;
 use common\helpers\user\Cash;
 use common\helpers\user\Info;
 use common\models\Config;
+use common\models\Countries;
+use common\models\CurrencyConversions;
 use common\models\DeclarationLevel;
 use common\models\DeclarationPackage;
 use common\models\DecLevelLog;
@@ -20,6 +23,7 @@ use common\models\Period;
 use common\models\ReceiveAddress;
 use common\models\Region;
 use common\models\ShopGoods;
+use common\models\ShopGoodsNature;
 use common\models\User;
 use common\models\UserInfo;
 use common\models\UserNetwork;
@@ -137,6 +141,14 @@ class DeclarationUpgradeForm extends Model
             if ($this->decWay != 2) {
                 throw new Exception(Yii::t('app', 'upgradeMethodIncorrect'));
             }
+
+            // 报单中心汇率
+            $decCountry = User::getEnCodeInfo(\Yii::$app->user->id)['COUNTRY_ID'];
+            $decUserCurrencyRate = CurrencyConversions::getToUSDRate($decCountry['LOCAL_CURRENCY_ID']);
+            // 升级会员汇率
+            $country = Countries::getById($baseInfo['COUNTRY_ID']);
+            $currencyRate = CurrencyConversions::getToUSDRate($country['LOCAL_CURRENCY_ID']);
+
             if($this->decWay==1) {
                 // 先不加套餐升级方式
                 // $decPackage = DeclarationPackage::findOneAsArray('ID=:ID', [':ID'=>$this->packageId]);
@@ -157,22 +169,28 @@ class DeclarationUpgradeForm extends Model
                 $totalAmount = 0;
                 $totalAmountStandard = 0;
                 $totalPv = 0;
-                $exchangeRate = floatval(Cache::getSystemConfig()['exchangeRate']['VALUE'] ?? 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('Products does not exists!');
                         }
+                        $goodsNature = ShopGoodsNature::findOneAsArray('GOODS_ID=:GOODS_ID AND COUNTRY_ID=:COUNTRY_ID',
+                            [':GOODS_ID' => $ids[$k], ':COUNTRY_ID' => $baseInfo['COUNTRY_ID']]);
+                        if (!$goodsNature) {
+                            throw new Exception(Yii::t('app', 'productsDoesSoldOut'));
+                        }
+
                         if($goods['STORE_NUMS']>0){
-                            $totalAmount += $goods['SELL_PRICE'] * intval($v);
+                            $totalAmount += $goodsNature['SELL_PRICE'] * intval($v);
                             $totalAmountStandard += $goods['SELL_PRICE_STANDARD'] * intval($v);
                             $realPriceStandard = $goods['SELL_PRICE_STANDARD'];
                             $totalPv += $goods['PRICE_PV'] * intval($v);
                             $this->_orderGoods[] = [
                                 'GOODS_ID' => $goods['ID'],
-                                'PRICE' => $goods['SELL_PRICE'],
-                                'REAL_PRICE' => $goods['SELL_PRICE'],
+                                'PRICE' => $goodsNature['SELL_PRICE'],
+                                'REAL_PRICE' => $goodsNature['SELL_PRICE'],
                                 'PV' => $goods['PRICE_PV'],
                                 'REAL_PV' => $goods['PRICE_PV'],
                                 'POINT' => $goods['POINT'],
@@ -182,8 +200,8 @@ class DeclarationUpgradeForm extends Model
                                 'EMAIL' => Info::getUserEmailByUserId(\Yii::$app->user->id) ?? '',
                                 'STANDARD_PRICE' => $goods['SELL_PRICE_STANDARD'],
                                 'REAL_STANDARD_PRICE' => $realPriceStandard,
-                                'EXCHANGE_RATE' => $exchangeRate,
-                                'TAX_RATE' => $goods['TAX_RATE'],
+                                'EXCHANGE_RATE' => $currencyRate,
+                                'TAX_RATE' => $goodsNature['TAX_RATE'],
                             ];
                         }
                         if($goods['INSTALMENT']>0){ // 如果有分期付款商品,检查用户的分期付款状态
@@ -227,7 +245,6 @@ class DeclarationUpgradeForm extends Model
 
                 // 会员已有PV+本次订单PV 不能多于 下一个级别所需PV
                 $nextDecLv = DeclarationLevel::getNextDecLv($toDecLevel);
-                LoggerTool::debug(['Ats', $nextDecLv, $checkPv]);
                 if ($nextDecLv && ($checkPv >= $nextDecLv['PERF'])) {
                     throw new Exception(Yii::t('app', 'totalPvExceedPv'), 400);
                 }
@@ -237,8 +254,12 @@ class DeclarationUpgradeForm extends Model
                 $this->_decAmountStandard = $totalAmountStandard;
                 $this->_standardAmount = $this->_decAmountStandard;
             }
+
             //看现金余额是否充足
-            if (Cash::getAvailableBalance($loginUserId) < $this->_decAmount){
+            $decCash = Cash::getAvailableBalance($loginUserId);
+            // 转换后的余额
+            $localCash = Tool::convertAmount($decCash, $decUserCurrencyRate, $currencyRate);
+            if ($localCash < $this->_decAmount){
                 throw new Exception(Yii::t('app', 'applicantCashShort'), 400);
             }
             $baseInfo = Info::baseInfoZhByUserName($this->insertUserName);
@@ -309,7 +330,13 @@ class DeclarationUpgradeForm extends Model
                 throw new Exception(Form::formatErrorsForApi($decOrderModel->getErrors()));
             }
 
-            $exchangeRate = floatval(Cache::getSystemConfig()['exchangeRate']['VALUE'] ?? 0);
+            // 升级会员
+            $userCountry = User::getEnCodeInfo($this->_insertUserId);
+            $userCurrencyRate = CurrencyConversions::getToUSDRate($userCountry['LOCAL_CURRENCY_ID']);
+            // 报单中心汇率
+            $decCountry = User::getEnCodeInfo(\Yii::$app->user->id)['COUNTRY_ID'];
+            $decUserCurrencyRate = CurrencyConversions::getToUSDRate($decCountry['LOCAL_CURRENCY_ID']);
+
             $orderModel = new Order();
             $orderModel->SN = 'OS'.$ord;
             $orderModel->DEC_SN = 'DS'.$ord;
@@ -340,7 +367,9 @@ class DeclarationUpgradeForm extends Model
             $orderModel->CREATE_USER = Info::getUserNameByUserId(\Yii::$app->user->id);
             $orderModel->ORDER_AMOUNT_STANDARD = $this->_decAmountStandard;
             $orderModel->PAY_AMOUNT_STANDARD = $this->_standardAmount;
-            $orderModel->EXCHANGE_RATE = $exchangeRate;
+            $orderModel->EXCHANGE_RATE = $userCurrencyRate;
+            $orderModel->COUNTRY_ID = $userCountry['COUNTRY_ID'];
+            $orderModel->CURRENCY_ID = $userCountry['LOCAL_CURRENCY_ID'] ?? 0;
             if(!$orderModel->save()){
                 $transaction->rollBack();
                 throw new Exception(Form::formatErrorsForApi($orderModel->getErrors()));
@@ -366,11 +395,9 @@ class DeclarationUpgradeForm extends Model
                                 $data->update();
                             }
                         }else{
-//                          throw new Exception("商品".$goods['GOODS_NAME']."库存不足");
                             throw new Exception("product".$goods['GOODS_NAME']."Insufficient inventory");
                         }
                     }else{
-//                          throw new Exception("商品".$goods['GOODS_NAME']."已下架");
                         throw new Exception("product".$goods['GOODS_NAME']."Removed from the shelf");
                     }
                 }
@@ -388,6 +415,7 @@ class DeclarationUpgradeForm extends Model
             $addressModel->USER_NAME = $this->insertUserName;
             $addressModel->CONSIGNEE = $this->consignee;
             $addressModel->MOBILE = $this->acceptMobile;
+            $addressModel->COUNTRY_ID = $userCountry['COUNTRY_ID'];
             $addressModel->PROVINCE = $this->province;
 //            $addressModel->CITY = $this->city;
 //            $addressModel->COUNTY = intval($this->county) ?? 0;
@@ -401,8 +429,8 @@ class DeclarationUpgradeForm extends Model
                 throw new Exception(Form::formatErrorsForApi($addressModel->getErrors()));
             }
             // 扣报单人现金钱包
-//            Cash::changeUserCash(\Yii::$app->user->id, 'CASH', -abs($this->_decAmount), ['REMARK' =>'为'.$this->insertUserName.'升级报单', 'ORDER_SN' => $orderModel->SN]);
-            Cash::changeUserCash(\Yii::$app->user->id, 'CASH', -abs($this->_decAmount), ['REMARK' =>'by'.$this->insertUserName.'Upgrade entry', 'ORDER_SN' => $orderModel->SN]);
+            $decAmount = Tool::convertAmount($this->_decAmount, $userCurrencyRate, $decUserCurrencyRate);
+            Cash::changeUserCash(\Yii::$app->user->id, 'CASH', -abs($decAmount), ['REMARK' =>'by'.$this->insertUserName.'Upgrade entry', 'ORDER_SN' => $orderModel->SN]);
             // 为被升级人进行升级操作
             $decLevelLog = new DecLevelLog();
             $decLog = [

+ 100 - 0
common/models/forms/FreeTemplateForm.php

@@ -0,0 +1,100 @@
+<?php
+namespace common\models\forms;
+
+use common\components\Model;
+use common\helpers\Form;
+use common\models\Countries;
+use common\models\FreeTemplate;
+use Yii;
+use yii\base\Exception;
+
+class FreeTemplateForm extends Model
+{
+    public $countryId;
+    public $freight;
+    public $freeShipping;
+    public $currencyId;
+    private $_model;
+
+    public function init() {
+        parent::init();
+
+        $this->_model = FreeTemplate::findOne(['country_id' => $this->countryId]) ?: new FreeTemplate();
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function rules()
+    {
+        return [
+            [['countryId', 'freight', 'freeShipping'], 'required'],
+            [['countryId'], 'isCountry'],
+        ];
+    }
+
+    public function attributeLabels()
+    {
+        return [
+            'country_id' => 'Country',
+            'freight' => 'Freight',
+            'free_shipping' => 'FreeShipping',
+            'currency_id' => 'currency',
+        ];
+    }
+
+    /**
+     * 指定场景
+     * @return array
+     */
+    public function scenarios()
+    {
+        $parentScenarios =  parent::scenarios();
+        $customScenarios = [
+            'setTransportation' => ['countryId', 'freight', 'freeShipping'],
+        ];
+
+        return array_merge($parentScenarios, $customScenarios);
+    }
+
+    public function isCountry($attribute){
+        $country = Countries::getById($this->countryId);
+        if (!$country) {
+            $this->addError($attribute, Yii::t('ctx', 'countryDoesNotExist'));
+        }
+
+        $this->currencyId = $country['LOCAL_CURRENCY_ID'];
+    }
+
+    /**
+     * 设置运费模板.
+     * @return true
+     */
+    public function setTransportation(): ?bool
+    {
+        if (!$this->validate()) {
+            return null;
+        }
+
+        $transaction = \Yii::$app->db->beginTransaction();
+        try {
+            // 添加/修改数据
+            $this->_model->country_id = $this->countryId;
+            $this->_model->freight = $this->freight;
+            $this->_model->free_shipping = $this->freeShipping;
+            $this->_model->currency_id = $this->currencyId;
+            if (!$this->_model->save()) {
+                $transaction->rollBack();
+                throw new Exception(Form::formatErrorsForApi($this->_model->getErrors()));
+            }
+
+            $transaction->commit();
+        } catch (Exception $e) {
+            $transaction->rollBack();
+            $this->addError('setTransportation', $e->getMessage());
+            return null;
+        }
+
+        return true;
+    }
+}

+ 166 - 0
common/models/forms/ImmigrantForm.php

@@ -0,0 +1,166 @@
+<?php
+namespace common\models\forms;
+
+use common\helpers\Date;
+use common\components\Model;
+use common\helpers\Form;
+use common\helpers\Tool;
+use common\helpers\user\Info;
+use common\libs\logging\operate\AdminOperate;
+use common\models\Countries;
+use common\models\CurrencyConversions;
+use common\models\EmployLevel;
+use common\models\HighestEmpLevelLog;
+use common\models\Period;
+use common\models\User;
+use common\models\UserBonus;
+use common\models\UserImmigrant;
+use common\models\UserWallet;
+use Yii;
+use yii\base\Exception;
+
+/**
+ * Login form
+ */
+class ImmigrantForm extends Model
+{
+    public $userName;
+    public $beforeCountryId;
+    public $afterCountryId;
+    public $periodNum;
+    private $_userId;
+    private $beforeCountry;
+    private $afterCountry;
+
+    public function init() {
+        parent::init();
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function rules()
+    {
+        return [
+            [['userName'], 'trim'],
+            [['userName', 'afterCountryId'], 'required'],
+            [['userName'], 'exist', 'targetClass' => User::class, 'targetAttribute' => 'USER_NAME'],
+            [['userName'], 'isUser'],
+            [['afterCountryId'], 'isAfterCountry'],
+        ];
+    }
+
+    public function attributeLabels()
+    {
+        return [
+            'userName' => '会员编号',
+            'beforeCountryId' => '移民前国家ID',
+            'afterCountryId' => '移民后国家ID',
+            'periodNum' => '期数',
+        ];
+    }
+
+    /**
+     * 指定校验场景
+     * @return array
+     */
+    public function scenarios()
+    {
+        $parentScenarios =  parent::scenarios();
+        $customScenarios = [
+            'adminChange' => ['userName', 'beforeCountryId', 'afterCountryId'],
+        ];
+        return array_merge($parentScenarios, $customScenarios);
+    }
+
+    /**
+     * 赋值UserId并校验会员是否存在
+     * @param $attribute
+     */
+    public function isUser($attribute){
+        $this->_userId = Info::getUserIdByUserName($this->userName);
+        if (!$this->_userId) {
+            $this->addError($attribute, Yii::t('ctx', 'memberDoesNotExist'));
+        }
+
+        $this->beforeCountryId = Info::getUserCountryByUserId($this->_userId);
+        $this->beforeCountry = Countries::getById($this->beforeCountryId);
+    }
+
+    public function isAfterCountry($attribute){
+        $this->afterCountry = Countries::getById($this->afterCountryId);
+        if (!$this->afterCountry) {
+            $this->addError($attribute, Yii::t('ctx', 'countryDoesNotExist'));
+        }
+    }
+
+    /**
+     * 执行移民.
+     */
+    public function userImmigrant()
+    {
+        if (!$this->validate()) {
+            return null;
+        }
+
+        $db = \Yii::$app->db;
+        $transaction = $db->beginTransaction();
+        try {
+            // 移民记录
+            $model = new UserImmigrant();
+            $model->user_id = $this->_userId;
+            $model->before_country_id = $this->beforeCountryId;
+            $model->after_country_id = $this->afterCountryId;
+            $model->period_num = Period::instance()->getNowPeriodNum();
+            $model->created_by = \Yii::$app->user->id;
+            if (!$model->save()) {
+                throw new Exception(Form::formatErrorsForApi($model->getErrors()));
+            }
+
+            // 修改国家
+            User::updateAll(['COUNTRY_ID' => $this->afterCountryId], 'ID=:USER_ID', [':USER_ID' => $this->_userId]);
+
+            // 移民前汇率
+            $beforeCurrency = CurrencyConversions::getToUSDRate($this->beforeCountry['LOCAL_CURRENCY_ID']);
+            // 移民后汇率
+            $afterCurrency = CurrencyConversions::getToUSDRate($this->afterCountry['LOCAL_CURRENCY_ID']);
+            if (!$afterCurrency) {
+                throw new Exception(Yii::t('app', 'currencyDoesNotExist'));
+            }
+
+            // 奖金账户余额转换(NG发放奖金为美元,所以不需要转换本地货币)
+//            $userBonus = UserBonus::findOne(['USER_ID' => $this->_userId]);
+//            if ($userBonus) {
+//                foreach ($userBonus as $index => $bonus) {
+//                    if ($index == 'ID' || $index == 'USER_ID') {
+//                        continue;
+//                    }
+//
+//                    $userBonus->$index = Tool::convertAmount($bonus, $beforeCurrency, $afterCurrency);
+//                }
+//                if (!$userBonus->save()) {
+//                    $transaction->rollBack();
+//                    throw new Exception(Form::formatErrorsForApi($model->getErrors()));
+//                }
+//            }
+
+            // 现金钱包余额转换
+            $userWallet = UserWallet::findOne(['USER_ID' => $this->_userId]);
+            if ($userWallet && $userWallet->CASH > 0) {
+                $userWallet->CASH = Tool::convertAmount($userWallet->CASH, $beforeCurrency, $afterCurrency);
+                if (!$userWallet->save()) {
+                    $transaction->rollBack();
+                    throw new Exception(Form::formatErrorsForApi($model->getErrors()));
+                }
+            }
+
+            $transaction->commit();
+        } catch (Exception $e) {
+            $transaction->rollBack();
+            $this->addError('userImmigrant', $e->getMessage());
+            return null;
+        }
+
+        return $model;
+    }
+}

+ 32 - 52
common/models/forms/OrderForm.php

@@ -11,7 +11,10 @@ use common\helpers\user\Balance;
 use common\helpers\user\Cash;
 use common\helpers\user\Info;
 use common\libs\logging\operate\AdminOperate;
+use common\models\Countries;
+use common\models\CurrencyConversions;
 use common\models\DealType;
+use common\models\FreeTemplate;
 use common\models\Instalment;
 use common\models\Order;
 use common\models\OrderGoods;
@@ -19,6 +22,7 @@ use common\models\Period;
 use common\models\ReceiveAddress;
 use common\models\Region;
 use common\models\ShopGoods;
+use common\models\ShopGoodsNature;
 use common\models\User;
 use common\models\UserNetwork;
 use common\models\RemainPv;
@@ -44,6 +48,7 @@ class OrderForm extends Model
     public $goodsNum;
     public $payPassword;
     public $email;
+    public $exchangeRate;
 
     public $userName;
     public $decUserName;
@@ -470,22 +475,31 @@ class OrderForm extends Model
         $this->_remainPv = 0;
         $hasInstalment = 0;
         $loginUserId = \Yii::$app->user->id;
-        $exchangeRate = floatval(Cache::getSystemConfig()['exchangeRate']['VALUE'] ?? 0); // 汇率
+        $user = User::getEnCodeInfo(\Yii::$app->user->id);
+
         foreach ($this->goodsNum as $k => $v) {
             if ($v) {
                 $goods = ShopGoods::findOneAsArray('ID=:ID AND STATUS=1',[':ID'=> $ids[$k]]);
                 if (!$goods) {
                     throw new Exception(Yii::t('app', 'productsDoesSoldOut'));
                 }
+                $goodsNature = ShopGoodsNature::findOneAsArray('GOODS_ID=:GOODS_ID AND COUNTRY_ID=:COUNTRY_ID',
+                    [':GOODS_ID' => $ids[$k], ':COUNTRY_ID' => $user['COUNTRY_ID']]);
+                if (!$goodsNature) {
+                    throw new Exception(Yii::t('app', 'productsDoesSoldOut'));
+                }
+                // 汇率
+                $this->exchangeRate = CurrencyConversions::getToUSDRate($goodsNature['LOCAL_CURRENCY_ID']);
+
                 if($goods['STORE_NUMS']>0){
                     if ($goods['TYPE'] == 1 || $goods['TYPE'] == 2) {
                         $discount = $goodsType[$goods['TYPE']]['discount'];
-                        $realPrice = $goods['SELL_PRICE'] * $discount/100;
+                        $realPrice = $goodsNature['SELL_PRICE'] * $discount/100;
                         $realPv = $goods['PRICE_PV'] * $discount/100;
                         $realPriceStandard = $goods['SELL_PRICE_STANDARD'] * $discount/100;
                     } else {
                         $discount = $goods['SELL_DISCOUNT'];
-                        $realPrice = $goods['SELL_PRICE'] * $discount;
+                        $realPrice = $goodsNature['SELL_PRICE'] * $discount;
                         $realPv = $goods['PRICE_PV'] * $discount;
                         $realPriceStandard = $goods['SELL_PRICE_STANDARD'] * $discount;
                     }
@@ -519,7 +533,7 @@ class OrderForm extends Model
 //                    }
                     $this->_orderGoods[] = [
                         'GOODS_ID' => $goods['ID'],
-                        'PRICE' => $goods['SELL_PRICE'],
+                        'PRICE' => $goodsNature['SELL_PRICE'],
                         'PV' => $currentPv, // $goods['PRICE_PV'],
                         'REAL_PRICE' => $realPrice,
                         'REAL_PV' => $realPv,
@@ -533,8 +547,8 @@ class OrderForm extends Model
                         'EMAIL' => $this->email,
                         'STANDARD_PRICE' => $goods['SELL_PRICE_STANDARD'],
                         'REAL_STANDARD_PRICE' => $realPriceStandard,
-                        'EXCHANGE_RATE' => $exchangeRate,
-                        'TAX_RATE' => $goods['TAX_RATE'],
+                        'EXCHANGE_RATE' => $this->exchangeRate,
+                        'TAX_RATE' => $goodsNature['TAX_RATE'],
                     ];
                 }
                 if($goods['INSTALMENT']>0){ // 如果有分期付款商品,检查用户的分期付款状态
@@ -572,10 +586,12 @@ class OrderForm extends Model
             }
         }
 
-        // 运费.美元转奈拉
-        $freight = floatval(Cache::getSystemConfig()['freight']['VALUE'] ?? 0);
-        // 普通商品免运费阈值.美元转奈拉
-        $freeShipping = floatval(Cache::getSystemConfig()['freeShipping']['VALUE'] ?? 0);
+        // 运费模板
+        $freeTemplate = FreeTemplate::getByCountryId($user['COUNTRY_ID']);
+        // 运费
+        $freight = $freeTemplate['freight'] ?? 0;
+        // 普通商品免运费阈值
+        $freeShipping = $freeTemplate['free_shipping'] ?? 0;
 
         $this->_decAmount = $totalAmount;
         $this->_decPv = $totalPv;
@@ -699,12 +715,14 @@ class OrderForm extends Model
         $nowCalcMonth = $periodObj->getYearMonth($nowPeriodNum);
 
         $userId = \Yii::$app->user->id;
+        $user = User::getEnCodeInfo(\Yii::$app->user->id);
 
         $userName = Info::getUserNameByUserId($userId);
         $userRealName = Info::getUserRealNameByUserId($userId);
         $userMobile = Info::getUserMobileByUserId($userId);
         $userEmail = Info::getUserEmailByUserId($userId);
-        $exchangeRate = floatval(Cache::getSystemConfig()['exchangeRate']['VALUE'] ?? 0);
+        $country = Countries::getById($user['COUNTRY_ID']);
+
         // 加入订单信息
         if ($this->_address['PROVINCE'] != 1) {
             $warehouse = Region::getWarehouseByCode($this->_address['PROVINCE']);//仓库
@@ -752,7 +770,9 @@ class OrderForm extends Model
         $orderModel->EMAIL = $userEmail ?? '';
         $orderModel->ORDER_AMOUNT_STANDARD = $this->_decAmountStandard;
         $orderModel->PAY_AMOUNT_STANDARD = $this->_standardAmount;
-        $orderModel->EXCHANGE_RATE = $exchangeRate;
+        $orderModel->EXCHANGE_RATE = $this->exchangeRate;
+        $orderModel->COUNTRY_ID = $user['COUNTRY_ID'];
+        $orderModel->CURRENCY_ID = $country['LOCAL_CURRENCY_ID'] ?? 0;
         if($this->_address['PROVINCE']==1){
             $orderModel->EXPRESS_TYPE = 1;
             $orderModel->CONSIGNEE = $userRealName;
@@ -794,46 +814,6 @@ class OrderForm extends Model
             Balance::changeUserBonus(\Yii::$app->user->id,'reconsume_points', -abs($this->_payAmount),['DEAL_TYPE_ID' => DealType::RECONSUME_POINTS_EXCHANGE,'REMARK' => '会员复销积分兑换', 'ORDER_SN' => $orderModel->SN]);
         }
 
-//        if($this->_remainPv>0) {
-//            $oRemainPv = RemainPv::find()->where(['USER_ID' => $userId])->one();
-//
-//            $transactionRemain = \Yii::$app->db->beginTransaction();
-//            try{
-//                $flowRemainPvModel = new FlowRemainPv();
-//                $flowRemainPvModel->ID = $this->_generateSn();
-//                $flowRemainPvModel->USER_ID = $userId;
-//                $flowRemainPvModel->REMAIN_PV_FLOW = $this->_remainPv;
-//                $flowRemainPvModel->REMAIN_PV_TOTAL = $oRemainPv['REMAIN_PV'] + $this->_remainPv;
-//                $flowRemainPvModel->PERIOD_NUM = $nowPeriodNum;
-//                $flowRemainPvModel->UPDATED_AT = Date::nowTime();
-//                $flowRemainPvModel->ORDER_SN = 'OS'.$ordNo;
-//                if(!$flowRemainPvModel->save()){
-//                    $this->addErrors($flowRemainPvModel->getErrors());
-//                    return false;
-//                }
-//
-//                $oRemainPv = RemainPv::find()->where(['USER_ID' => $userId])->one();
-//                if($oRemainPv){
-//                    $oRemainPv->updateCounters(['REMAIN_PV'=>$this->_remainPv]);
-//                }else{
-//                    $remainPvModel = new RemainPv();
-//                    $remainPvModel->ID = $this->_generateSn();
-//                    $remainPvModel->USER_ID = $userId;
-//                    $remainPvModel->UPDATED_AT = Date::nowTime();
-//                    $remainPvModel->REMAIN_PV = $this->_remainPv;
-//                    $remainPvModel->STATUS = 1;
-//                    if(!$remainPvModel->save()){
-//                        $this->addErrors($remainPvModel->getErrors());
-//                        return false;
-//                    }
-//                }
-//                $transactionRemain->commit();
-//            } catch (Exception $e) {
-//                $transactionRemain->rollBack();
-//                $this->addError('add', $e->getMessage());
-//                return null;
-//            }
-//        }
         return $orderModel;
     }
 

+ 71 - 48
common/models/forms/ShopGoodsForm.php

@@ -7,7 +7,10 @@ use common\helpers\Date;
 use common\helpers\Form;
 use common\helpers\LoggerTool;
 use common\libs\logging\operate\AdminOperate;
+use common\models\Countries;
+use common\models\CurrencyConversions;
 use common\models\ShopGoods;
+use common\models\ShopGoodsNature;
 use yii\base\Exception;
 
 /**
@@ -25,18 +28,15 @@ class ShopGoodsForm extends Model
     public $pvSplit;
     public $goodsNo;
     public $unit;
-    public $taxRate;
     public $cover;
-    public $sellPrice;
     public $sellPriceStandard;
-    public $marketPrice;
     public $pricePv;
-    //public $point;
     public $storeNums;
     public $content;
     public $sort;
     public $status;
     public $categoryType;
+    public $nature;
 
     private $_model;
 
@@ -53,8 +53,8 @@ class ShopGoodsForm extends Model
     public function rules()
     {
         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', 'categoryType', 'sellPriceStandard'], 'required'],
+            [['id','sellDiscount','giftType','sellType','goodsNo', 'goodsName', 'unit', 'pricePv', 'storeNums', 'content', 'sort','status','cover'], 'trim'],
+            [['goodsName','sellDiscount','giftType','goodsNo', 'storeNums','pricePv', 'sort','status', 'categoryType', 'sellPriceStandard', 'nature'], 'required'],
             [['id'], 'required', 'on'=>'edit'],
             [['id'], 'exist', 'targetClass'=>ShopGoods::class, 'targetAttribute'=>'ID'],
             [['sellPrice','marketPrice','pricePv', 'sellPriceStandard'], 'price'],
@@ -79,15 +79,11 @@ class ShopGoodsForm extends Model
             'goodsNo' => 'Product Code', // 产品编号
             'unit' => 'Unit', // 单位
             'cover' => 'Cover',// 封面
-            'sellPrice' => 'Price', // 销售价格
             'sellPriceStandard' => 'US price',
-            'marketPrice' => 'Market Price', // 市场价格
             'pricePv' => 'BV', // 销售PV
-            //'point' => '兑换积分',
             'storeNums' => 'Inventory', // 库存
             'content' => 'Content',
             'listOrder' => 'Order',// 排序
-            'taxRate' => 'Tax',// 税率
         ];
     }
 
@@ -99,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', 'categoryType', 'sellPriceStandard', 'taxRate', 'taxAmount','pvSplit'],
-            'edit' => ['id','goodsName','sellDiscount','giftType', 'sellType','goodsNo','unit','sellPrice','marketPrice','pricePv', 'storeNums', 'content','sort','cover', 'categoryType', 'sellPriceStandard', 'taxRate','pvSplit'],
+            'add' => ['goodsName','sellDiscount','giftType', 'sellType','goodsNo','unit','pricePv','storeNums', 'content','sort','cover', 'categoryType', 'sellPriceStandard', 'taxRate', 'taxAmount','pvSplit', 'nature'],
+            'edit' => ['id','goodsName','sellDiscount','giftType', 'sellType','goodsNo','unit','pricePv', 'storeNums', 'content','sort','cover', 'categoryType', 'sellPriceStandard', 'nature','pvSplit'],
             'changeStatus' => ['selectedIds', 'status'],
         ];
         return array_merge($parentScenarios, $customScenarios);
@@ -192,23 +188,17 @@ class ShopGoodsForm extends Model
             // 添加商品
             $shopGoods = new ShopGoods();
             $shopGoods->GOODS_NAME = $this->goodsName;
-            //$shopGoods->TYPE = $this->type;
             $shopGoods->SELL_DISCOUNT = $this->sellDiscount;
             $shopGoods->GIFT_TYPE = implode(',',$this->giftType);
-//             $shopGoods->SELL_TYPE = implode(',',$this->sellType);
             $shopGoods->SELL_TYPE = $this->sellType;
             $shopGoods->PV_SPLIT = $this->pvSplit;
             $shopGoods->GOODS_NO = $this->goodsNo;
-            $shopGoods->UNIT = $this->unit ? $this->unit : '个';
-            $shopGoods->COVER = $this->cover ? $this->cover : '';
+            $shopGoods->UNIT = $this->unit ?: '个';
+            $shopGoods->COVER = $this->cover ?: '';
             $shopGoods->SELL_PRICE_STANDARD = $this->sellPriceStandard;
-            $shopGoods->SELL_PRICE = $this->sellPrice;
-            $shopGoods->MARKET_PRICE = $this->marketPrice;
             $shopGoods->PRICE_PV = $this->pricePv;
-            //$shopGoods->POINT = $this->point;
             $shopGoods->CONTENT = $this->content;
             $shopGoods->STORE_NUMS = $this->storeNums;
-            $shopGoods->TAX_RATE = $this->taxRate;
             $shopGoods->SORT = $this->sort;
             $shopGoods->CATE_ID = '1';
             $shopGoods->CREATED_AT = Date::nowTime();
@@ -217,6 +207,26 @@ class ShopGoodsForm extends Model
                 throw new Exception(Form::formatErrorsForApi($shopGoods->getErrors()));
             }
 
+            // 商品属性
+            foreach ($this->nature as $item) {
+                // 国家
+                $currency = Countries::getById($item['countryId']);
+                // 转换美元汇率
+                $rate = CurrencyConversions::getToUSDRate($currency['LOCAL_CURRENCY_ID']);
+
+                $shopGoodsNature = new ShopGoodsNature();
+                $shopGoodsNature->GOODS_ID = $shopGoods->ID;
+                $shopGoodsNature->COUNTRY_ID = $item['countryId'];
+                $shopGoodsNature->LOCAL_CURRENCY_ID = $currency['LOCAL_CURRENCY_ID'];
+                $shopGoodsNature->MARKET_PRICE = $item['sellPrice'];
+                $shopGoodsNature->SELL_PRICE = $shopGoods->SELL_PRICE_STANDARD * $rate;
+                $shopGoodsNature->TAX_RATE = $item['taxRate'];
+                if (!$shopGoodsNature->save()) {
+                    $transaction->rollBack();
+                    throw new Exception(Form::formatErrorsForApi($shopGoodsNature->getErrors()));
+                }
+            }
+
             $transaction->commit();
         } catch (Exception $e) {
             $transaction->rollBack();
@@ -243,18 +253,13 @@ class ShopGoodsForm extends Model
             $model->TYPE = 0;
             $model->SELL_DISCOUNT = $this->sellDiscount;
             $model->GIFT_TYPE = implode(',',$this->giftType);
-//            $model->SELL_TYPE = implode(',',$this->sellType);
             $model->SELL_TYPE = $this->sellType;
             $model->PV_SPLIT = $this->pvSplit;
             $model->GOODS_NO = $this->goodsNo;
-            $model->UNIT = $this->unit ? $this->unit : '个';
-            $model->COVER = $this->cover ? $this->cover : '';
+            $model->UNIT = $this->unit ?: '个';
+            $model->COVER = $this->cover ?: '';
             $model->SELL_PRICE_STANDARD = $this->sellPriceStandard;
-            $model->SELL_PRICE = $this->sellPrice;
-            $model->MARKET_PRICE = $this->marketPrice;
             $model->PRICE_PV = $this->pricePv;
-            $model->TAX_RATE = $this->taxRate;
-            //$model->POINT = $this->point;
             $model->CONTENT = $this->content;
             $model->STORE_NUMS = $this->storeNums;
             $model->SORT = $this->sort;
@@ -263,6 +268,30 @@ class ShopGoodsForm extends Model
             if (!$model->save()) {
                 throw new Exception(Form::formatErrorsForApi($model->getErrors()));
             }
+
+            // 移除属性表中商品属性
+            ShopGoodsNature::deleteAll(['GOODS_ID' => $model->ID]);
+
+            // 商品属性
+            foreach ($this->nature as $item) {
+                // 国家
+                $currency = Countries::getById($item['countryId']);
+                // 转换美元汇率
+                $rate = CurrencyConversions::getToUSDRate($currency['LOCAL_CURRENCY_ID']);
+
+                $shopGoodsNature = new ShopGoodsNature();
+                $shopGoodsNature->GOODS_ID = $model->ID;
+                $shopGoodsNature->COUNTRY_ID = $item['countryId'];
+                $shopGoodsNature->LOCAL_CURRENCY_ID = $currency['LOCAL_CURRENCY_ID'];
+                $shopGoodsNature->MARKET_PRICE = $item['sellPrice'];
+                $shopGoodsNature->SELL_PRICE = $model->SELL_PRICE_STANDARD * $rate;
+                $shopGoodsNature->TAX_RATE = $item['taxRate'];
+                if (!$shopGoodsNature->save()) {
+                    $transaction->rollBack();
+                    throw new Exception(Form::formatErrorsForApi($shopGoodsNature->getErrors()));
+                }
+            }
+
             $transaction->commit();
         } catch (Exception $e) {
             $transaction->rollBack();
@@ -309,33 +338,27 @@ class ShopGoodsForm extends Model
      * 异步更新商品属性表
      * @return bool
      */
-    public function updateAsync(){
-        // 汇率
-        $exchangeRate = floatval(Cache::getSystemConfig()['exchangeRate']['VALUE'] ?? 0);
-        // 商品列表
-        $goods = ShopGoods::findAll(['STATUS' => 1]);
+    public function updateAsync($id){
+        // 汇率配置
+        $currencyConversions = CurrencyConversions::findOne(['ID' => $id]);
+        // 商品属性
+        $shopGoodsNature = ShopGoodsNature::findAll(['LOCAL_CURRENCY_ID' => $currencyConversions->TO_CURRENCY_ID]);
 
         $transaction = \Yii::$app->db->beginTransaction();
         try {
-            foreach ($goods as $good) {
-                $content = [
-                    'id'                => $good->ID,
-                    'exchangeRate'      => $exchangeRate,
-                    'priceStandard'     => $good->SELL_PRICE_STANDARD,
-                    'originSellPrice'   => $good->SELL_PRICE,
-                    'modernSellPrice'   => $good->SELL_PRICE_STANDARD * $exchangeRate,
-                ];
-
-                $good->SELL_PRICE = $good->SELL_PRICE_STANDARD * $exchangeRate;
-                $good->UPDATED_AT = Date::nowTime();
-                if (!$good->save()) {
-                    throw new Exception(Form::formatErrorsForApi($good->getErrors()));
+            foreach ($shopGoodsNature as $goodsNature) {
+                // 商品
+                $shopGoods = ShopGoods::findOne(['ID' => $goodsNature->GOODS_ID]);
+                // 刷新销售价格
+                $goodsNature->SELL_PRICE = $shopGoods->SELL_PRICE_STANDARD * $currencyConversions->RATE;
+                if (!$goodsNature->save()) {
+                    $transaction->rollBack();
+                    throw new Exception(Form::formatErrorsForApi($goodsNature->getErrors()));
                 }
-
-                $item = json_encode($content);
-                echo "商品 {$item} 更新成功!" . PHP_EOL;
             }
 
+            echo "商品更新成功!" . PHP_EOL;
+
             $transaction->commit();
         } catch (Exception $e) {
             $transaction->rollBack();

+ 9 - 0
common/models/forms/TransferForm.php

@@ -122,6 +122,15 @@ class TransferForm extends Model {
             $this->addError($attribute, 'Transferred member not exists'); // 转入会员不存在
             return null;
         }
+
+        // 不能跨国转账
+        $fromCountryId = User::getEnCodeInfo($fromUserId)['COUNTRY_ID'];
+        $toCountryId = User::getEnCodeInfo($toUserId)['COUNTRY_ID'];
+        if ($fromCountryId != $toCountryId) {
+            $this->addError($attribute, Yii::t('app',  'transferMemberDoesNotSame'));
+            return null;
+        }
+
         // 转账条件判断
         $orderAmount = Order::find()->where('USER_ID=:USER_ID', [':USER_ID' => $fromUserId])->SUM('ORDER_AMOUNT');
         $recNum = intval(DecOrder::find()->where('REC_USER_ID=:REC_USER_ID', [':REC_USER_ID' => $fromUserId])->count());

+ 1 - 1
console/controllers/ConfigController.php

@@ -40,7 +40,7 @@ class ConfigController extends BaseController
     {
         $params = Cache::getAsyncParams($taskKey);
         $formModel = new ShopGoodsForm();
-        if ($formModel->load($params, '') && $formModel->updateAsync()) {
+        if ($formModel->load($params, '') && $formModel->updateAsync($params['ID'])) {
             \Yii::$app->swooleAsyncTimer->pushAsyncResultToAdmin($params['handleUserId'], "更新汇率配置成功");
         } else {
             \Yii::$app->swooleAsyncTimer->pushAsyncResultToAdmin($params['handleUserId'], "更新汇率配置失败,原因:".Form::formatErrorsForApi($formModel->getErrors()), false);

+ 25 - 0
console/controllers/ToolController.php

@@ -40,6 +40,7 @@ use common\models\Period;
 use common\models\ReconsumePool;
 use common\models\ReconsumePoolFlow;
 use common\models\DecOrder;
+use common\models\Region;
 use common\models\RemainPv;
 use common\models\StarCrownLevel;
 use common\models\User;
@@ -397,4 +398,28 @@ class ToolController extends BaseController
             'BONUS_ISSUE' => true,
         ]);
     }
+
+    /**
+     * 构建行政区划js文件到cdn,刷新Redis数据
+     */
+    public function actionRegionBuild()
+    {
+        // 所有行政区划
+        $regions = Region::getAllData();
+
+        $regionData = [];
+        foreach ($regions as $region) {
+            $regionData[$region['COUNTRY_ID']][] = [$region['REGION_CODE'] => $region['REGION_NAME']];
+        }
+
+        // 1.生成js文件
+        $ar_region_data = json_encode($regionData,JSON_UNESCAPED_UNICODE);
+        $str = (string)$ar_region_data;
+        $str = "const AR_REGION_DATA = " . $str;
+
+        file_put_contents(\Yii::$app->params['cdnPath'] . "jsdata/ar_region_data.js", $str);
+
+        // 2.刷新缓存
+        Region::updateToCache();
+    }
 }

+ 3 - 0
frontendApi/config/params.php

@@ -18,6 +18,9 @@ return [
         'v1/site/config',
         'v1/shop/verify-approach-order',
         'v1/finance/prove-add',
+        'v1/site/get-instance',
+        'v1/site/languages',
+        'v1/site/countries',
         ],
     'noCheckPermissionActions' => [],
 ];

+ 5 - 1
frontendApi/config/urlManagerRules.php

@@ -22,6 +22,9 @@ return [
             'GET ba-base-info' => 'ba-base-info',
             'GET send-notice' => 'send-notice',
             'GET send-notify' => 'send-notify',
+            'GET get-instance' => 'get-instance',
+            'GET languages' => 'languages',
+            'GET countries' => 'countries',
         ],
     ],
     [
@@ -173,7 +176,7 @@ return [
             'GET available-balance' => 'available-balance',
             'GET dec-list' => 'dec-list',
             'GET transfer-list' => 'transfer-list',
-            'POST transfer-add' => 'transfer-add',
+            'GET,POST transfer-add' => 'transfer-add',
             'GET chk-transfer-user' => 'chk-transfer-user',
             'GET recharge' => 'recharge',
             'GET,POST recharge-add' => 'recharge-add',
@@ -203,6 +206,7 @@ return [
             'POST ba-receive-address-edit' => 'ba-receive-address-edit',
             'POST ba-receive-address-default' => 'ba-receive-address-default',
             'POST ba-receive-address-delete' => 'ba-receive-address-delete',
+            'GET region-list' => 'region-list',
         ],
     ],
     [

+ 24 - 2
frontendApi/modules/v1/controllers/ConfigController.php

@@ -10,12 +10,14 @@ namespace frontendApi\modules\v1\controllers;
 use common\helpers\Cache;
 use common\helpers\Form;
 use common\helpers\snowflake\SnowFake;
+use common\helpers\user\Info;
 use common\models\BaReceiveAddress;
 use common\models\forms\BaReceiveAddressForm;
 use common\models\forms\ReceiveAddressForm;
 use common\models\forms\UserConfigForm;
 use common\models\ReceiveAddress;
 use common\models\Region;
+use common\models\User;
 use common\models\UserInfo;
 use Yii;
 use yii\base\Exception;
@@ -87,13 +89,18 @@ class ConfigController extends BaseController
      * @throws \yii\web\HttpException
      */
     public function actionReceiveAddressList() {
-        $condition = ' AND USER_ID=:USER_ID';
+        // 会员信息
+        $user = User::getEnCodeInfo(\Yii::$app->user->id);
+
+        $condition = ' AND USER_ID=:USER_ID AND COUNTRY_ID=:COUNTRY_ID';
         $params[':USER_ID'] = \Yii::$app->user->id;
+        $params[':COUNTRY_ID'] = $user['COUNTRY_ID'];
         $data = ReceiveAddress::lists($condition, $params, [
             'SELECT' => 'ID,CONSIGNEE,MOBILE,PROVINCE,LGA_NAME,CITY_NAME,ADDRESS,IS_DEFAULT',
             'orderBy' => 'IS_DEFAULT DESC,CREATED_AT DESC',
             'useSlaves' => true,
         ]);
+
         if($data['list']){
             foreach($data['list'] as $key=>$row){
                 $data['list'][$key]['PROVINCE_NAME'] = Region::getCnName($row['PROVINCE']);
@@ -101,7 +108,22 @@ class ConfigController extends BaseController
 //                $data['list'][$key]['COUNTY_NAME'] = Region::getCnName($row['COUNTY']);
             }
         }
-//        print_r($data);exit;
+        return static::notice($data);
+    }
+
+    /**
+     * 行政区划列表
+     * @return mixed
+     * @throws \yii\web\HttpException
+     */
+    public function actionRegionList() {
+        $countryId = \Yii::$app->request->get('countryId');
+        if (!$countryId) {
+            $countryId = Info::getUserCountryByUserId(\Yii::$app->user->id);
+        }
+
+        $data = Region::getByCountryId($countryId);
+
         return static::notice($data);
     }
 

+ 16 - 2
frontendApi/modules/v1/controllers/FinanceController.php

@@ -30,6 +30,7 @@ use common\models\Region;
 use common\models\RegType;
 use common\models\Transfer;
 use common\models\Uploads;
+use common\models\User;
 use common\models\UserInfo;
 use common\models\Withdraw;
 use common\models\UserBonus;
@@ -441,8 +442,19 @@ class FinanceController extends BaseController {
             } else {
                 return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
             }
-        }
+        } else {
+            // 会员转账资格检查
+            $toUserName = \Yii::$app->request->get('toUserName');
+            $toCountryId = User::findOneAsArray('USER_NAME = :USER_NAME', [':USER_NAME' => trim($toUserName)])['COUNTRY_ID'];
+
+            // 不能跨国转账
+            $fromCountryId = User::getEnCodeInfo(\Yii::$app->user->id)['COUNTRY_ID'];
+            if ($fromCountryId != $toCountryId) {
+                return static::notice(['transfer' => false, 'message' => Yii::t('app',  'transferMemberDoesNotSame')]);
+            }
 
+            return static::notice(['transfer' => true]);
+        }
     }
 
     /**
@@ -545,8 +557,10 @@ class FinanceController extends BaseController {
                 return static::notice(Form::formatErrorsForApi($formModel->getErrors()), 400);
             }
         }
+
+        $countryId = User::getEnCodeInfo(\Yii::$app->user->id)['COUNTRY_ID'];
         // 所有开户行
-        $allOpenBank = OpenBank::findAllAsArray('STATUS=1');
+        $allOpenBank = OpenBank::findAllAsArray('STATUS=:STATUS AND COUNTRY_ID=:COUNTRY_ID', [':STATUS' => 1, ':COUNTRY_ID' => $countryId]);
         return static::notice(['allOpenBank' => $allOpenBank]);
     }
 

+ 50 - 33
frontendApi/modules/v1/controllers/ShopController.php

@@ -24,6 +24,8 @@ use common\models\BaOrder;
 use common\models\BaOrderGoods;
 use common\models\BaReceiveAddress;
 use common\models\BaUser;
+use common\models\Countries;
+use common\models\Currency;
 use common\models\DecOrder;
 use common\models\BaDecOrder;
 use common\models\forms\ApproachOrderForm;
@@ -31,12 +33,14 @@ use common\models\forms\ApproachReconsumeOrderForm;
 use common\models\forms\BaApproachOrderForm;
 use common\models\forms\DeclarationForm;
 use common\models\forms\OrderForm;
+use common\models\FreeTemplate;
 use common\models\Instalment;
 use common\models\Order;
 use common\models\OrderGoods;
 use common\models\ReceiveAddress;
 use common\models\Region;
 use common\models\ShopGoods;
+use common\models\ShopGoodsNature;
 use common\models\User;
 use common\models\UserBonus;
 use common\models\UserWallet;
@@ -57,27 +61,29 @@ class ShopController extends BaseController {
     public function actionIndex() {
         // 商品分类
         $categoryType = \Yii::$app->request->get('categoryType', 1);
+        // 会员信息
+        $user = User::getEnCodeInfo(\Yii::$app->user->id);
 
-        $condition = ' AND STATUS=1 AND (FIND_IN_SET(2,GIFT_TYPE)>0';
-        $isStudio = User::getEnCodeInfo(\Yii::$app->user->id)['IS_STUDIO'];
-        if($isStudio==1){
+        $condition = ' AND S.STATUS=1 AND (FIND_IN_SET(2, S.GIFT_TYPE)>0';
+        if ($user['IS_STUDIO'] == 1) {
             $condition.= " OR FIND_IN_SET(4,GIFT_TYPE)>0";
         }
-        $condition .= ") AND CATEGORY_TYPE = :CATEGORY_TYPE";
+        $condition .= ") AND S.CATEGORY_TYPE = :CATEGORY_TYPE";
         $params[':CATEGORY_TYPE'] = intval($categoryType);
 
         $data = ShopGoods::lists($condition, $params, [
-            'orderBy' => 'SORT ASC,CREATED_AT DESC',
-            'from' => ShopGoods::tableName(),
+            'select' => 'S.*,N.MARKET_PRICE,N.SELL_PRICE,N.TAX_RATE,N.LOCAL_CURRENCY_ID,N.COUNTRY_ID',
+            'from' => ShopGoods::tableName() . ' AS S',
+            'join' => [
+                ['INNER JOIN', ShopGoodsNature::tableName() . ' AS N', 'N.GOODS_ID = S.ID AND N.COUNTRY_ID = ' . $user['COUNTRY_ID']],
+            ],
+            'orderBy' => 'S.SORT ASC, S.CREATED_AT DESC',
         ]);
+
         foreach ($data['list'] as $key => $value) {
-            if ($value['TYPE'] == 1 || $value['TYPE'] == 2) {
-                $data['list'][$key]['DISCOUNT'] = ShopGoods::getGoodType()[$value['TYPE']]['discount'];
-            } else {
-                $data['list'][$key]['DISCOUNT'] = $value['SELL_DISCOUNT']*100;
-            }
-            // $data['list'][$key]['DISCOUNT'] = ShopGoods::GOODS_TYPE[$value['TYPE']]['discount'];
+            $data['list'][$key]['DISCOUNT'] = in_array($value['TYPE'], [1, 2]) ? ShopGoods::getGoodType()[$value['TYPE']]['discount'] : $value['SELL_DISCOUNT'] * 100;
         }
+        
         return static::notice($data);
     }
 
@@ -100,9 +106,11 @@ class ShopController extends BaseController {
      * @throws HttpException
      */
     public function actionShowCart(){
-        $userId = \Yii::$app->user->id;
+        // 会员信息
+        $user = User::getEnCodeInfo(\Yii::$app->user->id);
         $payList = ShopGoods::payTypes();
-        $allAddress = ReceiveAddress::findAllAsArray('USER_ID=:USER_ID', [':USER_ID'=>$userId]);
+        $allAddress = ReceiveAddress::findAllAsArray('USER_ID=:USER_ID AND COUNTRY_ID=:COUNTRY_ID',
+            [':USER_ID' => $user['ID'], ':COUNTRY_ID' => $user['COUNTRY_ID']]);
         if($allAddress) {
             foreach ($allAddress as $key => $row) {
                 $allAddress[$key]['PROVINCE_NAME'] = Region::getCnName($row['PROVINCE']);
@@ -118,23 +126,24 @@ class ShopController extends BaseController {
             'garage_points' => 0,
             'villa_points' => 0,
         ];
-        if ($userBonusResult = UserBonus::findOneAsArray(['USER_ID' => $userId])) {
+        if ($userBonusResult = UserBonus::findOneAsArray(['USER_ID' => $user['ID']])) {
 //            $userBalance['points'] = $userBonusResult['RECONSUME_POINTS'];
 //            $userBalance['exchange'] = $userBonusResult['EXCHANGE_POINTS'];
             $userBalance['tourism_points'] = $userBonusResult['TOURISM_POINTS'];
             $userBalance['garage_points'] = $userBonusResult['GARAGE_POINTS'];
             $userBalance['villa_points'] = $userBonusResult['VILLA_POINTS'];
         }
-        if ($userCashResult = UserWallet::findOneAsArray(['USER_ID' => $userId])) {
+        if ($userCashResult = UserWallet::findOneAsArray(['USER_ID' => $user['ID']])) {
             $userBalance['cash'] = $userCashResult['CASH'];
         }
 
-        // 汇率
-        $exchangeRate = floatval(Cache::getSystemConfig()['exchangeRate']['VALUE'] ?? 0);
-        // 运费.奈拉
-        $freight = floatval(Cache::getSystemConfig()['freight']['VALUE'] ?? 0);
-        // 普通商品免运费阈值.奈拉
-        $freeShipping = floatval(Cache::getSystemConfig()['freeShipping']['VALUE'] ?? 0);
+        // 运费模板
+        $freeTemplate = FreeTemplate::getByCountryId($user['COUNTRY_ID']);
+        // 运费
+        $freight = $freeTemplate['freight'] ?? 0;
+        // 普通商品免运费阈值
+        $freeShipping = $freeTemplate['free_shipping'] ?? 0;
+
         $isDec = User::getEnCodeInfo(\Yii::$app->user->id)['IS_DEC'];
         return static::notice(
             [
@@ -479,7 +488,7 @@ class ShopController extends BaseController {
         $orderQuery = Order::find()
             ->alias('O')
             ->where($condition, $params)
-            ->select('O.ID,O.SN,O.USER_NAME,O.ORDER_TYPE,O.ORDER_AMOUNT,O.STATUS,O.CREATED_AT,O.PAY_TYPE,O.PAY_AT,O.CONSIGNEE,O.MOBILE,O.ADDRESS,O.CITY_NAME,O.LGA_NAME,O.PROVINCE,U.REAL_NAME')
+            ->select('O.ID,O.SN,O.USER_NAME,O.ORDER_TYPE,O.ORDER_AMOUNT,O.STATUS,O.CREATED_AT,O.PAY_TYPE,O.PAY_AT,O.CONSIGNEE,O.MOBILE,O.ADDRESS,O.CITY_NAME,O.LGA_NAME,O.PROVINCE,U.REAL_NAME,O.COUNTRY_ID,O.CURRENCY_ID')
             ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID');
 
         // 订单中间表只查询待支付和支付失败的订单
@@ -488,7 +497,7 @@ class ShopController extends BaseController {
         $orderStandardQuery = ApproachOrder::find()
             ->alias('O')
             ->where($condition . ' AND (O.STATUS = :NOT_PAID OR O.STATUS = :FAIL_PAID)', $params)
-            ->select('O.ID,O.SN,O.USER_NAME,O.ORDER_TYPE,O.ORDER_AMOUNT,O.STATUS,O.CREATED_AT,O.PAY_TYPE,O.PAY_AT,O.CONSIGNEE,O.MOBILE,O.ADDRESS,O.CITY_NAME,O.LGA_NAME,O.PROVINCE,U.REAL_NAME')
+            ->select('O.ID,O.SN,O.USER_NAME,O.ORDER_TYPE,O.ORDER_AMOUNT,O.STATUS,O.CREATED_AT,O.PAY_TYPE,O.PAY_AT,O.CONSIGNEE,O.MOBILE,O.ADDRESS,O.CITY_NAME,O.LGA_NAME,O.PROVINCE,U.REAL_NAME,O.COUNTRY_ID,O.CURRENCY_ID')
             ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID');
 
         $queryAll = $orderQuery->union($orderStandardQuery, true);
@@ -521,6 +530,8 @@ class ShopController extends BaseController {
             $data['list'][$key]['STATUS'] = \Yii::$app->params['orderStatus'][$value['STATUS']]['label'] ?? '';
             $data['list'][$key]['FULL_ADDRESS'] = trim(implode(', ', [$value['ADDRESS'], $value['CITY_NAME'], $value['LGA_NAME'], Region::getCnName($value['PROVINCE'])]), ', ');
             $data['list'][$key]['SHOW_BV'] = !in_array($value['PAY_TYPE'], [5, 6]);
+            $data['list'][$key]['COUNTRY'] = Countries::getById($value['COUNTRY_ID'])['NAME'];
+            $data['list'][$key]['CURRENCY'] = Currency::getById($value['CURRENCY_ID'])['CODE'];
 
             unset($data['list'][$key]['ADDRESS'], $data['list'][$key]['CITY_NAME'], $data['list'][$key]['LGA_NAME'], $data['list'][$key]['PROVINCE']);
         }
@@ -541,7 +552,7 @@ class ShopController extends BaseController {
         $orderQuery = Order::find()
             ->alias('O')
             ->where($condition, $params)
-            ->select('O.ID,O.SN,O.USER_NAME,O.ORDER_TYPE,O.ORDER_AMOUNT,O.STATUS,O.CREATED_AT,O.PAY_TYPE,O.PAY_AT,O.CONSIGNEE,O.MOBILE,O.ADDRESS,O.CITY_NAME,O.LGA_NAME,O.PROVINCE,U.REAL_NAME')
+            ->select('O.ID,O.SN,O.USER_NAME,O.ORDER_TYPE,O.ORDER_AMOUNT,O.STATUS,O.CREATED_AT,O.PAY_TYPE,O.PAY_AT,O.CONSIGNEE,O.MOBILE,O.ADDRESS,O.CITY_NAME,O.LGA_NAME,O.PROVINCE,U.REAL_NAME,O.COUNTRY_ID,O.CURRENCY_ID')
             ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID');
 
         // 订单中间表只查询待支付和支付失败的订单
@@ -550,7 +561,7 @@ class ShopController extends BaseController {
         $orderStandardQuery = ApproachOrder::find()
             ->alias('O')
             ->where($condition . ' AND (O.STATUS = :NOT_PAID OR O.STATUS = :FAIL_PAID)', $params)
-            ->select('O.ID,O.SN,O.USER_NAME,O.ORDER_TYPE,O.ORDER_AMOUNT,O.STATUS,O.CREATED_AT,O.PAY_TYPE,O.PAY_AT,O.CONSIGNEE,O.MOBILE,O.ADDRESS,O.CITY_NAME,O.LGA_NAME,O.PROVINCE,U.REAL_NAME')
+            ->select('O.ID,O.SN,O.USER_NAME,O.ORDER_TYPE,O.ORDER_AMOUNT,O.STATUS,O.CREATED_AT,O.PAY_TYPE,O.PAY_AT,O.CONSIGNEE,O.MOBILE,O.ADDRESS,O.CITY_NAME,O.LGA_NAME,O.PROVINCE,U.REAL_NAME,O.COUNTRY_ID,O.CURRENCY_ID')
             ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID');
 
         $queryAll = $orderQuery->union($orderStandardQuery, true);
@@ -583,6 +594,8 @@ class ShopController extends BaseController {
             $data['list'][$key]['STATUS'] = \Yii::$app->params['orderStatus'][$value['STATUS']]['label'] ?? '';
             $data['list'][$key]['FULL_ADDRESS'] = trim(implode(', ', [$value['ADDRESS'], $value['CITY_NAME'], $value['LGA_NAME'], Region::getCnName($value['PROVINCE'])]), ', ');
             $data['list'][$key]['SHOW_BV'] = !in_array($value['PAY_TYPE'], [5, 6]);
+            $data['list'][$key]['COUNTRY'] = Countries::getById($value['COUNTRY_ID'])['NAME'];
+            $data['list'][$key]['CURRENCY'] = Currency::getById($value['CURRENCY_ID'])['CODE'];
 
             unset($data['list'][$key]['ADDRESS'], $data['list'][$key]['CITY_NAME'], $data['list'][$key]['LGA_NAME'], $data['list'][$key]['PROVINCE']);
         }
@@ -594,19 +607,23 @@ class ShopController extends BaseController {
      * 会员复消
      */
     public function actionReconsume() {
+        // 会员信息
+        $user = User::getEnCodeInfo(\Yii::$app->user->id);
+
         $condition = ' AND STATUS=1 AND (FIND_IN_SET(2,GIFT_TYPE)>0 OR FIND_IN_SET(4,GIFT_TYPE)>0)';
         $data = ShopGoods::lists($condition, [], [
+            'select' => 'S.*,N.MARKET_PRICE,N.SELL_PRICE,N.TAX_RATE,N.LOCAL_CURRENCY_ID,N.COUNTRY_ID',
+            'from' => ShopGoods::tableName() . ' AS S',
+            'join' => [
+                ['INNER JOIN', ShopGoodsNature::tableName() . ' AS N', 'N.GOODS_ID = S.ID AND N.COUNTRY_ID = ' . $user['COUNTRY_ID']],
+            ],
             'orderBy' => 'SORT ASC,CREATED_AT DESC',
-            'from' => ShopGoods::tableName(),
         ]);
+
         foreach ($data['list'] as $key => $value) {
-            if ($value['TYPE'] == 1 || $value['TYPE'] == 2) {
-                $data['list'][$key]['DISCOUNT'] = ShopGoods::getGoodType()[$value['TYPE']]['discount'];
-            } else {
-                $data['list'][$key]['DISCOUNT'] = $value['SELL_DISCOUNT']*100;
-            }
-            //$data['list'][$key]['DISCOUNT'] = ShopGoods::GOODS_TYPE[$value['TYPE']]['discount'];
+            $data['list'][$key]['DISCOUNT'] = in_array($value['TYPE'], [1, 2]) ? ShopGoods::getGoodType()[$value['TYPE']]['discount'] : $value['SELL_DISCOUNT'] * 100;
         }
+
         return static::notice($data);
     }
 

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

@@ -382,4 +382,30 @@ class SiteController extends BaseController
 
         return static::notice('成功', 0);
     }
+
+    public function actionGetInstance()
+    {
+        $sign = [];
+        for ($i = 0; $i < 8; $i++) {
+            $sign[] = PageSnowFake::instance()->generateId();
+        }
+
+        return static::notice($sign);
+    }
+
+    public function actionCountries()
+    {
+        // 国家列表
+        $data = Cache::getCountries();
+
+        return static::notice(['data' => $data]);
+    }
+
+    public function actionLanguages()
+    {
+        // 语言列表
+        $data = Cache::getLanguages();
+
+        return static::notice(['data' => $data]);
+    }
 }

+ 74 - 9
frontendApi/modules/v1/controllers/UserController.php

@@ -14,6 +14,8 @@ use common\helpers\Tool;
 use common\helpers\user\Info;
 use common\models\BaUser;
 use common\models\Config;
+use common\models\Countries;
+use common\models\CurrencyConversions;
 use common\models\DeclarationLevel;
 use common\models\DeclarationPackage;
 use common\models\DecOrder;
@@ -33,6 +35,7 @@ use common\models\OpenBank;
 use common\models\ReceiveAddress;
 use common\models\Region;
 use common\models\ShopGoods;
+use common\models\ShopGoodsNature;
 use common\models\UpgradeType;
 use common\models\User;
 use common\models\UserBind;
@@ -256,6 +259,7 @@ class UserController extends BaseController {
             'DEC_ID' => $userDecId, // 用户级别id
             'REAL_NAME' => $baseInfo['REAL_NAME'], // 真实姓名
             'ADD_AT' => date('Y-m-d', $baseInfo['CREATED_AT']), // 加入时间
+            'COUNTRY_NAME' => $baseInfo['COUNTRY_NAME'], // 国家
             'IS_OBSERVE' => $isObserve, // 是否是观察期  true为是观察期
             'IS_MAX' => $isMax, // 是否已是最大级别 最大级别不需要判断报单总PV是多少 只展示基本信息
         ];
@@ -334,6 +338,11 @@ class UserController extends BaseController {
             }
         }
 
+        // 升级的会员
+        $userName = \Yii::$app->request->get('userName');
+        // 会员信息
+        $user = User::findOne(['USER_NAME' => trim($userName)]);
+
         //所有报单套餐
         $allDecPackage = DeclarationPackage::getAllData();
         $decLevels = Cache::getDecLevelConfig();
@@ -355,18 +364,39 @@ class UserController extends BaseController {
         }
         $query_condition.= ")";
 
-        $allGoods = ShopGoods::find()->where("STATUS=1 AND CATEGORY_TYPE=1 " . $query_condition)->orderBy('SORT ASC')->asArray()->all();
+        $allGoods = ShopGoods::find()
+            ->alias('S')
+            ->select('S.*,N.MARKET_PRICE,N.SELL_PRICE,N.TAX_RATE,N.LOCAL_CURRENCY_ID,N.COUNTRY_ID')
+            ->join('LEFT JOIN', ShopGoodsNature::tableName() . ' AS N', 'N.GOODS_ID=S.ID AND N.COUNTRY_ID = ' . $user['COUNTRY_ID'])
+            ->where("STATUS=1 AND CATEGORY_TYPE=1 " . $query_condition)
+            ->orderBy('SORT ASC')
+            ->asArray()
+            ->all();
+
         foreach ($allGoods as &$goods) {
             $goods['TAX'] = Tool::calculateTax($goods['SELL_PRICE'], $goods['TAX_RATE']);
         }
 
-        // 会员账户
-        $userBalance = ['cash' => 0];
+        // 报单中心汇率
+        $decCountry = User::getEnCodeInfo(\Yii::$app->user->id)['COUNTRY_ID'];
+        $decUserCurrencyRate = CurrencyConversions::getToUSDRate($decCountry['LOCAL_CURRENCY_ID']);
+        // 升级会员汇率
+        $country = Countries::getById($user['COUNTRY_ID']);
+        $currencyRate = CurrencyConversions::getToUSDRate($country['LOCAL_CURRENCY_ID']);
+
+        $userBalance = [
+            'cash' => 0,
+            'localCash' => 0
+        ];
         $userCash = UserWallet::findOneAsArray(['USER_ID' => \Yii::$app->user->id]);
         if ($userCash) {
             $userBalance['cash'] = $userCash['CASH'];
+            $userBalance['localCash'] = Tool::convertAmount($userCash['CASH'], $decUserCurrencyRate, $currencyRate);
         }
 
+        // 行政区划
+        $region = Region::getByCountryId($user['COUNTRY_ID']);
+
         return static::notice([
             'allDecPackage' => $allDecPackage,
             'allGoods' => $allGoods,
@@ -375,6 +405,9 @@ class UserController extends BaseController {
             'sellType' => ShopGoods::getCategoryType(),
             'categoryType' => ShopGoods::getCategoryType()[0]['id'],
             'userBalance' => $userBalance,
+            'decUserCurrencyRate' => $decUserCurrencyRate,
+            'userCurrencyRate' => $currencyRate,
+            'region' => $region,
         ]);
     }
 
@@ -382,8 +415,13 @@ class UserController extends BaseController {
      * 报单管理
      */
     public function actionDec() {
+        // 默认国家
+        $countryId = \Yii::$app->request->get('countryId');
+        if (!$countryId) {
+            return static::notice(Yii::t('app', 'countryDoesNotSelect'), 400);
+        }
         // 生成随机码 , 初始化redis
-        $userName = Info::generateWebUserName('NG',9);
+        $userName = Info::generateWebName($countryId);
         $redis = \Yii::$app->redis;
         $post = \Yii::$app->request->post();
         if (\Yii::$app->request->isPost) {
@@ -467,23 +505,47 @@ class UserController extends BaseController {
         }
         $query_condition.= ")";
         // 只查询普通商品
-        $allGoods = ShopGoods::find()->where("STATUS=1 AND CATEGORY_TYPE=1".$query_condition)->orderBy('SORT ASC')->asArray()->all();
+        $allGoods = ShopGoods::find()
+            ->alias('S')
+            ->select('S.*,N.MARKET_PRICE,N.SELL_PRICE,N.TAX_RATE,N.LOCAL_CURRENCY_ID,N.COUNTRY_ID')
+            ->join('INNER JOIN', ShopGoodsNature::tableName() . ' AS N', 'N.GOODS_ID=S.ID AND N.COUNTRY_ID = ' . $countyId)
+            ->where("STATUS=1 AND CATEGORY_TYPE=1 " . $query_condition)
+            ->orderBy('SORT ASC')
+            ->asArray()
+            ->all();
+
+        // 银行开户行
+        $allOpenBank = OpenBank::find()
+            ->where('STATUS=:STATUS AND COUNTRY_ID=:COUNTRY_ID', [':STATUS' => 1, ':COUNTRY_ID' => $countryId])
+            ->orderBy('LIST_ORDER ASC')
+            ->asArray()
+            ->all();
 
-        //$allGoods = ShopGoods::findAllAsArray('STATUS=1');
-        // 所有开户行
-        $allOpenBank = OpenBank::find()->where('STATUS=1')->orderBy('LIST_ORDER ASC')->asArray()->all();
         if (!$userName) {
             return static::notice(Yii::t('app',  'failedToGenerateMemberNumber'), 400);
         }
         //随机码保存在redis中方便进行比对
         $redis->setex('key_'.$userName , 3600 , $userName);
 
+        // 报单中心会员的本地汇率
+        $decCountry = User::getEnCodeInfo(\Yii::$app->user->id)['COUNTRY_ID'];
+        $decUserCurrencyRate = CurrencyConversions::getToUSDRate($decCountry['LOCAL_CURRENCY_ID']);
+        // 新会员的本地汇率
+        $country = Countries::getById($countyId);
+        $currencyRate = CurrencyConversions::getToUSDRate($country['LOCAL_CURRENCY_ID']);
+
         // 会员账户
-        $userBalance = ['cash' => 0];
+        $userBalance = [
+            'cash' => 0,
+            'localCash' => 0
+        ];
         $userCash = UserWallet::findOneAsArray(['USER_ID' => \Yii::$app->user->id]);
         if ($userCash) {
             $userBalance['cash'] = $userCash['CASH'];
+            $userBalance['localCash'] = Tool::convertAmount($userCash['CASH'], $decUserCurrencyRate, $currencyRate);
         }
+        // 行政区划
+        $region = Region::getByCountryId($countyId);
 
         return static::notice([
             'allDecPackage' => $allDecPackage,
@@ -495,6 +557,9 @@ class UserController extends BaseController {
             'categoryType' => ShopGoods::getCategoryType()[0]['id'],
             'userBalance' => $userBalance,
             'isDec' => $isDec,
+            'decUserCurrencyRate' => $decUserCurrencyRate,
+            'userCurrencyRate' => $currencyRate,
+            'region' => $region,
         ]);
     }