feat(ai): 支持双模型多视角AI设计生图与后台管理系统
- 实现AI多视角设计图生成功能,支持6个可选设计参数配置 - 集成SiliconFlow FLUX.1与火山引擎Seedream 4.5双模型切换 - 构建专业中文转英文prompt系统,提升AI生成质量 - 前端设计预览支持多视角切换与视角指示器展示 - 增加多视角设计图片DesignImage模型关联及存储 - 后端设计服务异步调用AI接口,失败时降级生成mock图 - 新增管理员后台管理路由及完整的权限校验机制 - 实现后台模块:仪表盘、系统配置、用户/品类/设计管理 - 配置数据库系统配置表,支持动态AI配置及热更新 - 增加用户管理员标识字段,管理后台登录鉴权支持 - 更新API接口支持多视角设计参数及后台管理接口 - 优化设计删除逻辑,删除多视角相关图片文件 - 前端新增管理后台页面与路由,布局样式独立分离 - 更新环境变量增加AI模型相关Key与参数配置说明 - 引入httpx异步HTTP客户端用于AI接口调用及图片下载 - README文档完善AI多视角生图与后台管理详细功能与流程说明
This commit is contained in:
177
frontend/src/components/AdminLayout.vue
Normal file
177
frontend/src/components/AdminLayout.vue
Normal file
@@ -0,0 +1,177 @@
|
||||
<template>
|
||||
<div class="admin-layout">
|
||||
<aside class="admin-sidebar">
|
||||
<div class="sidebar-header">
|
||||
<router-link to="/admin" class="admin-logo">
|
||||
<span class="logo-icon">⚙</span>
|
||||
<span class="logo-text">管理后台</span>
|
||||
</router-link>
|
||||
</div>
|
||||
<nav class="sidebar-nav">
|
||||
<router-link to="/admin" class="nav-item" exact-active-class="active">
|
||||
<el-icon><DataBoard /></el-icon>
|
||||
<span>仪表盘</span>
|
||||
</router-link>
|
||||
<router-link to="/admin/configs" class="nav-item" active-class="active">
|
||||
<el-icon><Setting /></el-icon>
|
||||
<span>系统配置</span>
|
||||
</router-link>
|
||||
<router-link to="/admin/users" class="nav-item" active-class="active">
|
||||
<el-icon><User /></el-icon>
|
||||
<span>用户管理</span>
|
||||
</router-link>
|
||||
<router-link to="/admin/categories" class="nav-item" active-class="active">
|
||||
<el-icon><Grid /></el-icon>
|
||||
<span>品类管理</span>
|
||||
</router-link>
|
||||
<router-link to="/admin/designs" class="nav-item" active-class="active">
|
||||
<el-icon><PictureFilled /></el-icon>
|
||||
<span>设计管理</span>
|
||||
</router-link>
|
||||
<router-link to="/admin/prompts" class="nav-item" active-class="active">
|
||||
<el-icon><ChatLineSquare /></el-icon>
|
||||
<span>提示词管理</span>
|
||||
</router-link>
|
||||
</nav>
|
||||
<div class="sidebar-footer">
|
||||
<router-link to="/" class="back-link">
|
||||
<el-icon><Back /></el-icon>
|
||||
<span>返回前台</span>
|
||||
</router-link>
|
||||
</div>
|
||||
</aside>
|
||||
<div class="admin-main">
|
||||
<header class="admin-header">
|
||||
<div class="header-title">{{ pageTitle }}</div>
|
||||
<div class="header-user">
|
||||
<span>{{ userStore.userInfo?.nickname || '管理员' }}</span>
|
||||
</div>
|
||||
</header>
|
||||
<div class="admin-content">
|
||||
<router-view />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { DataBoard, Setting, User, Grid, PictureFilled, Back, ChatLineSquare } from '@element-plus/icons-vue'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
|
||||
const route = useRoute()
|
||||
const userStore = useUserStore()
|
||||
|
||||
const pageTitle = computed(() => {
|
||||
const titles: Record<string, string> = {
|
||||
'AdminDashboard': '仪表盘',
|
||||
'AdminConfigs': '系统配置',
|
||||
'AdminUsers': '用户管理',
|
||||
'AdminCategories': '品类管理',
|
||||
'AdminDesigns': '设计管理',
|
||||
'AdminPrompts': '提示词管理',
|
||||
}
|
||||
return titles[route.name as string] || '管理后台'
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.admin-layout {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
background: #f0f2f5;
|
||||
}
|
||||
|
||||
.admin-sidebar {
|
||||
width: 220px;
|
||||
background: #1d1e2c;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.sidebar-header {
|
||||
padding: 20px;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.08);
|
||||
|
||||
.admin-logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
|
||||
.logo-icon { font-size: 22px; }
|
||||
.logo-text { font-size: 18px; font-weight: 600; letter-spacing: 2px; }
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-nav {
|
||||
flex: 1;
|
||||
padding: 12px 0;
|
||||
|
||||
.nav-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px 24px;
|
||||
color: rgba(255,255,255,0.65);
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover { color: #fff; background: rgba(255,255,255,0.06); }
|
||||
&.active {
|
||||
color: #fff;
|
||||
background: #5B7E6B;
|
||||
border-right: 3px solid #A8D5BA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-footer {
|
||||
padding: 16px;
|
||||
border-top: 1px solid rgba(255,255,255,0.08);
|
||||
|
||||
.back-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: rgba(255,255,255,0.5);
|
||||
text-decoration: none;
|
||||
font-size: 13px;
|
||||
padding: 8px;
|
||||
border-radius: 6px;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover { color: #fff; background: rgba(255,255,255,0.06); }
|
||||
}
|
||||
}
|
||||
|
||||
.admin-main {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.admin-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 56px;
|
||||
padding: 0 24px;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
|
||||
.header-title { font-size: 16px; font-weight: 600; color: #1d1e2c; }
|
||||
.header-user { font-size: 14px; color: #666; }
|
||||
}
|
||||
|
||||
.admin-content {
|
||||
flex: 1;
|
||||
padding: 24px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user