初始化拉取,原文件名:admin-plus-webpack5
Some checks failed
Call HTTPS API / build (push) Has been cancelled

This commit is contained in:
2025-12-26 20:43:10 +08:00
parent 7c68ec3a42
commit 3e2da1115e
420 changed files with 75413 additions and 2 deletions

View File

@@ -0,0 +1,515 @@
<script lang="ts" setup>
import { translate } from '@/i18n'
import { useSettingsStore } from '@/store/modules/settings'
const $sub: any = inject('$sub')
const $unsub: any = inject('$unsub')
const $baseLoading: any = inject('$baseLoading')
const settingsStore: any = useSettingsStore()
const { theme, device }: any = storeToRefs(settingsStore)
const { saveTheme, resetTheme, updateTheme }: any = settingsStore
const state = reactive({
drawerVisible: false,
})
const handleOpenTheme = () => {
state.drawerVisible = true
}
const updateMenuWidth = () => {
useCssVar('--el-left-menu-width', ref(null)).value =
theme.value.menuWidth
}
const setDefaultTheme = async () => {
await resetTheme()
await updateTheme()
state.drawerVisible = false
if (document.body.getBoundingClientRect().width - 1 < 992)
location.reload()
}
const handleSaveTheme = async () => {
await saveTheme()
state.drawerVisible = false
if (document.body.getBoundingClientRect().width - 1 < 992)
location.reload()
}
const shuffle = (val: string | boolean, list: (string | boolean)[]) =>
list.filter((_) => _ !== val)[(Math.random() * (list.length - 1)) | 0]
const randomTheme = async () => {
const loading = $baseLoading(0)
// 随机换肤重置移除主题,防止代码更新影响样式
await resetTheme()
theme.value.themeName = shuffle(theme.value.themeName, [
'blue-black',
'blue-white',
'ocean',
'green-black',
'green-white',
'purple-black',
'purple-white',
'red-black',
'red-white',
])
theme.value.columnStyle = shuffle(theme.value.columnStyle, [
'vertical',
'horizontal',
'card',
'arrow',
])
// theme.value.background = shuffle(theme.value.background, [
// 'none',
// 'vab-background',
// ])
theme.value.tabsBarStyle = shuffle(theme.value.tabsBarStyle, [
'card',
'smart',
'smooth',
])
theme.value.showTabsIcon = shuffle(theme.value.showTabsIcon, [
true,
false,
])
theme.value.layout =
device.value === 'desktop'
? shuffle(theme.value.layout, [
'horizontal',
'vertical',
'column',
'comprehensive',
'common',
'float',
])
: 'vertical'
try {
await updateTheme()
await saveTheme()
} finally {
setTimeout(() => {
loading.close()
}, 1000)
}
}
$sub('theme', () => {
handleOpenTheme()
})
$sub('random-theme', () => {
randomTheme()
})
onBeforeUnmount(() => {
$unsub('theme')
$unsub('random-theme')
})
</script>
<template>
<el-drawer
v-model="state.drawerVisible"
append-to-body
class="vab-drawer"
direction="rtl"
size="285px"
:title="translate('主题配置')"
>
<el-scrollbar height="88vh">
<el-form ref="form" label-position="left" :model="theme">
<el-form-item>
<template #label>
{{ translate('布局') }}
<el-tooltip
:content="
translate(
'布局配置仅' +
'在电脑视窗下生效,手机视窗时将' +
'默认锁定为纵向布局'
)
"
effect="dark"
placement="top"
>
<vab-icon icon="question-line" />
</el-tooltip>
</template>
<el-select
v-model="theme.layout"
:disabled="device === 'mobile'"
placeholder="请选择"
>
<el-option
key="column"
:label="translate('分栏')"
value="column"
/>
<el-option
key="comprehensive"
:label="translate('综合')"
value="comprehensive"
/>
<el-option
key="vertical"
:label="translate('纵向')"
value="vertical"
/>
<el-option
key="horizontal"
:label="translate('横向')"
value="horizontal"
/>
<el-option
key="common"
:label="translate('常规')"
value="common"
/>
<el-option
key="float"
:label="translate('浮动')"
value="float"
/>
</el-select>
</el-form-item>
<el-form-item :label="translate('主题')">
<el-select v-model="theme.themeName" @change="updateTheme">
<el-option
key="blue-black"
:label="translate('蓝黑')"
value="blue-black"
/>
<el-option
key="blue-white"
:label="translate('蓝白')"
value="blue-white"
/>
<el-option
key="green-black"
:label="translate('绿黑')"
value="green-black"
/>
<el-option
key="green-white"
:label="translate('绿白')"
value="green-white"
/>
<el-option
key="purple-black"
:label="translate('紫黑')"
value="purple-black"
/>
<el-option
key="purple-white"
:label="translate('紫白')"
value="purple-white"
/>
<!-- 红黑红白主题完成群文档任务免费获取 -->
<el-option
key="red-black"
:label="translate('红黑')"
value="red-black"
/>
<el-option
key="red-white"
:label="translate('红白')"
value="red-white"
/>
<el-option
key="ocean"
:label="translate('渐变')"
value="ocean"
/>
</el-select>
</el-form-item>
<el-form-item class="vab-item-custom">
<template #label>
{{ translate('菜单背景') }}
<el-tooltip
:content="
translate(
'支持纵向布局' +
'、分栏布局、综合' +
'布局、常规布局,不支持横' +
'向布局、浮动' +
'布局'
)
"
effect="dark"
placement="top"
>
<vab-icon icon="question-line" />
</el-tooltip>
</template>
<el-radio-group
v-model="theme.background"
:disabled="
theme.layout === 'float' ||
theme.layout === 'horizontal'
"
@change="updateTheme"
>
<el-radio-button
class="none"
label="none"
value="none"
/>
<el-radio-button
class="vab-background"
label="vab-background"
value="vab-background"
/>
</el-radio-group>
</el-form-item>
<el-form-item :label="translate('菜单宽度')">
<el-select
v-model="theme.menuWidth"
:disabled="
theme.layout === 'float' ||
theme.layout === 'horizontal'
"
@change="updateMenuWidth"
>
<el-option key="266px" label="266px" value="266px" />
<el-option key="277px" label="277px" value="277px" />
<el-option key="288px" label="288px" value="288px" />
</el-select>
</el-form-item>
<el-form-item :label="translate('标签')">
<el-switch v-model="theme.showTabs" />
</el-form-item>
<el-form-item>
<template #label>
{{ translate('标签图标') }}
<el-tooltip
:content="translate('标签开启时生效')"
effect="dark"
placement="top"
>
<vab-icon icon="question-line" />
</el-tooltip>
</template>
<el-switch
v-model="theme.showTabsIcon"
:disabled="!theme.showTabs"
/>
</el-form-item>
<el-form-item>
<template #label>
{{ translate('标签风格') }}
<el-tooltip
:content="translate('标签开启时生效')"
effect="dark"
placement="top"
>
<vab-icon icon="question-line" />
</el-tooltip>
</template>
<el-select
v-model="theme.tabsBarStyle"
:disabled="!theme.showTabs"
>
<el-option
key="card"
:label="translate('卡片')"
value="card"
/>
<el-option
key="smart"
:label="translate('灵动')"
value="smart"
/>
<el-option
key="smooth"
:label="translate('圆滑')"
value="smooth"
/>
</el-select>
</el-form-item>
<el-form-item>
<template #label>
{{ translate('分栏风格') }}
<el-tooltip
:content="translate('分栏布局时生效')"
effect="dark"
placement="top"
>
<vab-icon icon="question-line" />
</el-tooltip>
</template>
<el-select
v-model="theme.columnStyle"
:disabled="theme.layout !== 'column'"
>
<el-option
key="vertical"
:label="translate('纵向')"
value="vertical"
/>
<el-option
key="horizontal"
:label="translate('横向')"
value="horizontal"
/>
<el-option
key="card"
:label="translate('卡片')"
value="card"
/>
<el-option
key="arrow"
:label="translate('箭头')"
value="arrow"
/>
</el-select>
</el-form-item>
<el-form-item :label="translate('头部固定')">
<el-switch
v-model="theme.fixedHeader"
:disabled="theme.layout === 'common'"
/>
</el-form-item>
<el-form-item :label="translate('国际化')">
<el-switch v-model="theme.showLanguage" />
</el-form-item>
<el-form-item :label="translate('进度条')">
<el-switch v-model="theme.showProgressBar" />
</el-form-item>
<el-form-item :label="translate('刷新')">
<el-switch v-model="theme.showRefresh" />
</el-form-item>
<el-form-item :label="translate('搜索')">
<el-switch v-model="theme.showSearch" />
</el-form-item>
<el-form-item :label="translate('通知')">
<el-switch v-model="theme.showNotice" />
</el-form-item>
<el-form-item :label="translate('全屏')">
<el-switch v-model="theme.showFullScreen" />
</el-form-item>
<el-form-item :label="translate('锁屏')">
<el-switch v-model="theme.showLock" />
</el-form-item>
<el-form-item :label="translate('页面动画')">
<el-switch v-model="theme.showPageTransition" />
</el-form-item>
</el-form>
</el-scrollbar>
<template #footer>
<el-button type="primary" @click="handleSaveTheme">
{{ translate('保存') }}
</el-button>
<el-button @click="setDefaultTheme">
{{ translate('恢复默认') }}
</el-button>
</template>
</el-drawer>
</template>
<style lang="scss">
@use 'sass:math';
.vab-drawer {
// position: relative;
.el-drawer__header {
padding: $base-padding $base-padding 0 $base-padding;
margin-bottom: 0;
}
.el-drawer__body {
padding-right: 0;
.el-scrollbar__wrap {
height: calc(100vh - 80px);
padding-right: $base-padding;
.el-divider--horizontal {
margin: $base-margin * 2 0 $base-margin * 2 0;
}
.el-form-item {
display: flex;
align-items: center;
&__label {
flex: 1 1;
i {
cursor: pointer;
}
}
&__content {
flex: 0 0 auto;
}
&.vab-item-custom {
display: block !important;
height: 130px;
}
.el-radio-button {
float: left;
display: block;
width: 80px;
height: 80px;
margin: 10px;
cursor: pointer;
border-radius: 5px;
&.is-disabled {
cursor: not-allowed;
opacity: 0.6;
}
&.is-active {
box-shadow: 0 0 2px 2px #1890ff;
}
.el-radio-button__orig-radio,
.el-radio-button__inner {
display: none;
}
&.none {
font-family: 'remixicon', sans-serif !important;
font-size: 16px;
font-weight: 580;
line-height: 80px;
text-align: center;
background: #f7f7f7 none;
background-size: cover;
&:before {
content: '\eace';
}
}
&.vab-background {
background: url(~@/assets/theme_images/background-1.png);
background-size: cover;
}
}
.el-input__inner {
width: 115px;
}
}
}
}
.el-drawer__footer {
position: absolute;
right: 0;
bottom: 0;
left: 0;
z-index: $base-z-index + 1;
display: flex;
padding: math.div($base-padding, 2);
background: var(--el-color-white);
border-top: 1px solid #{$base-border-color};
}
}
</style>

