SettlementTraffic.php 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. <?php
  2. namespace app\common\command;
  3. use app\common\model\FlowLogs;
  4. use app\common\model\User;
  5. use think\console\Command;
  6. use think\console\Input;
  7. use think\console\Output;
  8. use think\Db;
  9. use think\Exception;
  10. class SettlementTraffic extends Command
  11. {
  12. protected function configure()
  13. {
  14. // parent::configure(); // TODO: Change the autogenerated stub
  15. $this->setName('settlement')->setDescription('后台统计用户流量使用, 并扣除相关流量');
  16. }
  17. protected function execute(Input $input, Output $output)
  18. {
  19. // parent::execute($input, $output); // TODO: Change the autogenerated stub
  20. // $output->writeln("TestCommand");
  21. $dateTime = time() - 5; // 设置处理数据的时间为当前时间的前5秒,避免数据竞争
  22. // 分组统计出指定时间内用户使用了的流量
  23. $data = FlowLogs::where('created_at', '<=', $dateTime)
  24. ->field('username, sum(bytes) as bytes')
  25. ->group('username')
  26. ->select()->toArray();
  27. // 当前数据所有用户名的数组
  28. $userNames = array_column($data, 'username');
  29. $users = collection(User::whereIn('username', $userNames)->field('id, username')->select())->toArray();
  30. $userNameMapId = array_column($users, 'id', 'username');
  31. Db::startTrans();
  32. try {
  33. foreach ($data as $datum) {
  34. if (!$this->usedTraffic($userNameMapId[$datum['username']], $datum['bytes'])) {
  35. throw new Exception('统计用户使用流量失败');
  36. }
  37. }
  38. // 指定时间段的流量已统计,删除相关记录
  39. FlowLogs::where('created_at', '<=', $dateTime)->delete();
  40. // 统计数据成功,提交事物
  41. Db::commit();
  42. } catch (Exception $e) { // 操作失败,数据库信息回滚
  43. Db::rollback();
  44. }
  45. }
  46. protected function usedTraffic($uid, $bytes)
  47. {
  48. }
  49. }