fix: 🐛 代码规范检测问题修复
Former-commit-id: 6e75bc91ce33ea9e7a17fbcb896f086f768896f4
This commit is contained in:
@@ -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 的样式
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
|
||||||
&:nth-child(1) {
|
|
||||||
width: 30%;
|
|
||||||
height: 100%;
|
|
||||||
background: #1b2a47;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(2) {
|
&-mix div:nth-child(1) {
|
||||||
width: 70%;
|
width: 100%;
|
||||||
height: 30%;
|
height: 30%;
|
||||||
top: 0;
|
background: #1b2a47;
|
||||||
right: 0;
|
box-shadow: 0 0 1px #888;
|
||||||
background: #fff;
|
|
||||||
box-shadow: 0 0 1px #888;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&-top {
|
&-mix div:nth-child(2) {
|
||||||
div {
|
position: absolute;
|
||||||
&:nth-child(1) {
|
bottom: 0;
|
||||||
width: 100%;
|
left: 0;
|
||||||
height: 30%;
|
width: 30%;
|
||||||
background: #1b2a47;
|
height: 70%;
|
||||||
box-shadow: 0 0 1px #888;
|
background: #1b2a47;
|
||||||
}
|
box-shadow: 0 0 1px #888;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&-mix {
|
&-top div:nth-child(1) {
|
||||||
div {
|
width: 100%;
|
||||||
&:nth-child(1) {
|
height: 30%;
|
||||||
width: 100%;
|
background: #1b2a47;
|
||||||
height: 30%;
|
box-shadow: 0 0 1px #888;
|
||||||
background: #1b2a47;
|
}
|
||||||
box-shadow: 0 0 1px #888;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(2) {
|
&-left div:nth-child(1) {
|
||||||
width: 30%;
|
width: 30%;
|
||||||
height: 70%;
|
height: 100%;
|
||||||
bottom: 0;
|
background: #1b2a47;
|
||||||
left: 0;
|
}
|
||||||
background: #1b2a47;
|
|
||||||
box-shadow: 0 0 1px #888;
|
&-left div:nth-child(2) {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
top: 0;
|
||||||
}
|
right: 0;
|
||||||
|
width: 70%;
|
||||||
|
height: 30%;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 0 1px #888;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -1,33 +1,33 @@
|
|||||||
html.dark{
|
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);
|
||||||
.navbar-setting-item:hover{
|
background-color: var(--el-bg-color);
|
||||||
|
|
||||||
|
.navbar-setting-item:hover {
|
||||||
background: var(--el-fill-color-light);
|
background: var(--el-fill-color-light);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
|
||||||
padding: 18px 0 0 10px;
|
.search {
|
||||||
margin-bottom: 10px;
|
padding: 18px 0 0 10px;
|
||||||
border-radius: 4px;
|
margin-bottom: 10px;
|
||||||
border: 1px solid var(--el-border-color-light);
|
background-color: var(--el-bg-color-overlay);
|
||||||
box-shadow: var(--el-box-shadow-light);
|
border: 1px solid var(--el-border-color-light);
|
||||||
background-color: var(--el-bg-color-overlay);
|
border-radius: 4px;
|
||||||
|
box-shadow: var(--el-box-shadow-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -69,11 +68,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.is-active>.el-sub-menu__title {
|
.is-active > .el-sub-menu__title {
|
||||||
color: $subMenuActiveText !important;
|
color: $subMenuActiveText !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
& .nest-menu .el-sub-menu>.el-sub-menu__title,
|
& .nest-menu .el-sub-menu > .el-sub-menu__title,
|
||||||
& .el-sub-menu .el-menu-item {
|
& .el-sub-menu .el-menu-item {
|
||||||
min-width: $sideBarWidth !important;
|
min-width: $sideBarWidth !important;
|
||||||
background-color: $subMenuBg !important;
|
background-color: $subMenuBg !important;
|
||||||
@@ -89,7 +88,7 @@
|
|||||||
width: 54px !important;
|
width: 54px !important;
|
||||||
|
|
||||||
.svg-icon {
|
.svg-icon {
|
||||||
margin-right: 0px;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +99,7 @@
|
|||||||
.el-sub-menu {
|
.el-sub-menu {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
&>.el-sub-menu__title {
|
& > .el-sub-menu__title {
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
|
|
||||||
.svg-icon {
|
.svg-icon {
|
||||||
@@ -119,13 +118,13 @@
|
|||||||
|
|
||||||
.el-menu--collapse {
|
.el-menu--collapse {
|
||||||
.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;
|
||||||
@@ -167,7 +165,7 @@
|
|||||||
|
|
||||||
// when menu collapsed
|
// when menu collapsed
|
||||||
.el-menu--vertical {
|
.el-menu--vertical {
|
||||||
&>.el-menu {
|
& > .el-menu {
|
||||||
.svg-icon {
|
.svg-icon {
|
||||||
margin-right: 16px;
|
margin-right: 16px;
|
||||||
}
|
}
|
||||||
@@ -178,7 +176,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.nest-menu .el-sub-menu>.el-sub-menu__title,
|
.nest-menu .el-sub-menu > .el-sub-menu__title,
|
||||||
.el-menu-item {
|
.el-menu-item {
|
||||||
&:hover {
|
&:hover {
|
||||||
// you can use $subMenuHover
|
// you can use $subMenuHover
|
||||||
@@ -187,7 +185,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// the scroll bar appears when the subMenu is too long
|
// the scroll bar appears when the subMenu is too long
|
||||||
>.el-menu--popup {
|
> .el-menu--popup {
|
||||||
max-height: 100vh;
|
max-height: 100vh;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
|
|||||||
@@ -1,25 +1,22 @@
|
|||||||
// 全局SCSS变量
|
// 全局SCSS变量
|
||||||
|
|
||||||
:root{
|
:root {
|
||||||
--menuBg:#304156;
|
--menuBg: #304156;
|
||||||
--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);
|
||||||
$menuHover: var(--menuHover);
|
$menuHover: var(--menuHover);
|
||||||
|
|
||||||
$subMenuBg:var(--subMenuBg);
|
$subMenuBg: var(--subMenuBg);
|
||||||
$subMenuActiveText:var(--subMenuActiveText);
|
$subMenuActiveText: var(--subMenuActiveText);
|
||||||
$subMenuHover:var(--subMenuHover);
|
$subMenuHover: var(--subMenuHover);
|
||||||
|
|
||||||
$sideBarWidth: 210px;
|
$sideBarWidth: 210px;
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user