View File

@@ -0,0 +1,168 @@
<script lang="ts" setup>
import { useSettingsStore } from '@/store/modules/settings'
import { translate } from '@/i18n'
const $pub: any = inject('$pub')
//const $baseMessage: any = inject('$baseMessage')
const settingsStore: any = useSettingsStore()
const { theme }: any = storeToRefs(settingsStore)
const handleOpenTheme = () => {
$pub('theme')
}
const randomTheme = () => {
$pub('random-theme')
}
const buy = () => {
window.open('https://vuejs-core.cn/authorization')
}
// const getCode = () => {
// if (process.env.NODE_ENV === 'development') $pub('get-code')
// else
// ElMessageBox.prompt(
// '请输入密码(密码在购买时获得跳转后需登录购买时绑定的github账号)',
// '温馨提示',
// {
// confirmButtonText: '确定',
// cancelButtonText: '取消',
// }
// )
// .then(({ value }) => {
// if (value !== 'vabp') {
// $baseMessage(
// '密码不正确!',
// 'error',
// 'vab-hey-message-error'
// )
// return
// }
// $pub('get-code')
// })
// .catch(() => {})
// }
const removeLocalStorage = () => {
localStorage.clear()
location.reload()
}
</script>
<template>
<ul v-if="theme.showThemeSetting" class="vab-theme-setting">
<li @click="handleOpenTheme">
<a>
<vab-icon icon="brush-2-line" />
<p>{{ translate('主题配置') }}</p>
</a>
</li>
<li @click="randomTheme">
<a>
<vab-icon icon="apps-line" />
<p>{{ translate('随机换肤') }}</p>
</a>
</li>
<li @click="buy">
<a>
<vab-icon icon="shopping-cart-2-line" />
<p>{{ translate('购买源码') }}</p>
</a>
</li>
<!-- <li @click="getCode">
<a>
<vab-icon icon="file-copy-line" />
<p>{{ translate('拷贝源码') }}</p>
</a>
</li> -->
<li @click="removeLocalStorage">
<a>
<vab-icon icon="delete-bin-4-line" />
<p>
{{ translate('清理缓存') }}
</p>
</a>
</li>
</ul>
</template>
<style lang="scss" scoped>
.vab-theme-setting {
position: fixed;
top: 50%;
right: 0;
z-index: $base-z-index - 2;
padding: 10px 0 0 0;
margin: 0;
text-align: center;
cursor: pointer;
background: var(--el-color-white);
border: 1px solid #{$base-border-color};
border-top-left-radius: $base-border-radius + 3;
border-bottom-left-radius: $base-border-radius + 3;
box-shadow: 0 0 50px 0 rgb(82 63 105 / 15%);
transform: translateY(-50%);
> li {
display: flex;
align-items: center;
justify-content: center;
padding: 0 8px 10px 10px;
margin: 0;
list-style: none;
&:nth-child(2) {
[class*='ri-'] {
animation: rotate 6s linear infinite;
}
}
$colors: (
1: #3698fd,
2: #1bc3bb,
3: #faa500,
4: #b37feb,
5: #ef4c5d,
);
@each $key, $color in $colors {
&:nth-child(#{$key}) {
a {
color: $color;
background: mix($base-color-white, $color, 90%);
transition:
color 0.15s ease,
background-color 0.15s ease,
border-color 0.15s ease,
box-shadow 0.15s ease,
-webkit-box-shadow 0.15s ease;
&:hover {
color: var(--el-color-white);
background: $color;
}
}
}
}
a {
display: inline-block;
width: 60px;
height: 60px;
padding-top: 10px;
text-align: center;
background: #f6f8f9;
border-radius: $base-border-radius + 3;
p {
padding: 0;
margin: 0;
overflow: hidden;
text-overflow: ellipsis;
font-size: $base-font-size-small;
line-height: 25px;
white-space: nowrap;
}
}
}
}
</style>

View File

@@ -0,0 +1,18 @@
<script lang="ts" setup>
import { useSettingsStore } from '@/store/modules/settings'
const $pub: any = inject('$pub')
const settingsStore = useSettingsStore()
const { theme } = storeToRefs(settingsStore)
const handleOpenTheme = () => {
$pub('theme')
}
</script>
<template>
<span v-if="theme.showTheme">
<vab-icon icon="brush-2-line" @click="handleOpenTheme" />
</span>
</template>