mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-20 20:39:55 +00:00
1、系统配置修改上线 2、 pinia取代vuex
This commit is contained in:
@@ -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="初始化系统配置失败")
|
||||
|
||||
Reference in New Issue
Block a user