Explorar o código

根据贡献值的发放升级用户身份

sunxbiao hai 1 ano
pai
achega
f6fa4e5850

+ 7 - 0
app/command/PensionTasks.php

@@ -12,6 +12,7 @@ use app\common\repositories\merchant\order\OrderMerchantRepository;
12 12
 use app\common\repositories\store\order\StoreOrderStatusRepository;
13 13
 use app\common\repositories\store\product\ProductRepository;
14 14
 use app\common\repositories\user\UserBillRepository;
15
+use app\common\repositories\user\UserRepository;
15 16
 use app\traits\GzcApiRequest;
16 17
 use Carbon\Carbon;
17 18
 use think\console\Command;
@@ -524,6 +525,9 @@ class PensionTasks extends Command
524 525
                             'status'          => 1,
525 526
                             'settlement_time' => date('Y-m-d H:i:s')
526 527
                         ]);
528
+                    /** @var UserRepository $userRepository */
529
+                    $userRepository = app()->make(UserRepository::class);
530
+                    $userRepository->setUserIdentity($user_sign_gongxian['uid']);
527 531
                 }
528 532
 
529 533
             });
@@ -772,6 +776,9 @@ class PensionTasks extends Command
772 776
                             'status'          => 1,
773 777
                             'settlement_time' => date('Y-m-d H:i:s')
774 778
                         ]);
779
+                    /** @var UserRepository $userRepository */
780
+                    $userRepository = app()->make(UserRepository::class);
781
+                    $userRepository->setUserIdentity($user_sign_gongxian['uid']);
775 782
                 }
776 783
 
777 784
                 

+ 21 - 8
app/common/repositories/store/order/StoreOrderRepository.php

@@ -7435,9 +7435,13 @@ class StoreOrderRepository extends BaseRepository
7435 7435
                 ->whereIn('status', [0, 1, 2, 3])
7436 7436
                 ->sum('pay_price');
7437 7437
 //            if ($pay_price >= 365) {
7438
-            Db::name('user')->where('uid', $uid)->whereNotIn('user_group', [3, 4, 5, 6])->update([
7439
-                'user_group' => 2
7440
-            ]);
7438
+//            Db::name('user')->where('uid', $uid)->whereNotIn('user_group', [3, 4, 5, 6])->update([
7439
+//                'user_group' => 2
7440
+//            ]);
7441
+            // 设置用户 身份
7442
+            /** @var UserRepository $userRepository */
7443
+            $userRepository = app()->make(UserRepository::class);
7444
+            $userRepository->setUserIdentity($uid);
7441 7445
         }
7442 7446
 
7443 7447
         $shouxufei = systemConfig('online_yanglao');
@@ -7466,9 +7470,12 @@ class StoreOrderRepository extends BaseRepository
7466 7470
         }
7467 7471
 
7468 7472
         if ($product_id == 15323) {
7469
-            Db::name('user')->where('uid', $uid)->whereNotIn('user_group', [3, 4, 5, 6])->update([
7470
-                'user_group' => 4//升級創客
7471
-            ]);
7473
+//            Db::name('user')->where('uid', $uid)->whereNotIn('user_group', [3, 4, 5, 6])->update([
7474
+//                'user_group' => 4//升級創客
7475
+//            ]);
7476
+            /** @var UserRepository $userRepository */
7477
+            $userRepository = app()->make(UserRepository::class);
7478
+            $userRepository->setUserIdentity($uid);
7472 7479
         }
7473 7480
 
7474 7481
         Db::name('store_order')->where('order_id', $order_id)
@@ -10036,12 +10043,18 @@ class StoreOrderRepository extends BaseRepository
10036 10043
             if ($totalPayPrice >= 1180 && $totalPayPrice < 11800) {
10037 10044
 
10038 10045
                 if ($userdata['user_group'] <= 1) {
10039
-                    Db::name("user")->where("uid", $store_order_data['uid'])->update(["user_group" => 2]);
10046
+//                    Db::name("user")->where("uid", $store_order_data['uid'])->update(["user_group" => 2]);
10047
+                    /** @var UserRepository $userRepository */
10048
+                    $userRepository = app()->make(UserRepository::class);
10049
+                    $userRepository->setUserIdentity($store_order_data['uid']);
10040 10050
                 }
10041 10051
 
10042 10052
             } else if ($totalPayPrice >= 11800) {
10043 10053
                 if ($userdata['user_group'] <= 2) {
10044
-                    Db::name("user")->where("uid", $store_order_data['uid'])->update(["user_group" => 3]);
10054
+//                    Db::name("user")->where("uid", $store_order_data['uid'])->update(["user_group" => 3]);
10055
+                    /** @var UserRepository $userRepository */
10056
+                    $userRepository = app()->make(UserRepository::class);
10057
+                    $userRepository->setUserIdentity($store_order_data['uid']);
10045 10058
                 }
10046 10059
             }
