AirdropLogic.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. <?php
  2. namespace app\common\logic;
  3. use app\common\model\Config;
  4. use app\common\model\UserAirdrop;
  5. use app\api\logic\WelfareLoginc;
  6. use app\common\model\ProductPopular;
  7. use app\common\model\LedgerTokenChangeModel;
  8. use app\common\model\LedgerWalletModel;
  9. use app\common\model\TimedTaskLogModel;
  10. use app\common\model\UserModel;
  11. use app\common\model\UserPathModel;
  12. use fast\Action;
  13. use fast\Asset;
  14. use fast\MembershipLevel;
  15. use think\Cache;
  16. use think\Db;
  17. use think\Log;
  18. use think\Model;
  19. use think\console\Output;
  20. use fast\Http;
  21. /**
  22. * 团队奖励发放逻辑
  23. * 定时任务,定时发放,每天一次,一般在凌晨12一过开始
  24. */
  25. class AirdropLogic
  26. {
  27. /**
  28. * 奖励名称及类型ID
  29. * @var array
  30. */
  31. private array $rewards_type = [
  32. 1 => 'SMH拨币',
  33. 2 => 'Qubic拨币',
  34. ];
  35. /**
  36. * 空投发放
  37. */
  38. public function setAirdropRewards()
  39. {
  40. //查找会员资产列表
  41. $info_list = UserAirdrop::where('type_id', UserAirdrop::typeRwa)->where('status', UserAirdrop::NORMAL)->find();
  42. if(empty($info_list)){
  43. (new Output())->writeln("本次没有空投发放数据:");
  44. return false;
  45. }
  46. // 获取指定产品的热门信息
  47. $result = ProductPopular::getPopularByTime($info_list['product_id'], 'zh', $info_list->start_time);
  48. // 检查库存是否足够
  49. if(!$result || $info_list->total_num > $result->stock) {
  50. // 如果库存不足,输出信息并返回false
  51. (new Output())->writeln("本次执行库存不足:");
  52. return false;
  53. }
  54. // 更新用户福利信息
  55. WelfareLoginc::setUserExRwaNum(
  56. $info_list['rwa_num'],
  57. $info_list['product_id'],
  58. $result->is_area, $result->id, $result->price,
  59. $info_list['rwa_mod'],
  60. $info_list['num']
  61. );
  62. // 更新信息列表的状态和备注
  63. $info_list->status = UserAirdrop::STOP;
  64. $info_list->remark = '总发放'.$info_list->total_num.'套';
  65. // 保存更新后的信息列表
  66. return $info_list->save();
  67. }
  68. public function setParentRewards()
  69. {
  70. //查找会员资产列表
  71. $info_list = UserAirdrop::where('type_id', UserAirdrop::typeSuperWeal)
  72. ->where('user_id', '>', 0)
  73. ->where('status', UserAirdrop::NORMAL)
  74. ->select();
  75. if(empty($info_list)){
  76. (new Output())->writeln("本次没有层级奖励数据:");
  77. return false;
  78. }
  79. foreach ($info_list as $info){
  80. $user_info = UserModel::where('id', $info['user_id'])->find();
  81. if($user_info->is_super == 0){
  82. (new UserAirdrop)->updateDate($info['id'], UserAirdrop::STOP, '会员未领超级福利');
  83. }
  84. if($user_info->parent_id == 0){
  85. (new UserAirdrop)->updateDate($info['id'], UserAirdrop::STOP, '会员无上级');
  86. }
  87. $parents_info = UserPathModel::where('p.user_id', $info['user_id'])
  88. ->alias('p')
  89. ->join('user u', 'u.id = p.parent_id', 'left')
  90. ->field('u.id, u.is_super, u.direct_super, u.parent_id, p.distance')
  91. ->where('u.is_super', 1)
  92. ->order('p.distance asc')
  93. ->select();
  94. if(empty($parents_info)){
  95. (new UserAirdrop)->updateDate($info['id'], UserAirdrop::STOP, '所有上级无超级福利');
  96. }
  97. $level = 0;
  98. $send_user_ids = [];//需要发放的会员ID列表
  99. //分享 3 个拿 10 层,分享 10 个拿 31 层
  100. foreach ($parents_info as $parent){
  101. if($parent['direct_super'] >= 3 && $parent['distance'] <= 10){
  102. $send_user_ids[] = $parent['parent_id'];
  103. }else if($parent['direct_super'] >= 10 && $parent['distance'] <= 31){
  104. $send_user_ids[] = $parent['parent_id'];
  105. }
  106. }
  107. if(empty($send_user_ids)){
  108. (new UserAirdrop)->updateDate($info['id'], UserAirdrop::STOP, '所有上级都未满足发放条件');
  109. }
  110. }
  111. // 获取指定产品的热门信息
  112. $result = ProductPopular::getPopularByTime($info_list['product_id'], 'zh', $info_list->start_time);
  113. // 检查库存是否足够
  114. if(!$result || $info_list->total_num > $result->stock) {
  115. // 如果库存不足,输出信息并返回false
  116. (new Output())->writeln("本次执行库存不足:");
  117. return false;
  118. }
  119. // 更新用户福利信息
  120. WelfareLoginc::setUserExRwaNum(
  121. $info_list['rwa_num'],
  122. $info_list['product_id'],
  123. $result->is_area, $result->id, $result->price,
  124. $info_list['rwa_mod'],
  125. $info_list['num']
  126. );
  127. // 更新信息列表的状态和备注
  128. $info_list->status = UserAirdrop::STOP;
  129. $info_list->remark = '总发放'.$info_list->total_num.'套';
  130. // 保存更新后的信息列表
  131. return $info_list->save();
  132. }
  133. /**
  134. * 拨币
  135. * 向会员发放qubic
  136. * 每一万算力每天收益14-15万个币
  137. */
  138. public function AllocateQubic()
  139. {
  140. $type_id = 2;
  141. $date = $this->getExeDate($type_id);
  142. if(empty($date)){
  143. (new Output())->writeln("本次没有可用时间:" . $date);
  144. return ;
  145. }
  146. //创建定时任务执行日志
  147. $log_id = (new TimedTaskLogModel())->insertGetId([
  148. 'type_id' => $type_id,
  149. 'type_name' => $this->rewards_type[$type_id],
  150. 'date_time' => $date,
  151. 'create_time' => date('Y-m-d H:i:s'),
  152. ]);
  153. //查找会员资产列表
  154. $info_list = DB::table('ledger_wallet')
  155. ->alias('w')
  156. ->join('user u','u.id = w.user_id')
  157. ->field('user_id,power')
  158. ->where('power', '>', 0)
  159. ->where('effective_time', '>', 0) //报单有收益
  160. ->select();
  161. if(empty($info_list)){
  162. (new Output())->writeln("本次没有可用会员数据:" . $date);
  163. return $log_id;
  164. }
  165. $num =rand(120000,130000);
  166. $power_price = $num/10000;//每算力每日获得SMH的数量,算法为每一万算力每日产15万个Qubic
  167. foreach ($info_list as $info) {
  168. $amount = ($info['power']) * $power_price;
  169. $check = (new LedgerQubicChangeModel())
  170. ->where('user_id', $info['user_id'])
  171. ->where('action', LedgerQubicChangeModel::SysSend)
  172. ->where('from_id', strtotime($date))
  173. ->count();
  174. if($check){
  175. dump('用户ID:' . $info['user_id'] . '已拨过,拨币量为:' . $amount);
  176. }else{
  177. dump(['用户ID:' . $info['user_id'],'拨币量为:' . $amount]);
  178. //发放
  179. (new LedgerWalletModel)->changeWalletAccount($info['user_id'], Asset::QUBIC, $amount, LedgerQubicChangeModel::SysSend);
  180. }
  181. }
  182. return $log_id;
  183. }
  184. /**
  185. * 拨币
  186. * 向会员发放qubic
  187. * 每一万算力每天收益14-15万个币
  188. */
  189. public function AllocateAleo()
  190. {
  191. $type_id = 11;
  192. $date = $this->getExeDate($type_id);
  193. if(empty($date)){
  194. (new Output())->writeln("本次没有可用时间:" . $date);
  195. return ;
  196. }
  197. //创建定时任务执行日志
  198. $log_id = (new TimedTaskLogModel())->insertGetId([
  199. 'type_id' => $type_id,
  200. 'type_name' => $this->rewards_type[$type_id],
  201. 'date_time' => $date,
  202. 'create_time' => date('Y-m-d H:i:s'),
  203. ]);
  204. //查找会员资产列表
  205. $info_list = DB::table('ledger_wallet')
  206. ->alias('w')
  207. ->join('user u','u.id = w.user_id')
  208. ->field('user_id,power')
  209. ->where('power', '>', 0)
  210. ->where('effective_time', '>', 0) //报单有收益
  211. ->select();
  212. if(empty($info_list)){
  213. (new Output())->writeln("本次没有可用会员数据:" . $date);
  214. return $log_id;
  215. }
  216. $num = mt_rand(4030,4080) / 1000;//每一万算力每日获得Aleo的数量,算法为每一万算力每日产6.5个币,并从2024-9-20开始,每天递减5%
  217. // $date1 = '2024-9-26';
  218. // $date2 = date('Y-m-d');
  219. // $diff = strtotime($date2) - strtotime($date1);
  220. // // 将时间戳差转换为天数
  221. // $days = floor($diff / (60 * 60 * 24));
  222. // if($days > 0){
  223. // //每日递减3%
  224. // $num = $num * pow((1-0.03), $days);
  225. // }
  226. // if($num < 4){
  227. // $num = $num = mt_rand(3500,4500) / 1000;//每一万算力保底3个币
  228. // }
  229. $power_price = $num/10000;//每算力每日获得Aleo的数量,算法为每一万算力每日产6.5个币,并从2024-9-20开始,每天递减5%
  230. foreach ($info_list as $info) {
  231. $amount = ($info['power']) * $power_price;
  232. $check = (new LedgerQubicChangeModel())
  233. ->where('user_id', $info['user_id'])
  234. ->where('action', LedgerTokenChangeModel::SysSend)
  235. ->where('from_id', strtotime($date))
  236. ->count();
  237. if($check){
  238. dump('用户ID:' . $info['user_id'] . '已拨过,拨币量为:' . $amount);
  239. }else{
  240. dump(['用户ID:' . $info['user_id'],'拨币量为:' . $amount]);
  241. //发放
  242. (new LedgerWalletModel)->changeWalletAccount($info['user_id'], Asset::TOKEN, $amount, LedgerTokenChangeModel::SysSend);
  243. }
  244. }
  245. return $log_id;
  246. }
  247. /**
  248. * 获取可用日期
  249. * @var array
  250. */
  251. protected function getExeDate($type_id = 1)
  252. {
  253. $today = date('Y-m-d',strtotime("-1day"));//当前时间减一天为最后一次可用时间
  254. $dateInfo = DB::table('timed_task_log')
  255. ->where('type_id' ,$type_id)
  256. ->where('status', 1)
  257. ->order('date_time', 'desc')
  258. ->find();
  259. if(empty($dateInfo)){//首次
  260. return $today;
  261. }
  262. $new_date = date('Y-m-d',strtotime("+1day",strtotime($dateInfo['date_time'])));//最后一次发放日期+1天为本次执行时间
  263. if($new_date > $today){//超过今天
  264. return "";
  265. }
  266. return $new_date;
  267. }
  268. }