AccessTokenCron.php 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. <?php
  2. declare(strict_types=1);
  3. namespace SixShop\Wechat\Cron;
  4. use app\api\controller\Wechat;
  5. use EasyWeChat\Kernel\Contracts\AccessToken as AccessTokenInterface;
  6. use SixShop\Core\Attribute\Cron;
  7. use SixShop\Core\Job\BaseJob;
  8. use SixShop\System\Job\ClosureJob;
  9. use SixShop\Wechat\Log;
  10. use SixShop\Wechat\Service\MiniApp;
  11. use think\facade\Cache;
  12. use function Symfony\Component\String\s;
  13. class AccessTokenCron extends BaseJob
  14. {
  15. /**
  16. * 提前 60 秒执行
  17. */
  18. private const int LEAD_TIME = 60;
  19. private AccessTokenInterface $accessToken;
  20. private string $cacheKey;
  21. private bool $isRunning = false;
  22. /**
  23. * 刷新 AccessToken 的计划执行时间
  24. */
  25. private int $scheduleRefreshTime = 0;
  26. public function __construct(private MiniApp $miniApp, private Log $log)
  27. {
  28. $this->accessToken = $this->miniApp->getAccessToken();
  29. $this->cacheKey = Cache::getCachekey($this->accessToken->getKey());
  30. }
  31. #[Cron('0 0 */2 * * *', 'wechat.refreshMiniAppAccessToken')]
  32. public function refreshMiniAppAccessToken(): void
  33. {
  34. if (time() > $this->scheduleRefreshTime) {
  35. $expireIn = $this->execute();
  36. self::dispatch()->delay($expireIn - self::LEAD_TIME);
  37. $this->scheduleRefreshTime = time() + $expireIn - self::LEAD_TIME;
  38. $this->log->debug('定时刷新小程序 AccessToken 任务已启动,计划执行时间:{time}', [
  39. 'time' => date('Y-m-d H:i:s', $this->scheduleRefreshTime)
  40. ]);
  41. }
  42. }
  43. public function execute(): int
  44. {
  45. if ($this->isRunning) {
  46. return Cache::ttl($this->cacheKey);
  47. }
  48. $this->isRunning = true;
  49. try {
  50. $oldToken = $this->accessToken->getToken();
  51. $newToken = $this->accessToken->refresh();
  52. $expireIn = Cache::ttl($this->cacheKey);
  53. $this->log->debug('刷新小程序 AccessToken 成功,过期时间:{time}, 结果:{result}', [
  54. 'time' => date('Y-m-d H:i:s', time() + $expireIn),
  55. 'result' => $oldToken === $newToken ? '未更新' : '已更新',
  56. ]);
  57. } finally {
  58. $this->isRunning = false;
  59. }
  60. return $expireIn;
  61. }
  62. }