Преглед изворни кода

feat: NG-15: 新会员注册时增加国家与语言选项.

kevin пре 1 година
родитељ
комит
5491bc77e9

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

@@ -202,6 +202,7 @@ return [
     'totalPvExceedPv' => 'The total PV cannot exceed the PV value of the next level under the selected level',
     'deliveryTemporarilyNotSupported' => 'Delivery is temporarily not supported in the region. Contact customer service for details',
     'applicantCashShort' => 'The applicant is short of cash and cannot complete the declaration',
+    'applicantPrpShort' => 'The applicant is short of balance and cannot complete the declaration',
     'failedToUpgrade' => 'Failed to upgrade for member',
     'bulkDeclarationNotSames' => 'Bulk declaration member must be the same member',
     'reportFormatIncorrect' => 'The format of the report data is incorrect',

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

@@ -204,6 +204,7 @@ return [
     'totalPvExceedPv' => '总PV不能超过已选级别下一个级别的PV值',
     'deliveryTemporarilyNotSupported' => '地区暂时不支持配送,具体联系客服',
     'applicantCashShort' => '报单人现金不足,无法完成报单',
+    'applicantPrpShort' => '报单人余额不足,无法完成报单',
     'failedToUpgrade' => '为会员升级失败',
     'bulkDeclarationNotSames' => '批量报单会员必须是同一身份证',
     'reportFormatIncorrect' => '报单数据格式错误',

+ 92 - 0
common/models/UserPerformance.php

@@ -2,8 +2,12 @@
 
 namespace common\models;
 
+use common\helpers\Date;
+use common\libs\lock\RedisLock;
 use Yii;
 use common\libs\logging\operate\valueType\Config as ValueTypeConfig;
+use yii\base\Exception;
+use yii\db\Expression;
 
 /**
  * This is the model class for table "{{%USER_PERFORMANCE}}".
@@ -23,6 +27,8 @@ class UserPerformance extends \common\components\ActiveRecord
     const NULLIFY = 40;
     const EXPIRED = 50;
 
+    const USER_PERFORMANCE_BALANCE_LOCK_KEY = 'userPerformanceLock';
+
     public static function getEffective(): array
     {
         return [self::NEWS, self::USING];
@@ -92,4 +98,90 @@ class UserPerformance extends \common\components\ActiveRecord
 
         return $data['AMOUNTS'] ?? 0;
     }
+
+    /**
+     * @param $userId
+     * @param $amount
+     * @param string $orderId
+     * @return true
+     * @throws Exception
+     * @throws \yii\db\Exception
+     */
+    public static function changeUserPerformance($userId, $amount, string $orderId = ''): bool
+    {
+        if ($amount == 0) {
+            return true;
+        }
+
+        // 会员总绩效奖金
+        $userPerformanceAmount = self::getAmountByUserId($userId);
+        if ($amount > $userPerformanceAmount) {
+            throw new Exception(Yii::t('app', 'applicantPrpShort'));
+        }
+
+        $period = Period::instance();
+        $periodNum = $period->getNowPeriodNum();
+
+        $calcYearMonth = $period->getYearMonth($periodNum);
+        // redis加锁(防止并发余额数值不准确出错)
+        $lockKey = self::USER_PERFORMANCE_BALANCE_LOCK_KEY . $userId;
+
+        if (RedisLock::instance()->lock($lockKey)) {
+            // 根据规则获取绩效奖金:过期时间(升序) -> 发放时间(升序)
+            $records = self::find()
+                ->where('USER_ID=:USER_ID AND AMOUNTS>0 AND STATUS_ID<:STATUS_ID', [':USER_ID' => $userId, ':STATUS_ID' => self::FINISHED])
+                ->orderBy('EXPIRED_AT ASC, CREATED_AT ASC')
+                ->asArray()
+                ->all();
+
+            $db = \Yii::$app->db;
+            $transaction = $db->beginTransaction();
+            try {
+                // 循环扣除绩效奖金
+                $surplus = $amount;
+                foreach ($records as $record) {
+                    $balance = 0;
+                    if ($record['AMOUNTS'] > $surplus) {
+                        $balance = $record['AMOUNTS'] - $surplus;
+                        // 扣除奖金
+                        UserPerformance::updateAll(['AMOUNTS' => $balance, 'STATUS_ID' => self::USING], 'ID=:ID', [':ID' => $record['ID']]);
+                        // 写日志
+                        UserPerformanceLogs::changeAmountLogs($record['ID'], $surplus, $periodNum, $orderId);
+                        break;
+                    }
+
+                    if ($record['AMOUNTS'] == $surplus) {
+                        $balance = $record['AMOUNTS'] - $surplus;
+                        // 扣除奖金
+                        UserPerformance::updateAll(['AMOUNTS' => $balance, 'STATUS_ID' => self::FINISHED], 'ID=:ID', [':ID' => $record['ID']]);
+                        // 写日志
+                        UserPerformanceLogs::changeAmountLogs($record['ID'], $surplus, $periodNum, $orderId);
+
+                        break;
+                    }
+
+                    if ($record['AMOUNTS'] < $surplus) {
+                        $balance = $surplus - $record['AMOUNTS'];
+                        $surplus = $balance;
+                        // 扣除奖金
+                        UserPerformance::updateAll(['AMOUNTS' => 0, 'STATUS_ID' => self::FINISHED], 'ID=:ID', [':ID' => $record['ID']]);
+                        // 写日志
+                        UserPerformanceLogs::changeAmountLogs($record['ID'], $surplus, $periodNum, $orderId);
+                    }
+                }
+
+                $transaction->commit();
+            } catch (\Exception $e) {
+                $transaction->rollBack();
+                throw new Exception($e->getMessage());
+            }
+
+            // 解除锁
+            RedisLock::instance()->unlock($lockKey);
+        } else {
+            throw new Exception(Yii::t('app', 'flowCreateError'));
+        }
+
+        return true;
+    }
 }

+ 39 - 6
common/models/UserPerformanceLogs.php

@@ -2,15 +2,19 @@
 
 namespace common\models;
 
+use common\helpers\Date;
+use Exception;
+
 /**
  * This is the model class for table "{{%USER_PERFORMANCE_LOGS}}".
  *
- * @property string $ID
- * @property string $USER_ID
- * @property string $CASH
- * @property integer $UPDATED_AT
- * @property integer $CLEAR_BY_CLOSED_AT
- * @property User $user
+ * @property string ID
+ * @property string USER_PERFORMANCE_ID
+ * @property string ORDER_ID
+ * @property double AMOUNTS
+ * @property integer PERIOD_NUM
+ * @property integer CREATED_AT
+ * @property string REMARK
  */
 class UserPerformanceLogs extends \common\components\ActiveRecord
 {
@@ -47,4 +51,33 @@ class UserPerformanceLogs extends \common\components\ActiveRecord
             'CREATED_AT' => '修改时间',
         ];
     }
