Browse Source

feat: NC-55: 会员转账新规则.

zhangl 1 year ago
parent
commit
8ea41035c1

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

@@ -2,6 +2,7 @@
 
 namespace common\models\forms;
 
+use common\helpers\bonus\CalcCache;
 use common\helpers\Cache;
 use common\helpers\Date;
 use common\components\Model;
@@ -27,6 +28,7 @@ use common\models\UserBonus;
 use common\models\UserInfo;
 use common\models\UserRelation;
 use common\models\UserSystem;
+use frontendApi\modules\v1\models\Relation;
 use yii\base\Exception;
 use yii\helpers\Json;
 
@@ -39,6 +41,9 @@ class TransferForm extends Model {
     const BONUS_TO_BONUS = 2;
     const BALANCE_TO_BALANCE = 3;
     const POINT_TO_BALANCE = 4;
+    const LOOP_FINISH = 1;
+    const LOOP_CONTINUE = 2;
+    private $_periodNum = 0;
 
     public $toUserName;
     public $toRealName;
@@ -104,6 +109,7 @@ class TransferForm extends Model {
      * @param $attribute
      * @return null
      * @throws Exception
+     * @throws \Exception
      */
     public function initUser($attribute) {
         // 转账记录
@@ -137,8 +143,8 @@ class TransferForm extends Model {
 
 
         // 转账条件判断
-        $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());
+//        $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());
         //$recNum = UserRelation::firstFloorChildNum($fromUserId);
 //        if ($orderAmount < 300 && $recNum==0) {
 //            $this->addError($attribute, '消费未满300元或未推荐新人,暂不能转账');
@@ -179,6 +185,62 @@ class TransferForm extends Model {
                 return null;
             }
         }*/
+
+        // 转账网络限制
+        // 期数
+        $this->_periodNum = Period::instance()->getNowPeriodNum();
+
+        // 发起人
+        $initiator = Info::baseInfo($toUserId);
+        // 发起人是否报单中心
+        $initiatorIsDec = $initiator['IS_DEC'] == 1;
+        $initiatorId = $initiator['ID'];
+
+        // 接受者
+        $recipient = Info::baseInfo($fromUserId);
+        // 发起人是否报单中心
+        $recipientIsDec = $recipient['IS_DEC'] == 1;
+        $recipientId = $recipient['ID'];
+
+        // 1. 如果发起人和接受者都是报单中心,则转账无限制
+        if (($initiatorIsDec == 1) && ($recipientIsDec == 1)) {
+
+        }
+
+        // 2. 如果发起人是普通会员,则只能转给自己推荐网的上级某个节点
+        $relation = new Relation();
+        if (!$initiatorIsDec) {
+            // 判断接受者是否是自己的推荐网上级某个节点
+            $allowable = $relation->loopRelationParentDo($initiatorId, function ($parent) use ($recipientId) {
+                $parentUser = CalcCache::getUserInfo($parent['PARENT_UID'], $this->_periodNum);
+                if ($parentUser['ID'] == $recipientId) {
+                    return self::LOOP_FINISH;
+                }
+
+                unset($parent);
+            });
+
+            if (!$allowable) {
+                $this->addError($attribute, '转账失败:转入会员不是您的上级');
+                return null;
+            }
+        }
+
+        // 3. 如果发起人是报单中心或者普通会员, 则可以转账给自己的推荐网下级
+        // 判断接受者是否是自己的推荐网上级某个节点
+        $allowable = $relation->loopRelationParentDo($recipientId, function ($parent) use ($initiatorId) {
+            $parentUser = CalcCache::getUserInfo($parent['PARENT_UID'], $this->_periodNum);
+            if ($parentUser['ID'] == $initiatorId) {
+                return self::LOOP_FINISH;
+            }
+
+            unset($parent);
+        });
+
+        if (!$allowable) {
+            $this->addError($attribute, '转账失败:转入会员不是您的下级');
+            return null;
+        }
     }
 
     /**

+ 1 - 0
frontendApi/config/urlManagerRules.php

@@ -117,6 +117,7 @@ return [
             'GET network' => 'network',
             'GET network-list' => 'network-list',
             'GET get-period' => 'get-period',
+            'GET scour-relation'  => 'scour-relation',
         ],
     ],
     [

+ 75 - 0
frontendApi/modules/v1/controllers/AtlasController.php

@@ -8,17 +8,25 @@
 
 namespace frontendApi\modules\v1\controllers;
 
+use common\helpers\bonus\CalcCache;
 use common\helpers\Cache;
 use common\helpers\user\Info;
 use common\models\Period;
+use common\models\StorePerfLog;
 use common\models\UserNetwork;
 use common\models\UserNetworkHidden;
+use frontendApi\modules\v1\models\Relation;
 use Yii;
 use common\models\User;
+use yii\web\HttpException;
 
 class AtlasController extends BaseController {
     public $modelClass = User::class;
 
+    const LOOP_FINISH = 1;
+    const LOOP_CONTINUE = 2;
+    private $_periodNum = 0;
+
     public function behaviors() {
         $behaviors = parent::behaviors();
         return $behaviors;
@@ -150,4 +158,71 @@ class AtlasController extends BaseController {
         ]);
     }
 
+    /**
+     * 查询推荐网络的指定节点.
+     * @return void
+     * @throws HttpException
+     * @throws \Exception
+     */
+    public function actionScourRelation()
+    {
+        // 发起人
+        $initiator = Yii::$app->request->get('initiator');
+        // 接受者
+        $recipient = Yii::$app->request->get('recipient');
+        // 期数
+        $this->_periodNum = Period::instance()->getNowPeriodNum();
+
+        // 发起人
+        $initiatorInfo = Info::getBaseUserByUserName($initiator);
+        if (!$initiatorInfo) {
+            return static::notice('会员不存在', 400);
+        }
+        // 发起人是否报单中心
+        $initiatorIsDec = $initiatorInfo['IS_DEC'] == 1;
+        $initiatorId = $initiatorInfo['ID'];
+
+        // 接受者
+        $recipientInfo = Info::getBaseUserByUserName($recipient);
+        if (!$recipientInfo) {
+            return static::notice('会员不存在', 400);
+        }
+        // 发起人是否报单中心
+        $recipientIsDec = $recipientInfo['IS_DEC'] == 1;
+        $recipientId = $recipientInfo['ID'];
+
+        // 1. 如果发起人和接受者都是报单中心,则转账无限制
+        if (($initiatorIsDec == 1) && ($recipientIsDec == 1)) {
+            return static::notice(['allowable' => true]);
+        }
+
+        // 2. 如果发起人是普通会员,则只能转给自己推荐网的上级某个节点
+        $relation = new Relation();
+        if (!$initiatorIsDec) {
+            // 判断接受者是否是自己的推荐网上级某个节点
+            $allowable = $relation->loopRelationParentDo($initiatorId, function ($parent) use ($recipientId) {
+                $parentUser = CalcCache::getUserInfo($parent['PARENT_UID'], $this->_periodNum);
+                if ($parentUser['ID'] == $recipientId) {
+                    return self::LOOP_FINISH;
+                }
+
+                unset($parent);
+            });
+
+            return static::notice(['allowable' => $allowable]);
+        }
+
+        // 3. 如果发起人是报单中心或者普通会员, 则可以转账给自己的推荐网下级
+        // 判断接受者是否是自己的推荐网上级某个节点
+        $allowable = $relation->loopRelationParentDo($recipientId, function ($parent) use ($initiatorId) {
+            $parentUser = CalcCache::getUserInfo($parent['PARENT_UID'], $this->_periodNum);
+            if ($parentUser['ID'] == $initiatorId) {
+                return self::LOOP_FINISH;
+            }
+
+            unset($parent);
+        });
+
+        return static::notice(['allowable' => $allowable]);
+    }
 }

