UserUpgradeService.php 7.1 KB

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