From 81ee0d339da1aae2507fc0d7fbd7dcc366169673 Mon Sep 17 00:00:00 2001 From: zhang zhuo Date: Fri, 5 Dec 2025 14:28:14 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Aspect/AuthAspect.php | 7 +-- app/Controller/AbstractController.php | 4 ++ app/Controller/Admin/Login.php | 26 +++++------ app/Controller/Admin/System.php | 27 +++++++++--- app/Event/WebSocket.php | 6 +-- app/Listener/AppBootListener.php | 4 ++ app/Middleware/JWTMiddleware.php | 18 +++++--- app/Model/Dict.php | 15 +++++++ app/Model/Menu.php | 14 +++--- app/Model/Model.php | 1 + app/Service/ConfigCacheService.php | 63 +++++++++++++++++++++++++++ app/Utils/Cache.php | 14 ++++++ config/autoload/cache.php | 2 +- 13 files changed, 157 insertions(+), 44 deletions(-) create mode 100644 app/Service/ConfigCacheService.php create mode 100644 app/Utils/Cache.php diff --git a/app/Aspect/AuthAspect.php b/app/Aspect/AuthAspect.php index 2454b62..793b9cb 100644 --- a/app/Aspect/AuthAspect.php +++ b/app/Aspect/AuthAspect.php @@ -15,6 +15,7 @@ use Hyperf\Di\Aop\ProceedingJoinPoint; use Hyperf\Di\Exception\AnnotationException; use Hyperf\HttpServer\Contract\RequestInterface; use Hyperf\HttpServer\Contract\ResponseInterface; +use Psr\SimpleCache\CacheInterface; #[Aspect] class AuthAspect extends AbstractAspect @@ -23,6 +24,8 @@ class AuthAspect extends AbstractAspect protected RequestInterface $request; #[Inject] protected ResponseInterface $response; + #[Inject] + protected CacheInterface $cache; public array $annotations = [ Auth::class @@ -81,9 +84,7 @@ class AuthAspect extends AbstractAspect */ protected function checkPermission(string $auth, string $method, array $account): bool { if ($auth == "*" || $account['master_flag']) return true; - $container = ApplicationContext::getContainer(); - $redis = $container->get(\Hyperf\Redis\Redis::class); - $auths = $redis->get("AUTH:".$account['account_id']); + $auths = $this->cache->get("AUTH:".$account['account_id']); if (!$auths) return false; $auths = json_decode($auths, true); if (!empty($auths)) { diff --git a/app/Controller/AbstractController.php b/app/Controller/AbstractController.php index 4ce7b3e..4e33faa 100644 --- a/app/Controller/AbstractController.php +++ b/app/Controller/AbstractController.php @@ -10,6 +10,7 @@ use Hyperf\HttpServer\Contract\ResponseInterface; use Hyperf\View\RenderInterface; use Psr\Container\ContainerInterface; use Psr\EventDispatcher\EventDispatcherInterface; +use Psr\SimpleCache\CacheInterface; abstract class AbstractController { @@ -25,6 +26,9 @@ abstract class AbstractController #[Inject] protected EventDispatcherInterface $eventDispatcher; + #[Inject] + protected CacheInterface $cache; + #[Inject] protected RenderInterface $render; } diff --git a/app/Controller/Admin/Login.php b/app/Controller/Admin/Login.php index c52c3ec..e021923 100644 --- a/app/Controller/Admin/Login.php +++ b/app/Controller/Admin/Login.php @@ -13,7 +13,6 @@ use App\Model\Online; use App\Utils\Param; use App\Utils\Str; use App\Utils\Token; -use Hyperf\Context\ApplicationContext; use Hyperf\Filesystem\FilesystemFactory; use Hyperf\HttpServer\Annotation\Controller; use Hyperf\HttpServer\Annotation\GetMapping; @@ -21,6 +20,7 @@ use Hyperf\HttpServer\Annotation\PostMapping; use MathCaptcha\Captcha; use App\Request\Account as aRequest; use function Hyperf\Config\config; +use function Hyperf\Translation\__; #[Controller(prefix: "admin")] class Login extends Base @@ -36,9 +36,7 @@ class Login extends Base $code = $ca->setDigits(1)->setPoint(100)->setLine(2)->setFontSize(24)->result(); $image = $ca->base64(); // 缓存 - $container = ApplicationContext::getContainer(); - $redis = $container->get(\Hyperf\Redis\Redis::class); - $redis->set("VER:" . $uuid, md5((string)$code), 300); + $this->cache->set("VER:" . $uuid, md5((string)$code), 300); return $this->success(compact("uuid", "image")); } @@ -51,17 +49,15 @@ class Login extends Base $request = $this->container->get(aRequest::class); $request->scene('login')->validateResolved(); // 验证码 - $container = ApplicationContext::getContainer(); - $redis = $container->get(\Hyperf\Redis\Redis::class); - $code = $redis->get("VER:" . $param['uuid']); + $code = $this->cache->get("VER:" . $param['uuid']); if (!$code) { - return $this->error("验证码已失效!"); + return $this->error(__("login.codeExpired")); } if ($code != md5($param['code'])) { - return $this->error("验证码填写错误!"); + return $this->error(__("login.codeIncorrect")); } // 验证一次就失效 - $redis->del("VER:" . $param['uuid']); + $this->cache->delete("VER:" . $param['uuid']); // 查找用户 $account = Account::getByUsername($param['username'], ['account_id', 'username', 'password', 'salt', 'status', 'account_type', 'belong_id', 'master_flag', 'nickname', 'dept_id']); // 总后台和代理登录 @@ -91,8 +87,8 @@ class Login extends Base $this->eventDispatcher->dispatch(new LogEvent($tData)); // 根据账号所属角色缓存相应的权限数据 $auths = Account::getAuths($account['account_id'], $account['account_type'], $account['master_flag']); - $redis->set("AUTH:" . $account['account_id'], json_encode($auths)); - $redis->set("USER:" . $uuid, json_encode($tData), config("jwt.ttl")); + $this->cache->set("AUTH:" . $account['account_id'], json_encode($auths)); + $this->cache->set("USER:" . $uuid, json_encode($tData), config("jwt.ttl")); // 生成token return $this->success(compact("token")); } @@ -116,10 +112,8 @@ class Login extends Base public function logout() { // 退出登录状态 - $container = ApplicationContext::getContainer(); - $redis = $container->get(\Hyperf\Redis\Redis::class); - $redis->del("USER:" . $this->uuid()); - $redis->del("AUTH:" . $this->account()['account_id']); + $this->cache->delete("USER:" . $this->uuid()); + $this->cache->delete("AUTH:" . $this->account()['account_id']); // 设置离线 Online::leave($this->uuid()); return $this->success("登出成功"); diff --git a/app/Controller/Admin/System.php b/app/Controller/Admin/System.php index 4e978a9..0b1b833 100644 --- a/app/Controller/Admin/System.php +++ b/app/Controller/Admin/System.php @@ -32,6 +32,7 @@ use App\Model\DictData as ddModel; use App\Request\DictData as ddRequest; use App\Model\Translation as tsModel; use App\Request\Translation as tsRequest; +use App\Service\ConfigCacheService; use App\Utils\AppInfoHelper; use App\Utils\CpuHelper; use App\Utils\DiskInfoHelper; @@ -388,10 +389,8 @@ class System extends Base if (empty($online) || $online['status'] == 0) { return $this->success("用户已不在线"); } - $container = ApplicationContext::getContainer(); - $redis = $container->get(\Hyperf\Redis\Redis::class); - $redis->del("USER:" . $param['session_id']); - $redis->del("AUTH:" . $online['account_id']); + $this->cache->delete("USER:" . $param['session_id']); + $this->cache->delete("AUTH:" . $online['account_id']); // 设置离线 oModel::leave($param['session_id']); return $this->success("强退成功"); @@ -800,7 +799,12 @@ class System extends Base $request = $this->container->get(scRequest::class); $request->scene('add')->validateResolved(); $data = Param::only(["config_name", "config_key", "config_value", "remark"]); - return $this->toAjax(scModel::add($data)); + $res = scModel::add($data); + if (!$res) { + return $this->error(); + } + (new ConfigCacheService())->setItem($data['config_key'], $data['config_value']); + return $this->success(); } #[PutMapping(path: "system_config/edit")] @@ -810,7 +814,16 @@ class System extends Base $request = $this->container->get(scRequest::class); $request->scene('edit')->validateResolved(); $data = Param::only(["config_id", "config_name", "config_key", "config_value", "remark"]); - return $this->toAjax(scModel::edit($data)); + // 删除原来的缓存 + $info = scModel::getById($data['config_id'],['config_key']); + (new ConfigCacheService())->removeItem($info['config_key']); + // 变更数据 + $res = scModel::edit($data); + if (!$res) { + return $this->error(); + } + (new ConfigCacheService())->setItem($data['config_key'], $data['config_value']); + return $this->success(); } #[DeleteMapping(path: "system_config/del")] @@ -818,6 +831,8 @@ class System extends Base public function systemConfigDel() { $ids = $this->request->input("ids"); + $data = scModel::whereIn("config_id", $ids)->pluck("config_key")->toArray(); + (new ConfigCacheService())->multipleRemoveItem($data); return $this->toAjax(scModel::del($ids)); } diff --git a/app/Event/WebSocket.php b/app/Event/WebSocket.php index 0a75d74..527a525 100644 --- a/app/Event/WebSocket.php +++ b/app/Event/WebSocket.php @@ -12,6 +12,7 @@ use Hyperf\Contract\OnCloseInterface; use Hyperf\Contract\OnMessageInterface; use Hyperf\Contract\OnOpenInterface; use Hyperf\WebSocketServer\Context; +use Psr\SimpleCache\CacheInterface; /** * 商户端socket @@ -44,10 +45,9 @@ class WebSocket implements OnMessageInterface, OnOpenInterface, OnCloseInterface { $token = $request->get['Authorization']; $result = Token::parseToken(str_replace("Bearer ", "", $token)); - $container = ApplicationContext::getContainer(); - $redis = $container->get(\Hyperf\Redis\Redis::class); - $account = !empty($result) ? json_decode($redis->get("USER:" . $result['uuid']), true) : null; + $cache = $container->get(CacheInterface::class); + $account = !empty($result) ? json_decode($cache->get("USER:" . $result['uuid']), true) : null; if (!empty($account)) { Online::live($result['uuid'], $request->fd); Context::set('account', $account); diff --git a/app/Listener/AppBootListener.php b/app/Listener/AppBootListener.php index 5130ed4..f7baaf9 100644 --- a/app/Listener/AppBootListener.php +++ b/app/Listener/AppBootListener.php @@ -2,6 +2,8 @@ namespace App\Listener; +use App\Service\ConfigCacheService; +use App\Service\DictCacheService; use App\Utils\AppInfoHelper; use Hyperf\Event\Annotation\Listener; use Hyperf\Event\Contract\ListenerInterface; @@ -19,5 +21,7 @@ class AppBootListener implements ListenerInterface { // 在框架启动时初始化启动时间 AppInfoHelper::initStartTime(); + // 初始化配置项缓存 + (new ConfigCacheService())->loadAll(); } } \ No newline at end of file diff --git a/app/Middleware/JWTMiddleware.php b/app/Middleware/JWTMiddleware.php index cb3d5e0..f1d04c2 100644 --- a/app/Middleware/JWTMiddleware.php +++ b/app/Middleware/JWTMiddleware.php @@ -13,6 +13,7 @@ use Psr\Http\Message\ResponseInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; +use Psr\SimpleCache\CacheInterface; use function Hyperf\Config\config; class JWTMiddleware implements MiddlewareInterface @@ -20,11 +21,17 @@ class JWTMiddleware implements MiddlewareInterface /** * @var ContainerInterface */ - protected $container; + protected ContainerInterface $container; - public function __construct(ContainerInterface $container) + /** + * @var CacheInterface + */ + protected CacheInterface $cache; + + public function __construct(ContainerInterface $container, CacheInterface $cache) { $this->container = $container; + $this->cache = $cache; } /** @@ -36,7 +43,6 @@ class JWTMiddleware implements MiddlewareInterface public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { $container = ApplicationContext::getContainer(); - $redis = $container->get(\Hyperf\Redis\Redis::class); // 管理端 和 商户端 $request = $request->withAttribute("isLogin", false); $request = $request->withAttribute("account", []); @@ -45,7 +51,7 @@ class JWTMiddleware implements MiddlewareInterface $token = $request->getHeaderLine("Authorization", ""); $result = Token::parseToken(str_replace("Bearer ", "", $token)); if (!empty($result)) { - $user = $redis->get("USER:" . $result['uuid']); + $user = $this->cache->get("USER:" . $result['uuid']); if (!empty($user)) { $account = json_decode($user, true); } @@ -54,7 +60,7 @@ class JWTMiddleware implements MiddlewareInterface if (!empty($account)) { // 是否登录 $request = $request->withAttribute("isLogin", true); - $account = json_decode($redis->get("USER:" . $result['uuid']), true); + $account = json_decode($this->cache->get("USER:" . $result['uuid']), true); // 账号ID $request = $request->withAttribute("account_id", $account['account_id']); // 基础信息 @@ -71,7 +77,7 @@ class JWTMiddleware implements MiddlewareInterface $newToken = Token::buildToken(['uuid' => $result['uuid'], 'time' => time() + config("jwt.ttl")], config("jwt.ttl")); $response = $response->withHeader('X-Token-Refresh', $newToken); $response = $response->withHeader('X-Token-Expire', config("jwt.ttl")); - $redis->set("USER:" . $result['uuid'], json_encode($account), config("jwt.ttl")); + $this->cache->set("USER:" . $result['uuid'], json_encode($account), config("jwt.ttl")); } return $response; } diff --git a/app/Model/Dict.php b/app/Model/Dict.php index 5be2998..63c4379 100644 --- a/app/Model/Dict.php +++ b/app/Model/Dict.php @@ -50,4 +50,19 @@ class Dict extends Model { return self::select(["dict_id", "dict_name"])->get()->toArray(); } + + public static function getAll() + { + return self::with(["values" => function ($query) { + $query->select(["dict_label", "dict_value", "is_default"]); + }]) + ->select(["dict_type", "dict_id"]) + ->get() + ->toArray(); + } + + protected function values() + { + return $this->hasMany(DictData::class, "dict_id", "dict_id"); + } } diff --git a/app/Model/Menu.php b/app/Model/Menu.php index 34a1f7a..dbae785 100644 --- a/app/Model/Menu.php +++ b/app/Model/Menu.php @@ -4,9 +4,8 @@ declare(strict_types=1); namespace App\Model; -use Hyperf\Context\ApplicationContext; +use App\Utils\Cache; use Hyperf\DbConnection\Db; -use function Hyperf\Config\config; /** * @property int $menu_id @@ -27,6 +26,7 @@ use function Hyperf\Config\config; */ class Menu extends Model { + use Cache; /** * The table associated with the model. */ @@ -90,9 +90,7 @@ class Menu extends Model public static function getTitleByCache($method, $flag, $account_type) { // 先从缓存取数据,缓存中没则从数据库中取数据 - $container = ApplicationContext::getContainer(); - $redis = $container->get(\Hyperf\Redis\Redis::class); - $menus = $redis->get("AUTH:" . $account_type); + $menus = self::cache()->get("AUTH:" . $account_type); if (!empty($menus) && isset($menus[$method . ":" . $flag])) { // 存在则从缓存中读取 return $menus[$method . ":" . $flag]; @@ -114,7 +112,7 @@ class Menu extends Model /** * Author: cfn * @param $account_type - * @return bool|\Redis + * @return bool */ private static function setCache($account_type) { @@ -126,9 +124,7 @@ class Menu extends Model foreach ($arr as $v) { $newArr[$v['title']] = $v['flag']; } - $container = ApplicationContext::getContainer(); - $redis = $container->get(\Hyperf\Redis\Redis::class); - return $redis->set("AUTH:" . $account_type, json_encode($newArr), 72 * 60 * 60); + return self::cache()->set("AUTH:" . $account_type, json_encode($newArr), 72 * 60 * 60); } /** diff --git a/app/Model/Model.php b/app/Model/Model.php index 5958844..0faab0e 100644 --- a/app/Model/Model.php +++ b/app/Model/Model.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace App\Model; +use App\Utils\Cache; use App\Utils\Crud; use Hyperf\Database\Model\SoftDeletes; use Hyperf\DbConnection\Model\Model as BaseModel; diff --git a/app/Service/ConfigCacheService.php b/app/Service/ConfigCacheService.php new file mode 100644 index 0000000..c69d472 --- /dev/null +++ b/app/Service/ConfigCacheService.php @@ -0,0 +1,63 @@ +cache = ApplicationContext::getContainer()->get(CacheInterface::class); + } + + public function loadAll(): void + { + // 加载所有配置项 + $configs = scModel::pluck("config_value", "config_key")->toArray(); + if (!empty($configs)) { + $configs = array_combine( + array_map(fn($k) => $this->prefix . "$k", array_keys($configs)), + $configs + ); + $this->cache->setMultiple($configs); + } + } + + public function clearAll(): void + { + // 加载所有配置项 + $configs = scModel::pluck("config_key")->toArray(); + if (!empty($configs)) { + $keys = array_map(fn($k) => $this->prefix . "$k", $configs); + $this->cache->deleteMultiple($keys); + } + } + + public function setItem(string $key, string|null $value): bool + { + return $this->cache->set($this->prefix . $key, $value); + } + + public function getItem(string $key): mixed + { + return $this->cache->get($this->prefix . $key); + } + + public function removeItem(string $key): bool + { + return $this->cache->delete($this->prefix . $key); + } + + public function multipleRemoveItem(array $keys): bool + { + if (count($keys) === 0) return true; + $keys = array_map(fn($k) => $this->prefix . "$k", $keys); + return $this->cache->deleteMultiple($keys); + } +} \ No newline at end of file diff --git a/app/Utils/Cache.php b/app/Utils/Cache.php new file mode 100644 index 0000000..42eb208 --- /dev/null +++ b/app/Utils/Cache.php @@ -0,0 +1,14 @@ +get(CacheInterface::class); + } +} \ No newline at end of file diff --git a/config/autoload/cache.php b/config/autoload/cache.php index 24d0e5b..38f141f 100644 --- a/config/autoload/cache.php +++ b/config/autoload/cache.php @@ -13,7 +13,7 @@ return [ 'default' => [ 'driver' => Hyperf\Cache\Driver\RedisDriver::class, 'packer' => Hyperf\Codec\Packer\PhpSerializerPacker::class, - 'prefix' => 'c:', + 'prefix' => 'pi:', 'skip_cache_results' => [], ], ];