refactor: 重构系统权限与设置管理,新增多类型配置能力
1. 重构权限码规范,将系统权限前缀从perm:system改为system: 2. 扩展系统设置模型,支持string/image/select/boolean四种配置类型 3. 新增设置项选项配置、图片上传功能 4. 重构初始化权限数据,拆分权限与系统设置权限结构 5. 重写前端系统设置页面,支持按类型渲染不同配置表单 6. 添加python-multipart依赖支持文件上传 遗留问题: 1.系统设置页面的添加设置按钮无法使用
This commit is contained in:
parent
01bda3d0cc
commit
82cf0192e8
@ -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}"}
|
||||
|
||||
@ -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": "修改高级配置"},
|
||||
]
|
||||
|
||||
# 检查现有权限
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -29,3 +29,6 @@ redis>=7.2.0
|
||||
|
||||
# 验证码生成
|
||||
captcha>=0.7.1
|
||||
|
||||
# 文件上传
|
||||
python-multipart>=0.0.9
|
||||
@ -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="更新时间")
|
||||
|
||||
@ -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(() => {
|
||||
|
||||
@ -1,25 +1,245 @@
|
||||
<template>
|
||||
<fs-page>
|
||||
<fs-crud ref="crudRef" v-bind="crudBinding" />
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="flex items-center justify-between">
|
||||
<span>系统设置管理</span>
|
||||
<el-button type="primary" @click="openAddModal">添加设置</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-table :data="settings" border style="width: 100%">
|
||||
<el-table-column prop="id" label="ID" width="80" />
|
||||
<el-table-column prop="key" label="设置键名" />
|
||||
<el-table-column prop="value" label="设置值" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="type" label="类型" width="120">
|
||||
<template #default="scope">
|
||||
{{ getTypeLabel(scope.row.type) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="description" label="描述" />
|
||||
<el-table-column prop="createtime" label="创建时间" width="180" />
|
||||
<el-table-column label="操作" width="180">
|
||||
<template #default="scope">
|
||||
<el-button size="small" @click="openEditModal(scope.row)">编辑</el-button>
|
||||
<el-button size="small" type="danger" @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
|
||||
<!-- 添加/编辑弹窗 -->
|
||||
<el-dialog :title="isEdit ? '编辑设置' : '添加设置'" :visible.sync="showModal" width="600px">
|
||||
<el-form :model="form" label-width="120px">
|
||||
<el-form-item label="设置键名" prop="key">
|
||||
<el-input v-model="form.key" placeholder="请输入设置键名" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="类型" prop="type">
|
||||
<el-select v-model="form.type" placeholder="请选择类型">
|
||||
<el-option label="字符串" value="string" />
|
||||
<el-option label="图片" value="image" />
|
||||
<el-option label="下拉列表" value="select" />
|
||||
<el-option label="布尔值" value="boolean" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 字符串类型 -->
|
||||
<el-form-item v-if="form.type === 'string'" label="设置值" prop="value">
|
||||
<el-input v-model="form.value" type="textarea" :rows="3" placeholder="请输入值" />
|
||||
</el-form-item>
|
||||
|
||||
<!-- 图片类型 -->
|
||||
<el-form-item v-if="form.type === 'image'" label="设置值" prop="value">
|
||||
<el-upload
|
||||
action="#"
|
||||
accept="image/*"
|
||||
list-type="picture-card"
|
||||
:show-file-list="false"
|
||||
:before-upload="handleImageUpload"
|
||||
:on-remove="handleImageRemove"
|
||||
>
|
||||
<div v-if="!form.value">
|
||||
<el-icon><UploadIcon /></el-icon>
|
||||
<div>上传图片</div>
|
||||
</div>
|
||||
<img v-else :src="form.value" style="width: 100%; height: 100%" />
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 下拉列表类型 -->
|
||||
<template v-if="form.type === 'select'">
|
||||
<el-form-item label="选项配置" prop="options">
|
||||
<el-input v-model="form.options" type="textarea" :rows="2" placeholder="多个选项用 | 分隔,如:选项1|选项2|选项3" />
|
||||
</el-form-item>
|
||||
<el-form-item label="设置值" prop="value">
|
||||
<el-select v-model="form.value" placeholder="请选择">
|
||||
<el-option v-for="opt in optionsList" :key="opt" :label="opt" :value="opt" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<!-- 布尔值类型 -->
|
||||
<el-form-item v-if="form.type === 'boolean'" label="设置值" prop="value">
|
||||
<el-switch v-model="form.booleanValue" active-text="开启" inactive-text="关闭" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="描述" prop="description">
|
||||
<el-input v-model="form.description" type="textarea" :rows="2" placeholder="请输入描述" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<el-button @click="showModal = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</fs-page>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted } from "vue";
|
||||
import { useFs } from "@fast-crud/fast-crud";
|
||||
import { createSettingCrudOptions } from "./setting-crud";
|
||||
import { ref, computed, watch } from "vue";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { http } from "@/modules/admin/api/http";
|
||||
import type { SettingRow } from "./setting-crud";
|
||||
|
||||
const { crudBinding, crudRef, crudExpose } = useFs({
|
||||
createCrudOptions: createSettingCrudOptions,
|
||||
const settings = ref<SettingRow[]>([]);
|
||||
const showModal = ref(false);
|
||||
const isEdit = ref(false);
|
||||
|
||||
const form = ref({
|
||||
id: 0,
|
||||
key: "",
|
||||
value: "",
|
||||
type: "string",
|
||||
options: "",
|
||||
description: "",
|
||||
booleanValue: false,
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
crudExpose.doRefresh();
|
||||
const optionsList = computed(() => {
|
||||
if (!form.value.options) return [];
|
||||
return form.value.options.split("|").filter(Boolean).map((o) => o.trim());
|
||||
});
|
||||
|
||||
watch(() => form.value.type, (newType) => {
|
||||
if (newType === "boolean") {
|
||||
form.value.booleanValue = form.value.value === "true";
|
||||
}
|
||||
});
|
||||
|
||||
const getTypeLabel = (type: string) => {
|
||||
const types: Record<string, string> = {
|
||||
string: "字符串",
|
||||
image: "图片",
|
||||
select: "下拉列表",
|
||||
boolean: "布尔值",
|
||||
};
|
||||
return types[type] || type;
|
||||
};
|
||||
|
||||
const loadData = async () => {
|
||||
try {
|
||||
const { data } = await http.get<SettingRow[]>("/settings/");
|
||||
settings.value = data;
|
||||
} catch (error) {
|
||||
ElMessage.error("加载失败");
|
||||
}
|
||||
};
|
||||
|
||||
const openAddModal = () => {
|
||||
isEdit.value = false;
|
||||
form.value = {
|
||||
id: 0,
|
||||
key: "",
|
||||
value: "",
|
||||
type: "string",
|
||||
options: "",
|
||||
description: "",
|
||||
booleanValue: false,
|
||||
};
|
||||
showModal.value = true;
|
||||
};
|
||||
|
||||
const openEditModal = (row: SettingRow) => {
|
||||
isEdit.value = true;
|
||||
form.value = {
|
||||
id: row.id,
|
||||
key: row.key,
|
||||
value: row.value,
|
||||
type: row.type,
|
||||
options: row.options || "",
|
||||
description: row.description || "",
|
||||
booleanValue: row.value === "true",
|
||||
};
|
||||
showModal.value = true;
|
||||
};
|
||||
|
||||
const handleImageUpload = async (file: any) => {
|
||||
const formData = new FormData();
|
||||
formData.append("file", file.raw);
|
||||
try {
|
||||
const response = await http.post("/settings/upload", formData, {
|
||||
headers: { "Content-Type": "multipart/form-data" },
|
||||
});
|
||||
form.value.value = response.data.url;
|
||||
} catch (error) {
|
||||
ElMessage.error("上传失败");
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const handleImageRemove = () => {
|
||||
form.value.value = "";
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!form.value.key) {
|
||||
ElMessage.error("请输入设置键名");
|
||||
return;
|
||||
}
|
||||
|
||||
if (form.value.type === "boolean") {
|
||||
form.value.value = form.value.booleanValue ? "true" : "false";
|
||||
}
|
||||
|
||||
try {
|
||||
if (isEdit.value) {
|
||||
await http.put(`/settings/${form.value.id}`, form.value);
|
||||
ElMessage.success("修改成功");
|
||||
} else {
|
||||
await http.post("/settings/", form.value);
|
||||
ElMessage.success("添加成功");
|
||||
}
|
||||
showModal.value = false;
|
||||
await loadData();
|
||||
} catch (error: any) {
|
||||
ElMessage.error(error.response?.data?.detail || "操作失败");
|
||||
}
|
||||
};
|
||||
|
||||
const handleDelete = async (row: SettingRow) => {
|
||||
try {
|
||||
await ElMessageBox.confirm("确定要删除吗?");
|
||||
await http.delete(`/settings/${row.id}`);
|
||||
ElMessage.success("删除成功");
|
||||
await loadData();
|
||||
} catch {
|
||||
// 用户取消
|
||||
}
|
||||
};
|
||||
|
||||
loadData();
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.setting-manage {
|
||||
height: 100%;
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
.items-center {
|
||||
align-items: center;
|
||||
}
|
||||
.justify-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -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<SettingRow> = () => {
|
||||
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: {
|
||||
|
||||
@ -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"),
|
||||
},
|
||||
|
||||
Loading…
Reference in New Issue
Block a user