+ 41 - 0
frontendApi/modules/v1/models/Relation.php

@@ -0,0 +1,41 @@
+<?php
+
+namespace frontendApi\modules\v1\models;
+
+use common\helpers\Cache;
+
+class Relation extends \common\components\ActiveRecord
+{
+    const LOOP_FINISH = 1;
+    const LOOP_CONTINUE = 2;
+    private $_limit = 5000;
+
+    /**
+     * 循环推荐网络的父级
+     * @param $userId
+     * @param callable $callbackFunc
+     * @param int $offset
+     * @return bool
+     */
+    public function loopRelationParentDo($userId, callable $callbackFunc, int $offset = 0): bool
+    {
+        $allParents = Cache::getAllRelationParents($userId);
+        $allData = array_slice($allParents, $offset, $this->_limit);
+        unset($allParents);
+        if ($allData) {
+            foreach ($allData as $data) {
+                $funcResult = $callbackFunc($data);
+                if ($funcResult === self::LOOP_FINISH) {
+                    return true;
+                } elseif ($funcResult === self::LOOP_CONTINUE) {
+                    continue;
+                }
+                unset($data, $funcResult);
+            }
+
+            unset($allData);
+            return $this->loopRelationParentDo($userId, $callbackFunc, $offset + $this->_limit);
+        }
+        return true;
+    }
+}