UserUpgradeService.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. <?php
  2. namespace app\data\service;
  3. use app\data\model\BaseUserUpgrade;
  4. use app\data\model\DataUser;
  5. use app\data\model\DataUserBalance;
  6. use app\data\model\ShopOrder;
  7. use app\data\model\ShopOrderItem;
  8. use think\admin\Library;
  9. use think\admin\Service;
  10. /**
  11. * 用户等级升级服务
  12. * Class UserUpgradeService
  13. * @package app\data\service
  14. */
  15. class UserUpgradeService extends Service
  16. {
  17. /**
  18. * 尝试绑定上级代理
  19. * @param integer $uuid 用户UID
  20. * @param integer $pid0 代理UID
  21. * @param integer $mode 操作类型(0临时绑定, 1永久绑定, 2强行绑定)
  22. * @return array
  23. * @throws \think\db\exception\DataNotFoundException
  24. * @throws \think\db\exception\DbException
  25. * @throws \think\db\exception\ModelNotFoundException
  26. */
  27. public static function bindAgent(int $uuid, int $pid0 = 0, int $mode = 1): array
  28. {
  29. $user = DataUser::mk()->where(['id' => $uuid])->find();
  30. if (empty($user)) return [0, '查询用户资料失败'];
  31. if ($user['pids'] && in_array($mode, [0, 1])) return [1, '已经绑定代理'];
  32. // 检查代理用户
  33. if (empty($pid0)) $pid0 = $user['pid0'];
  34. if (empty($pid0)) return [0, '绑定的代理不存在'];
  35. if ($uuid == $pid0) return [0, '不能绑定自己为代理'];
  36. // 检查代理资格
  37. $agent = DataUser::mk()->where(['id' => $pid0])->find();
  38. if (empty($agent['vip_code'])) return [0, '代理无推荐资格'];
  39. if (strpos($agent['path'], "-{$uuid}-") !== false) return [0, '不能绑定下属'];
  40. try {
  41. Library::$sapp->db->transaction(function () use ($user, $agent, $mode) {
  42. // 更新用户代理
  43. $path1 = rtrim($agent['path'] ?: '-', '-') . "-{$agent['id']}-";
  44. $user->save(['pid0' => $agent['id'], 'pid1' => $agent['id'], 'pid2' => $agent['pid1'], 'pids' => $mode > 0 ? 1 : 0, 'path' => $path1, 'layer' => substr_count($path1, '-')]);
  45. // 更新下级代理
  46. $path2 = "{$user['path']}{$user['id']}-";
  47. if (DataUser::mk()->whereLike('path', "{$path2}%")->count() > 0) {
  48. foreach (DataUser::mk()->whereLike('path', "{$path2}%")->order('layer desc')->select() as $item) {
  49. $attr = array_reverse(str2arr($path3 = preg_replace("#^{$path2}#", "{$path1}{$user['id']}-", $item['path']), '-'));
  50. $item->save(['pid0' => $attr[0] ?? 0, 'pid1' => $attr[0] ?? 0, 'pid2' => $attr[1] ?? 0, 'path' => $path3, 'layer' => substr_count($path3, '-')]);
  51. }
  52. }
  53. });
  54. static::upgrade($user['id']);
  55. return [1, '绑定代理成功'];
  56. } catch (\Exception $exception) {
  57. return [0, "绑定代理失败, {$exception->getMessage()}"];
  58. }
  59. }
  60. /**
  61. * 同步计算用户等级
  62. * @param integer $uuid 指定用户UID
  63. * @param boolean $parent 同步计算上级
  64. * @param ?string $orderNo 升级触发订单
  65. * @return boolean
  66. * @throws \think\db\exception\DataNotFoundException
  67. * @throws \think\db\exception\DbException
  68. * @throws \think\db\exception\ModelNotFoundException
  69. */
  70. public static function upgrade(int $uuid, bool $parent = true, ?string $orderNo = null): bool
  71. {
  72. $user = DataUser::mk()->where(['id' => $uuid])->find();
  73. if (empty($user)) return true;
  74. // 初始化等级参数
  75. $levels = BaseUserUpgrade::items();
  76. [$vipName, $vipCode, $vipTeam] = [$levels[0]['name'] ?? '普通用户', 0, []];
  77. // 统计用户数据
  78. foreach ($levels as $key => $level) if ($level['upgrade_team'] === 1) $vipTeam[] = $key;
  79. $orderAmount = ShopOrder::mk()->where("uuid={$uuid} and status>=4")->sum('amount_total');
  80. $teamsDirect = DataUser::mk()->where(['pid1' => $uuid])->whereIn('vip_code', $vipTeam)->count();
  81. $teamsIndirect = DataUser::mk()->where(['pid2' => $uuid])->whereIn('vip_code', $vipTeam)->count();
  82. $teamsUsers = $teamsDirect + $teamsIndirect;
  83. // 动态计算用户等级
  84. foreach (array_reverse($levels) as $item) {
  85. $l1 = empty($item['goods_vip_status']) || $user['buy_vip_entry'] > 0;
  86. $l2 = empty($item['teams_users_status']) || $item['teams_users_number'] <= $teamsUsers;
  87. $l3 = empty($item['order_amount_status']) || $item['order_amount_number'] <= $orderAmount;
  88. $l4 = empty($item['teams_direct_status']) || $item['teams_direct_number'] <= $teamsDirect;
  89. $l5 = empty($item['teams_indirect_status']) || $item['teams_indirect_number'] <= $teamsIndirect;
  90. if (
  91. ($item['upgrade_type'] == 0 && ($l1 || $l2 || $l3 || $l4 || $l5)) /* 满足任何条件可以等级 */
  92. ||
  93. ($item['upgrade_type'] == 1 && ($l1 && $l2 && $l3 && $l4 && $l5)) /* 满足所有条件可以等级 */
  94. ) {
  95. [$vipName, $vipCode] = [$item['name'], $item['number']];
  96. break;
  97. }
  98. }
  99. // 购买入会商品升级
  100. $query = ShopOrderItem::mk()->alias('b')->join('shop_order a', 'b.order_no=a.order_no');
  101. $tmpCode = $query->whereRaw("a.uuid={$uuid} and a.payment_status=1 and a.status>=4 and b.vip_entry=1")->max('b.vip_upgrade');
  102. if ($tmpCode > $vipCode && isset($levels[$tmpCode])) {
  103. [$vipName, $vipCode] = [$levels[$tmpCode]['name'], $levels[$tmpCode]['number']];
  104. } else {
  105. $orderNo = null;
  106. }
  107. // 后台余额充值升级
  108. $tmpCode = DataUserBalance::mk()->where(['uuid' => $uuid, 'deleted' => 0])->max('upgrade');
  109. if ($tmpCode > $vipCode && isset($levels[$tmpCode])) {
  110. [$vipName, $vipCode] = [$levels[$tmpCode]['name'], $levels[$tmpCode]['number']];
  111. }
  112. // 统计用户订单金额
  113. $orderAmountTotal = ShopOrder::mk()->whereRaw("uuid={$uuid} and status>=4")->sum('amount_goods');
  114. $teamsAmountDirect = ShopOrder::mk()->whereRaw("puid1={$uuid} and status>=4")->sum('amount_goods');
  115. $teamsAmountIndirect = ShopOrder::mk()->whereRaw("puid2={$uuid} and status>=4")->sum('amount_goods');
  116. // 更新用户团队数据
  117. $data = [
  118. 'vip_name' => $vipName,
  119. 'vip_code' => $vipCode,
  120. 'teams_users_total' => $teamsUsers,
  121. 'teams_users_direct' => $teamsDirect,
  122. 'teams_users_indirect' => $teamsIndirect,
  123. 'teams_amount_total' => $teamsAmountDirect + $teamsAmountIndirect,
  124. 'teams_amount_direct' => $teamsAmountDirect,
  125. 'teams_amount_indirect' => $teamsAmountIndirect,
  126. 'order_amount_total' => $orderAmountTotal,
  127. ];
  128. if (!empty($orderNo)) $data['vip_order'] = $orderNo;
  129. if ($data['vip_code'] !== $user['vip_code']) $data['vip_datetime'] = date('Y-m-d H:i:s');
  130. DataUser::mk()->where(['id' => $uuid])->update($data);
  131. // 用户升级事件
  132. if ($user['vip_code'] < $vipCode) Library::$sapp->event->trigger('UserUpgradeLevel', [
  133. 'uuid' => $user['id'], 'order_no' => $orderNo, 'vip_code_old' => $user['vip_code'], 'vip_code_new' => $vipCode,
  134. ]);
  135. return !($parent && $user['pid1'] > 0) || static::upgrade($user['pid1'], false);
  136. }
  137. }