fix: 🐛 代码规范检测问题修复

Former-commit-id: 6e75bc91ce33ea9e7a17fbcb896f086f768896f4
This commit is contained in:
郝先瑞
2023-04-15 23:51:27 +08:00
parent 5b033246bc
commit 0605f89a67
24 changed files with 440 additions and 450 deletions

View File

@@ -18,11 +18,11 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { onBeforeMount, ref, watch } from 'vue'; import { onBeforeMount, ref, watch } from "vue";
import { useRoute, RouteLocationMatched } from 'vue-router'; import { useRoute, RouteLocationMatched } from "vue-router";
import { compile } from 'path-to-regexp'; import { compile } from "path-to-regexp";
import router from '@/router'; import router from "@/router";
import { translateRouteTitleI18n } from '@/utils/i18n'; import { translateRouteTitleI18n } from "@/utils/i18n";
const currentRoute = useRoute(); const currentRoute = useRoute();
const pathCompile = (path: string) => { const pathCompile = (path: string) => {
@@ -35,15 +35,15 @@ const breadcrumbs = ref([] as Array<RouteLocationMatched>);
function getBreadcrumb() { function getBreadcrumb() {
let matched = currentRoute.matched.filter( let matched = currentRoute.matched.filter(
item => item.meta && item.meta.title (item) => item.meta && item.meta.title
); );
const first = matched[0]; const first = matched[0];
if (!isDashboard(first)) { if (!isDashboard(first)) {
matched = [ matched = [
{ path: '/dashboard', meta: { title: 'dashboard' } } as any { path: "/dashboard", meta: { title: "dashboard" } } as any,
].concat(matched); ].concat(matched);
} }
breadcrumbs.value = matched.filter(item => { breadcrumbs.value = matched.filter((item) => {
return item.meta && item.meta.title && item.meta.breadcrumb !== false; return item.meta && item.meta.title && item.meta.breadcrumb !== false;
}); });
} }
@@ -55,27 +55,27 @@ function isDashboard(route: RouteLocationMatched) {
} }
return ( return (
name.toString().trim().toLocaleLowerCase() === name.toString().trim().toLocaleLowerCase() ===
'Dashboard'.toLocaleLowerCase() "Dashboard".toLocaleLowerCase()
); );
} }
function handleLink(item: any) { function handleLink(item: any) {
const { redirect, path } = item; const { redirect, path } = item;
if (redirect) { if (redirect) {
router.push(redirect).catch(err => { router.push(redirect).catch((err) => {
console.warn(err); console.warn(err);
}); });
return; return;
} }
router.push(pathCompile(path)).catch(err => { router.push(pathCompile(path)).catch((err) => {
console.warn(err); console.warn(err);
}); });
} }
watch( watch(
() => currentRoute.path, () => currentRoute.path,
path => { (path) => {
if (path.startsWith('/redirect/')) { if (path.startsWith("/redirect/")) {
return; return;
} }
getBreadcrumb(); getBreadcrumb();
@@ -90,9 +90,9 @@ onBeforeMount(() => {
<style lang="scss" scoped> <style lang="scss" scoped>
.app-breadcrumb.el-breadcrumb { .app-breadcrumb.el-breadcrumb {
display: inline-block; display: inline-block;
margin-left: 8px;
font-size: 14px; font-size: 14px;
line-height: 50px; line-height: 50px;
margin-left: 8px;
} }
// 覆盖 element-plus 的样式 // 覆盖 element-plus 的样式

View File

@@ -9,7 +9,7 @@
width="80" width="80"
height="80" height="80"
viewBox="0 0 250 250" viewBox="0 0 250 250"
style="fill: #40c9c6; color: #fff" style="color: #fff; fill: #40c9c6"
aria-hidden="true" aria-hidden="true"
> >
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z" /> <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z" />
@@ -38,22 +38,25 @@
100% { 100% {
transform: rotate(0); transform: rotate(0);
} }
20%, 20%,
60% { 60% {
transform: rotate(-25deg); transform: rotate(-25deg);
} }
40%, 40%,
80% { 80% {
transform: rotate(10deg); transform: rotate(10deg);
} }
} }
@media (max-width: 500px) { @media (width <= 500px) {
.github-corner:hover .octo-arm {
animation: none;
}
.github-corner .octo-arm { .github-corner .octo-arm {
animation: octocat-wave 560ms ease-in-out; animation: octocat-wave 560ms ease-in-out;
} }
.github-corner:hover .octo-arm {
animation: none;
}
} }
</style> </style>

View File

@@ -22,14 +22,14 @@ defineProps({
isActive: { isActive: {
required: true, required: true,
type: Boolean, type: Boolean,
default: false default: false,
} },
}); });
const emit = defineEmits(['toggleClick']); const emit = defineEmits(["toggleClick"]);
function toggleClick() { function toggleClick() {
emit('toggleClick'); emit("toggleClick");
} }
</script> </script>
@@ -38,6 +38,7 @@ function toggleClick() {
width: 20px; width: 20px;
height: 20px; height: 20px;
vertical-align: -4px; vertical-align: -4px;
&.is-active { &.is-active {
transform: rotate(180deg); transform: rotate(180deg);
} }

View File

@@ -2,18 +2,18 @@
const props = defineProps({ const props = defineProps({
modelValue: { modelValue: {
type: String, type: String,
require: false require: false,
} },
}); });
const emit = defineEmits(['update:modelValue']); const emit = defineEmits(["update:modelValue"]);
const inputValue = toRef(props, 'modelValue'); const inputValue = toRef(props, "modelValue");
const visible = ref(false); // 弹窗显示状态 const visible = ref(false); // 弹窗显示状态
const iconNames: string[] = []; // 所有的图标名称集合 const iconNames: string[] = []; // 所有的图标名称集合
const filterValue = ref(''); // 筛选的值 const filterValue = ref(""); // 筛选的值
const filterIconNames = ref<string[]>([]); // 过滤后的图标名称集合 const filterIconNames = ref<string[]>([]); // 过滤后的图标名称集合
const iconSelectorRef = ref(null); const iconSelectorRef = ref(null);
@@ -21,9 +21,9 @@ const iconSelectorRef = ref(null);
* icon 加载 * icon 加载
*/ */
function loadIcons() { function loadIcons() {
const icons = import.meta.glob('../../assets/icons/*.svg'); const icons = import.meta.glob("../../assets/icons/*.svg");
for (const icon in icons) { for (const icon in icons) {
const iconName = icon.split('assets/icons/')[1].split('.svg')[0]; const iconName = icon.split("assets/icons/")[1].split(".svg")[0];
iconNames.push(iconName); iconNames.push(iconName);
} }
filterIconNames.value = iconNames; filterIconNames.value = iconNames;
@@ -34,7 +34,7 @@ function loadIcons() {
*/ */
function handleFilter() { function handleFilter() {
if (filterValue.value) { if (filterValue.value) {
filterIconNames.value = iconNames.filter(iconName => filterIconNames.value = iconNames.filter((iconName) =>
iconName.includes(filterValue.value) iconName.includes(filterValue.value)
); );
} else { } else {
@@ -46,7 +46,7 @@ function handleFilter() {
* icon 选择 * icon 选择
*/ */
function handleSelect(iconName: string) { function handleSelect(iconName: string) {
emit('update:modelValue', iconName); emit("update:modelValue", iconName);
visible.value = false; visible.value = false;
} }
@@ -125,6 +125,7 @@ onMounted(() => {
.el-divider--horizontal { .el-divider--horizontal {
margin: 10px auto !important; margin: 10px auto !important;
} }
.iconselect-container { .iconselect-container {
position: relative; position: relative;
width: 400px; width: 400px;
@@ -137,18 +138,19 @@ onMounted(() => {
margin-top: 10px; margin-top: 10px;
.icon-item { .icon-item {
cursor: pointer;
width: 10%;
margin: 0 10px 10px 0;
padding: 5px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-items: center;
align-items: center; align-items: center;
justify-items: center;
width: 10%;
padding: 5px;
margin: 0 10px 10px 0;
cursor: pointer;
border: 1px solid #ccc; border: 1px solid #ccc;
&:hover { &:hover {
border-color: var(--el-color-primary);
color: var(--el-color-primary); color: var(--el-color-primary);
border-color: var(--el-color-primary);
transition: all 0.2s; transition: all 0.2s;
transform: scaleX(1.1); transform: scaleX(1.1);
} }

View File

@@ -14,54 +14,54 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, PropType } from 'vue'; import { computed, PropType } from "vue";
import { scrollTo } from '@/utils/scroll-to'; import { scrollTo } from "@/utils/scroll-to";
const props = defineProps({ const props = defineProps({
total: { total: {
required: true, required: true,
type: Number as PropType<number>, type: Number as PropType<number>,
default: 0 default: 0,
}, },
page: { page: {
type: Number, type: Number,
default: 1 default: 1,
}, },
limit: { limit: {
type: Number, type: Number,
default: 20 default: 20,
}, },
pageSizes: { pageSizes: {
type: Array as PropType<number[]>, type: Array as PropType<number[]>,
default() { default() {
return [10, 20, 30, 50]; return [10, 20, 30, 50];
} },
}, },
layout: { layout: {
type: String, type: String,
default: 'total, sizes, prev, pager, next, jumper' default: "total, sizes, prev, pager, next, jumper",
}, },
background: { background: {
type: Boolean, type: Boolean,
default: true default: true,
}, },
autoScroll: { autoScroll: {
type: Boolean, type: Boolean,
default: true default: true,
}, },
hidden: { hidden: {
type: Boolean, type: Boolean,
default: false default: false,
} },
}); });
const emit = defineEmits(['update:page', 'update:limit', 'pagination']); const emit = defineEmits(["update:page", "update:limit", "pagination"]);
const currentPage = computed<number | undefined>({ const currentPage = computed<number | undefined>({
get: () => props.page, get: () => props.page,
set: value => { set: (value) => {
emit('update:page', value); emit("update:page", value);
} },
}); });
const pageSize = computed<number | undefined>({ const pageSize = computed<number | undefined>({
@@ -69,12 +69,12 @@ const pageSize = computed<number | undefined>({
return props.limit; return props.limit;
}, },
set(val) { set(val) {
emit('update:limit', val); emit("update:limit", val);
} },
}); });
function handleSizeChange(val: number) { function handleSizeChange(val: number) {
emit('pagination', { page: currentPage, limit: val }); emit("pagination", { page: currentPage, limit: val });
if (props.autoScroll) { if (props.autoScroll) {
scrollTo(0, 800); scrollTo(0, 800);
} }
@@ -82,7 +82,7 @@ function handleSizeChange(val: number) {
function handleCurrentChange(val: number) { function handleCurrentChange(val: number) {
currentPage.value = val; currentPage.value = val;
emit('pagination', { page: val, limit: props.limit }); emit("pagination", { page: val, limit: props.limit });
if (props.autoScroll) { if (props.autoScroll) {
scrollTo(0, 800); scrollTo(0, 800);
} }
@@ -92,6 +92,7 @@ function handleCurrentChange(val: number) {
<style lang="scss" scoped> <style lang="scss" scoped>
.pagination { .pagination {
padding: 12px; padding: 12px;
&.hidden { &.hidden {
display: none; display: none;
} }

View File

@@ -1,45 +1,45 @@
<script setup lang="ts"> <script setup lang="ts">
import { onBeforeUnmount, onMounted, ref, watch } from 'vue'; import { onBeforeUnmount, onMounted, ref, watch } from "vue";
import { addClass, removeClass } from '@/utils/index'; import { addClass, removeClass } from "@/utils/index";
const show = ref(false); const show = ref(false);
defineProps({ defineProps({
buttonTop: { buttonTop: {
default: 250, default: 250,
type: Number type: Number,
} },
}); });
watch(show, value => { watch(show, (value) => {
if (value) { if (value) {
addEventClick(); addEventClick();
} }
if (value) { if (value) {
addClass(document.body, 'showRightPanel'); addClass(document.body, "showRightPanel");
} else { } else {
removeClass(document.body, 'showRightPanel'); removeClass(document.body, "showRightPanel");
} }
}); });
function addEventClick() { function addEventClick() {
window.addEventListener('click', closeSidebar, { passive: true }); window.addEventListener("click", closeSidebar, { passive: true });
} }
function closeSidebar(evt: any) { function closeSidebar(evt: any) {
// 主题选择点击不关闭 // 主题选择点击不关闭
let parent = evt.target.closest('.right-panel-container'); let parent = evt.target.closest(".right-panel-container");
if (!parent) { if (!parent) {
show.value = false; show.value = false;
window.removeEventListener('click', closeSidebar); window.removeEventListener("click", closeSidebar);
} }
} }
const rightPanel = ref(); const rightPanel = ref();
function insertToBody() { function insertToBody() {
const body = document.querySelector('body') as any; const body = document.querySelector("body") as any;
body.insertBefore(rightPanel.value, body.firstChild); body.insertBefore(rightPanel.value, body.firstChild);
} }
@@ -59,7 +59,7 @@ onBeforeUnmount(() => {
<div <div
class="right-panel-btn" class="right-panel-btn"
:style="{ :style="{
top: buttonTop + 'px' top: buttonTop + 'px',
}" }"
@click="show = !show" @click="show = !show"
> >
@@ -75,38 +75,40 @@ onBeforeUnmount(() => {
<style lang="scss" scoped> <style lang="scss" scoped>
.showRightPanel { .showRightPanel {
overflow: hidden;
position: relative; position: relative;
width: calc(100% - 15px); width: calc(100% - 15px);
overflow: hidden;
} }
.right-panel-overlay { .right-panel-overlay {
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
background: rgba(0, 0, 0, 0.2); background: rgb(0 0 0 / 20%);
} }
.right-panel-container { .right-panel-container {
background-color: var(--el-bg-color-overlay);
width: 100%;
max-width: 300px;
height: 100vh;
position: fixed; position: fixed;
top: 0; top: 0;
right: 0; right: 0;
box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.05); z-index: 999;
width: 100%;
max-width: 300px;
height: 100vh;
background-color: var(--el-bg-color-overlay);
box-shadow: 0 0 15px 0 rgb(0 0 0 / 5%);
transition: all 0.25s cubic-bezier(0.7, 0.3, 0.1, 1); transition: all 0.25s cubic-bezier(0.7, 0.3, 0.1, 1);
transform: translate(100%); transform: translate(100%);
z-index: 999;
} }
.show { .show {
transition: all 0.3s cubic-bezier(0.7, 0.3, 0.1, 1); transition: all 0.3s cubic-bezier(0.7, 0.3, 0.1, 1);
.right-panel-overlay { .right-panel-overlay {
z-index: 99; z-index: 99;
opacity: 1;
width: 100%; width: 100%;
height: 100%; height: 100%;
opacity: 1;
} }
.right-panel-container { .right-panel-container {
@@ -115,19 +117,20 @@ onBeforeUnmount(() => {
} }
.right-panel-btn { .right-panel-btn {
background-color: var(--el-color-primary); position: absolute;
color: var(--el-color-white); left: -36px;
width: 36px; width: 36px;
height: 36px; height: 36px;
left: -36px; color: var(--el-color-white);
position: absolute;
text-align: center; text-align: center;
border-radius: 6px 0 0 6px;
cursor: pointer; cursor: pointer;
background-color: var(--el-color-primary);
border-radius: 6px 0 0 6px;
svg { svg {
vertical-align: -10px;
width: 20px; width: 20px;
height: 20px; height: 20px;
vertical-align: -10px;
} }
} }
</style> </style>

View File

@@ -12,19 +12,19 @@
const props = defineProps({ const props = defineProps({
prefix: { prefix: {
type: String, type: String,
default: 'icon' default: "icon",
}, },
iconClass: { iconClass: {
type: String, type: String,
required: false required: false,
}, },
color: { color: {
type: String type: String,
}, },
size: { size: {
type: String, type: String,
default: '1em' default: "1em",
} },
}); });
const symbolId = computed(() => `#${props.prefix}-${props.iconClass}`); const symbolId = computed(() => `#${props.prefix}-${props.iconClass}`);
@@ -33,11 +33,11 @@ const symbolId = computed(() => `#${props.prefix}-${props.iconClass}`);
<style scoped> <style scoped>
.svg-icon { .svg-icon {
display: inline-block; display: inline-block;
outline: none;
width: 1em; width: 1em;
height: 1em; height: 1em;
vertical-align: -0.15em; /* 因icon大小被设置为和字体大小一致而span等标签的下边缘会和字体的基线对齐故需设置一个往下的偏移比例来纠正视觉上的未对齐效果 */
fill: currentColor; /* 定义元素的颜色currentColor是一个变量这个变量的值就表示当前元素的color值如果当前元素未设置color值则从父元素继承 */
overflow: hidden; overflow: hidden;
vertical-align: -0.15em; /* 因icon大小被设置为和字体大小一致而span等标签的下边缘会和字体的基线对齐故需设置一个往下的偏移比例来纠正视觉上的未对齐效果 */
outline: none;
fill: currentcolor; /* 定义元素的颜色currentColor是一个变量这个变量的值就表示当前元素的color值如果当前元素未设置color值则从父元素继承 */
} }
</style> </style>

View File

@@ -14,16 +14,16 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { UploadRawFile, UploadRequestOptions } from 'element-plus'; import { UploadRawFile, UploadRequestOptions } from "element-plus";
import { uploadFileApi } from '@/api/file'; import { uploadFileApi } from "@/api/file";
const emit = defineEmits(['update:modelValue']); const emit = defineEmits(["update:modelValue"]);
const props = defineProps({ const props = defineProps({
modelValue: { modelValue: {
type: String, type: String,
default: '' default: "",
} },
}); });
const imgUrl = computed<string | undefined>({ const imgUrl = computed<string | undefined>({
@@ -32,8 +32,8 @@ const imgUrl = computed<string | undefined>({
}, },
set(val) { set(val) {
// imgUrl改变时触发修改父组件绑定的v-model的值 // imgUrl改变时触发修改父组件绑定的v-model的值
emit('update:modelValue', val); emit("update:modelValue", val);
} },
}); });
/** /**
@@ -51,7 +51,7 @@ async function uploadFile(options: UploadRequestOptions): Promise<any> {
*/ */
function handleBeforeUpload(file: UploadRawFile) { function handleBeforeUpload(file: UploadRawFile) {
if (file.size > 2 * 1048 * 1048) { if (file.size > 2 * 1048 * 1048) {
ElMessage.warning('上传图片不能大于2M'); ElMessage.warning("上传图片不能大于2M");
return false; return false;
} }
return true; return true;
@@ -60,19 +60,19 @@ function handleBeforeUpload(file: UploadRawFile) {
<style scoped> <style scoped>
.single-uploader .single { .single-uploader .single {
display: block;
width: 178px; width: 178px;
height: 178px; height: 178px;
display: block;
} }
</style> </style>
<style> <style>
.single-uploader .el-upload { .single-uploader .el-upload {
border: 1px dashed var(--el-border-color);
border-radius: 6px;
cursor: pointer;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
cursor: pointer;
border: 1px dashed var(--el-border-color);
border-radius: 6px;
transition: var(--el-transition-duration-fast); transition: var(--el-transition-duration-fast);
} }
@@ -81,10 +81,10 @@ function handleBeforeUpload(file: UploadRawFile) {
} }
.el-icon.single-uploader-icon { .el-icon.single-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px; width: 178px;
height: 178px; height: 178px;
font-size: 28px;
color: #8c939d;
text-align: center; text-align: center;
} }
</style> </style>

View File

@@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { useTagsViewStore } from '@/store/modules/tagsView'; import { useTagsViewStore } from "@/store/modules/tagsView";
const tagsViewStore = useTagsViewStore(); const tagsViewStore = useTagsViewStore();
</script> </script>
@@ -18,10 +18,11 @@ const tagsViewStore = useTagsViewStore();
<style lang="scss" scoped> <style lang="scss" scoped>
.app-main { .app-main {
position: relative;
width: 100%;
/* 50= navbar 50 */ /* 50= navbar 50 */
min-height: calc(100vh - 50px); min-height: calc(100vh - 50px);
width: 100%;
position: relative;
overflow: hidden; overflow: hidden;
background-color: var(--el-bg-color-page); background-color: var(--el-bg-color-page);
} }
@@ -37,8 +38,8 @@ const tagsViewStore = useTagsViewStore();
} }
.fixed-header + .app-main { .fixed-header + .app-main {
padding-top: 84px;
min-height: 100vh; min-height: 100vh;
padding-top: 84px;
} }
} }
</style> </style>

View File

@@ -1,9 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { storeToRefs } from 'pinia'; import { storeToRefs } from "pinia";
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from "vue-router";
import { useAppStore } from '@/store/modules/app'; import { useAppStore } from "@/store/modules/app";
import { useTagsViewStore } from '@/store/modules/tagsView'; import { useTagsViewStore } from "@/store/modules/tagsView";
import { useUserStore } from '@/store/modules/user'; import { useUserStore } from "@/store/modules/user";
const appStore = useAppStore(); const appStore = useAppStore();
const tagsViewStore = useTagsViewStore(); const tagsViewStore = useTagsViewStore();
@@ -20,10 +20,10 @@ function toggleSideBar() {
// 注销 // 注销
function logout() { function logout() {
ElMessageBox.confirm('确定注销并退出系统吗?', '提示', { ElMessageBox.confirm("确定注销并退出系统吗?", "提示", {
confirmButtonText: '确定', confirmButtonText: "确定",
cancelButtonText: '取消', cancelButtonText: "取消",
type: 'warning' type: "warning",
}).then(() => { }).then(() => {
userStore userStore
.logout() .logout()
@@ -76,19 +76,19 @@ function logout() {
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <el-dropdown-menu>
<router-link to="/"> <router-link to="/">
<el-dropdown-item>{{ $t('navbar.dashboard') }}</el-dropdown-item> <el-dropdown-item>{{ $t("navbar.dashboard") }}</el-dropdown-item>
</router-link> </router-link>
<a target="_blank" href="https://github.com/hxrui"> <a target="_blank" href="https://github.com/hxrui">
<el-dropdown-item>Github</el-dropdown-item> <el-dropdown-item>Github</el-dropdown-item>
</a> </a>
<a target="_blank" href="https://gitee.com/haoxr"> <a target="_blank" href="https://gitee.com/haoxr">
<el-dropdown-item>{{ $t('navbar.gitee') }}</el-dropdown-item> <el-dropdown-item>{{ $t("navbar.gitee") }}</el-dropdown-item>
</a> </a>
<a target="_blank" href="https://www.cnblogs.com/haoxianrui/"> <a target="_blank" href="https://www.cnblogs.com/haoxianrui/">
<el-dropdown-item>{{ $t('navbar.document') }}</el-dropdown-item> <el-dropdown-item>{{ $t("navbar.document") }}</el-dropdown-item>
</a> </a>
<el-dropdown-item divided @click="logout"> <el-dropdown-item divided @click="logout">
{{ $t('navbar.logout') }} {{ $t("navbar.logout") }}
</el-dropdown-item> </el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</template> </template>
@@ -99,23 +99,24 @@ function logout() {
<style lang="scss" scoped> <style lang="scss" scoped>
.navbar { .navbar {
background-color: #fff;
height: 50px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
height: 50px;
background-color: #fff;
box-shadow: 0 0 1px #0003; box-shadow: 0 0 1px #0003;
.navbar-setting-item { .navbar-setting-item {
display: inline-block;
width: 30px;
height: 50px; height: 50px;
line-height: 50px; line-height: 50px;
width: 30px;
display: inline-block;
cursor: pointer;
text-align: center;
color: #5a5e66; color: #5a5e66;
text-align: center;
cursor: pointer;
&:hover { &:hover {
background: rgba(249, 250, 251, 1); background: rgb(249 250 251 / 100%);
} }
} }
} }

View File

@@ -1,8 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { useSettingsStore } from '@/store/modules/settings'; import { useSettingsStore } from "@/store/modules/settings";
import IconEpSunny from '~icons/ep/sunny'; import IconEpSunny from "~icons/ep/sunny";
import IconEpMoon from '~icons/ep/moon'; import IconEpMoon from "~icons/ep/moon";
/** /**
* 暗黑模式 * 暗黑模式
@@ -15,30 +15,30 @@ const toggleDark = () => useToggle(isDark);
* 切换布局 * 切换布局
*/ */
function changeLayout(layout: string) { function changeLayout(layout: string) {
settingsStore.changeSetting({ key: 'layout', value: layout }); settingsStore.changeSetting({ key: "layout", value: layout });
window.document.body.setAttribute('layout', settingsStore.layout); window.document.body.setAttribute("layout", settingsStore.layout);
} }
// 主题颜色 // 主题颜色
const themeColors = ref<string[]>([ const themeColors = ref<string[]>([
'#409EFF', "#409EFF",
'#304156', "#304156",
'#11a983', "#11a983",
'#13c2c2', "#13c2c2",
'#6959CD', "#6959CD",
'#f5222d' "#f5222d",
]); ]);
/** /**
* 切换主题颜色 * 切换主题颜色
*/ */
function changeThemeColor(color: string) { function changeThemeColor(color: string) {
document.documentElement.style.setProperty('--el-color-primary', color); document.documentElement.style.setProperty("--el-color-primary", color);
settingsStore.changeSetting({ key: 'layout', value: color }); settingsStore.changeSetting({ key: "layout", value: color });
} }
onMounted(() => { onMounted(() => {
window.document.body.setAttribute('layout', settingsStore.layout); window.document.body.setAttribute("layout", settingsStore.layout);
}); });
</script> </script>
@@ -133,6 +133,7 @@ onMounted(() => {
<style lang="scss" scoped> <style lang="scss" scoped>
.settings-container { .settings-container {
padding: 16px; padding: 16px;
.layout { .layout {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
@@ -141,67 +142,57 @@ onMounted(() => {
height: 50px; height: 50px;
&-item { &-item {
position: relative;
width: 18%; width: 18%;
height: 45px; height: 45px;
background: #f0f2f5;
position: relative;
overflow: hidden; overflow: hidden;
cursor: pointer; cursor: pointer;
background: #f0f2f5;
border-radius: 4px; border-radius: 4px;
} }
&-item.is-active { &-item.is-active {
border: 2px solid var(--el-color-primary); border: 2px solid var(--el-color-primary);
} }
&-left {
div { &-mix div:nth-child(1) {
&:nth-child(1) { width: 100%;
height: 30%;
background: #1b2a47;
box-shadow: 0 0 1px #888;
}
&-mix div:nth-child(2) {
position: absolute;
bottom: 0;
left: 0;
width: 30%;
height: 70%;
background: #1b2a47;
box-shadow: 0 0 1px #888;
}
&-top div:nth-child(1) {
width: 100%;
height: 30%;
background: #1b2a47;
box-shadow: 0 0 1px #888;
}
&-left div:nth-child(1) {
width: 30%; width: 30%;
height: 100%; height: 100%;
background: #1b2a47; background: #1b2a47;
} }
&:nth-child(2) { &-left div:nth-child(2) {
width: 70%; position: absolute;
height: 30%;
top: 0; top: 0;
right: 0; right: 0;
width: 70%;
height: 30%;
background: #fff; background: #fff;
box-shadow: 0 0 1px #888; box-shadow: 0 0 1px #888;
position: absolute;
}
}
}
&-top {
div {
&:nth-child(1) {
width: 100%;
height: 30%;
background: #1b2a47;
box-shadow: 0 0 1px #888;
}
}
}
&-mix {
div {
&:nth-child(1) {
width: 100%;
height: 30%;
background: #1b2a47;
box-shadow: 0 0 1px #888;
}
&:nth-child(2) {
width: 30%;
height: 70%;
bottom: 0;
left: 0;
background: #1b2a47;
box-shadow: 0 0 1px #888;
position: absolute;
}
}
} }
} }
} }

View File

@@ -1,12 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
import { useTagsViewStore, TagView } from '@/store/modules/tagsView'; import { useTagsViewStore, TagView } from "@/store/modules/tagsView";
const tagAndTagSpacing = ref(4); const tagAndTagSpacing = ref(4);
const { proxy } = getCurrentInstance() as any; const { proxy } = getCurrentInstance() as any;
const emits = defineEmits(['scroll']); const emits = defineEmits(["scroll"]);
const emitScroll = () => { const emitScroll = () => {
emits('scroll'); emits("scroll");
}; };
const tagsViewStore = useTagsViewStore(); const tagsViewStore = useTagsViewStore();
@@ -16,10 +16,10 @@ const scrollWrapper = computed(
); );
onMounted(() => { onMounted(() => {
scrollWrapper.value.addEventListener('scroll', emitScroll, true); scrollWrapper.value.addEventListener("scroll", emitScroll, true);
}); });
onBeforeUnmount(() => { onBeforeUnmount(() => {
scrollWrapper.value.removeEventListener('scroll', emitScroll); scrollWrapper.value.removeEventListener("scroll", emitScroll);
}); });
function handleScroll(e: WheelEvent) { function handleScroll(e: WheelEvent) {
@@ -47,14 +47,14 @@ function moveToTarget(currentTag: TagView) {
} else if (lastTag === currentTag) { } else if (lastTag === currentTag) {
$scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth; $scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth;
} else { } else {
const tagListDom = document.getElementsByClassName('tags-item'); const tagListDom = document.getElementsByClassName("tags-item");
const currentIndex = tagsViewStore.visitedViews.findIndex( const currentIndex = tagsViewStore.visitedViews.findIndex(
item => item === currentTag (item) => item === currentTag
); );
let prevTag = null; let prevTag = null;
let nextTag = null; let nextTag = null;
for (const k in tagListDom) { for (const k in tagListDom) {
if (k !== 'length' && Object.hasOwnProperty.call(tagListDom, k)) { if (k !== "length" && Object.hasOwnProperty.call(tagListDom, k)) {
if ( if (
(tagListDom[k] as any).dataset.path === (tagListDom[k] as any).dataset.path ===
tagsViewStore.visitedViews[currentIndex - 1].path tagsViewStore.visitedViews[currentIndex - 1].path
@@ -88,7 +88,7 @@ function moveToTarget(currentTag: TagView) {
} }
defineExpose({ defineExpose({
moveToTarget moveToTarget,
}); });
</script> </script>
@@ -105,19 +105,17 @@ defineExpose({
<style lang="scss" scoped> <style lang="scss" scoped>
.scroll-container { .scroll-container {
position: relative;
width: 100%;
overflow: hidden;
white-space: nowrap;
.el-scrollbar__bar { .el-scrollbar__bar {
bottom: 0px; bottom: 0;
} }
.el-scrollbar__wrap { .el-scrollbar__wrap {
height: 49px; height: 49px;
} }
} }
.scroll-container {
white-space: nowrap;
position: relative;
overflow: hidden;
width: 100%;
}
</style> </style>

View File

@@ -5,19 +5,19 @@ import {
ref, ref,
watch, watch,
onMounted, onMounted,
ComponentInternalInstance ComponentInternalInstance,
} from 'vue'; } from "vue";
import { storeToRefs } from 'pinia'; import { storeToRefs } from "pinia";
import path from 'path-browserify'; import path from "path-browserify";
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from "vue-router";
import { translateRouteTitleI18n } from '@/utils/i18n'; import { translateRouteTitleI18n } from "@/utils/i18n";
import { usePermissionStore } from '@/store/modules/permission'; import { usePermissionStore } from "@/store/modules/permission";
import { useTagsViewStore, TagView } from '@/store/modules/tagsView'; import { useTagsViewStore, TagView } from "@/store/modules/tagsView";
import ScrollPane from './ScrollPane.vue'; import ScrollPane from "./ScrollPane.vue";
const { proxy } = getCurrentInstance() as ComponentInternalInstance; const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const router = useRouter(); const router = useRouter();
@@ -42,30 +42,30 @@ watch(
}, },
{ {
//初始化立即执行 //初始化立即执行
immediate: true immediate: true,
} }
); );
const tagMenuVisible = ref(false); // 标签操作菜单显示状态 const tagMenuVisible = ref(false); // 标签操作菜单显示状态
watch(tagMenuVisible, value => { watch(tagMenuVisible, (value) => {
if (value) { if (value) {
document.body.addEventListener('click', closeTagMenu); document.body.addEventListener("click", closeTagMenu);
} else { } else {
document.body.removeEventListener('click', closeTagMenu); document.body.removeEventListener("click", closeTagMenu);
} }
}); });
function filterAffixTags(routes: any[], basePath = '/') { function filterAffixTags(routes: any[], basePath = "/") {
let tags: TagView[] = []; let tags: TagView[] = [];
routes.forEach(route => { routes.forEach((route) => {
if (route.meta && route.meta.affix) { if (route.meta && route.meta.affix) {
const tagPath = path.resolve(basePath, route.path); const tagPath = path.resolve(basePath, route.path);
tags.push({ tags.push({
fullPath: tagPath, fullPath: tagPath,
path: tagPath, path: tagPath,
name: route.name, name: route.name,
meta: { ...route.meta } meta: { ...route.meta },
}); });
} }
@@ -123,7 +123,7 @@ function isFirstView() {
return ( return (
(selectedTag.value as TagView).fullPath === (selectedTag.value as TagView).fullPath ===
tagsViewStore.visitedViews[1].fullPath || tagsViewStore.visitedViews[1].fullPath ||
(selectedTag.value as TagView).fullPath === '/index' (selectedTag.value as TagView).fullPath === "/index"
); );
} catch (err) { } catch (err) {
return false; return false;
@@ -145,7 +145,7 @@ function refreshSelectedTag(view: TagView) {
tagsViewStore.delCachedView(view); tagsViewStore.delCachedView(view);
const { fullPath } = view; const { fullPath } = view;
nextTick(() => { nextTick(() => {
router.replace({ path: '/redirect' + fullPath }).catch(err => { router.replace({ path: "/redirect" + fullPath }).catch((err) => {
console.warn(err); console.warn(err);
}); });
}); });
@@ -158,11 +158,11 @@ function toLastView(visitedViews: TagView[], view?: any) {
} else { } else {
// now the default is to redirect to the home page if there is no tags-view, // now the default is to redirect to the home page if there is no tags-view,
// you can adjust it according to your needs. // you can adjust it according to your needs.
if (view.name === 'Dashboard') { if (view.name === "Dashboard") {
// to reload home page // to reload home page
router.replace({ path: '/redirect' + view.fullPath }); router.replace({ path: "/redirect" + view.fullPath });
} else { } else {
router.push('/'); router.push("/");
} }
} }
} }
@@ -210,7 +210,7 @@ function closeAllTags(view: TagView) {
function openTagMenu(tag: TagView, e: MouseEvent) { function openTagMenu(tag: TagView, e: MouseEvent) {
const menuMinWidth = 105; const menuMinWidth = 105;
console.log('test', proxy?.$el); console.log("test", proxy?.$el);
const offsetLeft = proxy?.$el.getBoundingClientRect().left; // container margin left const offsetLeft = proxy?.$el.getBoundingClientRect().left; // container margin left
const offsetWidth = proxy?.$el.offsetWidth; // container width const offsetWidth = proxy?.$el.offsetWidth; // container width
@@ -300,18 +300,19 @@ onMounted(() => {
<style lang="scss" scoped> <style lang="scss" scoped>
.tags-container { .tags-container {
height: 34px;
width: 100%; width: 100%;
border: 1px solid var(--el-border-color-light); height: 34px;
box-shadow: 0px 1px 1px var(--el-box-shadow-light);
background-color: var(--el-bg-color); background-color: var(--el-bg-color);
border: 1px solid var(--el-border-color-light);
box-shadow: 0 1px 1px var(--el-box-shadow-light);
.tags-item { .tags-item {
display: inline-block; display: inline-block;
padding: 3px 8px;
margin: 4px 0 0 5px;
font-size: 12px;
cursor: pointer; cursor: pointer;
border: 1px solid var(--el-border-color-light); border: 1px solid var(--el-border-color-light);
padding: 3px 8px;
font-size: 12px;
margin: 4px 0 0 5px;
&:first-of-type { &:first-of-type {
margin-left: 15px; margin-left: 15px;
@@ -326,46 +327,44 @@ onMounted(() => {
} }
&.active { &.active {
background-color: var(--el-color-primary);
color: #fff; color: #fff;
background-color: var(--el-color-primary);
border-color: var(--el-color-primary); border-color: var(--el-color-primary);
&::before { &::before {
content: '';
background: #fff;
display: inline-block; display: inline-block;
width: 8px; width: 8px;
height: 8px; height: 8px;
border-radius: 50%;
margin-right: 5px; margin-right: 5px;
} content: "";
.tags-item-close { background: #fff;
&:hover { border-radius: 50%;
background: rgb(0 0 0 / 0.16);
}
} }
} }
&-close { &-close {
border-radius: 100%; border-radius: 100%;
&:hover { &:hover {
color: #fff; color: #fff;
background: rgb(0 0 0 / 0.16); background: rgb(0 0 0 / 16%);
} }
} }
} }
} }
.tag-menu { .tag-menu {
background: var(--el-bg-color-overlay);
z-index: 99;
position: absolute; position: absolute;
border-radius: 4px; z-index: 99;
font-size: 12px; font-size: 12px;
background: var(--el-bg-color-overlay);
border-radius: 4px;
box-shadow: var(--el-box-shadow-light); box-shadow: var(--el-box-shadow-light);
li { li {
padding: 8px 16px; padding: 8px 16px;
cursor: pointer; cursor: pointer;
&:hover { &:hover {
background: var(--el-fill-color-light); background: var(--el-fill-color-light);
} }

View File

@@ -1,12 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, watchEffect } from 'vue'; import { computed, watchEffect } from "vue";
import { useWindowSize } from '@vueuse/core'; import { useWindowSize } from "@vueuse/core";
import { AppMain, Navbar, Settings, TagsView } from './components/index'; import { AppMain, Navbar, Settings, TagsView } from "./components/index";
import Sidebar from './components/Sidebar/index.vue'; import Sidebar from "./components/Sidebar/index.vue";
import RightPanel from '@/components/RightPanel/index.vue'; import RightPanel from "@/components/RightPanel/index.vue";
import { useAppStore } from '@/store/modules/app'; import { useAppStore } from "@/store/modules/app";
import { useSettingsStore } from '@/store/modules/settings'; import { useSettingsStore } from "@/store/modules/settings";
const { width } = useWindowSize(); const { width } = useWindowSize();
@@ -30,15 +30,15 @@ const classObj = computed(() => ({
hideSidebar: !appStore.sidebar.opened, hideSidebar: !appStore.sidebar.opened,
openSidebar: appStore.sidebar.opened, openSidebar: appStore.sidebar.opened,
withoutAnimation: appStore.sidebar.withoutAnimation, withoutAnimation: appStore.sidebar.withoutAnimation,
mobile: appStore.device === 'mobile' mobile: appStore.device === "mobile",
})); }));
watchEffect(() => { watchEffect(() => {
if (width.value < WIDTH) { if (width.value < WIDTH) {
appStore.toggleDevice('mobile'); appStore.toggleDevice("mobile");
appStore.closeSideBar(true); appStore.closeSideBar(true);
} else { } else {
appStore.toggleDevice('desktop'); appStore.toggleDevice("desktop");
if (width.value >= 1200) { if (width.value >= 1200) {
//大屏 //大屏
@@ -84,15 +84,15 @@ function handleOutsideClick() {
<style lang="scss" scoped> <style lang="scss" scoped>
.app-wrapper { .app-wrapper {
&:after { &::after {
content: '';
display: table; display: table;
clear: both; clear: both;
content: "";
} }
position: relative; position: relative;
height: 100%;
width: 100%; width: 100%;
height: 100%;
&.mobile.openSidebar { &.mobile.openSidebar {
position: fixed; position: fixed;
@@ -108,20 +108,22 @@ function handleOutsideClick() {
width: calc(100% - #{$sideBarWidth}); width: calc(100% - #{$sideBarWidth});
transition: width 0.28s; transition: width 0.28s;
} }
.hideSidebar .fixed-header { .hideSidebar .fixed-header {
width: calc(100% - 54px); width: calc(100% - 54px);
} }
.mobile .fixed-header { .mobile .fixed-header {
width: 100%; width: 100%;
} }
.drawer-bg { .drawer-bg {
position: absolute;
top: 0;
z-index: 999;
width: 100%;
height: 100%;
background: #000; background: #000;
opacity: 0.3; opacity: 0.3;
width: 100%;
top: 0;
height: 100%;
position: absolute;
z-index: 999;
} }
</style> </style>

View File

@@ -2,16 +2,15 @@ html.dark{
--menuBg: var(--el-bg-color-overlay); --menuBg: var(--el-bg-color-overlay);
--menuText: #fff; --menuText: #fff;
--menuActiveText: var(--el-menu-active-color); --menuActiveText: var(--el-menu-active-color);
--menuHover:rgba(0,0,0,.2); --menuHover: rgb(0 0 0 / 20%);
--subMenuBg: var(--el-menu-bg-color); --subMenuBg: var(--el-menu-bg-color);
--subMenuActiveText: var(--el-menu-active-color); --subMenuActiveText: var(--el-menu-active-color);
--subMenuHover: rgba(0,0,0,.2); --subMenuHover: rgb(0 0 0 / 20%);
.navbar { .navbar {
background-color: var(--el-bg-color);
color: var(--el-text-color-regular); color: var(--el-text-color-regular);
background-color: var(--el-bg-color);
.navbar-setting-item:hover { .navbar-setting-item:hover {
background: var(--el-fill-color-light); background: var(--el-fill-color-light);
} }
@@ -20,11 +19,12 @@ html.dark{
.right-panel-btn { .right-panel-btn {
background-color: var(--el-color-primary-dark); background-color: var(--el-color-primary-dark);
} }
.svg-icon,svg{
.svg-icon,
svg {
fill: var(--el-text-color-regular); fill: var(--el-text-color-regular);
} }
.sidebar-container { .sidebar-container {
.el-menu-item.is-active .svg-icon { .el-menu-item.is-active .svg-icon {
fill: var(--el-color-primary); fill: var(--el-color-primary);

View File

@@ -1,18 +1,16 @@
@import './sidebar.scss'; @import "./sidebar";
@import './reset.scss'; @import "./reset";
@import './dark.scss'; @import "./dark";
.app-container { .app-container {
padding: 20px; padding: 20px;
.search { .search {
padding: 18px 0 0 10px; padding: 18px 0 0 10px;
margin-bottom: 10px; margin-bottom: 10px;
border-radius: 4px;
border: 1px solid var(--el-border-color-light);
box-shadow: var(--el-box-shadow-light);
background-color: var(--el-bg-color-overlay); background-color: var(--el-bg-color-overlay);
border: 1px solid var(--el-border-color-light);
border-radius: 4px;
box-shadow: var(--el-box-shadow-light);
} }
} }

View File

@@ -2,9 +2,9 @@
::before, ::before,
::after { ::after {
box-sizing: border-box; box-sizing: border-box;
border-width: 0; border-color: currentcolor;
border-style: solid; border-style: solid;
border-color: currentColor; border-width: 0;
} }
#app { #app {
@@ -13,69 +13,63 @@
} }
html { html {
line-height: 1.5; box-sizing: border-box;
-webkit-text-size-adjust: 100%;
-moz-tab-size: 4;
tab-size: 4;
width: 100%; width: 100%;
height: 100%; height: 100%;
box-sizing: border-box; line-height: 1.5;
tab-size: 4;
text-size-adjust: 100%;
} }
body { body {
margin: 0;
line-height: inherit;
width: 100%; width: 100%;
height: 100%; height: 100%;
margin: 0;
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB",
"Microsoft YaHei", "微软雅黑", Arial, sans-serif;
line-height: inherit;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
text-rendering: optimizelegibility; text-rendering: optimizelegibility;
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB",
"Microsoft YaHei", "微软雅黑", Arial, sans-serif;
} }
a { a {
color: inherit; color: inherit;
text-decoration: inherit; text-decoration: inherit;
} }
img, img,
svg svg {
{
display: inline-block; display: inline-block;
} }
svg { svg {
vertical-align: -0.15em; //因icon大小被设置为和字体大小一致而span等标签的下边缘会和字体的基线对齐故需设置一个往下的偏移比例来纠正视觉上的未对齐效果 vertical-align: -0.15em; //因icon大小被设置为和字体大小一致而span等标签的下边缘会和字体的基线对齐故需设置一个往下的偏移比例来纠正视觉上的未对齐效果
} }
ul,
ul,li{ li {
margin: 0;
padding: 0; padding: 0;
margin: 0;
list-style: none; list-style: none;
} }
*, *,
*::before, *::before,
*::after { *::after {
box-sizing: inherit; box-sizing: inherit;
} }
a:focus,
a:active ,
div:focus
{
outline: none;
}
a, a,
a:focus, a:focus,
a:hover { a:hover {
cursor: pointer;
color: inherit; color: inherit;
text-decoration: none; text-decoration: none;
cursor: pointer;
} }
a:focus,
a:active,
div:focus {
outline: none;
}

View File

@@ -1,22 +1,22 @@
#app { #app {
.main-container { .main-container {
min-height: 100%;
transition: margin-left 0.28s;
margin-left: $sideBarWidth;
position: relative; position: relative;
min-height: 100%;
margin-left: $sideBarWidth;
transition: margin-left 0.28s;
} }
.sidebar-container { .sidebar-container {
transition: width 0.28s;
width: $sideBarWidth !important;
background-color: $menuBg;
height: 100%;
position: fixed; position: fixed;
top: 0; top: 0;
bottom: 0; bottom: 0;
left: 0; left: 0;
z-index: 1001; z-index: 1001;
width: $sideBarWidth !important;
height: 100%;
overflow: hidden; overflow: hidden;
background-color: $menuBg;
transition: width 0.28s;
// reset element-ui css // reset element-ui css
.horizontal-collapse-transition { .horizontal-collapse-transition {
@@ -29,7 +29,7 @@
} }
.el-scrollbar__bar.is-vertical { .el-scrollbar__bar.is-vertical {
right: 0px; right: 0;
} }
.el-scrollbar { .el-scrollbar {
@@ -46,7 +46,6 @@
display: none; display: none;
} }
.svg-icon { .svg-icon {
margin-right: 16px; margin-right: 16px;
} }
@@ -57,9 +56,9 @@
} }
.el-menu { .el-menu {
border: none;
height: 100%;
width: 100% !important; width: 100% !important;
height: 100%;
border: none;
} }
// menu hover // menu hover
@@ -89,7 +88,7 @@
width: 54px !important; width: 54px !important;
.svg-icon { .svg-icon {
margin-right: 0px; margin-right: 0;
} }
} }
@@ -121,11 +120,11 @@
.el-sub-menu { .el-sub-menu {
& > .el-sub-menu__title { & > .el-sub-menu__title {
& > span { & > span {
height: 0; display: inline-block;
width: 0; width: 0;
height: 0;
overflow: hidden; overflow: hidden;
visibility: hidden; visibility: hidden;
display: inline-block;
} }
} }
} }
@@ -139,12 +138,12 @@
// mobile responsive // mobile responsive
.mobile { .mobile {
.main-container { .main-container {
margin-left: 0px; margin-left: 0;
} }
.sidebar-container { .sidebar-container {
transition: transform 0.28s;
width: $sideBarWidth !important; width: $sideBarWidth !important;
transition: transform 0.28s;
} }
&.hideSidebar { &.hideSidebar {
@@ -157,7 +156,6 @@
} }
.withoutAnimation { .withoutAnimation {
.main-container, .main-container,
.sidebar-container { .sidebar-container {
transition: none; transition: none;

View File

@@ -5,14 +5,11 @@
--menuText: #bfcbd9; --menuText: #bfcbd9;
--menuActiveText: #409eff; --menuActiveText: #409eff;
--menuHover: #263445; --menuHover: #263445;
--subMenuBg: #1f2d3d; --subMenuBg: #1f2d3d;
--subMenuActiveText: #f4f4f5; --subMenuActiveText: #f4f4f5;
--subMenuHover: #001528; --subMenuHover: #001528;
} }
$menuBg: var(--menuBg); $menuBg: var(--menuBg);
$menuText: var(--menuText); $menuText: var(--menuText);
$menuActiveText: var(--menuActiveText); $menuActiveText: var(--menuActiveText);

View File

@@ -1,16 +1,16 @@
<script lang="ts"> <script lang="ts">
export default { name: 'Dashboard' }; export default { name: "Dashboard" };
</script> </script>
<script setup lang="ts"> <script setup lang="ts">
import { useUserStore } from '@/store/modules/user'; import { useUserStore } from "@/store/modules/user";
import { useTransition, TransitionPresets } from '@vueuse/core'; import { useTransition, TransitionPresets } from "@vueuse/core";
import GithubCorner from '@/components/GithubCorner/index.vue'; import GithubCorner from "@/components/GithubCorner/index.vue";
import SvgIcon from '@/components/SvgIcon/index.vue'; import SvgIcon from "@/components/SvgIcon/index.vue";
import BarChart from './components/BarChart.vue'; import BarChart from "./components/BarChart.vue";
import PieChart from './components/PieChart.vue'; import PieChart from "./components/PieChart.vue";
import RadarChart from './components/RadarChart.vue'; import RadarChart from "./components/RadarChart.vue";
const userStore = useUserStore(); const userStore = useUserStore();
@@ -18,15 +18,15 @@ const date: Date = new Date();
const greetings = computed(() => { const greetings = computed(() => {
if (date.getHours() >= 6 && date.getHours() < 8) { if (date.getHours() >= 6 && date.getHours() < 8) {
return '晨起披衣出草堂,轩窗已自喜微凉🌅!'; return "晨起披衣出草堂,轩窗已自喜微凉🌅!";
} else if (date.getHours() >= 8 && date.getHours() < 12) { } else if (date.getHours() >= 8 && date.getHours() < 12) {
return '上午好🌞!'; return "上午好🌞!";
} else if (date.getHours() >= 12 && date.getHours() < 18) { } else if (date.getHours() >= 12 && date.getHours() < 18) {
return '下午好☕!'; return "下午好☕!";
} else if (date.getHours() >= 18 && date.getHours() < 24) { } else if (date.getHours() >= 18 && date.getHours() < 24) {
return '晚上好🌃!'; return "晚上好🌃!";
} else if (date.getHours() >= 0 && date.getHours() < 6) { } else if (date.getHours() >= 0 && date.getHours() < 6) {
return '偷偷向银河要了一把碎星,只等你闭上眼睛撒入你的梦中,晚安🌛!'; return "偷偷向银河要了一把碎星,只等你闭上眼睛撒入你的梦中,晚安🌛!";
} }
}); });
@@ -36,7 +36,7 @@ const duration = 5000;
const amount = ref(0); const amount = ref(0);
const amountOutput = useTransition(amount, { const amountOutput = useTransition(amount, {
duration: duration, duration: duration,
transition: TransitionPresets.easeOutExpo transition: TransitionPresets.easeOutExpo,
}); });
amount.value = 2000; amount.value = 2000;
@@ -44,7 +44,7 @@ amount.value = 2000;
const visitCount = ref(0); const visitCount = ref(0);
const visitCountOutput = useTransition(visitCount, { const visitCountOutput = useTransition(visitCount, {
duration: duration, duration: duration,
transition: TransitionPresets.easeOutExpo transition: TransitionPresets.easeOutExpo,
}); });
visitCount.value = 2000; visitCount.value = 2000;
@@ -52,7 +52,7 @@ visitCount.value = 2000;
const messageCount = ref(0); const messageCount = ref(0);
const messageCountOutput = useTransition(messageCount, { const messageCountOutput = useTransition(messageCount, {
duration: duration, duration: duration,
transition: TransitionPresets.easeOutExpo transition: TransitionPresets.easeOutExpo,
}); });
messageCount.value = 2000; messageCount.value = 2000;
@@ -60,7 +60,7 @@ messageCount.value = 2000;
const orderCount = ref(0); const orderCount = ref(0);
const orderCountOutput = useTransition(orderCount, { const orderCountOutput = useTransition(orderCount, {
duration: duration, duration: duration,
transition: TransitionPresets.easeOutExpo transition: TransitionPresets.easeOutExpo,
}); });
orderCount.value = 2000; orderCount.value = 2000;
</script> </script>
@@ -215,34 +215,36 @@ orderCount.value = 2000;
<style lang="scss" scoped> <style lang="scss" scoped>
.dashboard-container { .dashboard-container {
padding: 24px;
position: relative; position: relative;
padding: 24px;
.user-avatar { .user-avatar {
height: 40px;
width: 40px; width: 40px;
height: 40px;
border-radius: 50%; border-radius: 50%;
} }
.github-corner { .github-corner {
position: absolute; position: absolute;
top: 0px; top: 0;
border: 0;
right: 0; right: 0;
z-index: 99; z-index: 99;
border: 0;
} }
.data-box { .data-box {
font-weight: bold;
padding: 20px;
color: var(--el-text-color-regular);
background: var(--el-bg-color-overlay);
box-shadow: var(--el-box-shadow-dark);
border-color: var(--el-border-color);
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
padding: 20px;
font-weight: bold;
color: var(--el-text-color-regular);
background: var(--el-bg-color-overlay);
border-color: var(--el-border-color);
box-shadow: var(--el-box-shadow-dark);
} }
.svg-icon { .svg-icon {
fill: currentColor !important; fill: currentcolor !important;
} }
} }
</style> </style>

View File

@@ -2,7 +2,7 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<iframe <iframe
id="apidocIframe" id="apidoc-iframe"
src="https://www.apifox.cn/apidoc/shared-195e783f-4d85-4235-a038-eec696de4ea5" src="https://www.apifox.cn/apidoc/shared-195e783f-4d85-4235-a038-eec696de4ea5"
width="100%" width="100%"
frameborder="0" frameborder="0"
@@ -11,12 +11,12 @@
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
#apidocIframe { #apidoc-iframe {
height: calc(100vh - 100px); height: calc(100vh - 100px);
} }
.hasTagsView { .hasTagsView {
#apidocIframe { #apidoc-iframe {
height: calc(100vh - 140px); height: calc(100vh - 140px);
} }
} }

View File

@@ -1,20 +1,20 @@
<!-- setup 无法设置组件名称组件名称keepAlive必须 --> <!-- setup 无法设置组件名称组件名称keepAlive必须 -->
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'Page401' name: "Page401",
}; };
</script> </script>
<script setup lang="ts"> <script setup lang="ts">
import { reactive, toRefs } from 'vue'; import { reactive, toRefs } from "vue";
import { useRouter } from 'vue-router'; import { useRouter } from "vue-router";
const state = reactive({ const state = reactive({
errGif: new URL(`../../assets/401_images/401.gif`, import.meta.url).href, errGif: new URL(`../../assets/401_images/401.gif`, import.meta.url).href,
ewizardClap: ewizardClap:
'https://wpimg.wallstcn.com/007ef517-bafd-4066-aae4-6883632d9646', "https://wpimg.wallstcn.com/007ef517-bafd-4066-aae4-6883632d9646",
dialogVisible: false dialogVisible: false,
}); });
const { errGif, ewizardClap, dialogVisible } = toRefs(state); const { errGif, ewizardClap, dialogVisible } = toRefs(state);
@@ -72,20 +72,20 @@ function back() {
margin: 100px auto; margin: 100px auto;
.pan-back-btn { .pan-back-btn {
background: #008489;
color: #fff; color: #fff;
background: #008489;
border: none !important; border: none !important;
} }
.pan-gif { .pan-gif {
margin: 0 auto;
display: block; display: block;
margin: 0 auto;
} }
.pan-img { .pan-img {
display: block; display: block;
margin: 0 auto;
width: 100%; width: 100%;
margin: 0 auto;
} }
.text-jumbo { .text-jumbo {

View File

@@ -1,13 +1,13 @@
<!-- setup 无法设置组件名称组件名称keepAlive必须 --> <!-- setup 无法设置组件名称组件名称keepAlive必须 -->
<script lang="ts"> <script lang="ts">
export default { export default {
name: 'Page404' name: "Page404",
}; };
</script> </script>
<script setup lang="ts"> <script setup lang="ts">
function message() { function message() {
return 'The webmaster said that you can not enter this page...'; return "The webmaster said that you can not enter this page...";
} }
</script> </script>
@@ -60,10 +60,10 @@ function message() {
<style lang="scss" scoped> <style lang="scss" scoped>
.wscn-http404-container { .wscn-http404-container {
transform: translate(-50%, -50%);
position: absolute; position: absolute;
top: 40%; top: 40%;
left: 50%; left: 50%;
transform: translate(-50%, -50%);
} }
.wscn-http404 { .wscn-http404 {
@@ -86,39 +86,39 @@ function message() {
position: absolute; position: absolute;
&.left { &.left {
width: 80px;
top: 17px; top: 17px;
left: 220px; left: 220px;
width: 80px;
opacity: 0; opacity: 0;
animation-name: cloudLeft; animation-name: cloudLeft;
animation-duration: 2s; animation-duration: 2s;
animation-timing-function: linear; animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1s; animation-delay: 1s;
animation-fill-mode: forwards;
} }
&.mid { &.mid {
width: 46px;
top: 10px; top: 10px;
left: 420px; left: 420px;
width: 46px;
opacity: 0; opacity: 0;
animation-name: cloudMid; animation-name: cloudMid;
animation-duration: 2s; animation-duration: 2s;
animation-timing-function: linear; animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1.2s; animation-delay: 1.2s;
animation-fill-mode: forwards;
} }
&.right { &.right {
width: 62px;
top: 100px; top: 100px;
left: 500px; left: 500px;
width: 62px;
opacity: 0; opacity: 0;
animation-name: cloudRight; animation-name: cloudRight;
animation-duration: 2s; animation-duration: 2s;
animation-timing-function: linear; animation-timing-function: linear;
animation-fill-mode: forwards;
animation-delay: 1s; animation-delay: 1s;
animation-fill-mode: forwards;
} }
@keyframes cloudLeft { @keyframes cloudLeft {
@@ -209,24 +209,24 @@ function message() {
overflow: hidden; overflow: hidden;
&__oops { &__oops {
margin-bottom: 20px;
font-size: 32px; font-size: 32px;
font-weight: bold; font-weight: bold;
line-height: 40px; line-height: 40px;
color: #1482f0; color: #1482f0;
opacity: 0; opacity: 0;
margin-bottom: 20px;
animation-name: slideUp; animation-name: slideUp;
animation-duration: 0.5s; animation-duration: 0.5s;
animation-fill-mode: forwards; animation-fill-mode: forwards;
} }
&__headline { &__headline {
margin-bottom: 10px;
font-size: 20px; font-size: 20px;
font-weight: bold;
line-height: 24px; line-height: 24px;
color: #222; color: #222;
font-weight: bold;
opacity: 0; opacity: 0;
margin-bottom: 10px;
animation-name: slideUp; animation-name: slideUp;
animation-duration: 0.5s; animation-duration: 0.5s;
animation-delay: 0.1s; animation-delay: 0.1s;
@@ -234,11 +234,11 @@ function message() {
} }
&__info { &__info {
margin-bottom: 30px;
font-size: 13px; font-size: 13px;
line-height: 21px; line-height: 21px;
color: grey; color: grey;
opacity: 0; opacity: 0;
margin-bottom: 30px;
animation-name: slideUp; animation-name: slideUp;
animation-duration: 0.5s; animation-duration: 0.5s;
animation-delay: 0.2s; animation-delay: 0.2s;
@@ -250,14 +250,14 @@ function message() {
float: left; float: left;
width: 110px; width: 110px;
height: 36px; height: 36px;
background: #1482f0;
border-radius: 100px;
text-align: center;
color: #ffffff;
opacity: 0;
font-size: 14px; font-size: 14px;
line-height: 36px; line-height: 36px;
color: #fff;
text-align: center;
cursor: pointer; cursor: pointer;
background: #1482f0;
border-radius: 100px;
opacity: 0;
animation-name: slideUp; animation-name: slideUp;
animation-duration: 0.5s; animation-duration: 0.5s;
animation-delay: 0.3s; animation-delay: 0.3s;
@@ -266,13 +266,13 @@ function message() {
@keyframes slideUp { @keyframes slideUp {
0% { 0% {
transform: translateY(60px);
opacity: 0; opacity: 0;
transform: translateY(60px);
} }
100% { 100% {
transform: translateY(0);
opacity: 1; opacity: 1;
transform: translateY(0);
} }
} }
} }

View File

@@ -7,7 +7,7 @@
class="login-form" class="login-form"
> >
<div class="flex text-white items-center py-4"> <div class="flex text-white items-center py-4">
<span class="text-2xl flex-1 text-center">{{ $t('login.title') }}</span> <span class="text-2xl flex-1 text-center">{{ $t("login.title") }}</span>
<lang-select style="color: #fff" /> <lang-select style="color: #fff" />
</div> </div>
@@ -77,30 +77,30 @@
type="primary" type="primary"
class="w-full" class="w-full"
@click.prevent="handleLogin" @click.prevent="handleLogin"
>{{ $t('login.login') }} >{{ $t("login.login") }}
</el-button> </el-button>
<!-- 账号密码提示 --> <!-- 账号密码提示 -->
<div class="mt-4 text-white text-sm"> <div class="mt-4 text-white text-sm">
<span>{{ $t('login.username') }}: admin</span> <span>{{ $t("login.username") }}: admin</span>
<span class="ml-4"> {{ $t('login.password') }}: 123456</span> <span class="ml-4"> {{ $t("login.password") }}: 123456</span>
</div> </div>
</el-form> </el-form>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import router from '@/router'; import router from "@/router";
import LangSelect from '@/components/LangSelect/index.vue'; import LangSelect from "@/components/LangSelect/index.vue";
import SvgIcon from '@/components/SvgIcon/index.vue'; import SvgIcon from "@/components/SvgIcon/index.vue";
// 状态管理依赖 // 状态管理依赖
import { useUserStore } from '@/store/modules/user'; import { useUserStore } from "@/store/modules/user";
// API依赖 // API依赖
import { LocationQuery, LocationQueryValue, useRoute } from 'vue-router'; import { LocationQuery, LocationQueryValue, useRoute } from "vue-router";
import { getCaptchaApi } from '@/api/auth'; import { getCaptchaApi } from "@/api/auth";
import { LoginData } from '@/api/auth/types'; import { LoginData } from "@/api/auth/types";
const userStore = useUserStore(); const userStore = useUserStore();
const route = useRoute(); const route = useRoute();
@@ -128,14 +128,14 @@ const captchaBase64 = ref();
const loginFormRef = ref(ElForm); const loginFormRef = ref(ElForm);
const loginData = ref<LoginData>({ const loginData = ref<LoginData>({
username: 'admin', username: "admin",
password: '123456' password: "123456",
}); });
const loginRules = { const loginRules = {
username: [{ required: true, trigger: 'blur' }], username: [{ required: true, trigger: "blur" }],
password: [{ required: true, trigger: 'blur', validator: passwordValidator }], password: [{ required: true, trigger: "blur", validator: passwordValidator }],
verifyCode: [{ required: true, trigger: 'blur' }] verifyCode: [{ required: true, trigger: "blur" }],
}; };
/** /**
@@ -143,7 +143,7 @@ const loginRules = {
*/ */
function passwordValidator(rule: any, value: any, callback: any) { function passwordValidator(rule: any, value: any, callback: any) {
if (value.length < 6) { if (value.length < 6) {
callback(new Error('The password can not be less than 6 digits')); callback(new Error("The password can not be less than 6 digits"));
} else { } else {
callback(); callback();
} }
@@ -154,7 +154,7 @@ function passwordValidator(rule: any, value: any, callback: any) {
*/ */
function checkCapslock(e: any) { function checkCapslock(e: any) {
const { key } = e; const { key } = e;
isCapslock.value = key && key.length === 1 && key >= 'A' && key <= 'Z'; isCapslock.value = key && key.length === 1 && key >= "A" && key <= "Z";
} }
/** /**
@@ -180,11 +180,11 @@ function handleLogin() {
.then(() => { .then(() => {
const query: LocationQuery = route.query; const query: LocationQuery = route.query;
const redirect = (query.redirect as LocationQueryValue) ?? '/'; const redirect = (query.redirect as LocationQueryValue) ?? "/";
const otherQueryParams = Object.keys(query).reduce( const otherQueryParams = Object.keys(query).reduce(
(acc: any, cur: string) => { (acc: any, cur: string) => {
if (cur !== 'redirect') { if (cur !== "redirect") {
acc[cur] = query[cur]; acc[cur] = query[cur];
} }
return acc; return acc;
@@ -212,10 +212,10 @@ onMounted(() => {
<style lang="scss" scoped> <style lang="scss" scoped>
.login-container { .login-container {
min-height: 100%;
width: 100%; width: 100%;
background-color: #2d3a4b; min-height: 100%;
overflow: hidden; overflow: hidden;
background-color: #2d3a4b;
.login-form { .login-form {
width: 520px; width: 520px;
@@ -226,12 +226,12 @@ onMounted(() => {
.captcha { .captcha {
position: absolute; position: absolute;
right: 0;
top: 0; top: 0;
right: 0;
img { img {
height: 48px;
width: 120px; width: 120px;
height: 48px;
cursor: pointer; cursor: pointer;
} }
} }
@@ -239,8 +239,8 @@ onMounted(() => {
} }
.el-form-item { .el-form-item {
border: 1px solid rgba(255, 255, 255, 0.1); background: rgb(0 0 0 / 10%);
background: rgba(0, 0, 0, 0.1); border: 1px solid rgb(255 255 255 / 10%);
border-radius: 5px; border-radius: 5px;
} }
@@ -254,10 +254,10 @@ onMounted(() => {
box-shadow: none; box-shadow: none;
.el-input__inner { .el-input__inner {
background: transparent;
border: 0px;
border-radius: 0px;
color: #fff; color: #fff;
background: transparent;
border: 0;
border-radius: 0;
caret-color: #fff; caret-color: #fff;
&:-webkit-autofill { &:-webkit-autofill {
@@ -270,9 +270,8 @@ onMounted(() => {
&:-webkit-autofill:hover, &:-webkit-autofill:hover,
&:-webkit-autofill:focus, &:-webkit-autofill:focus,
&:-webkit-autofill:active { &:-webkit-autofill:active {
-webkit-transition-delay: 99999s; transition: color 99999s ease-out, background-color 99999s ease-out;
-webkit-transition: color 99999s ease-out, transition-delay: 99999s;
background-color 99999s ease-out;
} }
} }
} }