样式优化
This commit is contained in:
@@ -7,13 +7,17 @@ import DayNightSwitch from '@/components/switch/DayNightSwitch.vue';
|
||||
import { TagsOutlined, CopyOutlined, GithubOutlined } from '@ant-design/icons-vue';
|
||||
import Fullscreen from '../fullscreen/Fullscreen.vue';
|
||||
import { useApiStore } from '@/store';
|
||||
import { message, Popover } from 'ant-design-vue'; // 移除 notification
|
||||
import { message, Popover, Badge } from 'ant-design-vue'; // 新增:导入 Badge 组件用于气泡提示
|
||||
|
||||
// 版本数据和当前版本状态
|
||||
const dyVersions = ref<string[]>([]);
|
||||
const copyLoading = ref<Record<string, boolean>>({});
|
||||
// 版本 popover 显隐控制
|
||||
const versionPopoverVisible = ref<boolean>(false);
|
||||
// 新增:是否有新版本(用于气泡提示)
|
||||
const hasNewVersion = ref<boolean>(false);
|
||||
// 新增:localStorage 缓存 key(统一命名,方便维护)
|
||||
const VERSION_CACHE_KEY = 'dysync_version_cache';
|
||||
|
||||
// 仓库地址常量
|
||||
const gitRepos = ref([
|
||||
@@ -118,27 +122,64 @@ const copyGitUrl = (repo: { name: string; url: string; color: string }) => {
|
||||
doCopy();
|
||||
};
|
||||
|
||||
// 版本查看方法(获取数据后控制 popover 显隐)
|
||||
// 新增:统一处理版本数据的方法(提取公共逻辑,避免冗余)
|
||||
const handleVersionData = (rawData: string[]) => {
|
||||
const newVersions = [...rawData];
|
||||
const versionLen = newVersions.length;
|
||||
|
||||
if (versionLen > 0) {
|
||||
if (versionLen === 1) {
|
||||
newVersions[0] = `${newVersions[0]}(最新版)`;
|
||||
hasNewVersion.value = false; // 只有一个版本,无新版
|
||||
} else {
|
||||
newVersions[0] = `${newVersions[0]}(当前版本)`;
|
||||
const lastIndex = versionLen - 1;
|
||||
newVersions[lastIndex] = `${newVersions[lastIndex]}(最新版)`;
|
||||
// 判断是否有新版本:当前版本 !== 最新版本(去除备注后对比)
|
||||
const currentVersion = newVersions[0].replace('(当前版本)', '').trim();
|
||||
const latestVersion = newVersions[lastIndex].replace('(最新版)', '').trim();
|
||||
hasNewVersion.value = currentVersion !== latestVersion;
|
||||
}
|
||||
} else {
|
||||
hasNewVersion.value = false;
|
||||
}
|
||||
|
||||
return newVersions;
|
||||
};
|
||||
|
||||
// 新增:保存版本数据到 localStorage
|
||||
const saveVersionToLocalStorage = (versionData: string[]) => {
|
||||
try {
|
||||
localStorage.setItem(VERSION_CACHE_KEY, JSON.stringify(versionData));
|
||||
} catch (error) {
|
||||
console.warn('版本数据缓存到 localStorage 失败:', error);
|
||||
}
|
||||
};
|
||||
|
||||
// 新增:从 localStorage 获取缓存的版本数据
|
||||
const getVersionFromLocalStorage = (): string[] => {
|
||||
try {
|
||||
const cacheData = localStorage.getItem(VERSION_CACHE_KEY);
|
||||
if (cacheData) {
|
||||
return JSON.parse(cacheData) as string[];
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('从 localStorage 读取版本缓存失败:', error);
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
// 改造:版本查看方法(获取数据后更新缓存,控制 popover 显隐)
|
||||
const showVersionNotification = () => {
|
||||
useApiStore()
|
||||
.CheckTag()
|
||||
.then((res) => {
|
||||
if (res.code === 0) {
|
||||
dyVersions.value = res.data;
|
||||
const versionLen = dyVersions.value.length;
|
||||
|
||||
if (versionLen > 0) {
|
||||
const newVersions = [...dyVersions.value];
|
||||
if (versionLen === 1) {
|
||||
newVersions[0] = `${newVersions[0]}(最新版)`;
|
||||
} else {
|
||||
newVersions[0] = `${newVersions[0]}(当前版本)`;
|
||||
const lastIndex = versionLen - 1;
|
||||
newVersions[lastIndex] = `${newVersions[lastIndex]}(最新版)`;
|
||||
}
|
||||
dyVersions.value = newVersions;
|
||||
}
|
||||
|
||||
// 处理版本数据(添加备注、判断新版)
|
||||
const processedVersions = handleVersionData(res.data);
|
||||
dyVersions.value = processedVersions;
|
||||
// 点击后更新 localStorage 缓存
|
||||
saveVersionToLocalStorage(processedVersions);
|
||||
// 打开版本 popover
|
||||
versionPopoverVisible.value = true;
|
||||
} else {
|
||||
@@ -151,8 +192,42 @@ const showVersionNotification = () => {
|
||||
});
|
||||
};
|
||||
|
||||
// 新增:页面加载时自动调用接口获取版本并缓存
|
||||
const fetchVersionOnMount = () => {
|
||||
useApiStore()
|
||||
.CheckTag()
|
||||
.then((res) => {
|
||||
if (res.code === 0) {
|
||||
// 处理版本数据(添加备注、判断新版)
|
||||
const processedVersions = handleVersionData(res.data);
|
||||
dyVersions.value = processedVersions;
|
||||
// 页面加载时缓存到 localStorage
|
||||
saveVersionToLocalStorage(processedVersions);
|
||||
} else {
|
||||
// 接口失败时,尝试读取本地缓存
|
||||
const cacheVersions = getVersionFromLocalStorage();
|
||||
if (cacheVersions.length > 0) {
|
||||
dyVersions.value = handleVersionData(cacheVersions);
|
||||
}
|
||||
message.error(res.message);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
// 接口异常时,尝试读取本地缓存
|
||||
const cacheVersions = getVersionFromLocalStorage();
|
||||
if (cacheVersions.length > 0) {
|
||||
dyVersions.value = handleVersionData(cacheVersions);
|
||||
}
|
||||
message.error('获取版本列表失败,已加载本地缓存');
|
||||
console.error(err);
|
||||
});
|
||||
};
|
||||
|
||||
// 全局注入加载动画样式
|
||||
onMounted(() => {
|
||||
// 页面加载时自动调用版本接口
|
||||
fetchVersionOnMount();
|
||||
|
||||
if (!document.querySelector('#custom-spin-style')) {
|
||||
const style = document.createElement('style');
|
||||
style.id = 'custom-spin-style';
|
||||
@@ -178,7 +253,7 @@ const showGit = () => {
|
||||
<DayNightSwitch />
|
||||
</StepinHeaderAction>
|
||||
|
||||
<!-- 版本查看:纯模板实现,移除 renderVersionList -->
|
||||
<!-- 版本查看:改造为 Badge 包裹图标,实现气泡提示 -->
|
||||
<StepinHeaderAction>
|
||||
<div class="action-item">
|
||||
<a-popover v-model:visible="versionPopoverVisible" placement="bottom" trigger="click" overlay-class="version-popover-overlay" @visible-change="(visible) => versionPopoverVisible = visible">
|
||||
@@ -218,14 +293,21 @@ const showGit = () => {
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 暂无版本数据 -->
|
||||
<div class="no-version-data" v-else>
|
||||
暂无版本数据
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<a-tooltip placement="bottom">
|
||||
<template #title>
|
||||
<span>版本查看</span>
|
||||
</template>
|
||||
<!-- <a-tooltip placement="bottom"> -->
|
||||
<template #title>
|
||||
<!-- <span>版本查看</span> -->
|
||||
</template>
|
||||
<!-- 改造:用 Badge 包裹图标,有新版时显示气泡提示 -->
|
||||
<a-badge :dot="hasNewVersion">
|
||||
<TagsOutlined class="action-icon" @click="showVersionNotification" />
|
||||
</a-tooltip>
|
||||
</a-badge>
|
||||
<!-- </a-tooltip> -->
|
||||
</a-popover>
|
||||
</div>
|
||||
</StepinHeaderAction>
|
||||
@@ -362,7 +444,7 @@ const showGit = () => {
|
||||
.version-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
maxwidth: calc(100% - 40px);
|
||||
max-width: calc(100% - 40px); /* 修正:原 maxwidth 拼写错误 */
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
<script lang="ts" setup>
|
||||
import { GithubOutlined, CopyrightOutlined } from '@ant-design/icons-vue';
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { useApiStore } from '@/store';
|
||||
|
||||
// 响应式变量存储年份文本
|
||||
const yearText = ref('');
|
||||
|
||||
const currentVersion = ref(); // 已存在的版本号响应式变量
|
||||
onMounted(() => {
|
||||
const currentYear = new Date().getFullYear();
|
||||
const startYear = 2025;
|
||||
@@ -14,6 +15,13 @@ onMounted(() => {
|
||||
} else {
|
||||
yearText.value = `${startYear}-${currentYear}`;
|
||||
}
|
||||
useApiStore()
|
||||
.getVer()
|
||||
.then((r) => {
|
||||
if (r.code == 0) {
|
||||
currentVersion.value = r.data; // 接口返回后赋值版本号
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -26,14 +34,17 @@ onMounted(() => {
|
||||
<span>{{ yearText }} 抖小云 dysync.net. </span>
|
||||
|
||||
<!-- 将社交链接移动到这里 -->
|
||||
<div class="social-links">
|
||||
<!-- <div class="social-links">
|
||||
<a href="https://github.com/jianzhichu/dysync.net" target="_blank" rel="noopener noreferrer" aria-label="访问我们的 GitHub 仓库" class="social-link">
|
||||
<GithubOutlined />
|
||||
</a>
|
||||
<a href="https://gitee.com/deathvicky/dysync.net" target="_blank" rel="noopener noreferrer" aria-label="访问我们的 Gitee 仓库" class="social-link">
|
||||
<img class="gitee-icon" src="@/assets/gitee.svg" alt="Gitee" />
|
||||
</a>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- 新增:显示当前版本号,增加样式分隔提升美观度 -->
|
||||
<span class="version-text">{{currentVersion.deploy}}_{{ currentVersion.tag }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
@@ -44,6 +55,7 @@ onMounted(() => {
|
||||
// 使用 :root 变量,便于主题切换
|
||||
--footer-text-color: var(--text-color-secondary, #999);
|
||||
--footer-hover-color: var(--primary-color, #1890ff);
|
||||
--version-text-color: var(--text-color-tertiary, #666);
|
||||
|
||||
width: 100%;
|
||||
color: var(--footer-text-color);
|
||||
@@ -68,7 +80,24 @@ onMounted(() => {
|
||||
font-size: 13px;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
.version-text {
|
||||
// 核心修改1:白色文字(醒目,与绿底形成强烈对比)
|
||||
color: #ffffff;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
padding: 2px 6px; // 微调内边距,让绿底区域更饱满,视觉更舒适
|
||||
// 核心修改2:柔和绿色背景(两种可选方案,不刺眼、显高级)
|
||||
// 方案1:推荐!清新柔和绿(适配大多数页面,不张扬,高级感足)
|
||||
background-color: #722ed1;
|
||||
// 方案2:稍浅薄荷绿(更明亮,醒目度稍高,适合活泼风格页面)
|
||||
// background-color: #73d13d;
|
||||
border-radius: 4px; // 适当增大圆角,更显圆润柔和
|
||||
// 核心修改3:调整光效为白色光晕(匹配白字,提升质感,不突兀)
|
||||
// text-shadow: 0 0 3px rgba(255, 255, 255, 0.8), 0 0 6px rgba(255, 255, 255, 0.4);
|
||||
// 可选优化:轻微暗角阴影,让绿底更有层次感,不扁平
|
||||
// box-shadow: 0 1px 2px rgba(82, 196, 26, 0.2);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
// 社交链接组自身也是一个 flex 容器
|
||||
.social-links {
|
||||
display: flex;
|
||||
|
||||
@@ -141,40 +141,40 @@ body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
// 日志容器:正常宽度(继承父元素),高度适配
|
||||
// 日志容器:自适应高度,无固定上限,保留上下留白
|
||||
.container {
|
||||
width: 100%; // 继承父元素宽度,非全屏
|
||||
height: calc(100vh - 50px); // 留出顶部表单高度,固定高度不溢出
|
||||
padding: 0 8px; // 保留少量左右间距,视觉更友好
|
||||
width: 100%;
|
||||
padding: 0 8px;
|
||||
margin: 16px 0; // 上下留白,远离屏幕边缘
|
||||
box-sizing: border-box;
|
||||
overflow: hidden; // 新增:隐藏容器外溢出内容,避免挤压footer
|
||||
overflow: hidden;
|
||||
}
|
||||
// pre样式:继承card-body宽度(核心)
|
||||
// pre样式:自适应高度,内容过多时内部滚动
|
||||
.card-width-pre {
|
||||
width: 100% !important; // 完全继承父元素(card-body)宽度
|
||||
width: 100% !important;
|
||||
min-width: 100%;
|
||||
padding: 8px; // 合理内边距,避免内容贴边
|
||||
padding: 8px;
|
||||
margin: 0 !important;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
height: 100%; // 继承card-body高度
|
||||
max-height: calc(100vh - 66px); // 新增:严格限制最大高度,避开表单+卡片内边距
|
||||
// 核心:最小高度保证容器不塌陷,最大高度限制不超视口一半
|
||||
min-height: 200px;
|
||||
max-height: calc(67vh); // 最多占视口一半,绝对不会满屏
|
||||
box-sizing: border-box;
|
||||
overflow-y: auto; // 保留:纵向滚动(优先显示垂直滚动条)
|
||||
overflow-x: auto; // 保留:横向滚动(日志行过长时)
|
||||
overflow-y: auto;
|
||||
overflow-x: auto;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
// 可选:美化滚动条(适配现代浏览器)
|
||||
// 滚动条美化(保留)
|
||||
&::-webkit-scrollbar {
|
||||
width: 6px; // 垂直滚动条宽度
|
||||
height: 6px; // 水平滚动条高度
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
border-radius: 3px;
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
.date-control-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -241,7 +241,14 @@ export const useApiStore = defineStore('coreapi', () => {
|
||||
});
|
||||
}
|
||||
|
||||
//检查版本
|
||||
async function getVer() {
|
||||
return http.request<any, Response<any>>('/api/config/mytag', 'get').then(r => {
|
||||
return r;
|
||||
}).finally(() => {
|
||||
|
||||
});
|
||||
}
|
||||
//检查版本
|
||||
async function CheckTag() {
|
||||
return http.request<any, Response<any>>('/api/config/checktag', 'get').then(r => {
|
||||
@@ -364,6 +371,7 @@ export const useApiStore = defineStore('coreapi', () => {
|
||||
}
|
||||
|
||||
return {
|
||||
getVer,
|
||||
mp3List,
|
||||
BathRealDelete,
|
||||
DeleteByAuthor,
|
||||
|
||||
Reference in New Issue
Block a user