[update] Login Closes #37

This commit is contained in:
Lkeme 2020-06-25 22:45:00 +08:00
parent 3c73415e31
commit a03877ea9e
9 changed files with 413 additions and 184 deletions

View File

@ -1,7 +1,7 @@
# Release Notes
# 本项目Log
## v0.5.0.200624 alpha (2020-06-24)
## v0.5.0.200625 alpha (2020-06-25)
### Added
- 添加破产机(赔到破产)
@ -19,6 +19,7 @@
- 更新视频投币逻辑
- 更新实物抽奖API
- 修改硬币兑换延迟
- 重构部分登录逻辑
-
### Fixed
@ -92,7 +93,7 @@
### Changed
- 优化监控推送
- 优化登参数
- 优化登参数
- 同步黑屋提醒
### Fixed
@ -207,7 +208,7 @@
-
### Fixed
- 修复登繁忙
- 修复登繁忙
- 修复实物抽奖
- 修复日志输出
- 修复部分已知

4
DOC.md
View File

@ -2,7 +2,7 @@
<p align="center"><img width="300px" src="https://i.loli.net/2018/04/20/5ad97bd395912.jpeg"></p>
<p align="center">
<img src="https://img.shields.io/badge/version-0.5.0.200624 alpha-green.svg?longCache=true&style=for-the-badge">
<img src="https://img.shields.io/badge/version-0.5.0.200625 alpha-green.svg?longCache=true&style=for-the-badge">
<img src="https://img.shields.io/badge/license-mit-blue.svg?longCache=true&style=for-the-badge">
</p>
@ -127,7 +127,7 @@ $ php index.php
- 通过环境变量进行传入
```shell script
docker run -itd --rm -e USER_NAME=你的B站登账号 -e USER_PASSWORD=你的B站密码 zsnmwy/bilihelper-personal
docker run -itd --rm -e USER_NAME=你的B站登账号 -e USER_PASSWORD=你的B站密码 zsnmwy/bilihelper-personal
```
- 通过配置文件进行传入

View File

