Parcourir la source

用户升级功能整理

sunxiaobiao il y a 1 an
Parent
commit
d4394d07d1

+ 3 - 0
app/common/repositories/store/order/StoreOrderRepository.php

@@ -9308,6 +9308,9 @@ class StoreOrderRepository extends BaseRepository
9308 9308
 
9309 9309
                 if (strpos($mark, "购买") !== false) {
9310 9310
                     Db::name('user')->where("uid", $uid)->update(['contribute' => $con_data['contribute'] + $num]);
9311
+                    /** @var UserRepository $userRepository */
9312
+                    $userRepository = app()->make(UserRepository::class);
9313
+                    $userRepository->setUserIdentity($uid);
9311 9314
                 }
9312 9315
 
9313 9316
                 if (strpos($mark, "推广") !== false) {

+ 139 - 34
app/common/repositories/user/UserRepository.php

@@ -3236,11 +3236,16 @@ class UserRepository extends BaseRepository
3236 3236
      */
3237 3237
     public function setUserIdentity($uid, $identityId = null)
3238 3238
     {
3239
-        $result = null;
3240 3239
         if (empty($identityId)) {
3241 3240
             $identityId = $this->getUserIdentity($uid);
3242 3241
         }
3243
-        $this->dao->update($uid, ['user_group' => $identityId]);
3242
+
3243
+        $userData = $this->dao->get($uid)->toArray();
3244
+        $data = ['user_group' => $identityId];
3245
+        if (empty($userData['identity_up_time'] ?? null) && $userData['user_group'] == 1 && $identityId > 1) {
3246
+            $data['identity_up_time'] = date('Y-m-d H:i:s');
3247
+        }
3248
+        $this->dao->update($uid, $data);
3244 3249
         return $identityId;
3245 3250
     }
3246 3251
 
@@ -3263,27 +3268,53 @@ class UserRepository extends BaseRepository
3263 3268
         $lowerLevelNumList = array_column($identityList, 'lower_level_num');
3264 3269
         $lowerLevelNumMax = max($lowerLevelNumList);
3265 3270
         $lowerLevelNumMin = min($lowerLevelNumList);
3266
-        $needLower = $lowerLevelNumMax;
3267
-        if($lowerLevelNumMin == 0) {
3268
-            $needLower = $lowerLevelNumMin;
3271
+        // 获取需要 递归最深的层数,比如 高级合伙人需要递归10层 普通用户需要递归一层
3272
+        $needLower = 0;
3273
+        // 0 代表要递归无限极
3274
+        if($lowerLevelNumMax > 0) {
3275
+            $needLower = $lowerLevelNumMin - 1;
3276
+        }
3277
+        // 最大等级限制
3278
+        $maxLvRestrict = 0;
3279
+
3280
+
3281
+        // 3、获取个人贡献值
3282
+        $userData = $this->dao->get($uid)->toArray();
3283
+        if ($userData['is_old'] == 1 && $userData['user_group'] > 1 && empty($userData['identity_up_time'])) {
3284
+            if (empty($userData['create_time'])) {
3285
+                return $userData['user_group'];
3286
+            }
3287
+            $userData['identity_up_time'] = $userData['create_time'];
3288
+            $this->dao->update($uid, ['identity_up_time' => $userData['identity_up_time']]);
3289
+        }
3290
+        if ($userData['user_group'] == 1) {
3291
+            $maxLvRestrict = 2;
3269 3292
         }
3270 3293
 
3271
-        // 3、获取下级用户 贡献值
3294
+        // 4、获取下级用户 贡献值
3272 3295
         $userContributionSumMap = [];
3296
+        // 获取用户的直属下级
3273 3297
         $uidContributeList = $this->getUidContributeListBySpreadUidList([$uid]);
3274 3298
         foreach ($uidContributeList as $uidContribute) {
3275
-            $userContributionSumMap[$uidContribute['uid']] = $this->getContributionSumByLevel([$uidContribute['uid']], $needLower);
3299
+            // 获取每个下级(部门)的个人贡献值
3300
+            $userContributionSumMap[$uidContribute['uid']] = $this->getContributionSumByLevel(
3301
+                [$uidContribute['uid']],
3302
+                $needLower,
3303
+                $userData['is_old'],
3304
+                $userData['identity_up_time'] ?? null
3305
+            );
3276 3306
             $userContributionSumMap[$uidContribute['uid']][0] = $uidContribute['contribute'];
3307
+            // 假设 老大的 下级是 张三和李四, 董事(最高级身份)需要循环最深的等级是 3 级    得出来的结果↓  这样是为了计算大小部门
3308
+            // $userContributionSumMap[直属下级(部门)张三] =>[0 => 张三个人贡献值, 1 => 张三所有下级用户的个人贡献值, 2 => 张三所有下级用户的下级用户贡献值]
3309
+            // $userContributionSumMap[直属下级(部门)李四] =>[0 => 李四个人贡献值, 1 => 李四所有下级用户的个人贡献值, 2 => 李四所有下级用户的下级用户贡献值]
3277 3310
         }
3278 3311
 
3279
-        // 4、获取个人贡献值
3280
-        $userData = $this->dao->get($uid)->toArray();
3281
-
3282
-        // 5、当前用户等级
3283
-        $identityId = 0;
3312
+        // 5、将用户等级由低到高
3284 3313
         usort($identityList, function ($a, $b) {
3285
-            return $b['user_group_id'] <=> $a['user_group_id'];  // 反转顺序,倒序排列
3314
+            return $a['user_group_id'] <=> $b['user_group_id'];
3286 3315
         });
3316
+        // 循环记录 如果贡献值 满足了初级合伙人身份 并记录该身份ID,继续下一阶段循环,下一阶段不满足 则该用户身份为初级合伙人
3317
+        $identityId = 0;
3287 3318
         foreach ($identityList as $item) {
3288 3319
             $lowerLevelNum = $item['lower_level_num']??0;
3289 3320
 
@@ -3291,30 +3322,41 @@ class UserRepository extends BaseRepository
3291 3322
             $arriveNumTeam = 0;
3292 3323
             $subordinateContribution = [];
3293 3324
 
3294
-            foreach ($userContributionSumMap as $key => $value) {
3295
-                $subordinateContribution[$key] = 0;
3296
-                if ($lowerLevelNum != 0) {
3297
-                    foreach ($value as $k => $v) {
3298
-                        if ($k <= $lowerLevelNum) {
3299
-                            $subordinateContribution[$key] += $v;
3300
-                        } else {
3301
-                            break;
3325
+            // 只有 业务员及以上才需要团队贡献值
3326
+            if ($item['id'] > 1) {
3327
+                foreach ($userContributionSumMap as $key => $value) {
3328
+                    $subordinateContribution[$key] = 0;
3329
+                    if ($lowerLevelNum != 0) {
3330
+                        foreach ($value as $k => $v) {
3331
+                            if ($k < $lowerLevelNum) {
3332
+                                $subordinateContribution[$key] += $v;
3333
+                            } else {
3334
+                                break;
3335
+                            }
3302 3336
                         }
3337
+                    } else {
3338
+                        $subordinateContribution[$key] = array_sum($value);
3303 3339
                     }
3304
-                } else {
3305
-                    $subordinateContribution[$key] = array_sum($value);
3340
+                }
3341
+                if (!empty($subordinateContribution)) {
3342
+                    // 大区业绩
3343
+                    $dqYj = max($subordinateContribution);
3344
+                    // 总业绩
3345
+                    $zYj = array_sum($subordinateContribution);
3346
+                    // 小区团体业绩
3347
+                    $arriveNumTeam = bcsub($zYj, $dqYj, 2);
3306 3348
                 }
3307 3349
             }
3308
-            if (!empty($subordinateContribution)) {
3309
-                // 大区业绩
3310
-                $dqYj = max($subordinateContribution);
3311
-                // 总业绩
3312
-                $zYj = array_sum($subordinateContribution);
3313
-                // 小区团体业绩
3314
-                $arriveNumTeam = bcsub($zYj, $dqYj, 2);
3315
-            }
3350
+
3351
+            // 从小向大循环,满足则去 下一等级继续验证,不满足 则 返回上次循环记录的值,并结束循环
3316 3352
             if ($item['arrive_num_own'] <= $arriveNumOwn && $item['arrive_num_team'] <= $arriveNumTeam) {
3317 3353
                 $identityId = $item['user_group_id'];
3354
+
3355
+                // 用户等级限制,本次获取身份 最大可获取什么身份,比如 用户没有 团队贡献值,他最高只能升到 2 级 即业务员
3356
+                if ($identityId == $maxLvRestrict) {
3357
+                    break;
3358
+                }
3359
+            } else {
3318 3360
                 break;
3319 3361
             }
3320 3362
         }
@@ -3341,10 +3383,15 @@ class UserRepository extends BaseRepository
3341 3383
      *                      0 表示查询所有层级直到末端。
3342 3384
      *                      1 表示只计算第1层(直接下级)的总贡献。
3343 3385
      *                      N 表示计算到第 N 层(包含第N层)的总贡献。
3386
+     * @param int $is_old
3387
+     * @param null $identity_up_time
3344 3388
      * @return array 返回一个数组,键是层级号(从1开始),值是该层级所有用户的贡献值总和。
3345 3389
      *               例如:[ 1 => 600, 2 => 1300 ]
3390
+     * @throws DataNotFoundException
3391
+     * @throws DbException
3392
+     * @throws ModelNotFoundException
3346 3393
      */
3347
-    public function getContributionSumByLevel(array $initialUserIds, int $maxDepth = 0): array
3394
+    public function getContributionSumByLevel(array $initialUserIds, int $maxDepth = 0, $is_old = 0, $identity_up_time = null): array
3348 3395
     {
3349 3396
         $levelContributions = []; // 结果数组 [level => total_contribution]
3350 3397
         if (empty($initialUserIds)) {
@@ -3372,8 +3419,9 @@ class UserRepository extends BaseRepository
3372 3419
             $subordinatesOfCurrentLevel = [];
3373 3420
             foreach(array_chunk($currentLevelIds, $chunkSize) as $chunk) {
3374 3421
                 $subordinatesChunk = Db::name('user')
3375
-                    ->field('uid, contribute') // 只需要下级的uid和贡献值
3422
+                    ->field('uid') // 只需要下级的uid
3376 3423
                     ->whereIn('spread_uid', $chunk) // spread_uid 在当前层级用户块中
3424
+                    ->where('status', 1)
3377 3425
                     ->select()
3378 3426
                     ->toArray();
3379 3427
                 $subordinatesOfCurrentLevel = array_merge($subordinatesOfCurrentLevel, $subordinatesChunk);
@@ -3384,13 +3432,70 @@ class UserRepository extends BaseRepository
3384 3432
                 break;
3385 3433
             }
3386 3434
 
3435
+            $subordinatesOfCurrentLevelUidList =[];
3436
+            foreach ($subordinatesOfCurrentLevel as &$value){
3437
+                $subordinatesOfCurrentLevelUidList[$value['uid']] = 0;
3438
+                $value['contribute'] = 0;
3439
+            }
3440
+
3441
+            // 如果 传入 $identity_up_time 不为空 证明当前在 确定身份的 用户已经是 业务员了
3442
+            if (!empty($identity_up_time)) {
3443
+                // 用户有贡献值记录,我们要根据 用户的身份 从普通消费者 升级 成业务员 的时间来 查询时间范围内产生的贡献值
3444
+                $userSignGongxianList = Db::name('user_sign_gongxian')
3445
+                    ->whereIn('uid', array_keys($subordinatesOfCurrentLevelUidList))
3446
+                    ->where('addtime', '>=', strtotime($identity_up_time)) //   `addtime` int(10) NOT NULL COMMENT '添加时间'
3447
+                    ->where('status', 1) // 贡献值状态1-有效 0-失效 -1待确认
3448
+                    ->whereNotNull('settlement_time') // `settlement_time` datetime DEFAULT NULL COMMENT '结算时间',
3449
+                    ->field('uid, number, type') // 只需要下级的uid和贡献值
3450
+                    ->select()
3451
+                    ->toArray();
3452
+                foreach ($userSignGongxianList as $value) {
3453
+                    if($value['type'] == 1) {
3454
+                        $subordinatesOfCurrentLevelUidList[$value['uid']] += $value['number'];
3455
+                    } else {
3456
+                        $subordinatesOfCurrentLevelUidList[$value['uid']] -= $value['number'];
3457
+                    }
3458
+                }
3459
+
3460
+                if ($is_old == 1) {
3461
+                    // 如果是老用户,除了通过贡献值记录表  还要计算 老订单 产生的贡献值
3462
+                    $oldUserOfGoodsList = Db::name('old_user_of_goods')
3463
+                        ->whereIn('user_id', array_keys($subordinatesOfCurrentLevelUidList))
3464
+                        ->where('create_time', '>=', strtotime($identity_up_time)) //   `addtime` int(10) NOT NULL COMMENT '添加时间'
3465
+                        ->where('status', 1) // '是否完成 0, 未完成 1 已完成',
3466
+                        ->field('user_id, money, status, create_time') // 只需要下级的uid和贡献值
3467
+                        ->select()
3468
+                        ->toArray();
3469
+
3470
+                    foreach ($oldUserOfGoodsList as $storeProductData) {
3471
+                        if ($storeProductData['money'] == 1180) {
3472
+                            $subordinatesOfCurrentLevelUidList[$storeProductData['user_id']] += 700;
3473
+                        } else if ($storeProductData['money'] == 10620) {
3474
+                            $subordinatesOfCurrentLevelUidList[$storeProductData['user_id']] += 6300;
3475
+                        } else if ($storeProductData['money'] == 11800) {
3476
+                            $subordinatesOfCurrentLevelUidList[$storeProductData['user_id']] += 7000;
3477
+                        } else if ($storeProductData['money'] == 9440) {
3478
+                            $subordinatesOfCurrentLevelUidList[$storeProductData['user_id']] += 5600;
3479
+                        } else if ($storeProductData['money'] == 2360) {
3480
+                            $subordinatesOfCurrentLevelUidList[$storeProductData['user_id']] += 1400;
3481
+                        } else {
3482
+                            $subordinatesOfCurrentLevelUidList[$storeProductData['user_id']] += bcmul($storeProductData['money'], 0.7, 2);
3483
+                        }
3484
+                    }
3485
+                }
3486
+            } else {
3487
+                // 如果传入的 $identity_up_time 为空,说明该用户只是一个普通用户(消费者),没有团队业绩
3488
+                break;
3489
+            }
3490
+
3491
+
3387 3492
             $nextLevelTotalContribution = 0;
3388 3493
             $nextLevelIds = []; // 存储下一轮需要查询的用户ID
3389 3494
 
3390 3495
             // 遍历找到的所有下级
3391 3496
             foreach ($subordinatesOfCurrentLevel as $subordinate) {
3392 3497
                 $subordinateId = $subordinate['uid'];
3393
-                $subordinateContribution = $subordinate['contribute'] ?? 0; // 安全获取,默认为0
3498
+                $subordinateContribution = $subordinatesOfCurrentLevelUidList[$subordinate['uid']] ?? 0; // 安全获取,默认为0
3394 3499
 
3395 3500
                 // 累加下一层级的总贡献值
3396 3501
                 // 注意:这里简单累加,如果一个下级同时被当前层多个用户推荐,其贡献会被计算多次