10047 10060
 

+ 13 - 0
app/common/repositories/user/UserIdentityRepository.php

@@ -94,4 +94,17 @@ class UserIdentityRepository extends BaseRepository
94 94
     {
95 95
         return $this->form($id, $this->dao->get($id)->toArray());
96 96
     }
97
+
98
+    /**
99
+     * @param array $where
100
+     * @return array
101
+     * @throws DataNotFoundException
102
+     * @throws DbException
103
+     * @throws ModelNotFoundException
104
+     */
105
+    public function getIdentityList(array $where = [])
106
+    {
107
+        $query = $this->dao->search($where);
108
+        return $query->select()->toArray();
109
+    }
97 110
 }

+ 202 - 0
app/common/repositories/user/UserRepository.php

@@ -3225,4 +3225,206 @@ class UserRepository extends BaseRepository
3225 3225
         $resultArray = array_diff($originalArray, [$uid]);
3226 3226
         return $resultArray;
3227 3227
     }
3228
+
3229
+
3230
+    /**
3231
+     * 设置用户 身份
3232
+     * @param $uid
3233
+     * @param $identityId
3234
+     * @return int|mixed|null
3235
+     * @throws DbException
3236
+     */
3237
+    public function setUserIdentity($uid, $identityId = null)
3238
+    {
3239
+        $result = null;
3240
+        if (empty($identityId)) {
3241
+            $identityId = $this->getUserIdentity($uid);
3242
+        }
3243
+        $this->dao->update($uid, ['user_group' => $identityId]);
3244
+        return $identityId;
3245
+    }
3246
+
3247
+    /**
3248
+     * 获取用户 身份
3249
+     * @param $uid
3250
+     * @return int|mixed
3251
+     * @throws DataNotFoundException
3252
+     * @throws DbException
3253
+     * @throws ModelNotFoundException
3254
+     */
3255
+    public function getUserIdentity($uid)
3256
+    {
3257
+        // 1、获取所有等级信息
3258
+        /** @var UserIdentityRepository $identityRepository */
3259
+        $identityRepository = app()->make(UserIdentityRepository::class);
3260
+        $identityList = $identityRepository->getIdentityList();
3261
+
3262
+        // 2、获取身份需要的最深等级
3263
+        $lowerLevelNumList = array_column($identityList, 'lower_level_num');
3264
+        $lowerLevelNumMax = max($lowerLevelNumList);
3265
+        $lowerLevelNumMin = min($lowerLevelNumList);
3266
+        $needLower = $lowerLevelNumMax;
3267
+        if($lowerLevelNumMin == 0) {
3268
+            $needLower = $lowerLevelNumMin;
3269
+        }
3270
+
3271
+        // 3、获取下级用户 贡献值
3272
+        $userContributionSumMap = [];
3273
+        $uidContributeList = $this->getUidContributeListBySpreadUidList([$uid]);
3274
+        foreach ($uidContributeList as $uidContribute) {
3275
+            $userContributionSumMap[$uidContribute['uid']] = $this->getContributionSumByLevel([$uidContribute['uid']], $needLower);
3276
+            $userContributionSumMap[$uidContribute['uid']][0] = $uidContribute['contribute'];
3277
+        }
3278
+
3279
+        // 4、获取个人贡献值
3280
+        $userData = $this->dao->get($uid)->toArray();
3281
+
3282
+        // 5、当前用户等级
3283
+        $identityId = 0;
3284
+        usort($identityList, function ($a, $b) {
3285
+            return $b['user_group_id'] <=> $a['user_group_id'];  // 反转顺序,倒序排列
3286
+        });
3287
+        foreach ($identityList as $item) {
3288
+            $lowerLevelNum = $item['lower_level_num']??0;
3289
+
3290
+            $arriveNumOwn = $userData['contribute'];
3291
+            $arriveNumTeam = 0;
3292
+            $subordinateContribution = [];
3293
+
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;
3302
+                        }
3303
+                    }
3304
+                } else {
3305
+                    $subordinateContribution[$key] = array_sum($value);
3306
+                }
3307
+            }
3308
+            if (!empty($subordinateContribution)) {
3309
+                // 大区业绩
3310
+                $dqYj = max($subordinateContribution);
3311
+                // 总业绩
3312
+                $zYj = array_sum($subordinateContribution);
3313
+                // 小区团体业绩
3314
+                $arriveNumTeam = bcsub($zYj, $dqYj, 2);
3315
+            }
3316
+            if ($item['arrive_num_own'] <= $arriveNumOwn && $item['arrive_num_team'] <= $arriveNumTeam) {
3317
+                $identityId = $item['user_group_id'];
3318
+                break;
3319
+            }
3320
+        }
3321
+        return $identityId;
3322
+    }
3323
+
3324
+    /**
3325
+     * 获取该会员的所有下级会员
3326
+     */
3327
+    public function getUidContributeListBySpreadUidList(array $uidList)
3328
+    {
3329
+        return Db::name("user")
3330
+            ->whereIn("spread_uid", $uidList)
3331
+            ->field("uid, contribute, spread_uid")
3332
+            ->select()
3333
+            ->toArray();
3334
+    }
3335
+
3336
+    /**
3337
+     * 计算指定用户下属每一层级的总贡献值。
3338
+     *
3339
+     * @param array $initialUserIds 初始用户ID列表 (视为第0层)。
3340
+     * @param int $maxDepth 需要查询的最大深度(相对于初始列表)。
3341
+     *                      0 表示查询所有层级直到末端。
3342
+     *                      1 表示只计算第1层(直接下级)的总贡献。
3343
+     *                      N 表示计算到第 N 层(包含第N层)的总贡献。
3344
+     * @return array 返回一个数组,键是层级号(从1开始),值是该层级所有用户的贡献值总和。
3345
+     *               例如:[ 1 => 600, 2 => 1300 ]
3346
+     */
3347
+    public function getContributionSumByLevel(array $initialUserIds, int $maxDepth = 0): array
3348
+    {
3349
+        $levelContributions = []; // 结果数组 [level => total_contribution]
3350
+        if (empty($initialUserIds)) {
3351
+            return $levelContributions;
3352
+        }
3353
+
3354
+        $currentLevelIds = $initialUserIds; // 当前层级的用户ID (初始为第0层)
3355
+        $currentLevel = 0; // 当前层级号
3356
+
3357
+        // 使用一个集合跟踪所有已处理过的下级用户ID,防止重复计算和循环
3358
+        $processedSubordinateIds = [];
3359
+
3360
+        while (!empty($currentLevelIds)) {
3361
+            // 计算下一层级的编号
3362
+            $nextLevel = $currentLevel + 1;
3363
+
3364
+            // 检查是否达到最大深度限制
3365
+            if ($maxDepth > 0 && $nextLevel > $maxDepth) {
3366
+                break; // 停止查询更深的层级
3367
+            }
3368
+
3369
+            // 批量查询当前层级用户的直接下级
3370
+            // 使用 array_chunk 防止 WHERE IN 子句过长 (根据数据库限制调整 chunkSize)
3371
+            $chunkSize = 500;
3372
+            $subordinatesOfCurrentLevel = [];
3373
+            foreach(array_chunk($currentLevelIds, $chunkSize) as $chunk) {
3374
+                $subordinatesChunk = Db::name('user')
3375
+                    ->field('uid, contribute') // 只需要下级的uid和贡献值
3376
+                    ->whereIn('spread_uid', $chunk) // spread_uid 在当前层级用户块中
3377
+                    ->select()
3378
+                    ->toArray();
3379
+                $subordinatesOfCurrentLevel = array_merge($subordinatesOfCurrentLevel, $subordinatesChunk);
3380
+            }
3381
+
3382
+            // 如果没有找到任何下级,结束循环
3383
+            if (empty($subordinatesOfCurrentLevel)) {
3384
+                break;
3385
+            }
3386
+
3387
+            $nextLevelTotalContribution = 0;
3388
+            $nextLevelIds = []; // 存储下一轮需要查询的用户ID
3389
+
3390
+            // 遍历找到的所有下级
3391
+            foreach ($subordinatesOfCurrentLevel as $subordinate) {
3392
+                $subordinateId = $subordinate['uid'];
3393
+                $subordinateContribution = $subordinate['contribute'] ?? 0; // 安全获取,默认为0
3394
+
3395
+                // 累加下一层级的总贡献值
3396
+                // 注意:这里简单累加,如果一个下级同时被当前层多个用户推荐,其贡献会被计算多次
3397
+                // 如果要求每个下级只贡献一次(即使有多个上级),需要调整逻辑,
3398
+                // 例如在累加前检查 $processedSubordinateIds
3399
+
3400
+                // --- 修改点:确保每个下级贡献只被计算一次 ---
3401
+                // if (!isset($processedSubordinateIds[$subordinateId])) { // 如果这个下级还没被处理过
3402
+                $nextLevelTotalContribution += (float)$subordinateContribution;
3403
+                // }
3404
+                // 注释掉上面的检查,因为用户描述似乎是按层级直接累加,不管这个下级是否被上层处理过。
3405
+                // 如果A1和A2都属于第1层,他们各自的下级B1和B2都属于第2层,B1和B2的贡献值直接加到第2层的总和里。
3406
+                // 如果需要严格按“人”计算,即使一个人出现在多层或被多人推荐也只算一次,则需要解开注释并调整
3407
+
3408
+                // 收集下一轮需要查询的用户ID,同样需要防止重复处理
3409
+                if (!isset($processedSubordinateIds[$subordinateId])) {
3410
+                    $nextLevelIds[] = $subordinateId;
3411
+                    // 标记这个下级ID已处理过,避免在更深层级中再次将其加入查询队列
3412
+                    $processedSubordinateIds[$subordinateId] = true;
3413
+                }
3414
+
3415
+            }
3416
+
3417
+            // 存储下一层级的总贡献值 (只有当贡献值大于0或你想记录空层级时)
3418
+            // 根据例子,我们只记录有贡献的层级,或者至少有用户的层级
3419
+            if (!empty($subordinatesOfCurrentLevel)) { // 只要找到了下级就记录该层
3420
+                $levelContributions[$nextLevel] = $nextLevelTotalContribution;
3421
+            }
3422
+
3423
+            // 准备下一轮迭代
3424
+            $currentLevelIds = array_unique($nextLevelIds); // 去重下一层的用户ID
3425
+            $currentLevel = $nextLevel; // 更新当前层级
3426
+        }
3427
+
3428
+        return $levelContributions;
3429
+    }
3228 3430
 }