@ -7,7 +7,7 @@ Group: [55308141](https://jq.qq.com/?_wv=1027&k=5AIDaJg) | **仅用于BUG提交
## 公告
> Currently for Personal Edition **0.5.0.200624 alpha**
> Currently for Personal Edition **0.5.0.200625 alpha**
```notice
---- 免费的东西总是得不到人的珍惜。

View File

@ -6,6 +6,9 @@
APP_USER=
APP_PASS=
# 登录模式|[1.账密模式 2.短信验证码模式 3.行为验证码模式(暂未开放)]
LOGIN_MODE=1
# 令牌(自动生成)
ACCESS_TOKEN=
REFRESH_TOKEN=

View File

@ -233,7 +233,8 @@ class Curl
'Accept-Language' => 'zh-cn',
'Connection' => 'keep-alive',
// 'Content-Type' => 'application/x-www-form-urlencoded',
'User-Agent' => 'Mozilla/5.0 BiliDroid/5.51.1 (bbcallen@gmail.com)',
// 'User-Agent' => 'Mozilla/5.0 BiliDroid/5.51.1 (bbcallen@gmail.com)',
'User-Agent' => 'Mozilla/5.0 BiliDroid/6.3.0 (bbcallen@gmail.com) os/android model/MuMu mobi_app/android build/6030600 channel/bili innerVer/6030600 osVer/6.0.1 network/2',
// 'Referer' => 'https://live.bilibili.com/',
];
$pc_headers = [

View File

@ -30,7 +30,7 @@ class GiftSend
public static function run()
{
if (self::getLock() > time()) {
if (self::getLock() > time() || !self::inTime('23:50:00', '23:59:50')) {
return;
}
if (!self::$uid) {
@ -44,8 +44,8 @@ class GiftSend
self::$medal_list = [];
self::$tid = 0;
// 如果在每日最后5分钟内 就50s执行一次 否则 第二天固定时间执行
if (self::inTime('23:55:00', '23:59:59')) {
self::setLock(50);
if (self::inTime('23:52:00', '23:59:59')) {
self::setLock(60);
} else {
self::setLock(self::timing(23, 55));
}

View File

@ -19,46 +19,95 @@ class Login
{
use TimeLock;
// 账密
private static $username;
private static $password;
public static function run()
{
if (self::getLock()) {
self::check();
self::keepAuth();
return;
}
Log::info('开始启动程序...');
Log::info('启动登录程序');
if (getenv('ACCESS_TOKEN') == "") {
Log::info('令牌载入中...');
Log::info('准备载入登录令牌');
self::login();
}
Log::info('正在检查令牌合法性...');
if (!self::info()) {
Log::warning('令牌即将过期');
Log::info('申请更换令牌中...');
if (!self::refresh()) {
Log::warning('无效令牌,正在重新申请...');
Log::info('检查登录令牌有效性');
if (!self::checkToken()) {
Log::warning('登录令牌即将过期');
Log::info('申请更换登录令牌中');
if (!self::refreshToken()) {
Log::warning('无效的登录令牌,尝试重新申请');
self::login();
}
}
self::setLock(3600);
}
/**
* @use 检查令牌
* @use 登录控制中心
*/
private static function login()
{
self::checkLogin();
switch (intval(getenv('LOGIN_MODE'))) {
case 1:
// 账密模式
self::accountLogin();
break;
case 2:
// 短信验证码模式
self::smsLogin();
break;
case 3:
// 行为验证码模式(暂未开放)
// self::captchaLogin();
Log::error('此登录模式暂未开放');
die();
break;
default:
Log::error('登录模式配置错误');
die();
}
}
/**
* @use 检查登录
*/
private static function checkLogin()
{
$user = getenv('APP_USER');
$pass = getenv('APP_PASS');
if (empty($user) || empty($pass)) {
Log::error('空白的帐号和口令');
die();
}
self::clearAccount();
self::$username = $user;
self::$password = self::publicKeyEnc($pass);
}
/**
* @use 保持认证
* @return bool
*/
public static function check()
private static function keepAuth()
{
if (self::getLock() > time()) {
return true;
}
self::setLock(7200);
if (!self::info()) {
if (!self::checkToken()) {
Log::warning('令牌即将过期');
Log::info('申请更换令牌中...');
if (!self::refresh()) {
if (!self::refreshToken()) {
Log::warning('无效令牌,正在重新申请...');
self::login();
self::accountLogin();
}
return false;
}
@ -69,7 +118,7 @@ class Login
* @use 获取令牌信息
* @return bool
*/
protected static function info()
private static function checkToken()
{
$url = 'https://passport.bilibili.com/api/v2/oauth2/info';
$payload = [
@ -85,165 +134,46 @@ class Login
return $data['data']['expires_in'] > 14400;
}
/**
* @use 刷新token
* @return bool
* @use 刷新Token
*/
public static function refresh()
private static function refreshToken()
{
$url = 'https://passport.bilibili.com/api/oauth2/refreshToken';
$url = 'https://passport.bilibili.com/api/v2/oauth2/refresh_token';
$payload = [
'access_token' => getenv('ACCESS_TOKEN'),
'refresh_token' => getenv('REFRESH_TOKEN'),
];
$data = Curl::post('app', $url, Sign::common($payload));
$data = json_decode($data, true);
$raw = Curl::post('app', $url, Sign::common($payload));
$de_raw = json_decode($raw, true);
if (isset($data['code']) && $data['code']) {
Log::error('重新生成令牌失败', ['msg' => $data['message']]);
return false;
}
Log::info('令牌生成完毕!');
$access_token = $data['data']['access_token'];
Config::put('ACCESS_TOKEN', $access_token);
Log::info(" > access token: {$access_token}");
$refresh_token = $data['data']['refresh_token'];
Config::put('REFRESH_TOKEN', $refresh_token);
Log::info(" > refresh token: {$refresh_token}");
if (!self::saveCookie()) {
self::clearAccount();
die();
};
Log::info('重新令牌生成完毕');
$access_token = $de_raw['data']['token_info']['access_token'];
$refresh_token = $de_raw['data']['token_info']['refresh_token'];
self::saveConfig('ACCESS_TOKEN', $access_token);
self::saveConfig('REFRESH_TOKEN', $refresh_token);
self::saveCookie($de_raw);
Log::info('重置信息配置完毕');
return true;
}
/**
* @use 普通登陆
* @param string $captcha
* @param array $headers
* @use 检查Cookie
*/
protected static function login($captcha = '', $headers = [])
private static function checkCookie()
{
$user = getenv('APP_USER');
$pass = getenv('APP_PASS');
if (empty($user) || empty($pass)) {
Log::error('空白的帐号和口令!');
die();
}
self::clearAccount();
// get PublicKey
Log::info('正在载入安全模块...');
$url = 'https://passport.snm0516.aisee.tv/api/oauth2/getKey';
$payload = [];
$data = Curl::post('app', $url, Sign::login($payload));
$data = json_decode($data, true);
if (isset($data['code']) && $data['code']) {
Log::error('公钥获取失败', ['msg' => $data['message']]);
die();
} else {
Log::info('安全模块载入完毕!');
}
$public_key = $data['data']['key'];
$hash = $data['data']['hash'];
openssl_public_encrypt($hash . $pass, $crypt, $public_key);
for ($i = 0; $i < 30; $i++) {
// login
Log::info('正在获取令牌...');
$url = 'https://passport.snm0516.aisee.tv/api/tv/login';
$payload = [
'channel' => 'master',
'token' => '5598158bcd8511e9',
'guid' => 'XYEBAA3E54D502E73BD606F0589A356902FCF',
'username' => $user,
'password' => base64_encode($crypt),
'captcha' => $captcha,
];
$data = Curl::post('app', $url, Sign::login($payload), $headers);
$data = json_decode($data, true);
if (isset($data['code']) && $data['code'] == -105) {
$captcha_data = self::loginWithCaptcha();
$captcha = $captcha_data['captcha'];
$headers = $captcha_data['headers'];
continue;
}
// https://passport.bilibili.com/mobile/verifytel_h5.html
if ($data['code'] == -2100) {
Log::error('登录失败', ['msg' => '登录异常, 账号启用了设备锁或异地登录需验证手机!']);
die();
}
break;
}
if (isset($data['code']) && $data['code']) {
Log::error('登录失败', ['msg' => $data['message']]);
die();
}
Log::info('令牌获取成功!');
$access_token = $data['data']['token_info']['access_token'];
Config::put('ACCESS_TOKEN', $access_token);
Log::info(" > access token: {$access_token}");
$refresh_token = $data['data']['token_info']['refresh_token'];
Config::put('REFRESH_TOKEN', $refresh_token);
Log::info(" > refresh token: {$refresh_token}");
if (!self::saveCookie()) {
self::clearAccount();
die();
};
return;
}
/**
* @use 验证码登陆
* @return array
* @use 刷新Cookie
*/
protected static function loginWithCaptcha()
{
Log::info('登录需要验证, 启动验证码登录!');
$url = 'https://passport.snm0516.aisee.tv/api/captcha';
$payload = [
'token' => '5598158bcd8511e9'
];
$headers = [
'Accept' => 'application/json, text/plain, */*',
'Host' => 'passport.snm0516.aisee.tv',
'Cookie' => 'sid=blhelper'
];
$data = Curl::get('other', $url, $payload, $headers);
$data = base64_encode($data);
$captcha = self::ocrCaptcha($data);
return [
'captcha' => $captcha,
'headers' => $headers,
];
}
/**
* @use 识别验证码
* @param $captcha_img
* @return mixed
*/
private static function ocrCaptcha($captcha_img)
{
// $url = 'http://captcha-v1.mudew.com:19951/';
$url = 'http://47.102.120.84:19951/';
$payload = [
'image' => (string)$captcha_img
];
$headers = [
'Content-Type' => 'application/json',
];
$data = Curl::put('other', $url, $payload, $headers);
$de_raw = json_decode($data, true);
Log::info("验证码识别结果 {$de_raw['message']}");
return $de_raw['message'];
}
/**
* @use token转cookie
* @return string
*/
private static function token2cookie(): string
private static function refreshCookie()
{
$url = 'https://passport.bilibili.com/api/login/sso';
$payload = [
@ -261,20 +191,286 @@ class Login
/**
* @use 保存cookie
* @return bool
* @use 公钥加密
* @param $plaintext
* @return string
*/
private static function saveCookie(): bool
private static function publicKeyEnc($plaintext): string
{
$cookies = self::token2cookie();
if ($cookies == '') {
Log::error("COOKIE获取失败 {$cookies}");
return false;
Log::info('正在载入公钥');
$url = 'https://passport.bilibili.com/api/oauth2/getKey';
$payload = [];
$data = Curl::post('app', $url, Sign::login($payload));
$data = json_decode($data, true);
if (isset($data['code']) && $data['code']) {
Log::error('公钥载入失败', ['msg' => $data['message']]);
die();
} else {
Log::info('公钥载入完毕');
}
Log::info("COOKIE获取成功 !");
Log::info(" > cookie: {$cookies}");
Config::put('COOKIE', $cookies);
return true;
$public_key = $data['data']['key'];
$hash = $data['data']['hash'];
openssl_public_encrypt($hash . $plaintext, $crypt, $public_key);
return base64_encode($crypt);
}
/**
* @use 获取验证码
* @return array|string[]
*/
private static function getCaptcha(): array
{
$url = 'https://passport.bilibili.com/web/captcha/combine';
$payload = [
'plat' => 3
];
$raw = Curl::get('other', $url, $payload);
$de_raw = json_decode($raw, true);
// {"code":0,"data":{"result":{"success":1,"gt":"b6e5b7fad7ecd37f465838689732e788","challenge":"88148a764f94e5923564b356a69277fc","key":"230509df5ce048ca9bf29e1ee323af30"},"type":1}}
Log::info('正在获取验证码 ' . $de_raw['code']);
if ($de_raw['code'] == 0 && isset($de_raw['data']['result'])) {
return [
'gt' => $de_raw['data']['result']['gt'],
'challenge' => $de_raw['data']['result']['challenge'],
'key' => $de_raw['data']['result']['key'],
];
}
return [
'gt' => '',
'challenge' => '',
'key' => ''
];
}
/**
* @use 识别验证码
* @param array $captcha
* @return array
*/
private static function ocrCaptcha(array $captcha): array
{
$url = 'http://captcha-v1.mudew.com:19951/';
$payload = [
'type' => 'gt3',
'gt' => $captcha['gt'],
"challenge" => $captcha['challenge'],
"referer" => "https://passport.bilibili.com/"
];
$headers = [
'Content-Type' => 'application/json',
];
$data = Curl::post('other', $url, $payload, $headers);
$de_raw = json_decode($data, true);
Log::info('正在获取验证码 ' . $de_raw['code']);
return [
'validate' => $de_raw['data']['validate'],
'challenge' => $de_raw['data']['challenge']
];
}
/**
* @use 验证码登录
* @param string $mode
*/
private static function captchaLogin(string $mode = '验证码模式')
{
$captcha_ori = self::getCaptcha();
$captcha = self::ocrCaptcha($captcha_ori);
self::accountLogin($captcha['validate'], $captcha['challenge'], $mode);
}
/**
* @use 账密登录
* @param string $validate
* @param string $challenge
* @param string $mode
*/
private static function accountLogin(string $validate = '', string $challenge = '', string $mode = '账密模式')
{
Log::info("尝试{$mode}登录");
$url = 'https://passport.bilibili.com/api/v3/oauth2/login';
$payload = [
'seccode' => $validate ? "{$validate}|jordan" : '',
'validate' => $validate,
'challenge' => $challenge,
'subid' => 1,
'permission' => 'ALL',
'username' => self::$username,
'password' => self::$password,
'captcha' => '',
'cookies' => ''
];
$raw = Curl::post('app', $url, Sign::login($payload));
$de_raw = json_decode($raw, true);
// {"ts":1593079322,"code":-629,"message":"账号或者密码错误"}
// {"ts":1593082268,"code":-105,"data":{"url":"https://passport.bilibili.com/register/verification.html?success=1&gt=b6e5b7fad7ecd37f465838689732e788&challenge=7efb4020b22c0a9ac124aea624e11ad7&ct=1&hash=7fa8282ad93047a4d6fe6111c93b308a"},"message":"验证码错误"}
// {"ts":1593082432,"code":0,"data":{"status":0,"token_info":{"mid":123456,"access_token":"123123","refresh_token":"123123","expires_in":2592000},"cookie_info":{"cookies":[{"name":"bili_jct","value":"123123","http_only":0,"expires":1595674432},{"name":"DedeUserID","value":"123456","http_only":0,"expires":1595674432},{"name":"DedeUserID__ckMd5","value":"123123","http_only":0,"expires":1595674432},{"name":"sid","value":"bd6aagp7","http_only":0,"expires":1595674432},{"name":"SESSDATA","value":"6d74d850%123%2Cf0e36b61","http_only":1,"expires":1595674432}],"domains":[".bilibili.com",".biligame.com",".bigfunapp.cn"]},"sso":["https://passport.bilibili.com/api/v2/sso","https://passport.biligame.com/api/v2/sso","https://passport.bigfunapp.cn/api/v2/sso"]}}
// https://passport.bilibili.com/mobile/verifytel_h5.html
switch ($de_raw['code']) {
case 0:
// 正常登录
Log::info("{$mode}登录成功");
$access_token = $de_raw['data']['token_info']['access_token'];
$refresh_token = $de_raw['data']['token_info']['refresh_token'];
self::saveConfig('ACCESS_TOKEN', $access_token);
self::saveConfig('REFRESH_TOKEN', $refresh_token);
self::saveCookie($de_raw);
Log::info('信息配置完毕');
break;
case -105:
// 需要验证码
Log::error('登录失败', ['msg' => '此次登录需要验证码或' . $de_raw['message']]);
die();
break;
case -629:
// 密码错误
Log::error('登录失败', ['msg' => $de_raw['message']]);
die();
break;
case -2100:
// 验证手机号
Log::error('登录失败', ['msg' => '账号启用了设备锁或异地登录需验证手机号']);
die();
break;
default:
Log::error('登录失败', ['msg' => '未知错误: ' . $de_raw['message']]);
die();
break;
}
}
/**
* @use 短信登录
* @param string $mode
*/
private static function smsLogin(string $mode = '短信模式')
{
Log::info("尝试{$mode}登录");
self::checkPhone(self::$username);
$captcha = self::sendSms(self::$username);
$url = 'https://passport.bilibili.com/x/passport-login/login/sms';
$payload = [
'captcha_key' => $captcha['captcha_key'],
'cid' => $captcha['cid'],
'tel' => $captcha['tel'],
'statistics' => $captcha['statistics'],
'code' => self::cliInput('请输入收到的短信验证码: '),
];
$raw = Curl::post('app', $url, Sign::login($payload));
$de_raw = json_decode($raw, true);
switch ($de_raw['code']) {
case 0:
// 正常登录
Log::info("{$mode}登录成功");
$access_token = $de_raw['data']['token_info']['access_token'];
$refresh_token = $de_raw['data']['token_info']['refresh_token'];
self::saveConfig('ACCESS_TOKEN', $access_token);
self::saveConfig('REFRESH_TOKEN', $refresh_token);
self::saveCookie($de_raw);
Log::info('信息配置完毕');
break;
case -105:
// 需要验证码
Log::error('登录失败', ['msg' => '此次登录需要验证码或' . $de_raw['message']]);
die();
break;
case -629:
// 密码错误
Log::error('登录失败', ['msg' => $de_raw['message']]);
die();
break;
case -2100:
// 验证手机号
Log::error('登录失败', ['msg' => '账号启用了设备锁或异地登录需验证手机号']);
die();
break;
default:
Log::error('登录失败', ['msg' => '未知错误: ' . $de_raw['message']]);
die();
break;
}
}
/**
* @use 输入短信验证码
* @param string $msg
* @param int $max_char
* @return string
*/
private static function cliInput(string $msg, $max_char = 100): string
{
$stdin = fopen('php://stdin', 'r');
echo '# ' . $msg;
$input = fread($stdin, $max_char);
fclose($stdin);
return str_replace(PHP_EOL, '', $input);
}
/**
* @use 发送短信验证码
* @param string $phone
* @return array
*/
private static function sendSms(string $phone): array
{
$url = 'https://passport.bilibili.com//x/passport-login/sms/send';
$payload = [
'cid' => '86',
'tel' => $phone,
'statistics' => '{"appId":1,"platform":3,"version":"6.3.0","abtest":""}',
];
$raw = Curl::post('app', $url, Sign::login($payload));
$de_raw = json_decode($raw, true);
// {"code":0,"message":"0","ttl":1,"data":{"is_new":false,"captcha_key":"4e292933816755442c1568e2043b8e41","recaptcha_url":""}}
// {"code":0,"message":"0","ttl":1,"data":{"is_new":false,"captcha_key":"","recaptcha_url":"https://www.bilibili.com/h5/project-msg-auth/verify?ct=geetest\u0026recaptcha_token=ad520c3a4a3c46e29b1974d85efd2c4b\u0026gee_gt=1c0ea7c7d47d8126dda19ee3431a5f38\u0026gee_challenge=c772673050dce482b9f63ff45b681ceb\u0026hash=ea2850a43cc6b4f1f7b925d601098e5e"}}
if ($de_raw['code'] == 0 && isset($de_raw['data']['captcha_key']) && $de_raw['data']['recaptcha_url'] == '') {
Log::info("短信验证码发送成功 {$de_raw['data']['captcha_key']}");
$payload['captcha_key'] = $de_raw['data']['captcha_key'];
return $payload;
}
Log::error("短信验证码发送失败 {$raw}");
die();
}
/**
* @use 检查手机号格式
* @param string $phone
*/
private static function checkPhone(string $phone)
{
if (!preg_match("/^1[3456789]{1}\d{9}$/", $phone)) {
Log::error("当前用户名不是有效手机号格式");
die();
}
}
/**
* @use 保存配置
* @param string $key
* @param string $value
* @param bool $hide
*/
private static function saveConfig(string $key, string $value, $hide = true)
{
Config::put($key, $value);
Log::info(" > {$key}: " . ($hide ? substr_replace($value, '********', mb_strlen($value / 2), 8) : $value));
}
/**
* @use 保存配置
* @param array $data
*/
private static function saveCookie(array $data)
{
$c = '';
$cookies = $data['data']['cookie_info']['cookies'];
foreach ($cookies as $cookie) {
$c .= $cookie['name'] . '=' . $cookie['value'] . ';';
}
self::saveConfig('COOKIE', $c);
}
/**
@ -282,10 +478,11 @@ class Login
*/
private static function clearAccount()
{
$accounts = ['ACCESS_TOKEN', 'REFRESH_TOKEN', 'COOKIE'];
foreach ($accounts as $account) {
Config::put($account, '');
$variables = ['ACCESS_TOKEN', 'REFRESH_TOKEN', 'COOKIE'];
foreach ($variables as $variable) {
Config::put($variable, '');
}
}
}

View File

@ -15,6 +15,31 @@ use BiliHelper\Core\Log;
class Sign
{
// /**
// * @use 登录
// * @param $payload
// * @return array
// */
// public static function login($payload)
// {
// # 云视听 TV
// $appkey = '4409e2ce8ffd12b8';
// $appsecret = '59b43e04ad6965f34319062b478f83dd';
//
// $default = [
// 'access_key' => getenv('ACCESS_TOKEN'),
// 'actionKey' => 'appkey',
// 'appkey' => $appkey,
// 'build' => 101800,
// 'device' => 'android',
// 'mobi_app' => 'android_tv_yst',
// 'platform' => 'android',
// 'ts' => time(),
// ];
// $payload = array_merge($payload, $default);
// return self::encryption($payload, $appsecret);
// }
/**
* @use 登录
* @param $payload
@ -22,17 +47,18 @@ class Sign
*/
public static function login($payload)
{
# 云视听 TV
$appkey = '4409e2ce8ffd12b8';
$appsecret = '59b43e04ad6965f34319062b478f83dd';
# Android 新
$appkey = 'bca7e84c2d947ac6';
$appsecret = '60698ba2f68e01ce44738920a0ffe768';
$default = [
'access_key' => getenv('ACCESS_TOKEN'),
'actionKey' => 'appkey',
'appkey' => $appkey,
'build' => 101800,
'device' => 'android',
'mobi_app' => 'android_tv_yst',
'build' => 6030600,
'channel'=>'bili',
'device' => 'phone',
'mobi_app' => 'android',
'platform' => 'android',
'ts' => time(),
];
@ -50,7 +76,7 @@ class Sign
# iOS 6680
// $appkey = '27eb53fc9058f8c3';
// $appsecret = 'c2ed53a74eeefe3cf99fbd01d8c9c375';
# Android
# Android
$appkey = '1d8b6e7d45233436';
$appsecret = '560c52ccd288fed045859ed18bffd973';

View File

@ -102,7 +102,8 @@ class Statistics
*/
private static function timeTran(int $the_time): string
{
$t = time() - $the_time - 3;//现在时间-发布时间 获取时间差
$the_time = $the_time < 1577808000 ? time() : $the_time;
$t = time() - $the_time + 3;//现在时间-发布时间 获取时间差
$f = [
'31536000' => '年',
'2592000' => '个月',