UserBrokerageRepository.php 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace app\common\repositories\user;
  12. use app\common\dao\user\UserBrokerageDao;
  13. use app\common\model\user\User;
  14. use app\common\model\user\UserBrokerage;
  15. use app\common\repositories\BaseRepository;
  16. use app\common\repositories\system\CacheRepository;
  17. use FormBuilder\Factory\Elm;
  18. use think\exception\ValidateException;
  19. use think\facade\Db;
  20. use think\facade\Route;
  21. /**
  22. * @mixin UserBrokerageDao
  23. */
  24. class UserBrokerageRepository extends BaseRepository
  25. {
  26. public const BROKERAGE_RULE_TYPE = ['spread_user', 'pay_money', 'pay_num', 'spread_money', 'spread_pay_num'];
  27. public function __construct(UserBrokerageDao $dao)
  28. {
  29. $this->dao = $dao;
  30. }
  31. public function getList(array $where, $page, $limit)
  32. {
  33. $query = $this->dao->search($where)->order('brokerage_level DESC,create_time DESC');
  34. $count = $query->count();
  35. $list = $query->page($page, $limit)->select();
  36. return compact('list', 'count');
  37. }
  38. public function getNextLevel($level,$type = 0)
  39. {
  40. return $this->search(['next_level' => $level,'type' => $type])->order('brokerage_level ASC,create_time DESC')->find();
  41. }
  42. public function options(array $where)
  43. {
  44. return $this->dao->search($where)->field('brokerage_level as value,brokerage_name as label')->order('brokerage_level ASC,create_time DESC')->select();
  45. }
  46. public function all(int $type)
  47. {
  48. return $this->dao->search(['type' => $type])->order('brokerage_level ASC,create_time DESC')->select();
  49. }
  50. public function inc(User $user, $type, $inc)
  51. {
  52. $nextLevel = $this->getNextLevel($user->brokerage_level);
  53. if (!$nextLevel) return false;
  54. $make = app()->make(UserBillRepository::class);
  55. $bill = $make->getWhere(['uid' => $user->uid, 'link_id' => $nextLevel->user_brokerage_id, 'category' => 'sys_brokerage', 'type' => $type]);
  56. if ($bill) {
  57. $bill->number = bcadd($bill->number, $inc, 2);
  58. $bill->save();
  59. } else {
  60. $make->incBill($user->uid, 'sys_brokerage', $type, [
  61. 'number' => $inc,
  62. 'title' => $type,
  63. 'balance' => 0,
  64. 'status' => 0,
  65. 'link_id' => $nextLevel->user_brokerage_id
  66. ]);
  67. }
  68. return $this->checkLevel($user, $nextLevel);
  69. }
  70. public function checkLevel(User $user, UserBrokerage $nextLevel)
  71. {
  72. $info = app()->make(UserBillRepository::class)->search(['uid' => $user->uid, 'category' => 'sys_brokerage', 'link_id' => $nextLevel->user_brokerage_id])
  73. ->column('number', 'type');
  74. foreach ($nextLevel['brokerage_rule'] as $k => $rule) {
  75. if (!isset($info[$k]) && $rule['num'] > 0) return false;
  76. if ($rule['num'] > 0 && $rule['num'] > $info[$k]) return false;
  77. }
  78. $nextLevel->user_num++;
  79. Db::transaction(function () use ($nextLevel, $user) {
  80. $nextLevel->save();
  81. if ($user->brokerage && $user->brokerage->user_num > 0) {
  82. $user->brokerage->user_num--;
  83. $user->brokerage->save();
  84. }
  85. $user->brokerage_level = $nextLevel->brokerage_level;
  86. $user->save();
  87. $key = 'notice_brokerage_level_' . $user->uid;
  88. app()->make(CacheRepository::class)->save($key,$nextLevel->brokerage_level);
  89. });
  90. return true;
  91. }
  92. public function getLevelRate(User $user, UserBrokerage $nextLevel)
  93. {
  94. $info = app()->make(UserBillRepository::class)->search(['uid' => $user->uid, 'category' => 'sys_brokerage', 'link_id' => $nextLevel->user_brokerage_id])
  95. ->column('number', 'type');
  96. $brokerage_rule = $nextLevel['brokerage_rule'];
  97. foreach ($nextLevel['brokerage_rule'] as $k => $rule) {
  98. if ($rule['num'] <= 0) {
  99. unset($brokerage_rule[$k]);
  100. continue;
  101. }
  102. if (!isset($info[$k])) {
  103. $rate = 0;
  104. } else if ($rule['num'] > $info[$k]) {
  105. $rate = bcdiv($info[$k], $rule['num'], 2) * 100;
  106. } else {
  107. $rate = 100;
  108. }
  109. $brokerage_rule[$k]['rate'] = $rate;
  110. $brokerage_rule[$k]['task'] = (float)(min($info[$k] ?? 0, $rule['num']));
  111. }
  112. return $brokerage_rule;
  113. }
  114. public function form(?int $id = null)
  115. {
  116. $formData = [];
  117. if ($id) {
  118. $form = Elm::createForm(Route::buildUrl('systemUserMemberUpdate', ['id' => $id])->build());
  119. $data = $this->dao->get($id);
  120. if (!$data) throw new ValidateException('数据不存在');
  121. $formData = $data->toArray();
  122. } else {
  123. $form = Elm::createForm(Route::buildUrl('systemUserMemberCreate')->build());
  124. }
  125. $rules = [
  126. Elm::number('brokerage_level', '会员等级')->required(),
  127. Elm::input('brokerage_name', '会员名称')->required(),
  128. Elm::frameImage('brokerage_icon', '会员图标', '/' . config('admin.admin_prefix') . '/setting/uploadPicture?field=brokerage_icon&type=1')
  129. ->required()
  130. ->value($formData['brokerage_icon'] ?? '')
  131. ->modal(['modal' => false])
  132. ->width('896px')
  133. ->height('480px'),
  134. Elm::number('value', ' 所需成长值',$formData['brokerage_rule']['value'] ?? 0)->required(),
  135. Elm::frameImage('image', '背景图', '/' . config('admin.admin_prefix') . '/setting/uploadPicture?field=image&type=1')
  136. ->value($formData['brokerage_rule']['image']??'')
  137. ->required()
  138. ->modal(['modal' => false])
  139. ->width('896px')
  140. ->height('480px'),
  141. ];
  142. $form->setRule($rules);
  143. return $form->setTitle(is_null($id) ? '添加会员等级' : '编辑会员等级')->formData($formData);
  144. }
  145. public function incMemberValue(int $uid, string $type, int $id)
  146. {
  147. if (!systemConfig('member_status')) return ;
  148. $make = app()->make(UserBillRepository::class);
  149. $count = $make->getWhereCount(['type' => $type, 'link_id' => $id]);
  150. if ($count) return ;
  151. $config = [
  152. 'member_pay_num' => '下单获得成长值',
  153. 'member_sign_num' => '签到获得成长值',
  154. 'member_reply_num' => '评价获得成长值',
  155. 'member_share_num' => '邀请获得成长值',
  156. 'member_community_num' => '种草图文获得成长值',
  157. ];
  158. $inc = systemConfig($type) > 0 ? systemConfig($type) : 0;
  159. $user = app()->make(UserRepository::class)->getWhere(['uid' => $uid],'*',['member']);
  160. $svip_status = $user->is_svip > 0 && systemConfig('svip_switch_status') == '1';
  161. if ($svip_status) {
  162. $svipRate = app()->make(MemberinterestsRepository::class)->getSvipInterestVal(MemberinterestsRepository::HAS_TYPE_MEMBER);
  163. if ($svipRate > 0) {
  164. $inc = bcmul($svipRate, $inc, 0);
  165. }
  166. }
  167. $this->checkMemberValue($user, $inc);
  168. $make->incBill($user->uid, 'sys_members', $type, [
  169. 'number' => $inc,
  170. 'title' => $config[$type],
  171. 'balance' => $user->member_value,
  172. 'status' => 0,
  173. 'link_id' => $id,
  174. 'mark' => $config[$type].':'.$user->member_value,
  175. ]);
  176. }
  177. /**
  178. * TODO 连续升级
  179. * @param $nextLevel
  180. * @param $num
  181. * @return array
  182. * @author Qinii
  183. * @day 1/11/22
  184. */
  185. public function upUp($nextLevel, $num)
  186. {
  187. $newLevel = $this->getNextLevel($nextLevel->brokerage_level, 1);
  188. if ($newLevel) {
  189. $newNum = $num - $newLevel->brokerage_rule['value'];
  190. if ($newNum > 0) {
  191. [$nextLevel,$num] = $this->upUp($newLevel, $newNum);
  192. }
  193. }
  194. return [$nextLevel,$num];
  195. }
  196. /**
  197. * TODO 升级操作
  198. * @param User $user
  199. * @param int $inc
  200. * @author Qinii
  201. * @day 1/11/22
  202. */
  203. public function checkMemberValue(User $user, int $inc)
  204. {
  205. /**
  206. * 下一级所需经验值
  207. * 当前的经验值加上增加经验值是否够升级
  208. */
  209. Db::transaction(function () use ($inc, $user) {
  210. $nextLevel = $this->getNextLevel($user->member_level, 1);
  211. if (!$nextLevel) return ;
  212. if (($user->member_value + $inc) >= $nextLevel->brokerage_rule['value']) {
  213. $num = ($user->member_value + $inc) - $nextLevel->brokerage_rule['value'];
  214. if ($num > 0) {
  215. [$nextLevel,$num] = $this->upUp($nextLevel, $num);
  216. }
  217. if ($user->member) {
  218. $user->member->user_num--;
  219. $user->member->save();
  220. }
  221. $nextLevel->user_num++;
  222. $nextLevel->save();
  223. $user->member_level = $nextLevel->brokerage_level;
  224. $key = 'notice_member_level_' . $user->uid;
  225. app()->make(CacheRepository::class)->save($key,$nextLevel->brokerage_level);
  226. } else {
  227. $num = ($user->member_value + $inc);
  228. }
  229. $user->member_value = $num;
  230. $user->save();
  231. });
  232. }
  233. }