AirdropLogic.php 11 KB

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