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

Merge branch 'feature/NC-55' into new-version

zhangl 1 год назад
Родитель
Сommit
bcced4c72f

+ 174 - 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,172 @@ class TransferForm extends Model {
                 return null;
             }
         }*/
+
+        // 转账网络限制
+        // 期数
+        $this->_periodNum = Period::instance()->getNowPeriodNum();
+
+        // 发起人
+        $initiator = Info::getBaseUserByUserName($fromUser['USER_NAME']);
+        // 发起人是否报单中心
+        $initiatorIsDec = $initiator['IS_DEC'] == 1;
+
+        // 接受者
+        $recipient = Info::getBaseUserByUserName($this->toUserName);
+        // 发起人是否报单中心
+        $recipientIsDec = $recipient['IS_DEC'] == 1;
+
+        // 1. 如果发起人和接受者都是报单中心,则转账无限制
+        if (($initiatorIsDec == 1) && ($recipientIsDec == 1)) {
+            return true;
+        }
+
+        // 2. 如果发起人是报单中心, 则可以转账给自己的推荐网下级
+        if ($initiatorIsDec == 1) {
+            $sql = <<<SQL
+                WITH recursive t_rec AS 
+                (
+                    SELECT
+                        m.USER_ID,
+                        U.USER_NAME,
+                        m.PARENT_UID,
+                        U2.USER_NAME AS PARENT_NAME,
+                        1 AS node_level 
+                    FROM
+                        AR_USER_RELATION_NEW m 
+                        LEFT JOIN AR_USER U ON U.ID = m.USER_ID
+                        LEFT JOIN AR_USER U2 ON U2.ID = m.PARENT_UID
+                    WHERE
+                        U.USER_NAME = :USER_NAME 
+                        
+                    UNION ALL
+                    
+                    SELECT
+                        t1.USER_ID,
+                        U.USER_NAME,
+                        t1.PARENT_UID,
+                        U2.USER_NAME AS PARENT_NAME,
+                        t2.node_level + 1 -- 结点层级
+                        
+                    FROM
+                        AR_USER_RELATION_NEW t1
+                        JOIN t_rec t2 ON t2.PARENT_UID = t1.USER_ID
+                        LEFT JOIN AR_USER U ON U.ID = t1.USER_ID
+                        LEFT JOIN AR_USER U2 ON U2.ID = t1.PARENT_UID
+                    ) 
+                SELECT
+                    * 
+                FROM
+                    t_rec
+SQL;
+            // 查询接受者的所有上级,如果没有发起人,则不能转账
+            $relationNode = \Yii::$app->db->createCommand($sql)
+                ->bindValue(':USER_NAME', $this->toUserName)
+                ->queryAll();
+
+            $relationNode = array_column($relationNode, 'USER_NAME');
+            if (!in_array($fromUser['USER_NAME'], $relationNode)) {
+                $this->addError($attribute, '转账失败:转入会员不是您的下级');
+                return null;
+            }
+            return true;
+        }
+
+        // 3. 如果发起人是普通会员,则只能转给自己推荐网的某个节点
+        // 上级节点
+        $sqlUp =<<<SQL
+            WITH recursive t_rec AS 
+            (
+                SELECT
+                    m.USER_ID,
+                    U.USER_NAME,
+                    m.PARENT_UID,
+                    U2.USER_NAME AS PARENT_NAME,
+                    1 AS node_level 
+                FROM
+                    AR_USER_RELATION_NEW m 
+                    LEFT JOIN AR_USER U ON U.ID = m.USER_ID
+                    LEFT JOIN AR_USER U2 ON U2.ID = m.PARENT_UID
+                WHERE
+                    U.USER_NAME = :USER_NAME 
+                    
+                UNION ALL
+                
+                SELECT
+                    t1.USER_ID,
+                    U.USER_NAME,
+                    t1.PARENT_UID,
+                    U2.USER_NAME AS PARENT_NAME,
+                    t2.node_level + 1 -- 结点层级
+                    
+                FROM
+                    AR_USER_RELATION_NEW t1
+                    JOIN t_rec t2 ON t2.PARENT_UID = t1.USER_ID
+                    LEFT JOIN AR_USER U ON U.ID = t1.USER_ID
+                    LEFT JOIN AR_USER U2 ON U2.ID = t1.PARENT_UID
+                ) 
+            SELECT
+                * 
+            FROM
+                t_rec
+SQL;
+        // 上级
+        $relationNodeUp = \Yii::$app->db->createCommand($sqlUp)
+            ->bindValue(':USER_NAME' , $fromUser['USER_NAME'])
+            ->queryAll();
+
+        $relationNodeUp = array_column($relationNodeUp, 'USER_NAME');
+        unset($relationNodeUp[$fromUser['USER_NAME']]);
+        if (!in_array($this->toUserName, $relationNodeUp)) {
+            // 下级节点
+            $sqlFloor =<<<SQL
+                WITH recursive t_rec AS 
+                (
+                    SELECT
+                        m.USER_ID,
+                        U.USER_NAME,
+                        m.PARENT_UID,
+                        U2.USER_NAME AS PARENT_NAME,
+                        1 AS node_level 
+                    FROM
+                        AR_USER_RELATION_NEW m 
+                        LEFT JOIN AR_USER U ON U.ID = m.USER_ID
+                        LEFT JOIN AR_USER U2 ON U2.ID = m.PARENT_UID
+                    WHERE
+                        U.USER_NAME = :USER_NAME 
+                        
+                    UNION ALL
+                    
+                    SELECT
+                        t1.USER_ID,
+                        U.USER_NAME,
+                        t1.PARENT_UID,
+                        U2.USER_NAME AS PARENT_NAME,
+                        t2.node_level + 1 -- 结点层级
+                        
+                    FROM
+                        AR_USER_RELATION_NEW t1
+                        JOIN t_rec t2 ON t2.PARENT_UID = t1.USER_ID
+                        LEFT JOIN AR_USER U ON U.ID = t1.USER_ID
+                        LEFT JOIN AR_USER U2 ON U2.ID = t1.PARENT_UID
+                    ) 
+                SELECT
+                    * 
+                FROM
+                    t_rec
+SQL;
+            // 下级
+            $relationNodeFloor = \Yii::$app->db->createCommand($sqlFloor)
+                ->bindValue(':USER_NAME' , $this->toUserName)
+                ->queryAll();
+            $relationNodeFloor = array_column($relationNodeFloor, 'USER_NAME');
+            if (!in_array($fromUser['USER_NAME'], $relationNodeFloor)) {
+                $this->addError($attribute, '转账失败:转入会员不是您的上级');
+                return null;
+            }
+        }
+
+        return true;
     }
 
     /**

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