This commit is contained in:
2026-01-16 13:10:36 +08:00
parent 7a4ca4275e
commit b6bb8a6deb
7 changed files with 564 additions and 120 deletions

View File

@@ -1,9 +1,293 @@
<template>
<a-drawer v-model:open="open" title="布局配置"></a-drawer>
<a-drawer v-model:open="open" title="布局配置" placement="right" :width="420">
<div class="setting-content">
<div class="setting-item">
<div class="setting-title">布局模式</div>
<div class="layout-mode-list">
<div v-for="mode in layoutModes" :key="mode.value" class="layout-mode-item"
:class="{ active: layoutStore.layoutMode === mode.value }"
@click="handleLayoutChange(mode.value)">
<div class="layout-preview" :class="`preview-${mode.value}`">
<div class="preview-sidebar"></div>
<div class="preview-content">
<div class="preview-header"></div>
<div class="preview-body"></div>
</div>
</div>
<div class="layout-name">{{ mode.label }}</div>
<CheckOutlined v-if="layoutStore.layoutMode === mode.value" class="check-icon" />
</div>
</div>
</div>
<div class="setting-item">
<div class="setting-title">主题颜色</div>
<div class="color-list">
<div v-for="color in themeColors" :key="color" class="color-item"
:class="{ active: themeColor === color }" :style="{ backgroundColor: color }"
@click="changeThemeColor(color)">
<CheckOutlined v-if="themeColor === color" />
</div>
</div>
</div>
<div class="setting-item">
<div class="setting-title">显示设置</div>
<div class="toggle-list">
<div class="toggle-item">
<span>显示标签栏</span>
<a-switch v-model:checked="showTags" @change="handleShowTagsChange" />
</div>
</div>
</div>
</div>
</a-drawer>
</template>
<script setup>
import { ref } from 'vue';
import { ref, defineExpose } from 'vue'
import { message } from 'ant-design-vue'
import { useLayoutStore } from '@/stores/modules/layout'
import { CheckOutlined } from '@ant-design/icons-vue'
const layoutStore = useLayoutStore()
const open = ref(false)
const themeColor = ref('#1890ff')
const showTags = ref(true)
const layoutModes = [
{ value: 'default', label: '默认布局' },
{ value: 'menu', label: '菜单布局' },
{ value: 'top', label: '顶部布局' }
]
const themeColors = [
'#1890ff',
'#f5222d',
'#fa541c',
'#faad14',
'#13c2c2',
'#52c41a',
'#2f54eb',
'#722ed1'
]
const openDrawer = () => {
open.value = true
}
const closeDrawer = () => {
open.value = false
}
defineExpose({
openDrawer,
closeDrawer
})
// 切换布局
const handleLayoutChange = (mode) => {
layoutStore.setLayoutMode(mode)
const modeLabel = layoutModes.find(m => m.value === mode)?.label || mode
message.success(`已切换到${modeLabel}`)
}
// 切换主题颜色
const changeThemeColor = (color) => {
themeColor.value = color
// 这里可以实现主题切换逻辑
message.success('主题颜色已更新')
}
// 切换标签栏显示
const handleShowTagsChange = (checked) => {
// 这里可以实现标签栏显示/隐藏逻辑
console.log('showTags:', checked)
}
</script>
<style scoped lang="scss">
.setting-content {
.setting-item {
margin-bottom: 32px;
.setting-title {
font-size: 14px;
font-weight: 500;
margin-bottom: 16px;
color: #333;
}
.layout-mode-list {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 12px;
.layout-mode-item {
position: relative;
border: 2px solid #e8e8e8;
border-radius: 8px;
padding: 12px;
cursor: pointer;
transition: all 0.3s;
&:hover {
border-color: #1890ff;
}
&.active {
border-color: #1890ff;
}
.layout-preview {
width: 100%;
height: 60px;
border-radius: 4px;
margin-bottom: 8px;
overflow: hidden;
display: flex;
background-color: #f0f2f5;
&.preview-default {
.preview-sidebar {
width: 20px;
background-color: #001529;
}
.preview-sidebar-2 {
width: 24px;
background-color: #fff;
border-left: 1px solid #e8e8e8;
}
.preview-content {
flex: 1;
padding: 4px;
.preview-header {
height: 8px;
background-color: #fff;
margin-bottom: 4px;
}
.preview-body {
height: calc(100% - 12px);
background-color: #e8e8e8;
}
}
}
&.preview-menu {
.preview-sidebar {
width: 30px;
background-color: #fff;
border-right: 1px solid #e8e8e8;
}
.preview-content {
flex: 1;
padding: 4px;
.preview-header {
height: 8px;
background-color: #fff;
margin-bottom: 4px;
}
.preview-body {
height: calc(100% - 12px);
background-color: #e8e8e8;
}
}
}
&.preview-top {
flex-direction: column;
.preview-sidebar {
width: 100%;
height: 12px;
background-color: #fff;
}
.preview-content {
flex: 1;
padding: 4px;
.preview-header {
display: none;
}
.preview-body {
height: 100%;
background-color: #e8e8e8;
}
}
}
}
.layout-name {
font-size: 12px;
color: #666;
text-align: center;
}
.check-icon {
position: absolute;
top: 4px;
right: 4px;
color: #1890ff;
font-size: 12px;
}
}
}
.color-list {
display: flex;
flex-wrap: wrap;
gap: 12px;
.color-item {
width: 32px;
height: 32px;
border-radius: 4px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: transform 0.2s;
&:hover {
transform: scale(1.1);
}
&.active {
.anticon {
color: #fff;
}
}
}
}
.toggle-list {
.toggle-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 0;
border-bottom: 1px solid #f0f0f0;
&:last-child {
border-bottom: none;
}
span {
font-size: 14px;
color: #333;
}
}
}
}
}
</style>