#!/usr/bin/python # -*- coding: utf-8 -*- # @version : 1.0 # @Create Time : 2022/3/21 11:03 # @File : cache.py # @IDE : PyCharm # @desc : 缓存 from typing import List from sqlalchemy import false from sqlalchemy.future import select from sqlalchemy.orm import joinedload from core.logger import logger # 注意:报错就在这里,如果只写 core.logger 会写入日志报错,很难排查 from core.database import db_getter from apps.vadmin.system.models import VadminSystemSettingsTab import json from redis.asyncio.client import Redis from core.exception import CustomException from utils import status class Cache: DEFAULT_TAB_NAMES = ["wx_server", "aliyun_sms", "aliyun_oss", "web_email"] def __init__(self, rd: Redis): self.rd = rd async def __get_tab_name_values(self, tab_names: List[str]): """ 获取系统配置标签下的标签信息 """ async_session = db_getter() session = await async_session.__anext__() model = VadminSystemSettingsTab v_options = [joinedload(model.settings)] sql = select(model).where( model.is_delete == false(), model.tab_name.in_(tab_names), model.disabled == false() ).options(*[load for load in v_options]) queryset = await session.execute(sql) datas = queryset.scalars().unique().all() return self.__generate_values(datas) @classmethod def __generate_values(cls, datas: List[VadminSystemSettingsTab]): """ 生成字典值 """ return { tab.tab_name: { item.config_key: item.config_value for item in tab.settings if not item.disabled } for tab in datas } async def cache_tab_names(self, tab_names: List[str] = None): """ 缓存系统配置 如果手动修改了mysql数据库中的配置 那么需要在redis中将对应的tab_name删除 """ if not tab_names: tab_names = self.DEFAULT_TAB_NAMES datas = await self.__get_tab_name_values(tab_names) for k, v in datas.items(): await self.rd.client().set(k, json.dumps(v)) async def get_tab_name(self, tab_name: str, retry: int = 3): """ 获取系统配置 :param tab_name: 配置表标签名称 :param retry: 重试次数 """ result = await self.rd.get(tab_name) if not result and retry > 0: logger.error(f"未从Redis中获取到{tab_name}配置信息,正在重新更新配置信息,重试次数:{retry}。") await self.cache_tab_names([tab_name]) return await self.get_tab_name(tab_name, retry - 1) elif not result and retry == 0: raise CustomException(f"获取{tab_name}配置信息失败,请联系管理员!", code=status.HTTP_ERROR) else: return json.loads(result)