+
+    /**
+     * @throws Exception
+     */
+    public static function changeAmountLogs($prpId, $amount, $periodNum, $orderId = '')
+    {
+        $id = Date::today('Ymd') . self::_random(10, 1);
+        $model = new self();
+        $model->ID = $id;
+        $model->USER_PERFORMANCE_ID = $prpId;
+        $model->ORDER_ID = $orderId;
+        $model->AMOUNTS = $amount;
+        $model->PERIOD_NUM = $periodNum;
+        $model->CREATED_AT = time();
+        if(!$model->save()){
+            throw new Exception($model->getErrors());
+        }
+    }
+
+    private static function _random($length, $numeric = 0) {
+        $seed = base_convert(md5(microtime() . $_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);
+        $seed = $numeric ? (str_replace('0', '', $seed) . '012340567890') : ($seed . 'zZ' . strtoupper($seed));
+        $hash = '';
+        $max = strlen($seed) - 1;
+        for ($i = 0; $i < $length; $i++) {
+            $hash .= $seed[mt_rand(0, $max)];
+        }
+        return $hash;
+    }
 }

+ 26 - 36
common/models/forms/OrderForm.php

@@ -539,7 +539,7 @@ class OrderForm extends Model
                         'PRICE' => $goodsNature['SELL_PRICE'],
                         'PV' => $currentPv, // $goods['PRICE_PV'],
                         'REAL_PRICE' => $realPrice,
-                        'REAL_PV' => $realPv,
+                        'REAL_PV' => $this->payType == 'prp' ? 0 : $realPv,
                         'REMAIN_PV' => $remainPv,
                         'POINT' => $goods['POINT'],
                         'BUY_NUMS' => intval($v),
