SharingFees.php 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <?php
  2. namespace app\api\command;
  3. use think\console\Command;
  4. use think\console\Input;
  5. use think\console\Output;
  6. use fast\Asset;
  7. use app\common\model\ProductPledges;
  8. use app\common\model\ProductOrder;
  9. use app\common\model\LedgerTokenChangeModel;
  10. use app\common\model\LedgerFrozenChangeModel;
  11. use app\common\model\LedgerWalletModel;
  12. use app\common\model\Sharingfees as SharingFeesModel;
  13. use app\common\model\LedgerTeacChangeModel;
  14. class SharingFees extends Command
  15. {
  16. protected function configure()
  17. {
  18. $this->setName('sharingFees')->setDescription('手续费分润');
  19. }
  20. protected function execute(Input $input, Output $output)
  21. {
  22. /* 永不超时 */
  23. // ini_set('max_execution_time', 0);
  24. // 记录开始运行的时间
  25. $GLOBALS['_beginTime'] = microtime(TRUE);
  26. $output->writeln('定时任务开始执行:' . date('Y-m-d H:i:s', time()));
  27. /*** 发放分红收益 ***/
  28. $output->writeln("手续费分润:");
  29. $feeCount = self::setSharingFees($output);
  30. //存储服务费分润
  31. $pledgeCount = self::setSharingPledge($output);
  32. //销售分润
  33. $saleCount = self::setSharingSales($output);
  34. $output->writeln('定时任务执行结束,手续费执行:' . $feeCount . '个,服务费执行:' . $pledgeCount . '个,销售分润:' . $saleCount . '个');
  35. }
  36. /*手续费分润
  37. 当日使用(交易、赠送扣除)的茶宝手续费和茶宝(手续费账户)分别统计一下总量。
  38. 比如茶宝手续费有1000,茶宝(手续费账户)有2000,持有A的分润10%,则分别为100和200
  39. 1)先算出所有人产品A的持有量(如300),根据持有量算出每份产品应发放茶宝和茶宝(手续费账户)的数量。
  40. (茶宝:100/300=0.333 茶宝(手续费账户)200/300=0.666)
  41. 2)再算出持有A产品的用户,每人持有量;根据每人持有量*每份应发数量,计算出每人应发总额,发放到该用户的茶宝账户上。
  42. 3)按上述算法,以此计算持有B和持有CDE的用户
  43. */
  44. public static function setSharingFees($output){
  45. $list = SharingFeesModel::where(['status'=> SharingFeesModel::Normal])->where('type_id', SharingFeesModel::TypeFees)->select();
  46. if(empty($list)) return true;
  47. $wallet = new LedgerWalletModel();
  48. $productOrder = new ProductOrder();
  49. $i = 0;
  50. //茶宝手续费
  51. $tokenFee = abs(LedgerTokenChangeModel::whereTime('create_time', 'yesterday')->where('action', 'in', [LedgerTokenChangeModel::Giveaway, LedgerTokenChangeModel::Pledge, LedgerTokenChangeModel::TransferFee])->sum('change_amount'));
  52. //冻结手续费
  53. $frozenFee = abs(LedgerFrozenChangeModel::where('create_time', 'yesterday')->where('action', 'in', [LedgerFrozenChangeModel::Giveaway, LedgerFrozenChangeModel::Pledge, LedgerFrozenChangeModel::TransferFees])->sum('change_amount'));
  54. foreach($list as $item){
  55. //TOKEN产品的持有量
  56. $productHold = $productOrder::getHoldProductNum($item->product_id);
  57. //分润
  58. $tokenFees = bcmul($tokenFee, bcdiv($item->fees, 100, 3), 3);
  59. //统计产品总数量
  60. $productNum = array_sum(array_column($productHold, 'num')) ;
  61. //每份产品的分润
  62. $tave = bcdiv($tokenFees, $productNum, 6);
  63. //冻结分润
  64. $frozenFees = bcmul($frozenFee, bcdiv($item->fees, 100, 3), 3);
  65. //每份产品的分润
  66. $fave = bcdiv($frozenFees, $productNum, 6);
  67. //$output->writeln('产品:' . $item->product_id . '茶宝分润:' . $tave . ' 手续费账户分润:' . $fave );
  68. foreach ($productHold as $vv) {
  69. //茶宝
  70. $tokenNum = bcmul($vv->num, $tave, 6);
  71. if($tokenNum > 0) {
  72. $wallet->changeWalletAccount($vv->user_id, Asset::TOKEN, $tokenNum , LedgerTokenChangeModel::SharingFees);
  73. $output->writeln('用户:' . $vv->user_id . '茶宝分润:' . $tokenNum );
  74. }
  75. //手续费
  76. $frozenNum = bcmul($vv->num, $fave, 6);
  77. if($frozenNum > 0) {
  78. $wallet->changeWalletAccount($vv->user_id, Asset::FROZEN, $frozenNum , LedgerFrozenChangeModel::SharingFees);
  79. $output->writeln('用户:' . $vv->user_id. ' 手续费账户分润:' . $frozenNum );
  80. }
  81. $i +=1;
  82. }
  83. }
  84. return $i;
  85. }
  86. //存储服务费分润
  87. public static function setSharingPledge($output){
  88. $list = SharingFeesModel::where(['status'=> SharingFeesModel::Normal])->where('type_id', SharingFeesModel::TypeStorage)->select();
  89. if(empty($list)) return true;
  90. $tokenFee = abs(LedgerTokenChangeModel::whereTime('create_time', 'yesterday')->where('action', LedgerTokenChangeModel::Pledge)->sum('change_amount')); //TOKEN const PledgeFee = 7; //存储服务费
  91. $frozenFee = abs(LedgerFrozenChangeModel::whereTime('create_time', 'yesterday')->where('action', LedgerFrozenChangeModel::Pledge)->sum('change_amount')); //FROZEN const PledgeFee = 7; //存储服务费
  92. $i = 0;
  93. $wallet = new LedgerWalletModel();
  94. $productOrder = new ProductOrder();
  95. foreach($list as $item){
  96. //TOKEN产品的持有量
  97. $productHold = $productOrder::getHoldProductNum($item->product_id);
  98. //统计产品总数量
  99. $productNum = array_sum(array_column($productHold, 'num')) ;
  100. $divided = 0;
  101. //TOKEN分润
  102. $tokenFees = bcmul($tokenFee, bcdiv($item->fees, 100, 3), 3);
  103. //判断最大分润:0不限制
  104. if(!empty($item->max_fees)){
  105. //最大分润
  106. $divided = bcsub($item->max_fees, $item->divided_fees, 6);
  107. if($tokenFees > $divided) $tokenFees = $divided;
  108. }
  109. //每份产品的分润
  110. $cave = bcdiv($tokenFees, $productNum, 6);
  111. //冻结分润
  112. $frozenFees = bcmul($frozenFee, bcdiv($item->fees, 100, 3), 3);
  113. //判断最大分润:0不限制
  114. if($divided > 0){
  115. //最大分润
  116. $divided = bcsub($divided, $tokenFees, 6);
  117. if($frozenFees > $divided) $frozenFees = $divided;
  118. }
  119. //每份产品的分润
  120. $fave = bcdiv($frozenFees, $productNum, 6);
  121. $totalFees = 0; //用户总分润
  122. foreach ($productHold as $vv) {
  123. //茶宝
  124. $tokenNum = bcmul($vv->num, $cave, 6); //持有数量 * 每份产品的分润
  125. if($tokenNum > 0) {
  126. $wallet->changeWalletAccount($vv->user_id, Asset::TOKEN, $tokenNum , LedgerTokenChangeModel::SharingFees);
  127. $output->writeln('存储用户:' . $vv->user_id . '茶宝分润:' . $tokenNum );
  128. }
  129. //手续费
  130. $frozenNum = bcmul($vv->num, $fave, 6);
  131. if($frozenNum > 0) {
  132. $wallet->changeWalletAccount($vv->user_id, Asset::FROZEN, $frozenNum , LedgerFrozenChangeModel::SharingFees);
  133. $output->writeln('存储用户:' . $vv->user_id. ' 手续费账户分润:' . $frozenNum );
  134. }
  135. //用户总分润
  136. $totalFees += bcadd($tokenNum, $frozenNum, 6);
  137. }
  138. //更新分润
  139. if($totalFees > 0) {
  140. $item->divided_fees += $totalFees;
  141. //判断是否到最大分润
  142. if($item->max_fees == $item->divided_fees) $item->status = 0;
  143. $item->save();
  144. $i +=1;
  145. }
  146. }
  147. return $i;
  148. }
  149. //销售分润
  150. public static function setSharingSales($output){
  151. $list = SharingFeesModel::where(['status'=> SharingFeesModel::Normal])->where('chabao', '>', 0)->where('type_id', SharingFeesModel::TypeChabao)->select();
  152. if(empty($list)) return true;
  153. $i = 0;
  154. $wallet = new LedgerWalletModel();
  155. $productOrder = new ProductOrder();
  156. foreach($list as $item){
  157. //获取触发产品次数
  158. $productTripNum = $productOrder::getTripPopularProduct($item->sale_product_id);
  159. if($productTripNum == 0) continue;
  160. //TOKEN产品的持有量
  161. $productHold = $productOrder::getHoldProductNum($item->product_id);
  162. //每份产品的分润
  163. $cave =$item->chabao * $productTripNum;
  164. foreach ($productHold as $vv) {
  165. //茶宝
  166. $tokenNum = bcmul($vv->num, $cave, 6); //持有数量 * 每份产品的分润
  167. if($tokenNum > 0) {
  168. $wallet->changeWalletAccount($vv->user_id, Asset::TOKEN, $tokenNum , LedgerTokenChangeModel::SharingFees);
  169. $output->writeln('存储用户:' . $vv->user_id . '茶宝分润:' . $tokenNum );
  170. $i +=1;
  171. }
  172. }
  173. }
  174. return $i;
  175. }
  176. }