diff --git a/backend/auth/apps/settings/urls.py b/backend/auth/apps/settings/urls.py index 3c72af9..c3f4b33 100644 --- a/backend/auth/apps/settings/urls.py +++ b/backend/auth/apps/settings/urls.py @@ -1,7 +1,11 @@ -from fastapi import APIRouter, Depends, HTTPException +from fastapi import APIRouter, Depends, HTTPException, File, UploadFile from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, and_ from fastcrud import FastCRUD +from pathlib import Path +import os +import shutil +from datetime import datetime from database import get_db from models import SystemSetting, User @@ -18,6 +22,10 @@ router = APIRouter(prefix="/settings", tags=["settings"]) # 创建FastCRUD实例 setting_crud = FastCRUD(SystemSetting, SystemSettingResponse) +# 图片存储目录 +UPLOAD_DIR = Path(__file__).parent.parent.parent / "uploads" +UPLOAD_DIR.mkdir(exist_ok=True) + @router.post("/", response_model=SystemSettingResponse) async def create_setting( @@ -36,6 +44,8 @@ async def create_setting( db_setting = SystemSetting( key=setting_data.key, value=setting_data.value, + type=setting_data.type or "string", + options=setting_data.options, description=setting_data.description, ) @@ -129,3 +139,39 @@ async def delete_setting( # 使用FastCRUD删除设置 deleted = await setting_crud.delete(db, id=setting_id) return {"message": "设置项删除成功"} + + +@router.post("/upload") +async def upload_image( + file: UploadFile = File(...), + current_user: User = Depends(get_current_user), +): + """上传图片""" + # 检查文件类型 + if not file.filename or not file.filename.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.webp')): + raise HTTPException(status_code=400, detail="只支持图片格式(png, jpg, jpeg, gif, webp)") + + # 检查文件大小(2MB) + file_size = 0 + chunk = await file.read(1024) + while chunk: + file_size += len(chunk) + if file_size > 2 * 1024 * 1024: + raise HTTPException(status_code=400, detail="文件大小不能超过2MB") + chunk = await file.read(1024) + + # 重置文件指针 + await file.seek(0) + + # 生成文件名 + timestamp = datetime.now().strftime("%Y%m%d%H%M%S") + ext = file.filename.split('.')[-1] + filename = f"setting_{timestamp}.{ext}" + file_path = UPLOAD_DIR / filename + + # 保存文件 + with open(file_path, "wb") as buffer: + shutil.copyfileobj(file.file, buffer) + + # 返回文件路径 + return {"url": f"/uploads/{filename}"} diff --git a/backend/auth/init_data.py b/backend/auth/init_data.py index 365df89..d4838b6 100644 --- a/backend/auth/init_data.py +++ b/backend/auth/init_data.py @@ -50,49 +50,71 @@ async def init_permissions(db: AsyncSession): # 定义需要初始化的权限(树形结构) # parentid: 0 = 顶级模块, >0 = 子权限 permission_tree = [ + # ======================================== # 顶级模块 + # ======================================== {"name": "权限管理", "code": "perm", "parentid": 0, "description": "权限管理模块"}, + {"name": "系统设置", "code": "system", "parentid": 0, "description": "系统设置模块"}, - # 二级子模块 + # ======================================== + # 权限管理 -> 二级子模块 + # ======================================== {"name": "用户管理", "code": "perm:user", "parentid": 1, "description": "用户管理子模块"}, {"name": "角色管理", "code": "perm:role", "parentid": 1, "description": "角色管理子模块"}, {"name": "权限配置", "code": "perm:config", "parentid": 1, "description": "权限配置子模块"}, - {"name": "系统设置", "code": "perm:system", "parentid": 1, "description": "系统设置子模块"}, - # 用户管理操作 - {"name": "查看列表", "code": "perm:user:list", "parentid": 2, "description": "查看用户列表"}, - {"name": "查看详情", "code": "perm:user:detail", "parentid": 2, "description": "查看用户详情"}, - {"name": "搜索", "code": "perm:user:search", "parentid": 2, "description": "搜索用户"}, - {"name": "创建", "code": "perm:user:create", "parentid": 2, "description": "创建新用户"}, - {"name": "编辑", "code": "perm:user:edit", "parentid": 2, "description": "编辑用户信息"}, - {"name": "删除", "code": "perm:user:delete", "parentid": 2, "description": "删除用户"}, - {"name": "导出", "code": "perm:user:export", "parentid": 2, "description": "导出用户数据"}, + # ======================================== + # 系统设置 -> 二级子模块 + # ======================================== + {"name": "基础配置", "code": "system:basic", "parentid": 2, "description": "系统基础配置"}, + {"name": "高级配置", "code": "system:advanced", "parentid": 2, "description": "系统高级配置"}, - # 角色管理操作 - {"name": "查看列表", "code": "perm:role:list", "parentid": 3, "description": "查看角色列表"}, - {"name": "查看详情", "code": "perm:role:detail", "parentid": 3, "description": "查看角色详情"}, - {"name": "搜索", "code": "perm:role:search", "parentid": 3, "description": "搜索角色"}, - {"name": "创建", "code": "perm:role:create", "parentid": 3, "description": "创建新角色"}, - {"name": "编辑", "code": "perm:role:edit", "parentid": 3, "description": "编辑角色信息"}, - {"name": "删除", "code": "perm:role:delete", "parentid": 3, "description": "删除角色"}, - {"name": "导出", "code": "perm:role:export", "parentid": 3, "description": "导出角色数据"}, - {"name": "分配权限", "code": "perm:role:assign", "parentid": 3, "description": "为角色分配权限"}, + # ======================================== + # 用户管理操作(parentid=3) + # ======================================== + {"name": "查看列表", "code": "perm:user:list", "parentid": 3, "description": "查看用户列表"}, + {"name": "查看详情", "code": "perm:user:detail", "parentid": 3, "description": "查看用户详情"}, + {"name": "搜索", "code": "perm:user:search", "parentid": 3, "description": "搜索用户"}, + {"name": "创建", "code": "perm:user:create", "parentid": 3, "description": "创建新用户"}, + {"name": "编辑", "code": "perm:user:edit", "parentid": 3, "description": "编辑用户信息"}, + {"name": "删除", "code": "perm:user:delete", "parentid": 3, "description": "删除用户"}, + {"name": "导出", "code": "perm:user:export", "parentid": 3, "description": "导出用户数据"}, + {"name": "批量操作", "code": "perm:user:batch", "parentid": 3, "description": "批量操作用户"}, - # 权限配置操作 - {"name": "查看列表", "code": "perm:config:list", "parentid": 4, "description": "查看权限列表"}, - {"name": "查看详情", "code": "perm:config:detail", "parentid": 4, "description": "查看权限详情"}, - {"name": "搜索", "code": "perm:config:search", "parentid": 4, "description": "搜索权限"}, - {"name": "创建", "code": "perm:config:create", "parentid": 4, "description": "创建新权限"}, - {"name": "编辑", "code": "perm:config:edit", "parentid": 4, "description": "编辑权限信息"}, - {"name": "删除", "code": "perm:config:delete", "parentid": 4, "description": "删除权限"}, - {"name": "导出", "code": "perm:config:export", "parentid": 4, "description": "导岀权限数据"}, + # ======================================== + # 角色管理操作(parentid=4) + # ======================================== + {"name": "查看列表", "code": "perm:role:list", "parentid": 4, "description": "查看角色列表"}, + {"name": "查看详情", "code": "perm:role:detail", "parentid": 4, "description": "查看角色详情"}, + {"name": "搜索", "code": "perm:role:search", "parentid": 4, "description": "搜索角色"}, + {"name": "创建", "code": "perm:role:create", "parentid": 4, "description": "创建新角色"}, + {"name": "编辑", "code": "perm:role:edit", "parentid": 4, "description": "编辑角色信息"}, + {"name": "删除", "code": "perm:role:delete", "parentid": 4, "description": "删除角色"}, + {"name": "导出", "code": "perm:role:export", "parentid": 4, "description": "导出角色数据"}, + {"name": "分配权限", "code": "perm:role:assign", "parentid": 4, "description": "为角色分配权限"}, - # 系统设置操作(parentid 为 5,对应系统设置子模块) - {"name": "查看列表", "code": "perm:system:list", "parentid": 5, "description": "查看系统设置列表"}, - {"name": "查看详情", "code": "perm:system:detail", "parentid": 5, "description": "查看系统设置详情"}, - {"name": "创建", "code": "perm:system:create", "parentid": 5, "description": "创建设置项"}, - {"name": "编辑", "code": "perm:system:edit", "parentid": 5, "description": "编辑设置项"}, - {"name": "删除", "code": "perm:system:delete", "parentid": 5, "description": "删除设置项"}, + # ======================================== + # 权限配置操作(parentid=5) + # ======================================== + {"name": "查看列表", "code": "perm:config:list", "parentid": 5, "description": "查看权限列表"}, + {"name": "查看详情", "code": "perm:config:detail", "parentid": 5, "description": "查看权限详情"}, + {"name": "搜索", "code": "perm:config:search", "parentid": 5, "description": "搜索权限"}, + {"name": "创建", "code": "perm:config:create", "parentid": 5, "description": "创建新权限"}, + {"name": "编辑", "code": "perm:config:edit", "parentid": 5, "description": "编辑权限信息"}, + {"name": "删除", "code": "perm:config:delete", "parentid": 5, "description": "删除权限"}, + {"name": "导出", "code": "perm:config:export", "parentid": 5, "description": "导岀权限数据"}, + + # ======================================== + # 系统设置 -> 基础配置操作(parentid=6) + # ======================================== + {"name": "查看配置", "code": "system:basic:view", "parentid": 6, "description": "查看基础配置"}, + {"name": "修改配置", "code": "system:basic:edit", "parentid": 6, "description": "修改基础配置"}, + + # ======================================== + # 系统设置 -> 高级配置操作(parentid=7) + # ======================================== + {"name": "查看配置", "code": "system:advanced:view", "parentid": 7, "description": "查看高级配置"}, + {"name": "修改配置", "code": "system:advanced:edit", "parentid": 7, "description": "修改高级配置"}, ] # 检查现有权限 diff --git a/backend/auth/models.py b/backend/auth/models.py index 723248c..e602496 100644 --- a/backend/auth/models.py +++ b/backend/auth/models.py @@ -88,7 +88,9 @@ class SystemSetting(Base): __tablename__ = "system_setting" id = Column(Integer, primary_key=True, index=True, comment="设置ID") key = Column(String(100), nullable=False, unique=True, comment="设置键名") - value = Column(String(1000), nullable=False, comment="设置值") + value = Column(String(2000), nullable=False, comment="设置值") + type = Column(String(20), default="string", comment="类型:string/image/select/boolean") + options = Column(String(500), nullable=True, comment="下拉选项(用|分隔)") description = Column(String(255), nullable=True, comment="设置描述") createtime = Column(DateTime, default=datetime.utcnow, comment="创建时间") updatetime = Column( diff --git a/backend/auth/requirements.txt b/backend/auth/requirements.txt index 7ad7651..46eaa49 100644 --- a/backend/auth/requirements.txt +++ b/backend/auth/requirements.txt @@ -28,4 +28,7 @@ asyncpg>=0.31.0 redis>=7.2.0 # 验证码生成 -captcha>=0.7.1 \ No newline at end of file +captcha>=0.7.1 + +# 文件上传 +python-multipart>=0.0.9 \ No newline at end of file diff --git a/backend/auth/schemas.py b/backend/auth/schemas.py index d950489..1bf5961 100644 --- a/backend/auth/schemas.py +++ b/backend/auth/schemas.py @@ -190,7 +190,9 @@ class SystemSettingBase(BaseModel): """系统设置基础模型""" key: str = Field(..., max_length=100, description="设置键名") - value: str = Field(..., max_length=1000, description="设置值") + value: str = Field(..., max_length=2000, description="设置值") + type: Optional[str] = Field("string", max_length=20, description="类型:string/image/select/boolean") + options: Optional[str] = Field(None, max_length=500, description="下拉选项(用|分隔)") description: Optional[str] = Field(None, max_length=255, description="设置描述") model_config = {"extra": "ignore"} @@ -212,6 +214,8 @@ class SystemSettingResponse(BaseModel): id: int = Field(..., description="设置ID") key: str = Field(..., description="设置键名") value: str = Field(..., description="设置值") + type: str = Field(..., description="类型") + options: Optional[str] = Field(None, description="下拉选项") description: Optional[str] = Field(None, description="设置描述") createtime: datetime = Field(..., description="创建时间") updatetime: datetime = Field(..., description="更新时间") diff --git a/frontend/src/modules/admin/layout/AdminLayout.vue b/frontend/src/modules/admin/layout/AdminLayout.vue index cd37dda..dc30666 100644 --- a/frontend/src/modules/admin/layout/AdminLayout.vue +++ b/frontend/src/modules/admin/layout/AdminLayout.vue @@ -98,7 +98,7 @@ const hasPermissionPermission = computed(() => { }); const hasSystemPermission = computed(() => { - return auth.permissions.some(p => p.code.startsWith("perm:system")); + return auth.permissions.some(p => p.code.startsWith("system:")); }); const hasAnyPermission = computed(() => { diff --git a/frontend/src/modules/admin/views/settings/SettingManage.vue b/frontend/src/modules/admin/views/settings/SettingManage.vue index 509ae7e..08caf08 100644 --- a/frontend/src/modules/admin/views/settings/SettingManage.vue +++ b/frontend/src/modules/admin/views/settings/SettingManage.vue @@ -1,25 +1,245 @@ diff --git a/frontend/src/modules/admin/views/settings/setting-crud.ts b/frontend/src/modules/admin/views/settings/setting-crud.ts index 6f4bf1a..54cf9b4 100644 --- a/frontend/src/modules/admin/views/settings/setting-crud.ts +++ b/frontend/src/modules/admin/views/settings/setting-crud.ts @@ -1,4 +1,5 @@ import type { CreateCrudOptions } from "@fast-crud/fast-crud"; +import { dict } from "@fast-crud/fast-crud"; import dayjs from "dayjs"; import { http } from "@/modules/admin/api/http"; @@ -6,6 +7,8 @@ export type SettingRow = { id: number; key: string; value: string; + type: string; + options?: string | null; description?: string | null; createtime: string; updatetime: string; @@ -71,12 +74,42 @@ export const createSettingCrudOptions: CreateCrudOptions = () => { rules: [{ required: true, message: "请输入设置键名", trigger: "blur" }], }, }, + type: { + title: "类型", + key: "type", + type: "dict-select", + column: { width: 120 }, + dict: dict({ + data: [ + { value: "string", label: "字符串" }, + { value: "image", label: "图片" }, + { value: "select", label: "下拉列表" }, + { value: "boolean", label: "布尔值" }, + ], + value: "value", + label: "label", + }), + form: { + value: "string", + rules: [{ required: true, message: "请选择类型", trigger: "change" }], + }, + }, value: { title: "设置值", key: "value", type: "textarea", + column: { width: 200 }, form: { - rules: [{ required: true, message: "请输入设置值", trigger: "blur" }], + rules: [{ required: true, message: "请输入值", trigger: "blur" }], + }, + }, + options: { + title: "选项配置", + key: "options", + type: "textarea", + column: { show: false }, + form: { + placeholder: "多个选项用 | 分隔,如:选项1|选项2|选项3", }, }, description: { diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts index ebce710..c86d2fb 100644 --- a/frontend/src/router/index.ts +++ b/frontend/src/router/index.ts @@ -48,7 +48,7 @@ const router = createRouter({ { path: "settings", name: "admin-settings", - meta: { title: "系统设置", permission: "perm:system" }, + meta: { title: "系统设置", permission: "system:" }, component: () => import("@/modules/admin/views/settings/SettingManage.vue"), },