@@ -691,19 +691,7 @@ class OrderForm extends Model
             if ($payAmount > Balance::getBalanceExchangePoints($loginUserId)) {
                 return ['code' => 500, 'message' => Yii::t('app', 'exchangePointDoesNotAdequate')];
             }
-        } else if ($payType == 'tourism_points') {
-            if ($payAmount > Balance::getBalanceTourism($loginUserId)) {
-                return ['code' => 500, 'message' => Yii::t('app', 'travelPointDoesNotAdequate')];
-            }
-        } else if ($payType == 'garage_points') {
-            if ($payAmount > Balance::getBalanceGarage($loginUserId)) {
-                return ['code' => 500, 'message' => Yii::t('app', 'carFundPointDoesNotAdequate')];
-            }
-//        } else{
-//            if ($payAmount > Balance::getBalanceReconsumePoints($loginUserId)) {
-//                return ['code' => 500, 'message' => '复消积分不足,无法购买商品'];
-//            }
-        } else if ($payType == 'user_performance') {
+        } else if ($payType == 'prp') {
             if ($payAmount > UserPerformance::getAmounts($loginUserId)) {
                 return ['code' => 500, 'message' => Yii::t('app', 'userPerformanceDoesNotAdequate')];
             }
@@ -753,8 +741,8 @@ class OrderForm extends Model
         $orderModel->ORDER_AMOUNT = $this->_decAmount;
         $orderModel->PV = $_hasPV;
         $orderModel->PAY_AMOUNT = $this->_payAmount;
-        $orderModel->PAY_PV = $_hasRealPV; // 兑换积分不能算业绩
-        $orderModel->REMAIN_PV = $this->_remainPv;
+        $orderModel->PAY_PV = $this->payType == 'prp' ? 0 : $_hasRealPV; // 兑换积分不能算业绩
+        $orderModel->REMAIN_PV = $this->payType == 'prp' ? 0 : $this->_remainPv;
         $orderModel->PAY_AT = Date::nowTime();
         $orderModel->PAY_TYPE = $this->payType;
         $orderModel->PERIOD_NUM = $nowPeriodNum;
@@ -811,14 +799,8 @@ class OrderForm extends Model
             Cash::changeUserCash(\Yii::$app->user->id, 'CASH', -abs($this->_payAmount), ['REMARK' => 'Members reselling balance payment', 'ORDER_SN' => $orderModel->SN]); // 会员复销余额支付
         } else if ($this->payType=='exchange') {
             Balance::changeUserBonus(\Yii::$app->user->id,'exchange_points', -abs($this->_payAmount),['DEAL_TYPE_ID' => DealType::EXCHANGE_POINTS_EXCHANGE,'REMARK' => '会员兑换积分兑换', 'ORDER_SN' => $orderModel->SN]);
-        } else if ($this->payType == 'tourism_points') {
-            Balance::changeUserBonus(\Yii::$app->user->id, 'tourism_points', -abs($this->_payAmount), ['DEAL_TYPE_ID' => DealType::TOURISM_POINTS_EXCHANGE,'REMARK' => '会员旅游换积分兑换', 'ORDER_SN' => $orderModel->SN]);
-        } else if ($this->payType == 'garage_points') {
-            Balance::changeUserBonus(\Yii::$app->user->id, 'garage_points', -abs($this->_payAmount), ['DEAL_TYPE_ID' => DealType::GARAGE_POINTS_EXCHANGE,'REMARK' => '会员名车积分兑换', 'ORDER_SN' => $orderModel->SN]);
-        }  else if ($this->payType == 'villa_points') {
-            Balance::changeUserBonus(\Yii::$app->user->id, 'villa_points', -abs($this->_payAmount), ['DEAL_TYPE_ID' => DealType::VILLA_POINTS_EXCHANGE,'REMARK' => '会员房奖积分兑换', 'ORDER_SN' => $orderModel->SN]);
-        } else if ($this->payType == 'reconsume_points') {
-            Balance::changeUserBonus(\Yii::$app->user->id,'reconsume_points', -abs($this->_payAmount),['DEAL_TYPE_ID' => DealType::RECONSUME_POINTS_EXCHANGE,'REMARK' => '会员复销积分兑换', 'ORDER_SN' => $orderModel->SN]);
+        } else if ($this->payType == 'prp') {
+            UserPerformance::changeUserPerformance(\Yii::$app->user->id, $this->_payAmount, $orderModel->SN);
         }
 
         return $orderModel;