+ 7 - 0
app/controller/api/Notify.php

@@ -3,6 +3,7 @@ namespace app\controller\api;
3 3
 
4 4
 use AdaPaySdk\AdapayTools;
5 5
 use app\common\repositories\store\order\StoreRefundOrderRepository;
6
+use app\common\repositories\user\UserRepository;
6 7
 use app\controller\api\merchant\sxy\Access;
7 8
 use app\controller\api\store\service\Huafei;
8 9
 use think\facade\Db;
@@ -1410,6 +1411,9 @@ class Notify
1410 1411
 
1411 1412
                 if (strpos($mark, "购买") !== false) {
1412 1413
                     Db::name('user')->where("uid",$uid)->update(['contribute'=>$con_data['contribute'] + $num]);
1414
+                    /** @var UserRepository $userRepository */
1415
+                    $userRepository = app()->make(UserRepository::class);
1416
+                    $userRepository->setUserIdentity($uid);
1413 1417
                 }
1414 1418
 
1415 1419
                 if (strpos($mark, "推广") !== false) {
@@ -1466,6 +1470,9 @@ class Notify
1466 1470
                 // 检查是否包含“购买”
1467 1471
                 if (strpos($mark, "购买") !== false) {
1468 1472
                     Db::name('user')->where("uid",$uid)->update(['contribute'=>$con_data['contribute'] + $num]);
1473
+                    /** @var UserRepository $userRepository */
1474
+                    $userRepository = app()->make(UserRepository::class);
1475
+                    $userRepository->setUserIdentity($uid);
1469 1476
                 }
1470 1477
 
1471 1478