style(components): 调整组件样式和布局细节
This commit is contained in:
parent
e0f6b66ed1
commit
fbe85702a9
@ -178,7 +178,7 @@ const emit = defineEmits(['open-config', 'open-agent-modal']);
|
||||
const state = reactive({
|
||||
...props.state,
|
||||
debug_mode: computed(() => props.state.debug_mode ?? false),
|
||||
isSidebarOpen: localStorage.getItem('chat_sidebar_open') === 'true' || true,
|
||||
isSidebarOpen: localStorage.getItem('chat_sidebar_open', 'true') === 'true',
|
||||
waitingServerResponse: false,
|
||||
isProcessingRequest: false,
|
||||
creatingNewChat: false,
|
||||
@ -226,7 +226,7 @@ onMounted(() => {
|
||||
|
||||
// 延迟移除初始渲染标记,防止切换动画
|
||||
setTimeout(() => {
|
||||
state.isInitialRender = false;
|
||||
state.isInitialRender = false;
|
||||
}, 300);
|
||||
});
|
||||
|
||||
|
||||
@ -527,7 +527,7 @@ const toggleToolCall = (toolCallId) => {
|
||||
}
|
||||
|
||||
ol, ul {
|
||||
padding-left: 1rem;
|
||||
padding-left: 1.2rem;
|
||||
}
|
||||
|
||||
cite {
|
||||
|
||||
@ -178,8 +178,8 @@
|
||||
<div v-if="providerConfig.allModels.length === 0" class="modal-no-models">
|
||||
<a-alert v-if="!modelStatus[providerConfig.provider]" type="warning" message="请在 src/.env 中配置对应的 APIKEY,并重新启动服务" />
|
||||
<div v-else>
|
||||
<a-alert type="warning" message="该提供商暂未适配获取模型列表的方法,如果需要添加模型,请在 src/static/models.private.yml 中添加。" />
|
||||
<img src="@/assets/pics/guides/how-to-add-models.png" alt="添加模型指引" style="width: 100%; height: 100%;">
|
||||
<a-alert type="warning" message="该提供商暂未适配获取模型列表的方法,如果需要添加模型,请在 src/static/models.private.yml 中添加。(如没有此文件,则需要手动创建一个)" />
|
||||
<img src="@/assets/pics/guides/how-to-add-models.png" alt="添加模型指引" style="width: 100%; height: 100%; margin-top: 16px;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -450,14 +450,12 @@ const filteredModels = computed(() => {
|
||||
border: 1px solid var(--gray-200);
|
||||
background-color: white;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 12px;
|
||||
margin-bottom: 16px;
|
||||
padding: 0;
|
||||
// box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
|
||||
transition: all 0.2s ease;
|
||||
transition: all 0.3s ease;
|
||||
overflow: hidden;
|
||||
|
||||
&:hover {
|
||||
// box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
|
||||
border-color: var(--gray-300);
|
||||
}
|
||||
|
||||
@ -511,11 +509,11 @@ const filteredModels = computed(() => {
|
||||
.card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
gap: 12px;
|
||||
cursor: pointer;
|
||||
padding: 12px 14px;
|
||||
padding: 16px 20px;
|
||||
background: white;
|
||||
transition: all 0.2s ease;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
background: var(--gray-50);
|
||||
@ -644,8 +642,8 @@ const filteredModels = computed(() => {
|
||||
.card-body {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||||
gap: 10px;
|
||||
padding: 12px;
|
||||
gap: 12px;
|
||||
padding: 16px;
|
||||
background: #fafafa;
|
||||
|
||||
// 普通模型卡片样式
|
||||
@ -653,17 +651,17 @@ const filteredModels = computed(() => {
|
||||
width: 100%;
|
||||
border-radius: 6px;
|
||||
border: 1px solid var(--gray-200);
|
||||
padding: 10px 12px;
|
||||
padding: 12px 16px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
background: white;
|
||||
transition: all 0.2s ease;
|
||||
min-height: 42px;
|
||||
transition: all 0.3s ease;
|
||||
min-height: 48px;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
border-color: var(--gray-400);
|
||||
}
|
||||
|
||||
@ -697,17 +695,17 @@ const filteredModels = computed(() => {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
padding: 10px 12px;
|
||||
padding: 12px 16px;
|
||||
gap: 8px;
|
||||
cursor: pointer;
|
||||
min-height: 64px;
|
||||
min-height: 72px;
|
||||
background: white;
|
||||
border-radius: 6px;
|
||||
border: 1px solid var(--gray-200);
|
||||
transition: all 0.2s ease;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
|
||||
border-color: var(--gray-400);
|
||||
|
||||
.card-models__header .action {
|
||||
|
||||
@ -135,9 +135,9 @@ const handleSelectModel = (provider, name) => {
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="less">
|
||||
// 添加全局样式以确保滚动功能在dropdown内正常工作
|
||||
.ant-dropdown-menu {
|
||||
<style lang="less" scoped>
|
||||
// 将全局样式移到scoped中以避免样式污染
|
||||
:deep(.ant-dropdown-menu) {
|
||||
&.scrollable-menu {
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
|
||||
@ -1,212 +0,0 @@
|
||||
<template>
|
||||
<a-card class="config-card" style="max-width: 960px">
|
||||
<a-form layout="vertical">
|
||||
<div
|
||||
v-for="(item, index) in configList"
|
||||
:key="index"
|
||||
class="config-item"
|
||||
>
|
||||
<a-row :gutter="[16, 8]" align="middle">
|
||||
<a-col :span="8">
|
||||
<a-input
|
||||
v-model:value="item.key"
|
||||
placeholder="模型名称"
|
||||
readonly
|
||||
class="key-input"
|
||||
/>
|
||||
</a-col>
|
||||
<a-col :span="14">
|
||||
<a-input
|
||||
v-model:value="item.value"
|
||||
@change="updateValue(index)"
|
||||
placeholder="模型本地路径"
|
||||
class="value-input"
|
||||
/>
|
||||
</a-col>
|
||||
<a-col :span="2" class="delete-btn-col">
|
||||
<a-button
|
||||
type="link"
|
||||
danger
|
||||
class="delete-btn"
|
||||
@click="deleteConfig(index)"
|
||||
>
|
||||
<DeleteOutlined />
|
||||
</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
|
||||
<a-button block @click="addConfig" class="add-btn" :disabled="isAdding">
|
||||
<PlusOutlined /> 添加路径映射
|
||||
</a-button>
|
||||
</a-form>
|
||||
|
||||
<a-modal
|
||||
title="添加路径映射"
|
||||
v-model:open="addConfigModalVisible"
|
||||
@ok="confirmAddConfig"
|
||||
class="config-modal"
|
||||
>
|
||||
<a-form layout="vertical">
|
||||
<a-form-item label="模型名称(与Huggingface名称一致,比如 BAAI/bge-large-zh-v1.5" required>
|
||||
<a-input
|
||||
v-model:value="newConfig.key"
|
||||
placeholder="请输入模型名称"
|
||||
class="modal-input"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="模型本地路径(绝对路径,比如 /hdd/models/BAAI/bge-large-zh-v1.5)" required>
|
||||
<a-input
|
||||
v-model:value="newConfig.value"
|
||||
placeholder="请输入模型本地路径"
|
||||
class="modal-input"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, computed, watch } from 'vue';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { DeleteOutlined, PlusOutlined } from '@ant-design/icons-vue';
|
||||
|
||||
const props = defineProps({
|
||||
config: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:config']);
|
||||
|
||||
// 配置列表
|
||||
const configList = reactive([]);
|
||||
|
||||
// 初始化配置列表
|
||||
props.config && Object.entries(props.config).forEach(([key, value]) => {
|
||||
configList.push({ key, value });
|
||||
});
|
||||
|
||||
// 控制模态框显示
|
||||
const addConfigModalVisible = ref(false);
|
||||
const isAdding = ref(false); // 添加新的ref变量
|
||||
|
||||
// 新增配置项数据
|
||||
const newConfig = ref({ key: '', value: '' });
|
||||
|
||||
// 添加配置
|
||||
const addConfig = () => {
|
||||
isAdding.value = true; // 设置添加状态
|
||||
addConfigModalVisible.value = true;
|
||||
};
|
||||
|
||||
// 确认添加配置
|
||||
const confirmAddConfig = () => {
|
||||
if (newConfig.value.key === '' || newConfig.value.value === '') {
|
||||
message.warning('键或值不能为空');
|
||||
return;
|
||||
}
|
||||
if (configList.some(item => item.key === newConfig.value.key)) {
|
||||
message.warning('键已存在');
|
||||
return;
|
||||
}
|
||||
configList.push({ key: newConfig.value.key, value: newConfig.value.value });
|
||||
addConfigModalVisible.value = false;
|
||||
newConfig.value = { key: '', value: '' };
|
||||
isAdding.value = false; // 重置添加状态
|
||||
};
|
||||
|
||||
// 删除配置
|
||||
const deleteConfig = (index) => {
|
||||
configList.splice(index, 1);
|
||||
};
|
||||
|
||||
// 更新值
|
||||
const updateValue = (index) => {
|
||||
// 值的更新实时反映在 configList 中,无需额外处理
|
||||
};
|
||||
|
||||
// 将配置列表转换为对象
|
||||
const configObject = computed(() => {
|
||||
return configList.reduce((acc, item) => {
|
||||
acc[item.key] = item.value;
|
||||
return acc;
|
||||
}, {});
|
||||
});
|
||||
|
||||
// 监听配置变化并传递回父组件
|
||||
watch(configObject, (newValue) => {
|
||||
emit('update:config', newValue);
|
||||
}, { deep: true });
|
||||
|
||||
// 监听模态框关闭
|
||||
watch(addConfigModalVisible, (newValue) => {
|
||||
if (!newValue) {
|
||||
isAdding.value = false; // 当模态框关闭时重置添加状态
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.config-card {
|
||||
background-color: var(--gray-10);
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--gray-300);
|
||||
}
|
||||
|
||||
.config-item {
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
padding: 12px 0;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
.config-item:hover {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.config-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.key-input {
|
||||
background-color: #f8f8f8;
|
||||
border-color: #e8e8e8;
|
||||
}
|
||||
|
||||
.delete-btn-col {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
opacity: 0.6;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.delete-btn:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.add-btn {
|
||||
margin-top: 16px;
|
||||
height: 40px;
|
||||
transition: all 0.3s ease;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.modal-input {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
:deep(.ant-modal-content) {
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
:deep(.ant-card-body) {
|
||||
padding: 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -76,7 +76,7 @@
|
||||
|
||||
<!-- 用户表单模态框 -->
|
||||
<a-modal
|
||||
v-model:visible="userManagement.modalVisible"
|
||||
v-model:open="userManagement.modalVisible"
|
||||
:title="userManagement.modalTitle"
|
||||
@ok="handleUserFormSubmit"
|
||||
:confirmLoading="userManagement.loading"
|
||||
|
||||
@ -126,7 +126,6 @@ import {
|
||||
GlobalOutlined
|
||||
} from '@ant-design/icons-vue';
|
||||
import HeaderComponent from '@/components/HeaderComponent.vue';
|
||||
import TableConfigComponent from '@/components/TableConfigComponent.vue';
|
||||
import ModelProvidersComponent from '@/components/ModelProvidersComponent.vue';
|
||||
import UserManagementComponent from '@/components/UserManagementComponent.vue';
|
||||
import { notification, Button } from 'ant-design-vue';
|
||||
@ -302,7 +301,6 @@ const openLink = (url) => {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
// box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
border: 1px solid var(--gray-200);
|
||||
}
|
||||
|
||||
@ -310,9 +308,12 @@ const openLink = (url) => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
// padding: 12px 0;
|
||||
|
||||
.label {
|
||||
margin-right: 20px;
|
||||
font-weight: 500;
|
||||
color: var(--gray-800);
|
||||
|
||||
button {
|
||||
margin-left: 10px;
|
||||
@ -325,13 +326,9 @@ const openLink = (url) => {
|
||||
|
||||
.services-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 16px;
|
||||
margin-top: 20px;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
.service-link-card {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user