mirror of
https://github.com/continew-org/continew-admin-ui.git
synced 2026-01-12 05:01:39 +08:00
Co-authored-by: kiki1373639299<zkai0106@163.com> # message auto-generated for no-merge-commit merge: !11 merge dev into dev feat: 增强布局组件(同步GI-DEMO),支持更多布局选项并优化布局切换功能 Created-by: kiki1373639299 Commit-by: kiki1373639299 Merged-by: Charles_7c Description: <!-- 非常感谢您的 PR!在提交之前,请务必确保您 PR 的代码经过了完整测试,并且通过了代码规范检查。 --> <!-- 在 [] 中输入 x 来勾选) --> ## PR 类型 <!-- 您的 PR 引入了哪种类型的变更? --> <!-- 只支持选择一种类型,如果有多种类型,可以在更新日志中增加 “类型” 列。 --> - [X] 新 feature - [ ] Bug 修复 - [ ] 功能增强 - [ ] 文档变更 - [ ] 代码样式变更 - [ ] 重构 - [ ] 性能改进 - [ ] 单元测试 - [ ] CI/CD - [ ] 其他 ## PR 目的 同步GI-DEMO系统布局,并自定义样式增强 <!-- 描述一下您的 PR 解决了什么问题。如果可以,请链接到相关 issues。 --> ## 解决方案 <!-- 详细描述您是如何解决的问题 --> ## PR 测试 <!-- 如果可以,请为您的 PR 添加或更新单元测试。 --> <!-- 请描述一下您是如何测试 PR 的。例如:创建/更新单元测试或添加相关的截图。 --> ## Changelog | 模块 | Changelog | Related issues | |-----|-----------| -------------- | | | | | <!-- 如果有多种类型的变更,可以在变更日志表中增加 “类型” 列,该列的值与上方 “PR 类型” 相同。 --> <!-- Related issues 格式为 Closes #<issue号>,或者 Fixes #<issue号>,或者 Resolves #<issue号>。 --> ## 其他信息 <!-- 请描述一下还有哪些注意事项。例如:如果引入了一个不向下兼容的变更,请描述其影响。 --> ## 提交前确认 - [X] PR 代码经过了完整测试,并且通过了代码规范检查 - [ ] 已经完整填写 Changelog,并链接到了相关 issues - [X] PR 代码将要提交到 dev 分支 See merge request: continew/continew-admin-ui!11
203 lines
6.6 KiB
Vue
203 lines
6.6 KiB
Vue
<template>
|
||
<a-drawer v-model:visible="visible" title="项目配置" width="300px" unmount-on-close :footer="false">
|
||
<a-space :size="15" direction="vertical" fill>
|
||
<a-alert v-if="settingOpen" :show-icon="false" type="info">
|
||
「复制配置」按钮,并将配置粘贴到 src/config/settings.ts 文件中。
|
||
</a-alert>
|
||
<a-divider v-if="settingOpen" orientation="center">系统布局</a-divider>
|
||
<a-row v-if="settingOpen" :gutter="[8, 8]">
|
||
<a-col v-for="item in LAYOUT_OPTIONS" :key="item.value" :span="8">
|
||
<LayoutItem :mode="item.value" :name="item.label" @click="toggleLayout(item.value)" />
|
||
</a-col>
|
||
</a-row>
|
||
|
||
<a-divider orientation="center">系统主题</a-divider>
|
||
<a-row justify="center">
|
||
<ColorPicker
|
||
theme="dark" :color="appStore.themeColor" :sucker-hide="true" :colors-default="defaultColorList"
|
||
@change-color="changeColor"
|
||
></ColorPicker>
|
||
</a-row>
|
||
|
||
<a-divider v-if="settingOpen" orientation="center">界面显示</a-divider>
|
||
|
||
<a-descriptions v-if="settingOpen" :column="1" :align="{ value: 'right' }" :value-style="{ paddingRight: 0 }">
|
||
<a-descriptions-item label="页签显示">
|
||
<a-switch v-model="appStore.tab" />
|
||
</a-descriptions-item>
|
||
<a-descriptions-item label="页签风格">
|
||
<a-select
|
||
v-model="appStore.tabMode" placeholder="请选择" :options="tabModeList" :disabled="!appStore.tab"
|
||
:trigger-props="{ autoFitPopupMinWidth: true }" :style="{ width: '120px' }"
|
||
>
|
||
</a-select>
|
||
</a-descriptions-item>
|
||
<a-descriptions-item label="动画显示">
|
||
<a-switch v-model="appStore.animate" />
|
||
</a-descriptions-item>
|
||
<a-descriptions-item label="动画显示">
|
||
<a-select
|
||
v-model="appStore.animateMode" placeholder="请选择" :options="animateModeList"
|
||
:disabled="!appStore.animate" :style="{ width: '120px' }"
|
||
>
|
||
</a-select>
|
||
</a-descriptions-item>
|
||
<a-descriptions-item label="深色菜单">
|
||
<a-switch v-model="appStore.menuDark" />
|
||
</a-descriptions-item>
|
||
<a-descriptions-item label="手风琴效果">
|
||
<a-switch v-model="appStore.menuAccordion" />
|
||
</a-descriptions-item>
|
||
<a-descriptions-item label="版权显示">
|
||
<a-switch v-model="appStore.copyrightDisplay" />
|
||
</a-descriptions-item>
|
||
<a-descriptions-item label="水印">
|
||
<a-switch v-model="appStore.isOpenWatermark" />
|
||
</a-descriptions-item>
|
||
<a-descriptions-item label="水印信息">
|
||
<a-input v-model="appStore.watermark" placeholder="留空则显示用户名" />
|
||
</a-descriptions-item>
|
||
</a-descriptions>
|
||
|
||
<a-divider orientation="center">其它</a-divider>
|
||
<a-descriptions :column="1" :align="{ value: 'right' }" :value-style="{ paddingRight: 0 }">
|
||
<a-descriptions-item label="色弱模式">
|
||
<a-switch v-model="appStore.enableColorWeaknessMode" />
|
||
</a-descriptions-item>
|
||
<a-descriptions-item v-if="settingOpen" label="哀悼模式">
|
||
<a-switch v-model="appStore.enableMourningMode" />
|
||
</a-descriptions-item>
|
||
</a-descriptions>
|
||
<a-space v-if="settingOpen" direction="vertical" fill>
|
||
<a-button type="primary" long @click="copySettings">
|
||
<template #icon>
|
||
<icon-copy />
|
||
</template>
|
||
复制配置
|
||
</a-button>
|
||
</a-space>
|
||
</a-space>
|
||
</a-drawer>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ColorPicker } from 'vue-color-kit'
|
||
import 'vue-color-kit/dist/vue-color-kit.css'
|
||
import { useClipboard } from '@vueuse/core'
|
||
import { Message } from '@arco-design/web-vue'
|
||
import LayoutItem from './components/LayoutItem.vue'
|
||
import { useAppStore } from '@/stores'
|
||
|
||
defineOptions({ name: 'SettingDrawer' })
|
||
const appStore = useAppStore()
|
||
const visible = ref(false)
|
||
const settingOpen = JSON.parse(import.meta.env.VITE_APP_SETTING)
|
||
interface LayoutItemProps { label: string, value: App.AppSettings['layout'] }
|
||
|
||
/** 布局选项 */
|
||
const LAYOUT_OPTIONS: LayoutItemProps[] = [
|
||
{ label: '默认布局', value: 'left' },
|
||
{ label: '混合布局', value: 'mix' },
|
||
{ label: '顶部布局', value: 'top' },
|
||
{ label: '双列布局', value: 'columns' },
|
||
]
|
||
const tabModeList: App.TabItem[] = [
|
||
{ label: '卡片', value: 'card' },
|
||
{ label: '间隔卡片', value: 'card-gutter' },
|
||
{ label: '圆角', value: 'rounded' },
|
||
]
|
||
|
||
const animateModeList: App.AnimateItem[] = [
|
||
{ label: '默认', value: 'zoom-fade' },
|
||
{ label: '滑动', value: 'fade-slide' },
|
||
{ label: '渐变', value: 'fade' },
|
||
{ label: '底部滑出', value: 'fade-bottom' },
|
||
{ label: '缩放消退', value: 'fade-scale' },
|
||
]
|
||
|
||
const open = () => {
|
||
visible.value = true
|
||
}
|
||
|
||
// 默认显示的主题色列表
|
||
const defaultColorList = [
|
||
'#165DFF',
|
||
'#409EFF',
|
||
'#18A058',
|
||
'#2d8cf0',
|
||
'#007AFF',
|
||
'#5ac8fa',
|
||
'#5856D6',
|
||
'#536dfe',
|
||
'#9c27b0',
|
||
'#AF52DE',
|
||
'#0096c7',
|
||
'#00C1D4',
|
||
'#43a047',
|
||
'#e53935',
|
||
'#f4511e',
|
||
'#6d4c41',
|
||
]
|
||
|
||
interface ColorObj {
|
||
hex: string
|
||
hsv: { h: number, s: number, v: number }
|
||
rgba: { r: number, g: number, b: number, a: number }
|
||
}
|
||
|
||
// 改变主题色
|
||
const changeColor = (colorObj: ColorObj) => {
|
||
if (!/^#[0-9A-Z]{6}/i.test(colorObj.hex)) return
|
||
appStore.setThemeColor(colorObj.hex)
|
||
}
|
||
|
||
// 复制配置
|
||
const copySettings = () => {
|
||
const settings: App.AppSettings = {
|
||
theme: 'light',
|
||
themeColor: appStore.themeColor,
|
||
tab: appStore.tab,
|
||
tabMode: appStore.tabMode,
|
||
animate: appStore.animate,
|
||
animateMode: appStore.animateMode,
|
||
menuCollapse: appStore.menuCollapse,
|
||
menuAccordion: appStore.menuAccordion,
|
||
menuDark: appStore.menuDark,
|
||
copyrightDisplay: appStore.copyrightDisplay,
|
||
layout: appStore.layout,
|
||
isOpenWatermark: appStore.isOpenWatermark,
|
||
watermark: appStore.watermark,
|
||
enableColorWeaknessMode: appStore.enableColorWeaknessMode,
|
||
enableMourningMode: appStore.enableMourningMode,
|
||
}
|
||
|
||
const settingJson = JSON.stringify(settings, null, 2)
|
||
const { isSupported, copy } = useClipboard({ source: settingJson })
|
||
if (isSupported) {
|
||
copy(settingJson)
|
||
Message.success({ content: '复制成功!' })
|
||
} else {
|
||
Message.error({ content: '请检查浏览器权限是否开启' })
|
||
}
|
||
}
|
||
/** 切换布局 */
|
||
const toggleLayout = (layout: App.AppSettings['layout']) => {
|
||
appStore.layout = layout
|
||
}
|
||
|
||
defineExpose({ open })
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
:deep(.arco-descriptions-item-label-block) {
|
||
color: var(--color-text-1);
|
||
}
|
||
|
||
.layout-text {
|
||
font-size: 12px;
|
||
text-align: center;
|
||
color: var(--color-text-2);
|
||
margin-top: 4px;
|
||
}
|
||
</style>
|