feat:导出板块的静态实现
This commit is contained in:
@@ -0,0 +1,418 @@
|
||||
<template>
|
||||
<div class="export-list">
|
||||
<!-- 导出样式选择 -->
|
||||
<div class="export-style-grid">
|
||||
<div
|
||||
v-for="item in exportStyles"
|
||||
:key="item.type"
|
||||
class="export-style-item"
|
||||
@click="handleSelect(item)"
|
||||
>
|
||||
<div class="style-icon" :style="{ color: item.color }">
|
||||
<SvgIcon :icon-class="item.icon" size="24px" />
|
||||
</div>
|
||||
<div class="style-name">{{ item.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 导出结果列表 -->
|
||||
<div class="export-result-section">
|
||||
<div v-if="exportResults.length > 0" class="result-list">
|
||||
<div v-for="(result, index) in exportResults" :key="index" class="result-item">
|
||||
<div class="result-icon" :style="{ color: result.color }">
|
||||
<SvgIcon :icon-class="result.icon" size="30px" />
|
||||
</div>
|
||||
<div class="result-info">
|
||||
<div class="result-name">{{ result.name }}</div>
|
||||
<div class="result-time">{{ formatTime(result.exportTime || Date.now()) }}</div>
|
||||
</div>
|
||||
<div class="result-actions">
|
||||
<el-popover
|
||||
placement="bottom-end"
|
||||
:width="120"
|
||||
:show-arrow="false"
|
||||
trigger="click"
|
||||
popper-class="action-popover"
|
||||
>
|
||||
<template #reference>
|
||||
<button class="more-btn" @click.stop>
|
||||
<SvgIcon icon-class="more" class="more-icon" size="16px" />
|
||||
</button>
|
||||
</template>
|
||||
<div class="action-menu">
|
||||
<div class="action-item" @click="previewResult(result)">
|
||||
<SvgIcon icon-class="YuLan" size="14px" />
|
||||
<span>预览文件</span>
|
||||
</div>
|
||||
<div class="action-item" @click="downloadResult(result)">
|
||||
<SvgIcon icon-class="XiaZai" size="14px" />
|
||||
<span>下载文件</span>
|
||||
</div>
|
||||
<div class="action-item" @click="shareResult(result)">
|
||||
<SvgIcon icon-class="FenXiang" size="14px" />
|
||||
<span>分享文件</span>
|
||||
</div>
|
||||
<div class="action-item" @click="deleteResult(result)">
|
||||
<SvgIcon icon-class="ShanChu" size="14px" />
|
||||
<span>删除文件</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="result-empty">暂无导出记录</div>
|
||||
</div>
|
||||
|
||||
<!-- 删除确认对话框 -->
|
||||
<DeleteConfirmDialog
|
||||
v-model="dialogVisible"
|
||||
title="确认删除该导出记录 ?"
|
||||
content="删除后,该记录无法恢复 !"
|
||||
@confirm="confirmDelete"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import SvgIcon from '@/components/SvgIcon/index.vue'
|
||||
import DeleteConfirmDialog from '@/components/DeleteConfirmDialog/index.vue'
|
||||
import { useAgentsStore } from '@/stores'
|
||||
|
||||
const agentsStore = useAgentsStore()
|
||||
|
||||
// 事件定义
|
||||
const emit = defineEmits<{
|
||||
(e: 'close'): void
|
||||
}>()
|
||||
|
||||
// 导出样式类型
|
||||
interface ExportStyle {
|
||||
type: string
|
||||
name: string
|
||||
icon: string
|
||||
color: string
|
||||
}
|
||||
|
||||
// 导出结果类型
|
||||
interface ExportResult {
|
||||
name: string
|
||||
icon: string
|
||||
type: string
|
||||
color: string
|
||||
exportTime?: number // 时间戳
|
||||
}
|
||||
|
||||
// 导出样式数据
|
||||
const exportStyles = ref<ExportStyle[]>([
|
||||
{ type: 'doc', name: '文本报告', icon: 'DOCX', color: '#00A2D2' },
|
||||
{ type: 'markdown', name: 'Markdown', icon: 'Markdown', color: '#FF5B5B' },
|
||||
{ type: 'mindmap', name: '思维导图', icon: 'SiWeiDaoTu', color: '#FF5BEE' },
|
||||
{ type: 'infographic', name: '信息图', icon: 'XinXiTu', color: '#FCE460' },
|
||||
{ type: 'excel', name: '数据表格', icon: 'XLSX', color: '#65AE00' },
|
||||
{ type: 'ppt', name: '演示文稿', icon: 'PPT', color: '#FF7914' }
|
||||
])
|
||||
|
||||
// 导出结果列表
|
||||
const exportResults = ref<ExportResult[]>([])
|
||||
|
||||
// 删除对话框相关
|
||||
const dialogVisible = ref(false)
|
||||
const resultToDelete = ref<ExportResult | null>(null)
|
||||
|
||||
// 格式化时间显示
|
||||
const formatTime = (timestamp: number): string => {
|
||||
const now = Date.now()
|
||||
const diff = now - timestamp
|
||||
const minutes = Math.floor(diff / 60000)
|
||||
const hours = Math.floor(diff / 3600000)
|
||||
const days = Math.floor(diff / 86400000)
|
||||
|
||||
if (minutes < 1) return '刚刚'
|
||||
if (minutes < 60) return `${minutes}分钟前`
|
||||
if (hours < 24) return `${hours}小时前`
|
||||
if (days < 7) return `${days}天前`
|
||||
|
||||
const date = new Date(timestamp)
|
||||
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(
|
||||
date.getDate()
|
||||
).padStart(2, '0')}`
|
||||
}
|
||||
|
||||
// 预览文件
|
||||
const previewResult = (_result: ExportResult) => {
|
||||
ElMessage.success('预览功能开发中')
|
||||
}
|
||||
|
||||
// 下载文件
|
||||
const downloadResult = (_result: ExportResult) => {
|
||||
ElMessage.success('下载功能开发中')
|
||||
}
|
||||
|
||||
// 分享
|
||||
const shareResult = (_result: ExportResult) => {
|
||||
ElMessage.success('分享功能开发中')
|
||||
}
|
||||
|
||||
// 删除
|
||||
const deleteResult = (result: ExportResult) => {
|
||||
resultToDelete.value = result
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
// 确认删除
|
||||
const confirmDelete = () => {
|
||||
if (!resultToDelete.value) return
|
||||
|
||||
const index = exportResults.value.indexOf(resultToDelete.value)
|
||||
if (index > -1) {
|
||||
exportResults.value.splice(index, 1)
|
||||
ElMessage.success('删除成功')
|
||||
}
|
||||
dialogVisible.value = false
|
||||
resultToDelete.value = null
|
||||
}
|
||||
|
||||
// 选择导出样式
|
||||
const handleSelect = (item: ExportStyle) => {
|
||||
const currentTask = agentsStore.currentTask
|
||||
if (!currentTask) {
|
||||
ElMessage.warning('请先选择任务')
|
||||
return
|
||||
}
|
||||
|
||||
// 生成导出名称:任务名称 + 样式名称
|
||||
const taskName = currentTask.StepName || '未知任务'
|
||||
const exportName = `${taskName}${item.name}`
|
||||
|
||||
// 添加到导出结果列表(添加到最前面)
|
||||
const newItem = {
|
||||
name: exportName,
|
||||
icon: item.icon,
|
||||
type: item.type,
|
||||
color: item.color,
|
||||
exportTime: Date.now()
|
||||
}
|
||||
|
||||
exportResults.value.unshift(newItem)
|
||||
|
||||
console.log('导出任务:', { task: currentTask, style: item })
|
||||
ElMessage.success(`已开始导出: ${item.name}`)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.export-list {
|
||||
padding: 16px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.export-style-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 152px);
|
||||
gap: 12px;
|
||||
justify-content: center;
|
||||
margin: 0 -16px 16px -16px;
|
||||
padding: 0 16px 16px 16px;
|
||||
border-bottom: 1px solid var(--color-border-separate);
|
||||
}
|
||||
|
||||
.export-style-item {
|
||||
width: 152px;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding: 0 12px;
|
||||
gap: 8px;
|
||||
border-radius: 12px;
|
||||
background: var(--color-bg-detail);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
background: var(--color-bg-content-hover);
|
||||
}
|
||||
|
||||
.style-icon {
|
||||
flex-shrink: 0;
|
||||
color: var(--color-text-plan-item);
|
||||
}
|
||||
|
||||
.style-name {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--color-text-plan-item);
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.export-result-section {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
|
||||
.result-title {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: var(--color-text-primary);
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.result-list {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
max-height: calc(100vh - 430px);
|
||||
}
|
||||
|
||||
.result-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px;
|
||||
margin-bottom: 8px;
|
||||
border-radius: 8px;
|
||||
background: var(--color-bg-three);
|
||||
transition: background 0.2s;
|
||||
|
||||
&:hover {
|
||||
background: var(--color-bg-hover);
|
||||
|
||||
.result-name {
|
||||
color: var(--color-text-plan-item-hover);
|
||||
}
|
||||
}
|
||||
.result-icon {
|
||||
color: var(--color-text-plan-item);
|
||||
}
|
||||
|
||||
.result-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
|
||||
.result-name {
|
||||
font-size: 14px;
|
||||
color: var(--color-text-placeholder);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.result-time {
|
||||
font-size: 12px;
|
||||
color: var(--color-text-plan-item);
|
||||
margin-top: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.result-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-left: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
// 更多按钮
|
||||
.more-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 4px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
transition: background-color 0.2s;
|
||||
|
||||
.more-icon {
|
||||
color: var(--color-text-plan-item);
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-card-border-three);
|
||||
|
||||
.more-icon {
|
||||
color: var(--color-text-plan-item-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 操作菜单
|
||||
.action-menu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.result-empty {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--color-text-placeholder);
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
.action-popover {
|
||||
padding: 0 !important;
|
||||
border-radius: 8px !important;
|
||||
width: 120px !important;
|
||||
min-width: 120px !important;
|
||||
background: var(--color-bg-three) !important;
|
||||
border: 1px solid var(--color-card-border-three) !important;
|
||||
}
|
||||
|
||||
.action-menu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.el-popover__content {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.action-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 16px;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
color: var(--color-text-plan-item);
|
||||
transition: background-color 0.2s, color 0.2s;
|
||||
|
||||
.svg-icon {
|
||||
color: var(--color-text-plan-item);
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-card-border-three);
|
||||
color: var(--color-text-plan-item-hover);
|
||||
|
||||
.svg-icon {
|
||||
color: var(--color-text-plan-item-hover);
|
||||
}
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-radius: 8px 8px 0 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-radius: 0 0 8px 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -23,6 +23,7 @@ const props = defineProps<{
|
||||
const emit = defineEmits<{
|
||||
(e: 'refreshLine'): void
|
||||
(e: 'setCurrentTask', task: IRawStepTask): void
|
||||
(e: 'openExport'): void
|
||||
}>()
|
||||
|
||||
const agentsStore = useAgentsStore()
|
||||
@@ -1148,7 +1149,7 @@ onMounted(() => {
|
||||
})
|
||||
|
||||
// 按钮交互状态管理
|
||||
type ButtonState = 'process' | 'execute' | 'refresh' | null
|
||||
type ButtonState = 'process' | 'execute' | 'refresh' | 'export' | null
|
||||
const buttonHoverState = ref<ButtonState>(null)
|
||||
let buttonHoverTimer: ReturnType<typeof setTimeout> | null = null
|
||||
|
||||
@@ -1173,6 +1174,8 @@ const handleExecuteMouseEnter = () =>
|
||||
setButtonHoverState('execute', !!agentsStore.agentRawPlan.data)
|
||||
const handleRefreshMouseEnter = () =>
|
||||
setButtonHoverState('refresh', agentsStore.executePlan.length > 0)
|
||||
const handleExportMouseEnter = () =>
|
||||
setButtonHoverState('export', agentsStore.executePlan.length > 0)
|
||||
|
||||
const handleButtonMouseLeave = () => {
|
||||
clearButtonHoverTimer()
|
||||
@@ -1189,21 +1192,44 @@ onUnmounted(() => {
|
||||
})
|
||||
// 计算按钮类名
|
||||
const processBtnClass = computed(() => {
|
||||
if (buttonHoverState.value === 'refresh' || buttonHoverState.value === 'execute') {
|
||||
if (
|
||||
buttonHoverState.value === 'refresh' ||
|
||||
buttonHoverState.value === 'execute' ||
|
||||
buttonHoverState.value === 'export'
|
||||
) {
|
||||
return 'circle'
|
||||
}
|
||||
return buttonHoverState.value === 'process' ? 'ellipse' : 'circle'
|
||||
})
|
||||
|
||||
const executeBtnClass = computed(() => {
|
||||
if (buttonHoverState.value === 'process' || buttonHoverState.value === 'refresh') {
|
||||
if (
|
||||
buttonHoverState.value === 'process' ||
|
||||
buttonHoverState.value === 'refresh' ||
|
||||
buttonHoverState.value === 'export'
|
||||
) {
|
||||
return 'circle task-execute-btn'
|
||||
}
|
||||
return agentsStore.agentRawPlan.data ? 'ellipse task-execute-btn' : 'circle task-execute-btn'
|
||||
})
|
||||
|
||||
const refreshBtnClass = computed(() => {
|
||||
if (buttonHoverState.value === 'process' || buttonHoverState.value === 'execute') {
|
||||
if (
|
||||
buttonHoverState.value === 'process' ||
|
||||
buttonHoverState.value === 'execute' ||
|
||||
buttonHoverState.value === 'export'
|
||||
) {
|
||||
return 'circle'
|
||||
}
|
||||
return agentsStore.executePlan.length > 0 ? 'ellipse' : 'circle'
|
||||
})
|
||||
|
||||
const exportBtnClass = computed(() => {
|
||||
if (
|
||||
buttonHoverState.value === 'process' ||
|
||||
buttonHoverState.value === 'execute' ||
|
||||
buttonHoverState.value === 'refresh'
|
||||
) {
|
||||
return 'circle'
|
||||
}
|
||||
return agentsStore.executePlan.length > 0 ? 'ellipse' : 'circle'
|
||||
@@ -1223,6 +1249,10 @@ const showRefreshText = computed(() => {
|
||||
return buttonHoverState.value === 'refresh'
|
||||
})
|
||||
|
||||
const showExportText = computed(() => {
|
||||
return buttonHoverState.value === 'export'
|
||||
})
|
||||
|
||||
// 计算按钮标题
|
||||
const processBtnTitle = computed(() => {
|
||||
return buttonHoverState.value === 'process' ? '查看任务流程' : '点击查看任务流程'
|
||||
@@ -1255,7 +1285,7 @@ defineExpose({
|
||||
<div class="text-[18px] font-bold mb-[7px] flex justify-between items-center px-[20px]">
|
||||
<span class="text-[var(--color-text-title-header)]">执行结果</span>
|
||||
<div
|
||||
class="flex items-center justify-end gap-[10px] task-button-group w-[230px]"
|
||||
class="flex items-center justify-end gap-[10px] task-button-group w-[280px]"
|
||||
@mouseleave="handleButtonMouseLeave"
|
||||
>
|
||||
<!-- 刷新按钮 -->
|
||||
@@ -1266,11 +1296,24 @@ defineExpose({
|
||||
:disabled="agentsStore.executePlan.length === 0"
|
||||
@mouseenter="handleRefreshMouseEnter"
|
||||
@click="handleRefresh"
|
||||
style="order: 0"
|
||||
style="order: 1"
|
||||
>
|
||||
<svg-icon icon-class="refresh" />
|
||||
<span v-if="showRefreshText" class="btn-text">重置</span>
|
||||
</el-button>
|
||||
<!-- 导出按钮 -->
|
||||
<el-button
|
||||
:class="exportBtnClass"
|
||||
:color="variables.tertiary"
|
||||
title="导出"
|
||||
:disabled="agentsStore.executePlan.length === 0"
|
||||
@mouseenter="handleExportMouseEnter"
|
||||
@click="emit('openExport')"
|
||||
style="order: 0"
|
||||
>
|
||||
<svg-icon icon-class="DaoChu" />
|
||||
<span v-if="showExportText" class="btn-text">导出</span>
|
||||
</el-button>
|
||||
<!-- Task Process按钮 -->
|
||||
<el-button
|
||||
:class="processBtnClass"
|
||||
@@ -1278,7 +1321,7 @@ defineExpose({
|
||||
:title="processBtnTitle"
|
||||
@mouseenter="handleProcessMouseEnter"
|
||||
@click="handleTaskProcess"
|
||||
style="order: 1"
|
||||
style="order: 3"
|
||||
>
|
||||
<svg-icon icon-class="process" />
|
||||
<span v-if="showProcessText" class="btn-text">任务过程</span>
|
||||
|
||||
@@ -3,6 +3,7 @@ import AgentRepo from './AgentRepo/index.vue'
|
||||
import TaskSyllabus from './TaskSyllabus/index.vue'
|
||||
import TaskResult from './TaskResult/index.vue'
|
||||
import HistoryList from './HistoryList/index.vue'
|
||||
import ExportList from './ExportList/index.vue'
|
||||
import SvgIcon from '@/components/SvgIcon/index.vue'
|
||||
import { Jsplumb } from './utils.ts'
|
||||
import { type IRawStepTask, useAgentsStore } from '@/stores'
|
||||
@@ -24,11 +25,19 @@ const agentsStore = useAgentsStore()
|
||||
// 历史记录弹窗控制
|
||||
const historyDialogVisible = ref(false)
|
||||
|
||||
// 导出弹窗控制
|
||||
const exportDialogVisible = ref(false)
|
||||
|
||||
// 打开历史记录弹窗
|
||||
const openHistoryDialog = () => {
|
||||
historyDialogVisible.value = true
|
||||
}
|
||||
|
||||
// 打开导出弹窗
|
||||
const openExportDialog = () => {
|
||||
exportDialogVisible.value = true
|
||||
}
|
||||
|
||||
// 处理历史任务恢复
|
||||
const handleRestorePlan = (plan: any) => {
|
||||
// 关闭弹窗
|
||||
@@ -102,6 +111,7 @@ function clear() {
|
||||
|
||||
defineExpose({
|
||||
openHistoryDialog,
|
||||
openExportDialog,
|
||||
changeTask,
|
||||
resetAgentRepoLine,
|
||||
clear
|
||||
@@ -133,6 +143,7 @@ defineExpose({
|
||||
:TaskID="props.TaskID"
|
||||
@refresh-line="taskResultJsplumb.repaintEverything"
|
||||
@set-current-task="handleTaskResultCurrentTask"
|
||||
@open-export="openExportDialog"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -151,6 +162,22 @@ defineExpose({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 导出弹窗 -->
|
||||
<div v-if="exportDialogVisible" class="export-drawer">
|
||||
<div class="export-drawer-content">
|
||||
<div class="export-drawer-header">
|
||||
<span class="export-drawer-title">导出</span>
|
||||
<button class="export-drawer-close" @click="exportDialogVisible = false">
|
||||
<SvgIcon icon-class="close" size="20px" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="h-[1px] w-full bg-[var(--color-border-separate)] my-[8px]"></div>
|
||||
<div class="export-drawer-body">
|
||||
<ExportList @close="exportDialogVisible = false" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -247,4 +274,72 @@ defineExpose({
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
// 导出 Drawer 样式
|
||||
:deep(.export-drawer) {
|
||||
// 强制使用绝对定位,相对于父容器
|
||||
position: absolute !important;
|
||||
top: 0 !important;
|
||||
bottom: 0 !important;
|
||||
right: 0 !important;
|
||||
z-index: 1000;
|
||||
// 高度由 top/bottom 控制
|
||||
height: auto !important;
|
||||
width: 500px !important;
|
||||
|
||||
background-color: var(--color-bg-three);
|
||||
border: 1px solid var(--color-card-border-three);
|
||||
border-radius: 24px;
|
||||
box-shadow: var(--color-card-shadow-three);
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
|
||||
// 动画:从右向左滑入
|
||||
animation: export-drawer-slide-in 0.5s ease-out;
|
||||
|
||||
// 头部
|
||||
.export-drawer-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 16px;
|
||||
background-color: var(--color-bg-three);
|
||||
}
|
||||
|
||||
// 标题
|
||||
.export-drawer-title {
|
||||
color: var(--color-text-primary);
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
// 关闭按钮
|
||||
.export-drawer-close {
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 4px;
|
||||
color: var(--color-text-regular);
|
||||
transition: transform 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes export-drawer-slide-in {
|
||||
from {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
to {
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user