主题和样式以及动画过渡的首页修改
This commit is contained in:
@@ -150,8 +150,7 @@ watch(
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
gap: 16px;
|
||||
padding: 28px 0 10px;
|
||||
padding: 8px 0 16px;
|
||||
scrollbar-width: none;
|
||||
&::-webkit-scrollbar { display: none; }
|
||||
}
|
||||
@@ -167,10 +166,18 @@ watch(
|
||||
}
|
||||
}
|
||||
|
||||
/* 节奏化消息间距:AI↔AI 24,用户↔AI 16 */
|
||||
.message-row + .message-row {
|
||||
margin-top: 16px;
|
||||
}
|
||||
.message-row:not(.is-user) + .message-row:not(.is-user) {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.bubble-wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
gap: 4px;
|
||||
max-width: 100%;
|
||||
align-items: flex-start;
|
||||
|
||||
@@ -183,7 +190,7 @@ watch(
|
||||
|
||||
.bubble {
|
||||
font-size: 15px;
|
||||
line-height: 1.75;
|
||||
line-height: 1.7;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
word-break: break-word;
|
||||
@@ -192,12 +199,18 @@ watch(
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
|
||||
/* AI 消息:无背景卡片,纯文本左对齐(DeepSeek 式) */
|
||||
.message-row:not(.is-user) & {
|
||||
width: 100%;
|
||||
max-width: 880px;
|
||||
}
|
||||
|
||||
.message-row.is-user & {
|
||||
width: fit-content;
|
||||
max-width: 85%;
|
||||
padding: 10px 14px;
|
||||
border-radius: 16px 16px 4px 16px;
|
||||
background: #d3f5d8;
|
||||
max-width: 72%;
|
||||
padding: 10px 16px;
|
||||
border-radius: 18px 18px 6px 18px;
|
||||
background: #e8ecff;
|
||||
color: #1f2328;
|
||||
box-shadow: none;
|
||||
}
|
||||
@@ -223,17 +236,17 @@ watch(
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
border-radius: 8px;
|
||||
background: transparent;
|
||||
color: #9ca3af;
|
||||
cursor: pointer;
|
||||
transition: background 0.15s, color 0.15s;
|
||||
|
||||
&:hover {
|
||||
background: #f1f2f4;
|
||||
background: #eef0f3;
|
||||
color: #4b5563;
|
||||
}
|
||||
|
||||
@@ -247,10 +260,10 @@ watch(
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
margin-top: 10px;
|
||||
padding: 5px 12px;
|
||||
margin-top: 8px;
|
||||
padding: 7px 14px;
|
||||
border: 1px solid #fecaca;
|
||||
border-radius: 8px;
|
||||
border-radius: 10px;
|
||||
background: #fef2f2;
|
||||
color: #dc2626;
|
||||
font-size: 12px;
|
||||
@@ -271,10 +284,12 @@ watch(
|
||||
|
||||
/* 思考区:DeepSeek 风格折叠块 */
|
||||
.thinking-block {
|
||||
margin: 2px 0 10px;
|
||||
background: #f5f5f6;
|
||||
border-radius: 10px;
|
||||
margin: 0 0 12px;
|
||||
background: #f5f6f7;
|
||||
border: 1px solid #eef0f3;
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
max-width: 880px;
|
||||
}
|
||||
|
||||
.thinking-toggle {
|
||||
@@ -282,7 +297,7 @@ watch(
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
width: 100%;
|
||||
padding: 8px 12px;
|
||||
padding: 9px 14px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
font-size: 13px;
|
||||
@@ -321,7 +336,7 @@ watch(
|
||||
}
|
||||
|
||||
.thinking-content {
|
||||
padding: 0 12px 12px;
|
||||
padding: 0 14px 14px;
|
||||
animation: thinking-fade-in 0.2s ease;
|
||||
}
|
||||
|
||||
@@ -332,7 +347,7 @@ watch(
|
||||
font-style: italic;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
border-top: 1px solid #ececee;
|
||||
border-top: 1px solid #eef0f3;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
@@ -350,9 +365,10 @@ watch(
|
||||
/* 回答区:Markdown 渲染(DeepSeek 风格排版) */
|
||||
.answer-block {
|
||||
white-space: normal;
|
||||
line-height: 1.75;
|
||||
line-height: 1.7;
|
||||
font-size: 15px;
|
||||
word-break: break-word;
|
||||
max-width: 880px;
|
||||
|
||||
& > :first-child {
|
||||
margin-top: 0;
|
||||
@@ -550,7 +566,7 @@ watch(
|
||||
.time {
|
||||
font-size: 11px;
|
||||
color: #8f9aae;
|
||||
padding: 4px 6px;
|
||||
padding: 4px 2px;
|
||||
|
||||
.message-row.is-user & {
|
||||
text-align: right;
|
||||
|
||||
@@ -2,13 +2,15 @@
|
||||
<div class="input-shell">
|
||||
<div class="input-card" :class="{ 'is-focused': isFocused }">
|
||||
<!-- 已选中状态标签栏 -->
|
||||
<div v-if="selectedWorkflowId !== null" class="selected-tags">
|
||||
<div class="selected-tag workflow-tag">
|
||||
<el-icon><Promotion /></el-icon>
|
||||
<span>{{ commonWorkflows.find((w) => w.id === selectedWorkflowId)?.name }}</span>
|
||||
<el-icon v-if="!workflowLocked" class="tag-close" @click="clearWorkflow"><Close /></el-icon>
|
||||
<Transition name="capsule-slide" @enter="onCapsuleEnter" @after-enter="onCapsuleAfterEnter" @leave="onCapsuleLeave" @after-leave="onCapsuleAfterLeave">
|
||||
<div v-if="selectedWorkflowId !== null" class="selected-tags">
|
||||
<div class="selected-tag workflow-tag">
|
||||
<el-icon><Promotion /></el-icon>
|
||||
<span>{{ commonWorkflows.find((w) => w.id === selectedWorkflowId)?.name }}</span>
|
||||
<el-icon v-if="!workflowLocked" class="tag-close" @click="clearWorkflow"><Close /></el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
|
||||
<!-- 文本输入区 -->
|
||||
<el-input
|
||||
@@ -47,19 +49,21 @@
|
||||
</div>
|
||||
|
||||
<!-- 快捷工作流胶囊(输入框下方) -->
|
||||
<div v-if="visibleWorkflows.length > 0" class="workflow-shortcuts">
|
||||
<button
|
||||
v-for="wf in visibleWorkflows"
|
||||
:key="wf.id"
|
||||
class="shortcut-pill"
|
||||
:class="{ active: selectedWorkflowId === wf.id }"
|
||||
@click="toggleWorkflow(wf.id)"
|
||||
>
|
||||
<el-icon><Promotion /></el-icon>
|
||||
{{ wf.name }}
|
||||
<span v-if="wf.isTemplate" class="pill-tag">模板</span>
|
||||
</button>
|
||||
</div>
|
||||
<Transition name="capsule-slide" @enter="onCapsuleEnter" @after-enter="onCapsuleAfterEnter" @leave="onCapsuleLeave" @after-leave="onCapsuleAfterLeave">
|
||||
<div v-if="visibleWorkflows.length > 0 && !hideShortcuts" class="workflow-shortcuts">
|
||||
<button
|
||||
v-for="wf in visibleWorkflows"
|
||||
:key="wf.id"
|
||||
class="shortcut-pill"
|
||||
:class="{ active: selectedWorkflowId === wf.id }"
|
||||
@click="toggleWorkflow(wf.id)"
|
||||
>
|
||||
<el-icon><Promotion /></el-icon>
|
||||
{{ wf.name }}
|
||||
<span v-if="wf.isTemplate" class="pill-tag">模板</span>
|
||||
</button>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -72,6 +76,7 @@ import { getWorkflowList } from '/@/api/settings/creation';
|
||||
interface Props {
|
||||
sendDisabled?: boolean;
|
||||
workflowLocked?: boolean;
|
||||
hideShortcuts?: boolean;
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
@@ -90,6 +95,7 @@ interface Workflow {
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
sendDisabled: false,
|
||||
workflowLocked: false,
|
||||
hideShortcuts: false,
|
||||
});
|
||||
const emit = defineEmits<Emits>();
|
||||
const message = ref('');
|
||||
@@ -167,21 +173,56 @@ onMounted(() => {
|
||||
fetchWorkflows();
|
||||
});
|
||||
|
||||
// —— 胶囊高度动画:JS 测量实际高度,让 max-height 与内容高度精确匹配,
|
||||
// 进入时从 0 展开、离开时收缩到 0,配合 CSS transition 消除底部高度突变 ——
|
||||
const onCapsuleEnter = (el: Element) => {
|
||||
const e = el as HTMLElement;
|
||||
e.style.maxHeight = '0px';
|
||||
requestAnimationFrame(() => {
|
||||
e.style.maxHeight = e.scrollHeight + 'px';
|
||||
});
|
||||
};
|
||||
const onCapsuleAfterEnter = (el: Element) => {
|
||||
(el as HTMLElement).style.maxHeight = '';
|
||||
};
|
||||
const onCapsuleLeave = (el: Element) => {
|
||||
const e = el as HTMLElement;
|
||||
e.style.maxHeight = e.scrollHeight + 'px';
|
||||
requestAnimationFrame(() => {
|
||||
e.style.maxHeight = '0px';
|
||||
});
|
||||
};
|
||||
const onCapsuleAfterLeave = (el: Element) => {
|
||||
(el as HTMLElement).style.maxHeight = '';
|
||||
};
|
||||
|
||||
defineExpose({ resetAll, clearWorkflow, selectWorkflow, fetchWorkflows, selectedWorkflowId, commonWorkflows });
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
/* ===== 胶囊显示/隐藏过渡:淡入淡出 + 轻位移 + 高度展开/收缩 ===== */
|
||||
.capsule-slide-enter-active,
|
||||
.capsule-slide-leave-active {
|
||||
transition: opacity 0.25s ease, transform 0.25s ease, max-height 0.25s ease;
|
||||
overflow: hidden;
|
||||
}
|
||||
.capsule-slide-enter-from,
|
||||
.capsule-slide-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(-6px);
|
||||
}
|
||||
|
||||
.input-shell {
|
||||
padding: 0 24px 24px;
|
||||
padding: 0 20px 20px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.input-card {
|
||||
max-width: 800px;
|
||||
max-width: 880px;
|
||||
margin: 0 auto;
|
||||
background: #fff;
|
||||
border: 1.5px solid #e2e8f0;
|
||||
border-radius: 16px;
|
||||
border: 1.5px solid #e5e8ee;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 2px 12px rgba(15, 23, 42, 0.07);
|
||||
transition:
|
||||
border-color 0.2s,
|
||||
@@ -238,7 +279,7 @@ onMounted(() => {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
resize: none;
|
||||
padding: 14px 16px 8px;
|
||||
padding: 16px 18px 10px;
|
||||
font-size: 15px;
|
||||
line-height: 1.6;
|
||||
color: #0f172a;
|
||||
@@ -257,7 +298,7 @@ onMounted(() => {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 6px 10px 10px 12px;
|
||||
padding: 8px 12px 12px 14px;
|
||||
}
|
||||
|
||||
.toolbar-left,
|
||||
@@ -271,10 +312,10 @@ onMounted(() => {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
height: 30px;
|
||||
height: 34px;
|
||||
padding: 0 10px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
border-radius: 10px;
|
||||
background: transparent;
|
||||
color: #64748b;
|
||||
font-size: 13px;
|
||||
@@ -315,10 +356,10 @@ onMounted(() => {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
border-radius: 10px;
|
||||
background: #2563eb;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
@@ -347,8 +388,8 @@ onMounted(() => {
|
||||
|
||||
/* 快捷工作流胶囊 */
|
||||
.workflow-shortcuts {
|
||||
max-width: 800px;
|
||||
margin: 10px auto 0;
|
||||
max-width: 880px;
|
||||
margin: 8px auto 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
@@ -358,13 +399,13 @@ onMounted(() => {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
height: 28px;
|
||||
height: 32px;
|
||||
padding: 0 12px;
|
||||
border: 1px solid #e2e8f0;
|
||||
border: 1px solid #e5e8ee;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
color: #475569;
|
||||
font-size: 12px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
backdrop-filter: blur(4px);
|
||||
@@ -372,7 +413,7 @@ onMounted(() => {
|
||||
outline: none;
|
||||
|
||||
.el-icon {
|
||||
font-size: 12px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<template>
|
||||
<div class="main-content">
|
||||
<Transition name="content-fade" mode="out-in">
|
||||
<!-- 工作流动态表单 -->
|
||||
<div v-if="workflowDetail" class="content-body workflow-form-body">
|
||||
<div v-if="workflowDetail" :key="'workflow'" class="content-body workflow-form-body">
|
||||
<div class="workflow-form-card">
|
||||
<div class="workflow-form-header">
|
||||
<div>
|
||||
@@ -130,12 +131,12 @@
|
||||
</div>
|
||||
|
||||
<!-- 对话页 — 无工作流但有消息时展示消息流 -->
|
||||
<div v-else-if="hasMessages" class="content-body chat-body">
|
||||
<div v-else-if="hasMessages" :key="'chat'" class="content-body chat-body">
|
||||
<ChatList :messages="messages" @retry="emit('retry', $event)" />
|
||||
</div>
|
||||
|
||||
<!-- 默认占位 — 无工作流时显示引导 -->
|
||||
<div v-else class="content-body placeholder-body">
|
||||
<div v-else :key="'placeholder'" class="content-body placeholder-body">
|
||||
<div class="placeholder-content">
|
||||
<h2 class="placeholder-title">你好,我能帮你解决什么问题?</h2>
|
||||
<p class="placeholder-desc">选择一个工作流,填写参数后一键生成</p>
|
||||
@@ -156,6 +157,7 @@
|
||||
<div v-else class="placeholder-empty">暂无工作流,可在工作流管理中创建</div>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -429,7 +431,22 @@ onMounted(() => {
|
||||
defineExpose({ formValues, fieldFiles, templates, validateFormFields });
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">.main-content {
|
||||
<style scoped lang="scss">
|
||||
/* ===== 页面切换过渡:淡入淡出 + 轻微上移 ===== */
|
||||
.content-fade-enter-active,
|
||||
.content-fade-leave-active {
|
||||
transition: opacity 0.25s ease, transform 0.25s ease;
|
||||
}
|
||||
.content-fade-enter-from {
|
||||
opacity: 0;
|
||||
transform: translateY(8px);
|
||||
}
|
||||
.content-fade-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(-8px);
|
||||
}
|
||||
|
||||
.main-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -446,19 +463,19 @@ defineExpose({ formValues, fieldFiles, templates, validateFormFields });
|
||||
|
||||
/* ===== 工作流表单 ===== */
|
||||
.workflow-form-body {
|
||||
width: min(800px, 100%);
|
||||
width: min(880px, calc(100% - 40px));
|
||||
margin: 0 auto;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 16px 20px;
|
||||
padding: 16px 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.workflow-form-card {
|
||||
background: #fff;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 12px;
|
||||
border: 1px solid #e5e8ee;
|
||||
border-radius: 14px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-height: 100%;
|
||||
@@ -569,12 +586,12 @@ defineExpose({ formValues, fieldFiles, templates, validateFormFields });
|
||||
|
||||
/* ===== 对话页 ===== */
|
||||
.chat-body {
|
||||
width: min(800px, 92%);
|
||||
width: min(880px, calc(100% - 40px));
|
||||
margin: 0 auto;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 16px;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: none;
|
||||
@@ -582,16 +599,16 @@ defineExpose({ formValues, fieldFiles, templates, validateFormFields });
|
||||
}
|
||||
|
||||
.placeholder-body { display: flex; align-items: center; justify-content: center; }
|
||||
.placeholder-content { text-align: center; padding: 24px 20px; width: 100%; max-width: 640px; }
|
||||
.placeholder-content { text-align: center; padding: 24px 20px; width: 100%; max-width: 740px; }
|
||||
|
||||
/* ===== 标题与描述 ===== */
|
||||
.placeholder-title { font-size: 20px; font-weight: 700; color: #0f172a; margin: 0 0 8px; letter-spacing: -0.2px; line-height: 1.4; }
|
||||
.placeholder-desc { font-size: 14px; color: #94a3b8; margin: 0 0 28px; line-height: 1.5; }
|
||||
.placeholder-title { font-size: 26px; font-weight: 700; color: #0f172a; margin: 0 0 8px; letter-spacing: -0.2px; line-height: 1.4; }
|
||||
.placeholder-desc { font-size: 15px; color: #94a3b8; margin: 0 0 24px; line-height: 1.5; }
|
||||
|
||||
/* ===== 工作流功能卡片(DeepSeek 式引导) ===== */
|
||||
.workflow-cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||||
gap: 12px;
|
||||
text-align: left;
|
||||
}
|
||||
@@ -599,9 +616,9 @@ defineExpose({ formValues, fieldFiles, templates, validateFormFields });
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 14px 16px;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 12px;
|
||||
padding: 18px 20px;
|
||||
border: 1px solid #e5e8ee;
|
||||
border-radius: 14px;
|
||||
background: #fff;
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
@@ -613,13 +630,20 @@ defineExpose({ formValues, fieldFiles, templates, validateFormFields });
|
||||
}
|
||||
}
|
||||
.wf-card-icon {
|
||||
font-size: 18px;
|
||||
color: #3b82f6;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 12px;
|
||||
background: #eaf1ff;
|
||||
color: #2563eb;
|
||||
font-size: 20px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.wf-card-name {
|
||||
flex: 1;
|
||||
font-size: 14px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #1e293b;
|
||||
white-space: nowrap;
|
||||
@@ -638,6 +662,6 @@ defineExpose({ formValues, fieldFiles, templates, validateFormFields });
|
||||
.placeholder-empty {
|
||||
font-size: 13px;
|
||||
color: #cbd5e1;
|
||||
padding: 24px 0;
|
||||
padding: 16px 0;
|
||||
}
|
||||
</style>
|
||||
@@ -139,8 +139,8 @@ const handleDeleteNode = (data: TreeNode) => emit('delete-node', data);
|
||||
.sidebar {
|
||||
width: 240px;
|
||||
flex-shrink: 0;
|
||||
background: #f8fafc;
|
||||
border-right: 1px solid #e2e8f0;
|
||||
background: #f7f8fa;
|
||||
border-right: 1px solid #e5e8ee;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
@@ -152,20 +152,27 @@ const handleDeleteNode = (data: TreeNode) => emit('delete-node', data);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 16px 12px 12px;
|
||||
border-bottom: 1px solid #e2e8f0;
|
||||
padding: 16px 14px 14px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.brand-logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
gap: 9px;
|
||||
}
|
||||
|
||||
.brand-icon {
|
||||
font-size: 20px;
|
||||
color: #2563eb;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 9px;
|
||||
background: linear-gradient(135deg, #2563eb, #4f8bff);
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
box-shadow: 0 2px 8px rgba(37, 99, 235, 0.25);
|
||||
}
|
||||
|
||||
.brand-name {
|
||||
@@ -194,18 +201,17 @@ const handleDeleteNode = (data: TreeNode) => emit('delete-node', data);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: #e2e8f0;
|
||||
background: #e8ebf0;
|
||||
color: #0f172a;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tab 切换 */
|
||||
/* Tab 切换(圆角胶囊) */
|
||||
.sidebar-tabs {
|
||||
display: flex;
|
||||
padding: 8px 8px 0;
|
||||
padding: 12px 12px 8px;
|
||||
gap: 4px;
|
||||
flex-shrink: 0;
|
||||
border-bottom: 1px solid #e2e8f0;
|
||||
}
|
||||
|
||||
.tab-btn {
|
||||
@@ -213,26 +219,24 @@ const handleDeleteNode = (data: TreeNode) => emit('delete-node', data);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
height: 34px;
|
||||
gap: 6px;
|
||||
height: 36px;
|
||||
border: none;
|
||||
border-radius: 8px 8px 0 0;
|
||||
border-radius: 10px;
|
||||
background: transparent;
|
||||
color: #64748b;
|
||||
font-size: 12px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: background 0.15s, color 0.15s;
|
||||
outline: none;
|
||||
border-bottom: 2px solid transparent;
|
||||
margin-bottom: -1px;
|
||||
|
||||
.el-icon {
|
||||
font-size: 14px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
&:hover:not(.active) {
|
||||
background: #f1f5f9;
|
||||
background: #eef0f3;
|
||||
color: #334155;
|
||||
}
|
||||
|
||||
@@ -240,7 +244,7 @@ const handleDeleteNode = (data: TreeNode) => emit('delete-node', data);
|
||||
color: #2563eb;
|
||||
font-weight: 600;
|
||||
background: #fff;
|
||||
border-bottom-color: #2563eb;
|
||||
box-shadow: 0 1px 4px rgba(15, 23, 42, 0.06);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,7 +252,7 @@ const handleDeleteNode = (data: TreeNode) => emit('delete-node', data);
|
||||
.panel {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 8px 8px 12px;
|
||||
padding: 4px 8px 12px;
|
||||
scrollbar-width: none;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
@@ -273,14 +277,14 @@ const handleDeleteNode = (data: TreeNode) => emit('delete-node', data);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px;
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
transition: background 0.15s;
|
||||
margin-bottom: 1px;
|
||||
margin-bottom: 2px;
|
||||
|
||||
&:hover {
|
||||
background: #f1f5f9;
|
||||
background: #eef0f3;
|
||||
|
||||
.item-del-btn {
|
||||
opacity: 1;
|
||||
@@ -288,7 +292,7 @@ const handleDeleteNode = (data: TreeNode) => emit('delete-node', data);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: #eff6ff;
|
||||
background: #e6f0ff;
|
||||
|
||||
.item-icon {
|
||||
color: #2563eb;
|
||||
@@ -325,17 +329,17 @@ const handleDeleteNode = (data: TreeNode) => emit('delete-node', data);
|
||||
.item-time {
|
||||
font-size: 11px;
|
||||
color: #94a3b8;
|
||||
margin-top: 1px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.item-del-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
border-radius: 6px;
|
||||
background: transparent;
|
||||
color: #94a3b8;
|
||||
cursor: pointer;
|
||||
@@ -365,7 +369,7 @@ const handleDeleteNode = (data: TreeNode) => emit('delete-node', data);
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: #94a3b8;
|
||||
padding: 6px 4px 2px;
|
||||
padding: 8px 6px 4px;
|
||||
letter-spacing: 0.4px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
@@ -374,13 +378,13 @@ const handleDeleteNode = (data: TreeNode) => emit('delete-node', data);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 5px 8px 5px 24px;
|
||||
border-radius: 6px;
|
||||
padding: 7px 10px 7px 24px;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: background 0.15s;
|
||||
|
||||
&:hover {
|
||||
background: #f1f5f9;
|
||||
background: #eef0f3;
|
||||
|
||||
.file-actions {
|
||||
opacity: 1;
|
||||
@@ -412,14 +416,6 @@ const handleDeleteNode = (data: TreeNode) => emit('delete-node', data);
|
||||
}
|
||||
|
||||
.file-action-btn {
|
||||
&--del {
|
||||
color: #ef4444;
|
||||
|
||||
&:hover {
|
||||
background: #fee2e2;
|
||||
color: #dc2626;
|
||||
}
|
||||
}
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: #3b82f6;
|
||||
@@ -433,7 +429,17 @@ const handleDeleteNode = (data: TreeNode) => emit('delete-node', data);
|
||||
&:hover {
|
||||
background: #dbeafe;
|
||||
}
|
||||
|
||||
&--del {
|
||||
color: #ef4444;
|
||||
|
||||
&:hover {
|
||||
background: #fee2e2;
|
||||
color: #dc2626;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.status-badge {
|
||||
font-size: 11px;
|
||||
padding: 1px 8px;
|
||||
@@ -449,8 +455,6 @@ const handleDeleteNode = (data: TreeNode) => emit('delete-node', data);
|
||||
animation: pulse 1.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.6; }
|
||||
|
||||
Reference in New Issue
Block a user