1、系统配置修改上线 2、 pinia取代vuex

This commit is contained in:
zhangtao
2025-01-10 10:39:15 +08:00
parent 8d9a64aed3
commit 1ae731eafe
21 changed files with 379 additions and 568 deletions
@@ -19,26 +19,23 @@ from app.api.v1.services.system.config_service import ConfigService
router = APIRouter(route_class=OperationLogRoute)
@router.get("/list", summary="查询配置", description="查询配置")
@router.get("/info", summary="获取配置", description="获取配置")
async def get_obj_list(
page: PaginationQueryParams = Depends(),
search: ConfigQueryParams = Depends(),
auth: AuthSchema = Depends(AuthPermission(permissions=["system:config:query"])),
) -> JSONResponse:
result_dict_list = await ConfigService.list_services(auth=auth, search=search, order_by=page.order_by)
result_dict = await PaginationService.get_page_obj(data_list=result_dict_list, page_no=page.page_no, page_size=page.page_size)
logger.info(f"{auth.user.name} 查询配置列表成功")
result_dict = await ConfigService.get_services(auth=auth, id=1)
logger.info(f"{auth.user.name} 获取配置成功")
return SuccessResponse(data=result_dict, msg="查询配置列表成功")
@router.put("/batch", summary="批量修改配置", description="批量修改配置")
async def batch_objs(
@router.put("/update", summary="修改配置", description="修改配置")
async def update_objs(
request: Request,
data: List[ConfigUpdateSchema],
data: ConfigUpdateSchema,
auth: AuthSchema = Depends(AuthPermission(permissions=["system:config:update"])),
) -> JSONResponse:
result_list_dict = await ConfigService.batch_services(auth=auth, request=request, data=data)
logger.info(f"{auth.user.name} 批量更新配置成功 {result_list_dict}")
return SuccessResponse(data=result_list_dict, msg="批量更新配置成功")
result_dict = await ConfigService.update_services(auth=auth, request=request, data=data)
logger.info(f"{auth.user.name} 更新配置成功 {result_dict}")
return SuccessResponse(data=result_dict, msg="更新配置成功")
@router.post("/upload", summary="上传文件", dependencies=[Depends(AuthPermission(permissions=["system:config:upload"]))])
async def upload_file(
@@ -16,10 +16,10 @@ class ConfigCRUD(CRUDBase[ConfigModel, ConfigCreateSchema, ConfigUpdateSchema]):
self.auth = auth
super().__init__(model=ConfigModel, auth=auth)
async def list_curd(self, search: Dict = None, order_by: List[Dict[str, str]] = None) -> Sequence[ConfigModel]:
"""获取配置列表"""
return await self.list(search=search, order_by=order_by)
async def get_curd(self, id: int) -> Optional[ConfigModel]:
"""获取配置"""
return await self.get(id=id)
async def update_curd(self, id: int, data: ConfigUpdateSchema) -> Optional[ConfigModel]:
"""更新配置"""
return await self.update(id=id, data=data)
@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
from sqlalchemy import Boolean, Column, ForeignKey, String, Integer, Text, DateTime, JSON
from sqlalchemy.orm import relationship
from sqlalchemy import Column, String, Integer
from app.core.base_model import ModelBase
@@ -15,21 +14,15 @@ class ConfigModel(ModelBase):
# 基础字段
id = Column(Integer, primary_key=True, autoincrement=True, unique=True, comment='主键ID')
name = Column(String(40), nullable=False, comment="配置名称", unique=True)
order = Column(Integer, nullable=False, default=1, comment="显示排序")
fied_key = Column(String(100), nullable=False, comment="", unique=True)
fied_value = Column(Text, nullable=True, comment="")
# 层级关系
parent_id = Column(
Integer,
ForeignKey("system_config.id", ondelete="CASCADE", onupdate="CASCADE"),
nullable=True,
index=True,
comment="父级配置ID"
)
parent = relationship(
"ConfigModel",
cascade='all, delete-orphan',
uselist=False
)
title = Column(String(40), nullable=False, default="FastAPI Vue Admin", comment="网站标题")
favicon = Column(String(100), nullable=False, default="http://localhost:8000/api/v1/static/upload/image/png/2025/01/09/logo_20250109090456A114.png", comment="网站favicon")
logo = Column(String(100), nullable=False, default="http://localhost:8000/api/v1/static/upload/image/png/2025/01/09/logo_20250109090448A263.png", comment="网站logo")
background = Column(String(100), nullable=False, default="http://localhost:8000/api/v1/static/upload/image/png/2025/01/09/background_20250109090435A357.png", comment="网站背景")
description = Column(String(100), nullable=False, default="FastAPI Vue Admin 是完全开源的权限管理系统", comment="网站描述")
copyright = Column(String(100), nullable=False, default="Copyright © 2021-2025 fastapi-vue-admin.com 版权所有", comment="版权信息")
keep_record = Column(String(100), nullable=False, default="晋ICP备18005113号-3", comment="备案信息")
help_url = Column(String(100), nullable=False, default="https://django-vue-admin.com", comment="帮助链接")
privacy_url = Column(String(100), nullable=False, default="https://gitee.com/tao__tao/fastapi_vue_admin/blob/main/docs/clause/privacy.md", comment="隐私政策链接")
clause_url = Column(String(100), nullable=False, default="https://gitee.com/tao__tao/fastapi_vue_admin/blob/main/docs/clause/terms_service.md", comment="服务条款链接")
code_url = Column(String(100), nullable=False, default="https://gitee.com/tao__tao/fastapi_vue_admin.git", comment="源码地址")
@@ -9,11 +9,11 @@ class ConfigQueryParams:
def __init__(
self,
name: Optional[str] = Query(None, description="配置名称", min_length=2, max_length=50),
title: Optional[str] = Query(None, description="网站标题", min_length=2, max_length=50),
) -> None:
super().__init__()
# 模糊查询字段
self.name = ("like", name)
self.title = ("like", title)
@@ -7,18 +7,17 @@ from pydantic import BaseModel, ConfigDict, Field, model_validator
class ConfigCreateSchema(BaseModel):
"""配置创建模型"""
name: str = Field(..., max_length=40, description="配置名称")
order: int = Field(default=1, ge=0, description="显示顺序")
fied_key: str = Field(..., description="")
fied_value: Optional[str] = Field(default=None, description="")
parent_id: Optional[int] = Field(default=None, ge=0, description="父配置ID")
@classmethod
@model_validator(mode='after')
def validate_fields(cls, data):
if not data.name or len(data.name.strip()) == 0:
raise ValueError("配置名称不能为空")
return data
title: str = Field(..., max_length=40, description="网站标题")
favicon: str = Field(..., max_length=100, description="网站favicon")
logo: str = Field(..., max_length=100, description="网站logo")
background: str = Field(..., max_length=100, description="网站背景")
description: str = Field(..., max_length=100, description="网站描述")
copyright: str = Field(..., max_length=100, description="版权信息")
keep_record: str = Field(..., max_length=100, description="备案信息")
help_url: str = Field(..., max_length=100, description="帮助链接")
privacy_url: str = Field(..., max_length=100, description="隐私政策链接")
clause_url: str = Field(..., max_length=100, description="服务条款链接")
code_url: str = Field(..., max_length=100, description="源码地址")
class ConfigUpdateSchema(ConfigCreateSchema):
@@ -1,19 +1,17 @@
# -*- coding: utf-8 -*-
import json
from typing import List, Dict
from typing import Dict
from fastapi import Depends, Request, UploadFile
from fastapi import Request, UploadFile
from sqlalchemy.ext.asyncio import AsyncSession
from aioredis import Redis
from app.api.v1.schemas.system.auth_schema import AuthSchema
from app.api.v1.schemas.system.config_schema import ConfigOutSchema, ConfigUpdateSchema
from app.api.v1.params.system.config_param import ConfigQueryParams
from app.api.v1.cruds.system.config_crud import ConfigCRUD
from app.common.enums import RedisInitKeyConfig
from app.core.cache_crud import Cache
from app.core.dependencies import db_getter
from app.utils.upload_util import UploadUtil
from app.core.base_schema import UploadResponseSchema
from app.core.exceptions import CustomException
@@ -27,20 +25,17 @@ class ConfigService:
"""
@classmethod
async def list_services(cls, auth: AuthSchema, search: ConfigQueryParams = None, order_by: List[Dict[str, str]] = None) -> List[Dict]:
config_obj_list = await ConfigCRUD(auth).list_curd(search=search.__dict__, order_by=order_by)
return [ConfigOutSchema.model_validate(config_obj).model_dump() for config_obj in config_obj_list]
async def get_services(cls, auth: AuthSchema, id: int) -> Dict:
config_obj = await ConfigCRUD(auth).get_curd(id=id)
return ConfigOutSchema.model_validate(config_obj).model_dump()
@classmethod
async def batch_services(cls, auth: AuthSchema, request: Request, data: List[ConfigUpdateSchema]) -> List[Dict]:
result = []
for obj in data:
new_obj = await ConfigCRUD(auth).update_curd(id=obj.id, data=obj)
new_obj_dict = ConfigOutSchema.model_validate(new_obj).model_dump()
result.append(new_obj_dict)
async def update_services(cls, auth: AuthSchema, request: Request, data: ConfigUpdateSchema) -> Dict:
new_obj = await ConfigCRUD(auth).update_curd(id=data.id, data=data)
new_obj_dict = ConfigOutSchema.model_validate(new_obj).model_dump()
cls.init_config(redis=request.app.state.redis, db=auth.db)
return result
return new_obj_dict
@classmethod
async def upload_services(cls, request: Request, file: UploadFile) -> Dict:
@@ -59,19 +54,19 @@ class ConfigService:
@classmethod
async def init_config(cls, redis: Redis, db: AsyncSession):
auth = AuthSchema(db=db)
config_obj_list = await ConfigCRUD(auth).list_curd()
config_obj_list_dict = [ConfigOutSchema.model_validate(config_obj).model_dump() for config_obj in config_obj_list]
config_obj = await ConfigCRUD(auth).get_curd(id=1)
config_obj_dict = ConfigOutSchema.model_validate(config_obj).model_dump()
# 保存到Redis并设置过期时间
redis_key = f"{RedisInitKeyConfig.System_Config.key}:{'init_system_config'}"
try:
value = json.dumps(config_obj_list_dict, ensure_ascii=False)
value = json.dumps(config_obj_dict, ensure_ascii=False)
await Cache(redis).set(
key=redis_key,
value=value,
expire=settings.ACCESS_TOKEN_EXPIRE_MINUTES * 60
)
logger.info(f"初始化系统配置成功: {config_obj_list_dict}")
logger.info(f"初始化系统配置成功: {config_obj_dict}")
except Exception as e:
logger.error(f"初始化系统配置失败: {e}")
raise CustomException(msg="初始化系统配置失败")