perf: 优化 doo 模块

This commit is contained in:
kuaifan 2023-03-15 11:34:23 +08:00
parent 37e1c864d1
commit eb6c335b8a
11 changed files with 125 additions and 221 deletions

View File

@ -8,6 +8,7 @@ use App\Models\UserCheckinRecord;
use App\Module\Base; use App\Module\Base;
use App\Module\BillExport; use App\Module\BillExport;
use App\Module\BillMultipleExport; use App\Module\BillMultipleExport;
use App\Module\Doo;
use App\Module\Extranet; use App\Module\Extranet;
use Arr; use Arr;
use Carbon\Carbon; use Carbon\Carbon;
@ -536,7 +537,7 @@ class SystemController extends AbstractController
'ip-gcj02' => Extranet::getIpGcj02(Base::getIp()), 'ip-gcj02' => Extranet::getIpGcj02(Base::getIp()),
'ip-iscn' => Base::isCnIp(Base::getIp()), 'ip-iscn' => Base::isCnIp(Base::getIp()),
'header' => Request::header(), 'header' => Request::header(),
'token' => Base::getToken(), 'token' => Doo::userToken(),
'url' => url('') . Base::getUrl(), 'url' => url('') . Base::getUrl(),
]); ]);
} }

View File

@ -131,7 +131,7 @@ class UsersController extends AbstractController
]; ];
$user->updateInstance($array); $user->updateInstance($array);
$user->save(); $user->save();
User::token($user); User::generateToken($user);
LdapUser::userSync($user, $password); LdapUser::userSync($user, $password);
// //
if (!Project::withTrashed()->whereUserid($user->userid)->wherePersonal(1)->exists()) { if (!Project::withTrashed()->whereUserid($user->userid)->wherePersonal(1)->exists()) {
@ -189,7 +189,7 @@ class UsersController extends AbstractController
]; ];
$user->updateInstance($array); $user->updateInstance($array);
$user->save(); $user->save();
User::token($user); User::generateToken($user);
return Base::retSuccess("success", $user); return Base::retSuccess("success", $user);
} }
// //
@ -299,7 +299,7 @@ class UsersController extends AbstractController
public function info() public function info()
{ {
$user = User::auth(); $user = User::auth();
User::token($user); User::generateToken($user);
// //
$data = $user->toArray(); $data = $user->toArray();
$data['nickname_original'] = $user->getRawOriginal('nickname'); $data['nickname_original'] = $user->getRawOriginal('nickname');
@ -382,7 +382,7 @@ class UsersController extends AbstractController
} }
// //
$user->save(); $user->save();
User::token($user); User::generateToken($user);
LdapUser::userUpdate($user->email, $upLdap); LdapUser::userUpdate($user->email, $upLdap);
// //
return Base::retSuccess('修改成功', $user); return Base::retSuccess('修改成功', $user);
@ -415,7 +415,7 @@ class UsersController extends AbstractController
} }
User::passwordPolicy($newpass); User::passwordPolicy($newpass);
// //
$verify = User::whereUserid($user->userid)->wherePassword(Doo::md5s($oldpass, User::token2encrypt()))->count(); $verify = User::whereUserid($user->userid)->wherePassword(Doo::md5s($oldpass, Doo::userEncrypt()))->count();
if (empty($verify)) { if (empty($verify)) {
return Base::retError('请填写正确的旧密码'); return Base::retError('请填写正确的旧密码');
} }
@ -424,7 +424,7 @@ class UsersController extends AbstractController
$user->password = Doo::md5s($newpass, $user->encrypt); $user->password = Doo::md5s($newpass, $user->encrypt);
$user->changepass = 0; $user->changepass = 0;
$user->save(); $user->save();
User::token($user); User::generateToken($user);
LdapUser::userUpdate($user->email, ['userPassword' => $newpass]); LdapUser::userUpdate($user->email, ['userPassword' => $newpass]);
return Base::retSuccess('修改成功', $user); return Base::retSuccess('修改成功', $user);
} }
@ -1272,7 +1272,7 @@ class UsersController extends AbstractController
$user->email = $newEmail; $user->email = $newEmail;
$user->save(); $user->save();
User::token($user); User::generateToken($user);
return Base::retSuccess('修改成功', $user); return Base::retSuccess('修改成功', $user);
} }

