Reward.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2017 https://www.sapixx.com All rights reserved.
  4. * @license Licensed (http://www.apache.org/licenses/LICENSE-2.0).
  5. * @author pillar<ltmn@qq.com>
  6. * 奖励计算
  7. */
  8. namespace app\fastshop\widget;
  9. use app\fastshop\model\BankAll;
  10. use app\fastshop\model\RegNum;
  11. class Reward{
  12. /**
  13. * 代理收益
  14. * @param integer $miniapp_id 来源小程序
  15. * @param integer $uid 用户ID
  16. * @param float $cash_fee (元)
  17. * @param object $config 系统配置
  18. * @return void
  19. */
  20. public function agent(int $miniapp_id,int $uid,$order,$config){
  21. $cash_fee = $order->real_amount;
  22. $rel = model('Agent')->agentUid(['user_id' => $uid],$miniapp_id);
  23. if(empty($rel)){
  24. return;
  25. }
  26. $rebate = $rel['rebate']/1000; //反比(千分之x)
  27. if($rebate <= 0){
  28. return;
  29. }
  30. $user_id = $rel['user_id']; //反比
  31. $shopping = $config['shopping']/100; //购物金比例
  32. //推荐收益结算
  33. $print = $cash_fee*$rebate;
  34. $shop = money($print*$shopping); //购物
  35. $due = money($print-$shop); //剩下多少
  36. $shop_print = intval($shop*100); //换算成分
  37. $due_print = intval($due*100);
  38. if ($due_print > 0) {
  39. model('Bank')->due_up($miniapp_id, $user_id,$due_print,$shop_print);
  40. model('BankLogs')->add($miniapp_id, $user_id,intval($print*100),money($print).'代理奖励',$order->user_id,$order->order_no);
  41. }
  42. }
  43. /**
  44. * 推荐人收益(方式1)
  45. * 直接按照推荐人和间接推荐人的成交额的比例奖励给推荐人
  46. * @param integer $miniapp_id 来源小程序
  47. * @param integer $uid 用户ID
  48. * @param float $cash_fee (元)
  49. * @param object $config 系统配置
  50. * @return void
  51. */
  52. public function level(int $miniapp_id,int $uid,$order,$config){
  53. $cash_fee = $order->real_amount;
  54. $level = model('SystemUserLevel')->where(['user_id' => $uid,'level'=>[1,2]])->select();
  55. $level1 = 0;
  56. $level2 = 0;
  57. foreach ($level as $value) {
  58. if($value['level'] == 1){
  59. $level1 = $value['parent_id'];
  60. }
  61. if($value['level'] == 2){
  62. $level2 = $value['parent_id'];
  63. }
  64. }
  65. $shopping = $config['shopping']/100; //购物金比例
  66. //一级
  67. if($level1){
  68. $small_print = $cash_fee*($config->reward_nth/100);
  69. $small_shop = money($small_print*$shopping); //购物
  70. $small_due = money($small_print-$small_shop); //剩下多少
  71. $small_shop_print = intval($small_shop*100); //换算成分
  72. $small_due_print = intval($small_due*100);
  73. if($small_due_print > 0){
  74. model('Bank')->due_up($miniapp_id,$level1,$small_due_print,$small_shop_print);
  75. model('Bank')->isProfit($level1,$small_print);
  76. model('BankLogs')->add($miniapp_id,$level1,intval($small_print*100),'活动奖励['.money($small_print).']',$order->user_id,$order->order_no);
  77. }
  78. }
  79. //二级
  80. if($level2){
  81. $big_print = $cash_fee*($config->reward_ratio/100);
  82. $big_shop = money($big_print*$shopping); //购物
  83. $big_due = money($big_print-$big_shop); //剩下多少
  84. $big_shop_print = intval($big_shop*100); //换算成分
  85. $big_due_print = intval($big_due*100);
  86. if($big_due_print > 0){
  87. model('Bank')->due_up($miniapp_id,$level2,$big_due_print,$big_shop_print);
  88. model('Bank')->isProfit($level2,$big_print);
  89. model('BankLogs')->add($miniapp_id,$level2,intval($big_print*100),'活动奖励['.money($big_print).']',$order->user_id,$order->order_no);
  90. }
  91. }
  92. }
  93. /**
  94. * 推荐人收益(2)
  95. * 直接按照产品利润的50%递减给满足条件的推荐人
  96. * @param integer $miniapp_id 来源小程序
  97. * @param integer $uid 用户ID
  98. * @param float $cash_fee (元)
  99. * @param object $config 系统配置
  100. * @return void
  101. */
  102. public function performance(int $miniapp_id,int $uid,$order,$config){
  103. $cash_fee = $order->real_amount;
  104. if($cash_fee <= 0){
  105. return;
  106. }
  107. //计算利润
  108. $cash_fee = $cash_fee*($config->profit/100); //计算利润比
  109. if($cash_fee <= 0){
  110. return;
  111. }
  112. //递归计算层级利润
  113. $money = numProgress($cash_fee,$config->reward_nth);
  114. $level = count($money);
  115. //查询曾经用户
  116. $levelUser = model('SystemUserLevel')->where(['user_id' => $uid])->where('level','<=',$level)->field('parent_id,level')->select()->toArray();
  117. if(!empty($levelUser)){
  118. $temp_key = array_column($levelUser,'level'); //键值
  119. $levelUser = array_combine($temp_key,$levelUser) ;
  120. }
  121. //查找每个用户的直推人数,如果没有就实时统计并增加,如果有就读取当前用户
  122. $uids = array_column($levelUser,'parent_id');
  123. $num = RegNum::where(['uid' => $uids])->select()->toArray();
  124. $num_uid = array_column($num,'uid');
  125. $uids = array_diff($uids,$num_uid);
  126. foreach ($uids as $key => $value) {
  127. RegNum::countMum($miniapp_id,$value);
  128. }
  129. //人数统计
  130. $regnum = [];
  131. foreach ($num as $key => $value) {
  132. $regnum[$value['uid']] = $value['num'];
  133. }
  134. //用户ID和利润配对
  135. $uida = [];
  136. foreach ($money as $key => $value) {
  137. if (isset($levelUser[$key])) {
  138. $uida[$levelUser[$key]['parent_id']]['money'] = intval($value);
  139. $uida[$levelUser[$key]['parent_id']]['level'] = $levelUser[$key]['level'];
  140. $uida[$levelUser[$key]['parent_id']]['num'] = empty($regnum[$levelUser[$key]['parent_id']]) ? 0 : $regnum[$levelUser[$key]['parent_id']];
  141. }
  142. }
  143. foreach ($uida as $key => $value) {
  144. if($value['num'] <= 4){
  145. if($value['num'] >= $value['level']){
  146. model('Bank')->due_up($miniapp_id,$key,$value['money']*100,0);
  147. model('Bank')->isProfit($key,$value['money']);
  148. model('BankLogs')->add($miniapp_id,$key,$value['money']*100,'任务奖励['.money($value['money']).']',$order->user_id,$order->order_no);
  149. }
  150. }else{
  151. model('Bank')->due_up($miniapp_id,$key,$value['money']*100,0);
  152. model('Bank')->isProfit($key,$value['money']);
  153. model('BankLogs')->add($miniapp_id,$key,$value['money']*100,'任务奖励['.money($value['money']).']',$order->user_id,$order->order_no);
  154. }
  155. }
  156. }
  157. /**
  158. * 任务计算
  159. * @param integer $miniapp_id 来源小程序
  160. * @param integer $uid 用户ID
  161. * @param float $cash_fee (元)
  162. * @param object $config 系统配置
  163. * @return void
  164. */
  165. public function range(int $miniapp_id,int $uid,$order,$config){
  166. $cash_fee = $order->real_amount;
  167. if ($cash_fee <= 0) {
  168. return;
  169. }
  170. $cash_fee = $order->real_amount;
  171. if($cash_fee <= 0){
  172. return;
  173. }
  174. if($cash_fee <= 0 || $config->reward_ratio <= 0){
  175. return;
  176. }
  177. //规则
  178. $rules = empty($config->rules) ? [] : json_decode($config->rules,true);
  179. if(empty($rules)){
  180. return;
  181. }
  182. //查询溯源用户
  183. $level = model('SystemUserLevel')->children_user($uid);
  184. if(empty($level)){
  185. return;
  186. }
  187. ksort($level);
  188. //增加流水
  189. if(isset($level[1]['user_id'])){
  190. BankAll::add($miniapp_id,$level[1]['user_id'],$cash_fee);
  191. }
  192. //查询伞下直推人数,伞下业绩和分成比例
  193. $account = [];
  194. $i = 0;
  195. foreach ($level as $value) {
  196. $selectMoney = self::selectMoney($value['parent_id'],$rules);
  197. if($selectMoney['ratio'] > 0){
  198. $account[$i] = self::selectMoney($value['parent_id'],$rules);
  199. $account[$i]['uid'] = $value['parent_id'];
  200. $account[$i]['level'] = $value['level'];
  201. $i++;
  202. }
  203. }
  204. //查询UID和应分配业绩
  205. $data = self::howMoney($account,$cash_fee,$config);
  206. foreach ($data as $value) {
  207. model('Bank')->due_up($miniapp_id,$value['uid'],$value['money']*100,0);
  208. model('Bank')->isProfit($value['uid'],$value['money']);
  209. model('BankLogs')->add($miniapp_id,$value['uid'],$value['money']*100,'绩效奖励['.$value['money'].']',$order->user_id,$order->order_no);
  210. }
  211. //平台奖励
  212. self::platformMoney($order,$config);
  213. }
  214. /**
  215. * 计算极差规则奖金比例
  216. */
  217. protected function howMoney($account,float $cash_fee,$config){
  218. $base = 100;
  219. $money = $cash_fee*($config->reward_ratio/100);
  220. foreach ($account as $key => $value) {
  221. if($key == 0){
  222. $ratio = $value['ratio'];
  223. }else{
  224. $ratio = $value['ratio'] - $account[$key-1]['ratio'];
  225. }
  226. $base = $base-$ratio;
  227. if($base > 0 && $ratio > 0){
  228. $data[$key]['uid'] = $value['uid'];
  229. $data[$key]['ratio'] = $ratio;
  230. $data[$key]['money'] = money($money*($ratio/100));
  231. }
  232. }
  233. return $data;
  234. }
  235. /**
  236. * 查询某个用户的伞下绩效和直推用户
  237. * @param integer $uid 用户ID
  238. * @param object $rules 系统配置
  239. * @return void
  240. */
  241. protected function selectMoney(int $uid,$rules){
  242. //统计推荐人数
  243. $peple_num = model('SystemUserLevel')->where(['parent_id' => $uid,'level'=>1])->count();
  244. if($peple_num <= 0){
  245. return ['num' => 0,'money' => 0,'ratio' => 0];
  246. }
  247. //查询伞下业绩
  248. $uids = model('SystemUserLevel')->where(['parent_id' => $uid])->column('user_id');
  249. $uids[] = $uid;
  250. $account = BankAll::where(['uid' => $uids])->sum('account');
  251. $account = intval($account);
  252. BankAll::where(['uid' => $uid])->update(['pyramid' => $account]); //更新伞下业绩
  253. krsort($rules);
  254. $ratio = 0;
  255. foreach ($rules as $value) {
  256. if($peple_num >= $value['num'] && $account >= $value['much']){
  257. $ratio = $value['ratio'];
  258. break;
  259. }
  260. }
  261. //判断分配比例
  262. return ['ratio' => $ratio,'money' => $account,'num' => $peple_num];
  263. }
  264. /**
  265. * 平台评价奖励
  266. * @param integer $uid 用户ID
  267. * @param object $config 系统配置
  268. * @return void
  269. */
  270. protected function platformMoney($order,$config){
  271. $cash_fee = $order->real_amount;
  272. if($config->platform_ratio <= 0 || $config->platform_amout <= 0){
  273. return;
  274. }
  275. $info = BankAll::where(['member_miniapp_id' => $config->member_miniapp_id])->where('pyramid','>=',$config->platform_amout)->select();
  276. if(empty($info)){
  277. return;
  278. }
  279. $info = $info->toArray();
  280. $peple_num = count($info);
  281. $money = money($cash_fee*($config->platform_ratio/100)/$peple_num);
  282. if($money >= 0.01){
  283. $uid = array_column($info,'uid');
  284. foreach ($uid as $value) {
  285. model('Bank')->due_up($config->member_miniapp_id,$value,$money*100,0);
  286. model('Bank')->isProfit($value,$money);
  287. model('BankLogs')->add($config->member_miniapp_id,$value,$money*100,'平台奖励['.$money.']',$order->user_id,$order->order_no);
  288. }
  289. }
  290. }
  291. }