refactor: 重构 Settings 页面样式
- 移除旧的 settings.css 和 modelSettings.css 引用 - 采用 Tailwind CSS 进行样式重构 - 优化布局和交互体验 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,8 +3,6 @@ import { ref, watch, computed } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { useModelSettings } from './settings/useModelSettings'
|
||||
import FormDialog from '@/components/FormDialog.vue'
|
||||
import './settings/settings.css'
|
||||
import './settings/modelSettings.css'
|
||||
|
||||
// 当前选中的设置菜单
|
||||
const activeMenu = ref('general')
|
||||
@@ -164,22 +162,25 @@ const clearLogs = () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="settings-page">
|
||||
<div class="p-6 min-h-screen">
|
||||
<!-- 页面标题 -->
|
||||
<div class="flex items-center gap-2 mb-6">
|
||||
<i class="fa-solid fa-gear text-orange-500"></i>
|
||||
<span class="font-medium">Settings</span>
|
||||
</div>
|
||||
|
||||
<div class="settings-container">
|
||||
<div class="flex gap-6">
|
||||
<!-- 左侧菜单 -->
|
||||
<nav class="settings-nav">
|
||||
<ul>
|
||||
<nav class="w-48 flex-shrink-0">
|
||||
<ul class="space-y-1">
|
||||
<li
|
||||
v-for="item in menuItems"
|
||||
:key="item.key"
|
||||
:class="['nav-item', { active: activeMenu === item.key }]"
|
||||
@click="activeMenu = item.key"
|
||||
class="px-4 py-3 rounded-lg cursor-pointer transition-colors flex items-center gap-3"
|
||||
:class="activeMenu === item.key
|
||||
? 'bg-orange-500/10 text-orange-400'
|
||||
: 'text-gray-400 hover:bg-dark-600 hover:text-white'"
|
||||
>
|
||||
<i :class="['fa-solid', item.icon]"></i>
|
||||
<span>{{ item.label }}</span>
|
||||
@@ -188,130 +189,150 @@ const clearLogs = () => {
|
||||
</nav>
|
||||
|
||||
<!-- 右侧内容 -->
|
||||
<div class="settings-content">
|
||||
<div class="flex-1 space-y-4">
|
||||
<!-- General 设置 -->
|
||||
<div v-if="activeMenu === 'general'" class="settings-section">
|
||||
<h2 class="section-title">General Settings</h2>
|
||||
<p class="section-desc">Manage your personal information and preferences</p>
|
||||
<div v-if="activeMenu === 'general'">
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<div>
|
||||
<h2 class="text-xl font-semibold">General Settings</h2>
|
||||
<p class="text-sm text-gray-400 mt-1">Manage your personal information and preferences</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-form :model="generalForm" label-position="top" class="settings-form">
|
||||
<el-form-item label="Name">
|
||||
<el-input v-model="generalForm.name" placeholder="Enter your name" />
|
||||
</el-form-item>
|
||||
<div class="bg-dark-700 rounded-xl p-6">
|
||||
<el-form :model="generalForm" label-position="top">
|
||||
<div class="grid grid-cols-2 gap-6">
|
||||
<el-form-item label="Name">
|
||||
<el-input v-model="generalForm.name" placeholder="Enter your name" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Email">
|
||||
<el-input v-model="generalForm.email" placeholder="Enter your email" />
|
||||
</el-form-item>
|
||||
<el-form-item label="Email">
|
||||
<el-input v-model="generalForm.email" placeholder="Enter your email" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Password">
|
||||
<div class="password-field">
|
||||
<el-input v-model="generalForm.password" type="password" disabled />
|
||||
<el-button @click="showChangePassword">Change</el-button>
|
||||
<el-form-item label="Password">
|
||||
<div class="flex gap-3">
|
||||
<el-input v-model="generalForm.password" type="password" disabled class="flex-1" />
|
||||
<el-button @click="showChangePassword">Change</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Language">
|
||||
<el-select v-model="generalForm.language" placeholder="Select language" class="w-full">
|
||||
<el-option
|
||||
v-for="lang in languageOptions"
|
||||
:key="lang.value"
|
||||
:label="lang.label"
|
||||
:value="lang.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Timezone">
|
||||
<el-select v-model="generalForm.timezone" placeholder="Select timezone" class="w-full">
|
||||
<el-option
|
||||
v-for="tz in timezoneOptions"
|
||||
:key="tz.value"
|
||||
:label="tz.label"
|
||||
:value="tz.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Language">
|
||||
<el-select v-model="generalForm.language" placeholder="Select language">
|
||||
<el-option
|
||||
v-for="lang in languageOptions"
|
||||
:key="lang.value"
|
||||
:label="lang.label"
|
||||
:value="lang.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="Timezone">
|
||||
<el-select v-model="generalForm.timezone" placeholder="Select timezone">
|
||||
<el-option
|
||||
v-for="tz in timezoneOptions"
|
||||
:key="tz.value"
|
||||
:label="tz.label"
|
||||
:value="tz.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="saveChanges">Save Changes</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="mt-4">
|
||||
<el-button type="primary" @click="saveChanges">Save Changes</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Members 设置 -->
|
||||
<div v-if="activeMenu === 'members'" class="settings-section">
|
||||
<h2 class="section-title">Members</h2>
|
||||
<p class="section-desc">Manage team members</p>
|
||||
<div v-if="activeMenu === 'members'">
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<div>
|
||||
<h2 class="text-xl font-semibold">Members</h2>
|
||||
<p class="text-sm text-gray-400 mt-1">Manage team members</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Notifications 设置 -->
|
||||
<div v-if="activeMenu === 'notifications'" class="settings-section">
|
||||
<h2 class="section-title">Notifications</h2>
|
||||
<p class="section-desc">Configure notification preferences</p>
|
||||
<div v-if="activeMenu === 'notifications'">
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<div>
|
||||
<h2 class="text-xl font-semibold">Notifications</h2>
|
||||
<p class="text-sm text-gray-400 mt-1">Configure notification preferences</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Model Settings 设置 -->
|
||||
<div v-if="activeMenu === 'modelSettings'" class="settings-section">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<div v-if="activeMenu === 'modelSettings'">
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<div>
|
||||
<h2 class="section-title">Model Settings</h2>
|
||||
<p class="section-desc">Configure AI model settings</p>
|
||||
<h2 class="text-xl font-semibold">Model Settings</h2>
|
||||
<p class="text-sm text-gray-400 mt-1">Configure AI model settings</p>
|
||||
</div>
|
||||
<el-button type="primary" class="add-model-btn" @click="showAddModelForm = true">
|
||||
<i class="fa-solid fa-plus mr-2"></i>
|
||||
<button class="bg-gradient-to-r from-primary-orange to-red-500 hover:from-orange-500 hover:to-red-600 text-white px-4 py-2 rounded-lg font-medium flex items-center gap-2 transition-all" @click="showAddModelForm = true">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
Add New Model
|
||||
</el-button>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 模型列表 -->
|
||||
<div v-if="modelsLoading" class="loading-spinner">
|
||||
<i class="fa-solid fa-spinner"></i>
|
||||
<div v-if="modelsLoading" class="py-12 text-center text-gray-500">
|
||||
<i class="fa-solid fa-spinner fa-spin text-2xl"></i>
|
||||
</div>
|
||||
<div v-else class="bg-dark-700 rounded-xl overflow-hidden">
|
||||
<table class="w-full">
|
||||
<thead class="bg-dark-600">
|
||||
<tr>
|
||||
<th class="text-left px-5 py-3 text-sm font-medium text-gray-400">Model Name</th>
|
||||
<th class="text-left px-5 py-3 text-sm font-medium text-gray-400">Provider</th>
|
||||
<th class="text-left px-5 py-3 text-sm font-medium text-gray-400">Model</th>
|
||||
<th class="text-left px-5 py-3 text-sm font-medium text-gray-400">Model Type</th>
|
||||
<th class="text-left px-5 py-3 text-sm font-medium text-gray-400">Base URL</th>
|
||||
<th class="text-left px-5 py-3 text-sm font-medium text-gray-400">Status</th>
|
||||
<th class="text-right px-5 py-3 text-sm font-medium text-gray-400">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="model in models" :key="model.id" class="border-t border-dark-600 hover:bg-dark-600/50">
|
||||
<td class="px-5 py-4">
|
||||
<span class="font-medium">{{ model.name }}</span>
|
||||
</td>
|
||||
<td class="px-5 py-4 text-sm text-gray-300">
|
||||
{{ model.provider }}
|
||||
</td>
|
||||
<td class="px-5 py-4 text-sm text-gray-300">
|
||||
{{ model.model }}
|
||||
</td>
|
||||
<td class="px-5 py-4">
|
||||
<span class="px-2 py-1 rounded text-xs" :class="model.model_type === 'chat' ? 'bg-primary-cyan/20 text-primary-cyan' : 'bg-purple-500/20 text-purple-400'">{{ model.model_type }}</span>
|
||||
</td>
|
||||
<td class="px-5 py-4 text-sm text-gray-300">
|
||||
{{ model.base_url }}
|
||||
</td>
|
||||
<td class="px-5 py-4">
|
||||
<span v-if="model.status === 'active'" class="px-2 py-1 rounded text-xs bg-primary-success/20 text-primary-success">Active</span>
|
||||
<span v-else class="px-2 py-1 rounded text-xs bg-gray-500/20 text-gray-400">Inactive</span>
|
||||
</td>
|
||||
<td class="px-5 py-4">
|
||||
<div class="flex items-center justify-end gap-2">
|
||||
<button class="p-2 rounded-lg hover:bg-dark-500 transition-colors" title="Edit" @click="openEditDialog(model)">
|
||||
<i class="fa-solid fa-pen text-gray-400 hover:text-white"></i>
|
||||
</button>
|
||||
<button class="p-2 rounded-lg hover:bg-dark-500 transition-colors" title="Delete" @click="deleteModel(model.id)">
|
||||
<i class="fa-solid fa-trash text-gray-400 hover:text-red-400"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<table v-else class="model-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Model Name</th>
|
||||
<th class="text-center">Provider</th>
|
||||
<th class="text-center">Model</th>
|
||||
<th class="text-center">Model Type</th>
|
||||
<th class="text-center">Base URL</th>
|
||||
<th class="text-center">Status</th>
|
||||
<th class="text-center">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="model in models" :key="model.id" class="table-row">
|
||||
<td>
|
||||
<span class="font-medium">{{ model.name }}</span>
|
||||
</td>
|
||||
<td class="text-center text-sm">
|
||||
{{ model.provider }}
|
||||
</td>
|
||||
<td class="text-center text-sm">
|
||||
{{ model.model }}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span class="model-type-tag" :class="model.model_type">{{ model.model_type }}</span>
|
||||
</td>
|
||||
<td class="text-center text-sm">
|
||||
{{ model.base_url }}
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span v-if="model.status === 'active'" class="status-active">Active</span>
|
||||
<span v-else class="status-inactive">Inactive</span>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<button class="btn-icon" title="Edit" @click="openEditDialog(model)">
|
||||
<i class="fa-solid fa-pen"></i>
|
||||
</button>
|
||||
<button class="btn-icon" title="Delete" @click="deleteModel(model.id)">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- 新增模型弹窗 -->
|
||||
<FormDialog
|
||||
@@ -514,11 +535,11 @@ const clearLogs = () => {
|
||||
</div>
|
||||
|
||||
<!-- Logs 设置 -->
|
||||
<div v-if="activeMenu === 'logs'" class="settings-section">
|
||||
<div v-if="activeMenu === 'logs'">
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<div>
|
||||
<h2 class="section-title">Logs</h2>
|
||||
<p class="section-desc">View system logs</p>
|
||||
<h2 class="text-xl font-semibold">Logs</h2>
|
||||
<p class="text-sm text-gray-400 mt-1">View system logs</p>
|
||||
</div>
|
||||
<button @click="clearLogs" class="px-4 py-2 rounded-lg bg-dark-600 text-gray-300 hover:bg-dark-500 transition-colors flex items-center gap-2">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
|
||||
Reference in New Issue
Block a user