View File

@ -32,7 +32,7 @@ class WebApi
if (in_array(strtolower($APP_SCHEME), ['https', 'on', 'ssl', '1', 'true', 'yes'], true)) { if (in_array(strtolower($APP_SCHEME), ['https', 'on', 'ssl', '1', 'true', 'yes'], true)) {
$request->setTrustedProxies([$request->getClientIp()], $request::HEADER_X_FORWARDED_PROTO); $request->setTrustedProxies([$request->getClientIp()], $request::HEADER_X_FORWARDED_PROTO);
} }
Doo::init(); Doo::load();
return $next($request); return $next($request);
} }

View File

@ -283,9 +283,9 @@ class User extends AbstractModel
if (!Base::isEmail($email)) { if (!Base::isEmail($email)) {
throw new ApiException('请输入正确的邮箱地址'); throw new ApiException('请输入正确的邮箱地址');
} }
if (User::email2userid($email) > 0) { $user = self::whereEmail($email)->first();
if ($user) {
$isRegVerify = Base::settingFind('emailSetting', 'reg_verify') === 'open'; $isRegVerify = Base::settingFind('emailSetting', 'reg_verify') === 'open';
$user = self::whereUserid(User::email2userid($email))->first();
if ($isRegVerify && $user->email_verity === 0) { if ($isRegVerify && $user->email_verity === 0) {
UserEmailVerification::userEmailSend($user); UserEmailVerification::userEmailSend($user);
throw new ApiException('您的帐号已注册过,请验证邮箱', ['code' => 'email']); throw new ApiException('您的帐号已注册过,请验证邮箱', ['code' => 'email']);
@ -320,73 +320,6 @@ class User extends AbstractModel
return $user->find($user->userid); return $user->find($user->userid);
} }
/**
* 邮箱获取userid
* @param $email
* @return int
*/
public static function email2userid($email)
{
if (empty($email)) {
return 0;
}
return intval(self::whereEmail($email)->value('userid'));
}
/**
* token获取会员userid
* @return int
*/
public static function token2userid()
{
return self::authFind('userid', Base::getToken());
}
/**
* token获取会员邮箱
* @return int
*/
public static function token2email()
{
return self::authFind('email', Base::getToken());
}
/**
* token获取encrypt
* @return mixed|string
*/
public static function token2encrypt()
{
return self::authFind('encrypt', Base::getToken());
}
/**
* 获取token身份信息
* @param $find
* @param null $token
* @return array|mixed|string
*/
public static function authFind($find, $token = null)
{
if ($token === null) {
$token = Base::getToken();
}
list($userid, $email, $encrypt, $timestamp) = explode("#$", base64_decode($token) . "#$#$#$#$");
$array = [
'userid' => intval($userid),
'email' => $email ?: '',
'encrypt' => $encrypt ?: '',
'timestamp' => intval($timestamp),
];
if (isset($array[$find])) {
return $array[$find];
}
if ($find == 'all') {
return $array;
}
return '';
}
/** /**
* 获取我的ID * 获取我的ID
* @return int * @return int
@ -422,9 +355,15 @@ class User extends AbstractModel
{ {
$user = self::authInfo(); $user = self::authInfo();
if (!$user) { if (!$user) {
$authorization = Base::getToken(); if (Base::headerOrInput('token')) {
if ($authorization) { throw new ApiException('身份已失效,请重新登录', [
throw new ApiException('身份已失效,请重新登录', [], -1); 'token' => Base::headerOrInput('token'),
'tokenDecode' => Doo::tokenDecode(Base::headerOrInput('token')),
'userToken' => Doo::userToken(),
'userId' => Doo::userId(),
'userEmail' => Doo::userEmail(),
'userEncrypt' => Doo::userEncrypt(),
], -1);
} else { } else {
throw new ApiException('请登录后继续...', [], -1); throw new ApiException('请登录后继续...', [], -1);
} }
@ -448,61 +387,46 @@ class User extends AbstractModel
if (isset($_A["__static_auth"])) { if (isset($_A["__static_auth"])) {
return $_A["__static_auth"]; return $_A["__static_auth"];
} }
$authorization = Base::getToken(); if (Doo::userId() > 0
if ($authorization) { && !Doo::userExpired()
$authInfo = self::authFind('all', $authorization); && $user = self::whereUserid(Doo::userId())->whereEmail(Doo::userEmail())->whereEncrypt(Doo::userEncrypt())->first()) {
if ($authInfo['userid'] > 0) {
$loginValid = floatval(Base::settingFind('system', 'loginValid')) ?: 720;
$loginValid *= 3600;
if ($authInfo['timestamp'] + $loginValid > time() || $authInfo['timestamp'] === -1) {
$row = self::whereUserid($authInfo['userid'])->whereEmail($authInfo['email'])->whereEncrypt($authInfo['encrypt'])->first();
if ($row) {
if (!$row->bot && $authInfo['timestamp'] === -1) {
return $_A["__static_auth"] = false; // 非机器人token时间不允许-1
}
$upArray = []; $upArray = [];
if (Base::getIp() && $row->line_ip != Base::getIp()) { if (Base::getIp() && $user->line_ip != Base::getIp()) {
$upArray['line_ip'] = Base::getIp(); $upArray['line_ip'] = Base::getIp();
} }
if (Carbon::parse($row->line_at)->addSeconds(30)->lt(Carbon::now())) { if (Carbon::parse($user->line_at)->addSeconds(30)->lt(Carbon::now())) {
$upArray['line_at'] = Carbon::now(); $upArray['line_at'] = Carbon::now();
} }
if ($upArray) { if ($upArray) {
$row->updateInstance($upArray); $user->updateInstance($upArray);
$row->save(); $user->save();
}
return $_A["__static_auth"] = $row;
}
}
} }
return $_A["__static_auth"] = $user;
} }
return $_A["__static_auth"] = false; return $_A["__static_auth"] = false;
} }
/** /**
* 生成token * 生成 token
* @param self $userinfo * @param self $userinfo
* @param bool $force 获取新的token
* @return string * @return string
*/ */
public static function token($userinfo) public static function generateToken($userinfo, $force = false)
{ {
$time = $userinfo->bot ? -1 : time(); if (!$force && Doo::userId() == $userinfo->userid) {
$userinfo->token = base64_encode($userinfo->userid . '#$' . $userinfo->email . '#$' . $userinfo->encrypt . '#$' . $time . '#$' . Base::generatePassword(6)); $token = Doo::userToken();
} else {
if ($userinfo->bot) {
$days = 0;
} else {
$days = max(1, intval(Base::settingFind('system', 'token_valid_days', 7)));
}
$token = Doo::tokenEncode($userinfo->userid, $userinfo->email, $userinfo->encrypt, $days);
}
unset($userinfo->encrypt); unset($userinfo->encrypt);
unset($userinfo->password); unset($userinfo->password);
return $userinfo->token; return $userinfo->token = $token;
}
/**
* 判断用户权限(身份)
* @param $identity
* @param $userIdentity
* @return bool
*/
public static function identityRaw($identity, $userIdentity)
{
$userIdentity = is_array($userIdentity) ? $userIdentity : explode(",", trim($userIdentity, ","));
return $identity && in_array($identity, $userIdentity);
} }
/** /**
@ -536,8 +460,7 @@ class User extends AbstractModel
*/ */
public static function userid2nickname($userid) public static function userid2nickname($userid)
{ {
$basic = self::userid2basic($userid); return self::userid2basic($userid)?->nickname ?: '';
return $basic ? $basic->nickname : '';
} }
/** /**

View File

@ -2019,29 +2019,6 @@ class Base
return $array; return $array;
} }
/**
* 获取tonken
* @return string
*/
public static function getToken()
{
global $_A;
if (!isset($_A["__static_token"])) {
$_A["__static_token"] = self::headerOrInput('token');
}
return $_A["__static_token"];
}
/**
* 设置tonken
* @param $token
*/
public static function setToken($token)
{
global $_A;
$_A["__static_token"] = $token;
}
/** /**
* 是否微信 * 是否微信
* @return bool * @return bool

View File

@ -9,29 +9,28 @@ use FFI;
class Doo class Doo
{ {
public static $doo = null; private static $doo = null;
private static $token = null;
public function __construct() private static $language = null;
{
return self::init();
}
/** /**
* 初始化 * 加载模块
* @return mixed * @param $token
* @param $language
* @return null
*/ */
public static function init() public static function load($token = null, $language = null)
{ {
if (self::$doo === null) { if (self::$doo === null) {
$doo = FFI::cdef(<<<EOF self::$doo = FFI::cdef(<<<EOF
void initialize(char* work, char* lang); void initialize(char* work, char* token, char* lang);
void setUserToken(char* val);
char* license(); char* license();
char* licenseDecode(char* license); char* licenseDecode(char* license);
bool licenseSave(char* license); bool licenseSave(char* license);
int userId(); int userId();
char* userExpiredAt(); char* userExpiredAt();
char* userEmail(); char* userEmail();
char* userEncrypt();
char* userToken(); char* userToken();
char* userCreate(char* email, char* password); char* userCreate(char* email, char* password);
char* tokenEncode(int userid, char* email, char* encrypt, int days); char* tokenEncode(int userid, char* email, char* encrypt, int days);
@ -39,10 +38,10 @@ class Doo
char* translate(char* val, char* val); char* translate(char* val, char* val);
char* md5s(char* text, char* password); char* md5s(char* text, char* password);
EOF, app_path("Module/Lib/doo.so")); EOF, app_path("Module/Lib/doo.so"));
$doo->initialize("/var/www", Base::headerOrInput('language')); self::$token = $token ?: Base::headerOrInput('token');
$doo->setUserToken(Base::getToken()); self::$language = $language ?: Base::headerOrInput('language');
self::$doo = $doo;
} }
self::$doo->initialize("/var/www", self::$token, self::$language);
return self::$doo; return self::$doo;
} }
@ -51,7 +50,7 @@ class Doo
* @param $text * @param $text
* @return string * @return string
*/ */
public static function string($text) private static function string($text)
{ {
return FFI::string($text); return FFI::string($text);
} }
@ -62,7 +61,7 @@ class Doo
*/ */
public static function license() public static function license()
{ {
$array = Base::json2array(self::string(self::init()->license())); $array = Base::json2array(self::string(self::load()->license()));
$ips = explode(",", $array['ip']); $ips = explode(",", $array['ip']);
$array['ip'] = []; $array['ip'] = [];
@ -98,7 +97,7 @@ class Doo
*/ */
public static function licenseDecode($license) public static function licenseDecode($license)
{ {
return Base::json2array(self::string(self::init()->licenseDecode($license))); return Base::json2array(self::string(self::load()->licenseDecode($license)));
} }
/** /**
@ -108,7 +107,7 @@ class Doo
*/ */
public static function licenseSave($license) public static function licenseSave($license)
{ {
return (bool)self::init()->licenseSave($license); return (bool)self::load()->licenseSave($license);
} }
/** /**
@ -117,7 +116,7 @@ class Doo
*/ */
public static function userId() public static function userId()
{ {
return self::init()->userId(); return intval(self::load()->userId());
} }
/** /**
@ -126,7 +125,17 @@ class Doo
*/ */
public static function userExpired() public static function userExpired()
{ {
return Carbon::parse(self::string(self::init()->userExpiredAt()))->isBefore(Carbon::now()); $expiredAt = self::userExpiredAt();
return $expiredAt != 'forever' && Carbon::parse($expiredAt)->isBefore(Carbon::now());
}
/**
* token过期时间来自请求的token
* @return bool
*/
public static function userExpiredAt()
{
return self::string(self::load()->userExpiredAt());
} }
/** /**
@ -135,7 +144,16 @@ class Doo
*/ */
public static function userEmail() public static function userEmail()
{ {
return self::string(self::init()->userEmail()); return self::string(self::load()->userEmail());
}
/**
* 当前会员Encrypt来自请求的token
* @return string
*/
public static function userEncrypt()
{
return self::string(self::load()->userEncrypt());
} }
/** /**
@ -144,7 +162,7 @@ class Doo
*/ */
public static function userToken() public static function userToken()
{ {
return self::string(self::init()->userToken()); return self::string(self::load()->userToken());
} }
/** /**
@ -155,7 +173,7 @@ class Doo
*/ */
public static function userCreate($email, $password) public static function userCreate($email, $password)
{ {
$data = Base::json2array(self::string(self::init()->userCreate($email, $password))); $data = Base::json2array(self::string(self::load()->userCreate($email, $password)));
if (Base::isError($data)) { if (Base::isError($data)) {
throw new ApiException($data['msg'] ?: '注册失败'); throw new ApiException($data['msg'] ?: '注册失败');
} }
@ -176,7 +194,7 @@ class Doo
*/ */
public static function tokenEncode($userid, $email, $encrypt, $days = 7) public static function tokenEncode($userid, $email, $encrypt, $days = 7)
{ {
return self::string(self::init()->tokenEncode($userid, $email, $encrypt, $days)); return self::string(self::load()->tokenEncode($userid, $email, $encrypt, $days));
} }
/** /**
@ -186,9 +204,7 @@ class Doo
*/ */
public static function tokenDecode($token) public static function tokenDecode($token)
{ {
$array = Base::json2array(self::string(self::init()->tokenDecode($token))); return Base::json2array(self::string(self::load()->tokenDecode($token)));
$array['is_expired'] = Carbon::parse($array['expired_at'])->isBefore(Carbon::now());
return $array;
} }
/** /**
@ -199,7 +215,7 @@ class Doo
*/ */
public static function translate($text, $type = "") public static function translate($text, $type = "")
{ {
return self::string(self::init()->translate($text, $type)); return self::string(self::load()->translate($text, $type));
} }
/** /**
@ -210,6 +226,6 @@ class Doo
*/ */
public static function md5s($text, $password = "") public static function md5s($text, $password = "")
{ {
return self::string(self::init()->md5s($text, $password)); return self::string(self::load()->md5s($text, $password));
} }
} }

View File

@ -82,6 +82,7 @@ extern GoUint8 licenseSave(char* license);
extern int userId(); extern int userId();
extern char* userExpiredAt(); extern char* userExpiredAt();
extern char* userEmail(); extern char* userEmail();
extern char* userEncrypt();
extern char* userToken(); extern char* userToken();
extern char* userCreate(char* email, char* password); extern char* userCreate(char* email, char* password);
extern char* tokenEncode(int userid, char* email, char* encrypt, int days); extern char* tokenEncode(int userid, char* email, char* encrypt, int days);

Binary file not shown.

View File

@ -8,6 +8,7 @@ use App\Models\User;
use App\Models\WebSocket; use App\Models\WebSocket;
use App\Models\WebSocketDialogMsg; use App\Models\WebSocketDialogMsg;
use App\Module\Base; use App\Module\Base;
use App\Module\Doo;
use App\Tasks\LineTask; use App\Tasks\LineTask;
use App\Tasks\PushTask; use App\Tasks\PushTask;
use Cache; use Cache;
@ -39,45 +40,23 @@ class WebSocketService implements WebSocketHandlerInterface
*/ */
public function onOpen(Server $server, Request $request) public function onOpen(Server $server, Request $request)
{ {
global $_A;
$_A = [
'__static_langdata' => [],
];
$fd = $request->fd; $fd = $request->fd;
$data = Base::newTrim($request->get); $get = Base::newTrim($request->get);
$action = $data['action']; $action = $get['action'];
switch ($action) { switch ($action) {
/** /**
* 网页访问 * 网页访问
*/ */
case 'web': case 'web':
{ {
// 判断token参数 Doo::load($get['token'], $get['language']);
$token = $data['token']; //
$cacheKey = "ws::token:" . md5($token); if (Doo::userId() > 0
$userid = Cache::remember($cacheKey, now()->addSeconds(1), function () use ($token) { && !Doo::userExpired()
$authInfo = User::authFind('all', $token); && $user = User::whereUserid(Doo::userId())->whereEmail(Doo::userEmail())->whereEncrypt(Doo::userEncrypt())->first()) {
if ($authInfo['userid'] > 0) { // 保存用户
if (User::whereUserid($authInfo['userid'])->whereEmail($authInfo['email'])->whereEncrypt($authInfo['encrypt'])->exists()) { $this->saveUser($fd, $user->userid);
return $authInfo['userid']; // 发送open事件
}
}
return 0;
});
if (empty($userid)) {
Cache::forget($cacheKey);
$server->push($fd, Base::array2json([
'type' => 'error',
'data' => [
'error' => '成员不存在'
],
]));
$server->close($fd);
$this->deleteUser($fd);
return;
}
// 保存用户、发送open事件
$this->saveUser($fd, $userid);
$server->push($fd, Base::array2json([ $server->push($fd, Base::array2json([
'type' => 'open', 'type' => 'open',
'data' => [ 'data' => [
@ -85,9 +64,20 @@ class WebSocketService implements WebSocketHandlerInterface
], ],
])); ]));
// 通知上线 // 通知上线
Task::deliver(new LineTask($userid, true)); Task::deliver(new LineTask($user->userid, true));
// 推送离线时收到的消息 // 推送离线时收到的消息
Task::deliver(new PushTask("RETRY::" . $userid)); Task::deliver(new PushTask("RETRY::" . $user->userid));
} else {
// 用户不存在
$server->push($fd, Base::array2json([
'type' => 'error',
'data' => [
'error' => 'No member'
],
]));
$server->close($fd);
$this->deleteUser($fd);
}
} }
break; break;
@ -103,11 +93,6 @@ class WebSocketService implements WebSocketHandlerInterface
*/ */
public function onMessage(Server $server, Frame $frame) public function onMessage(Server $server, Frame $frame)
{ {
global $_A;
$_A = [
'__static_langdata' => [],
];
//
$msg = Base::json2array($frame->data); $msg = Base::json2array($frame->data);
$type = $msg['type']; // 消息类型 $type = $msg['type']; // 消息类型
$msgId = $msg['msgId']; // 消息ID用于回调 $msgId = $msg['msgId']; // 消息ID用于回调

View File

@ -222,7 +222,7 @@ class BotReceiveMsgTask extends AbstractTask
$botId = $isManager ? $array[1] : $botUser->userid; $botId = $isManager ? $array[1] : $botUser->userid;
$data = $this->botManagerOne($botId, $msg->userid); $data = $this->botManagerOne($botId, $msg->userid);
if ($data) { if ($data) {
User::token($data); User::generateToken($data);
} else { } else {
$type = "notice"; $type = "notice";
$notice = "机器人不存在。"; $notice = "机器人不存在。";
@ -345,7 +345,7 @@ class BotReceiveMsgTask extends AbstractTask
if ($userBot && preg_match("/^https*:\/\//", $userBot->webhook_url)) { if ($userBot && preg_match("/^https*:\/\//", $userBot->webhook_url)) {
Ihttp::ihttp_post($userBot->webhook_url, [ Ihttp::ihttp_post($userBot->webhook_url, [
'text' => $command, 'text' => $command,
'token' => User::token($botUser), 'token' => User::generateToken($botUser),
'dialog_id' => $msg->dialog_id, 'dialog_id' => $msg->dialog_id,
'msg_id' => $msg->id, 'msg_id' => $msg->id,
'msg_uid' => $msg->userid, 'msg_uid' => $msg->userid,

1
cmd
View File

@ -345,6 +345,7 @@ if [ $# -gt 0 ]; then
;; ;;
esac esac
$COMPOSE down $COMPOSE down
env_set APP_DEBUG "false"
rm -rf "./docker/mysql/data" rm -rf "./docker/mysql/data"
rm -rf "./docker/log/supervisor" rm -rf "./docker/log/supervisor"
find "./storage/logs" -name "*.log" | xargs rm -rf find "./storage/logs" -name "*.log" | xargs rm -rf