@@ -885,13 +867,13 @@ class OrderForm extends Model
                         $pvSplit = $this->_pvSplit($realPv);
                         $currentPv = $pvSplit['current'];
                         $remainPv = $pvSplit['remain'];
-                        $totalPv += $currentPv * intval($v);
-                        $totalRealPv += $realPv * intval($v);
+                        $totalPv += $this->payType == 'prp' ? 0 : $currentPv * intval($v);
+                        $totalRealPv += $this->payType == 'prp' ? 0 : $realPv * intval($v);
                         $this->_remainPv += $remainPv * intval($v);
                     }else{
                         $currentPv = $goods['PRICE_PV'];
-                        $totalPv += $realPv * intval($v);
-                        $totalRealPv += $realPv * intval($v);
+                        $totalPv += $this->payType == 'prp' ? 0 : $realPv * intval($v);
+                        $totalRealPv += $this->payType == 'prp' ? 0 : $realPv * intval($v);
                         $remainPv = 0;
                         $this->_remainPv += 0;
                     }
@@ -962,8 +944,8 @@ class OrderForm extends Model
         $freeShipping = $freeTemplate['free_shipping'] ?? 0;
 
         $this->_decAmount = $totalAmount;
-        $this->_decPv = $totalPv;
-        $this->_realPv = $totalRealPv;
+        $this->_decPv = $this->payType == 'prp' ? 0 : $totalPv;
+        $this->_realPv = $this->payType == 'prp' ? 0 : $totalRealPv;
         $this->_freight = ($totalAmount >= $freeShipping) ? 0 : $freight;
 
         $this->_payAmount = $this->_decAmount + $this->_freight;
@@ -987,12 +969,18 @@ class OrderForm extends Model
                 }
             }
 
-            //看现金余额是否充足
-            $decCash = Cash::getAvailableBalance($loginUserId);
+            if ($this->payType == 'prp') {
+                //看余额是否充足
+                $decCash = UserPerformance::getAmounts($loginUserId);
+            } else {
+                //看现金余额是否充足
+                $decCash = Cash::getAvailableBalance($loginUserId);
+            }
+
             // 转换后的余额
             $localCash = Tool::convertAmount($decCash, $decUserCurrencyRate, $currencyRate);
             if ($localCash < $this->_decAmount){
-                throw new Exception(Yii::t('app', 'applicantCashShort'), 400);
+                throw new Exception(Yii::t('app', 'applicantPrpShort'), 400);
             }
 
             foreach ($this->goodsNum as $k => $v){
@@ -1079,9 +1067,9 @@ class OrderForm extends Model
         $orderModel->USER_ID = $userId;
         $orderModel->USER_NAME = $this->userName;
         $orderModel->ORDER_AMOUNT = $this->_decAmount;
-        $orderModel->PV = $this->_decPv;
+        $orderModel->PV = $this->payType == 'prp' ? 0 : $this->_decPv;
         $orderModel->PAY_AMOUNT = $this->_payAmount;
-        $orderModel->PAY_PV = $this->_decPv;
+        $orderModel->PAY_PV = $this->payType == 'prp' ? 0 : $this->_decPv;
         $orderModel->PAY_AT = Date::nowTime();
         $orderModel->PAY_TYPE = $this->payType;
         $orderModel->PERIOD_NUM = $nowPeriodNum;
@@ -1118,7 +1106,9 @@ class OrderForm extends Model
         //扣除会员余额/积分
         if($this->payType=='cash') {
             Cash::changeUserCash($loginUserId, 'CASH', -abs($this->_payAmount), ['REMARK' => Yii::t('app', 'membersResellingBalancePayment')]);
-        }else{
+        } else if ($this->payType == 'prp') {
+            UserPerformance::changeUserPerformance($loginUserId, $this->_payAmount, $orderModel->SN);
+        } else{
             Balance::changeUserBonus($loginUserId,'reconsume_points', -abs($this->_payAmount),['DEAL_TYPE_ID' => DealType::RECONSUME_POINTS_EXCHANGE, 'REMARK' => Yii::t('app', 'membersExchangePointPayment')]);
         }
         return $orderModel;