🐛 fix dark mode issue

This commit is contained in:
landaiqing
2024-08-20 23:28:46 +08:00
parent 498807ca66
commit 7683fffb34
36 changed files with 1249 additions and 237 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
src/assets/images/cloud.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

BIN
src/assets/images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 KiB

View File

@@ -1,18 +1,22 @@
@import "theme";
body {
:root {
--background-color: #ffffff;
--text-color: #000000;
}
[data-theme="dark"] {
--background-color: #121212;
--text-color: #ffffff;
}
#app {
position: relative;
transition: background-color 0.3s,
color 0.3s;
width: 100vw;
height: 100vh;
@include useTheme {
background-color: getModeVar('bgColor') !important;
color: getModeVar('infoColor') !important;
}
}
#app {
overflow-x: hidden;
@include useTheme {
background-color: getModeVar('bgColor') !important;
color: getModeVar('infoColor') !important;
@@ -35,3 +39,5 @@ body {
#nprogress .peg {
box-shadow: 0 0 10px cyan, 0 0 5px cyan !important;
}

View File

@@ -1,7 +1,7 @@
::-webkit-scrollbar {
width: 6px;
height: 8px;
width: 1px;
height: 1px;
}
::-webkit-scrollbar-button {

View File

@@ -1,16 +1,15 @@
@import "colors.module";
$modes: (
light: (
bgColor: #fff,
"light": (
bgColor: transparent,
infoColor: #000
),
dark: (
"dark": (
bgColor: #000,
infoColor: #fff
)
);
$curMode: light;
$curTheme: red;
@mixin useTheme() {

View File

@@ -1,4 +1,3 @@
html,
body {
height: 100%;
@@ -18,7 +17,7 @@ html {
body {
position: relative;
background: transparent;
background: transparent !important;
padding: 0;
margin: 0;
}

View File

@@ -4,7 +4,7 @@
<h1>Popular</h1>
<div class="card card__one">
<div class="card__bg" style="background-position: -8.01px 4.59px;"></div>
<img class="card__img" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/3dr_mono.png"
<img class="card__img" src="@/assets/images/3dr_mono.png"
style="transform: translateX(17.8px) translateY(-10.2px);">
<div class="card__text">
<p class="card__title">Princess Mononoke</p>
@@ -12,7 +12,7 @@
</div>
<div class="card card__two">
<div class="card__bg" style="background-position: -8.01px 4.59px;"></div>
<img class="card__img" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/3dr_chihiro.png"
<img class="card__img" src="@/assets/images/3dr_chihiro.png"
style="transform: translateX(17.8px) translateY(-10.2px);">
<div class="card__text">
<p class="card__title">Spirited Away</p>
@@ -20,7 +20,7 @@
</div>
<div class="card card__three">
<div class="card__bg" style="background-position: -8.01px 4.59px;"></div>
<img class="card__img" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/3dr_howlcastle.png"
<img class="card__img" src="@/assets/images/3dr_howlcastle.png"
style="transform: translateX(17.8px) translateY(-10.2px);">
<div class="card__text">
<p class="card__title">Howl's Moving Castle</p>
@@ -65,25 +65,7 @@ onMounted(() => {
});
</script>
<style scoped>
@import url("https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700,800");
html, body {
height: 100%;
}
body {
align-items: center;
background: #642B73;
background: linear-gradient(to bottom, #C6426E, #642B73);
display: flex;
font-family: "Open Sans", sans;
justify-content: center;
overflow: hidden;
perspective: 1800px;
text-align: center;
margin: 0 20px;
}
<style scoped lang="scss">
h1 {
color: #3e3e42;
@@ -157,7 +139,7 @@ h3 {
}
.card__one .card__bg {
background: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/3dr_monobg.jpg") center/cover no-repeat;
background: url("@/assets/images/3dr_monobg.jpg") center/cover no-repeat;
}
.card__two .card__img {
@@ -165,7 +147,7 @@ h3 {
}
.card__two .card__bg {
background: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/3dr_spirited.jpg") center/cover no-repeat;
background: url("@/assets/images/3dr_spirited.jpg") center/cover no-repeat;
}
.card__three .card__img {
@@ -175,7 +157,7 @@ h3 {
}
.card__three .card__bg {
background: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/62105/3dr_howlbg.jpg") center/cover no-repeat;
background: url("@/assets/images/3dr_howlbg.jpg") center/cover no-repeat;
}
.card__text {

View File

@@ -0,0 +1,226 @@
<template>
<div class="flex-wrapper">
<section class="container">
<img id="cloudOne" class="clouds" src="@/assets/images/clouds.png"
style="transform: translateY(8.42555px);" alt="">
<img id="cloudTwo" class="clouds" src="@/assets/images/cloud.png"
style="transform: translateY(-1.92713px);" alt="">
<img id="cloudThree" class="clouds" src="@/assets/images/cloud.png"
style="transform: translateY(-13.9905px);" alt="">
<img id="cloudFour" class="clouds" src="@/assets/images/cloud.png"
style="transform: translateY(2.24832px);" alt="">
<div class="card-content">
<h1>{{ t("landing.title") }}</h1>
<p>{{ t("landing.description") }}</p>
<AButton class="button-text" type="primary">{{ t("landing.learnMore") }}</AButton>
</div>
<div class="background-container"></div>
</section>
</div>
</template>
<script setup lang="ts">
import {onMounted} from "vue";
import anime from 'animejs/lib/anime.es.js';
import {useI18n} from "vue-i18n";
const {t} = useI18n();
onMounted(() => {
anime({
targets: '#cloudOne',
translateY: '20',
duration: 2000,
loop: true,
direction: 'alternate',
easing: 'linear'
});
anime({
targets: '#cloudTwo',
translateY: '-20',
duration: 2500,
loop: true,
direction: 'alternate',
easing: 'linear'
});
anime({
targets: '#cloudThree',
translateY: '-30',
duration: 3000,
loop: true,
direction: 'alternate',
easing: 'linear'
});
anime({
targets: '#cloudFour',
translateY: '40',
duration: 5000,
loop: true,
direction: 'alternate',
easing: 'linear'
});
});
</script>
<style scoped lang="scss">
* {
box-sizing: border-box;
}
button {
background: #55B4FB;
border-radius: 30px;
border: 2px solid #55B4FB;
height: 44px;
width: 165px;
color: white;
position: relative;
cursor: pointer;
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.15);
transition: box-shadow 0.25s;
}
button:hover {
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25);
background: #46adfb;
}
button i {
background: #75C2FB;
padding: 10px;
border-radius: 50px;
position: absolute;
border: 1px solid white;
right: 2px;
top: 50%;
transform: translate(0%, -50%);
}
button .button-text {
position: absolute;
top: 50%;
transform: translate(0%, -50%);
left: 25px;
}
body {
background: #F4F5F8;
padding: 0 30px;
overflow: hidden;
}
.card-content {
z-index: 10;
width: 80%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -65%);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.card-content h1 {
color: white;
font-size: 2.5rem;
text-align: center;
margin-bottom: 10px;
font-family: Lato, sans-serif;
font-weight: 500;
text-shadow: 0px 1px 0px rgba(0, 0, 0, 0.15);
}
.card-content p {
color: white;
line-height: 1.5;
text-align: center;
margin-bottom: 25px;
margin-top: 0px;
font-size: 1.2rem;
font-weight: lighter;
max-width: 650px;
font-family: "Source Sans Pro", sans-serif;
font-weight: 300;
text-shadow: 0px 1px 0px rgba(0, 0, 0, 0.15);
}
.flex-wrapper {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
}
.container {
max-width: 800px;
min-width: 320px;
width: 100%;
background: #7A90F6;
/* fallback for old browsers */
/* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to right, #7A90F6, #7B6FF6);
/* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
position: relative;
height: 400px;
border-radius: 10px;
box-shadow: 0 25px 60px rgba(0, 0, 0, 0.15);
}
.background-container {
position: relative;
overflow: hidden;
width: 100%;
height: 100%;
border-radius: 10px;
}
.background-container:before {
position: absolute;
top: 0;
left: 50%;
z-index: 1;
width: 2000px;
height: 100%;
//background: url("https://www.digitalocean.com/assets/media/products/header-04dcc3be.svg");
//background-position: bottom;
//background-repeat: no-repeat;
content: "";
transform: translateX(-50%);
}
.clouds {
width: 225px;
position: absolute;
}
#cloudOne {
top: -100px;
left: -90px;
}
#cloudTwo {
right: -100px;
bottom: -90px;
z-index: 3;
}
#cloudThree {
left: 150px;
bottom: -150px;
z-index: -1;
}
#cloudFour {
right: 80px;
top: -100px;
z-index: -1;
width: 100px;
}
</style>

View File

@@ -1,12 +1,20 @@
<template>
<div style="display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 20px;">
<div style="height: 100px;margin-top: 50px;">
<span style="font-size: 50px; font-weight: bold;">{{ t('landing.title') }}</span>
</div>
<Card3D/>
<Clouds/>
</div>
</template>
<script setup lang="ts">
import Card3D from "@/components/3DCard/Card3D.vue";
import Card3D from "@/components/Card3D/Card3D.vue";
import Clouds from "@/components/Clouds/Clouds.vue";
import {useI18n} from "vue-i18n";
const {t} = useI18n();
</script>
<style scoped>
<style scoped lang="scss">
</style>

View File

@@ -1,11 +1,41 @@
<template>
<div>
<div class="landing-footer">
<div class="landing-footer-content">
<div class="landing-footer-content-left">
<div class="landing-footer-content-left-top">
<a href="#" class="landing-footer-content-a">{{t('landing.userAgreement')}}</a>
<a class="landing-footer-content-a">{{t('landing.privacyPolicy')}}</a>
<a class="landing-footer-content-a">{{t('landing.termsOfService')}}</a>
<a class="landing-footer-content-a">{{t('landing.contactUs')}}</a>
<a class="landing-footer-content-a">{{t('landing.friends')}}</a>
<a class="landing-footer-content-a">{{ t('landing.helpCenter')}}</a>
</div>
<div class="landing-footer-content-left-bottom">
<p class="landing-footer-content-p">{{t('landing.copyright')}}</p>
<p class="landing-footer-content-p">京ICP备19053963号-1</p>
<p class="landing-footer-content-p">京公网安备11010502037888号</p>
</div>
</div>
<div class="landing-footer-content-right">
<div style="width: 200px; display: flex; justify-content: space-between; align-items: center;">
<GithubOutlined class="landing-footer-content-icon"/>
<QqOutlined class="landing-footer-content-icon"/>
<WechatOutlined class="landing-footer-content-icon"/>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import {useI18n} from "vue-i18n";
const { t } = useI18n();
</script>
<style scoped>
<style src="./index.scss" scoped>
</style>

View File

@@ -0,0 +1,67 @@
.landing-footer {
width: 100%;
height: 200px;
background-color: #333;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
.landing-footer-content {
display: flex;
height: 100%;
max-width: 1200px;
min-width: 1200px;
width: 1200px;
.landing-footer-content-left {
display: flex;
flex-direction: column;
align-items: center;
width: 800px;
.landing-footer-content-left-top {
width: 100%;
height: 100px;
display: flex;
flex-direction: row;
align-items: flex-end;
justify-content: space-between;
font-size: 15px;
font-weight: bold;
.landing-footer-content-a {
color: #fff !important;
}
}
.landing-footer-content-left-bottom {
width: 100%;
height: 100px;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: space-around;
color: #777777;
font-size: 15px;
}
}
.landing-footer-content-right {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
width: 400px;
.landing-footer-content-icon {
font-size: 40px;
color: #777777;
}
}
}
}

View File

@@ -1,23 +1,45 @@
<template>
<div class="landing-header">
<AFlex :vertical="false" align-items="center" justify-content="space-between">
<div class="logo">
<img class="landing-header-logo" src="@/assets/svgs/logo-schisandra.svg" alt="logo">
</div>
</AFlex>
<AFlex :vertical="false" justify="space-between">
<div style="display: flex; align-items: center;justify-content: center;">
<div class="toggle-box" style="margin-top: 20px;">
<input @click="app.toggleDarkMode" v-model="isDarkMode" type="checkbox" name="checkbox1"
id="toggle-box-checkbox">
<label for="toggle-box-checkbox" class="toggle-box-label-left"></label>
<label for="toggle-box-checkbox" class="toggle-box-label"></label>
<div
style="display: flex; align-items: center;justify-content: space-between; width: 1200px;min-width: 1200px; max-width: 1200px;">
<AFlex :vertical="false" align-items="center" justify-content="space-between">
<div class="logo" style="display: flex; align-items: center;justify-content: center;cursor: pointer;">
<img class="landing-header-logo" src="@/assets/svgs/logo-schisandra.svg" alt="logo">
<img style="width: 200px;" src="@/assets/images/logo.png" alt="logo">
</div>
<AButton @click="router.push('/login')" type="primary" size="large" style="margin-right: 10px;">立即进入
</AButton>
</div>
</AFlex>
</AFlex>
<AFlex :vertical="false" justify="space-between">
<div style="display: flex; align-items: center;justify-content: center;">
<div class="toggle-box" style="margin-top: 20px;margin-right: 20px;">
<input @click="toggleTheme" v-model="isDarkMode" type="checkbox" name="checkbox1"
id="toggle-box-checkbox">
<label for="toggle-box-checkbox" class="toggle-box-label-left"></label>
<label for="toggle-box-checkbox" class="toggle-box-label"></label>
</div>
<div style="margin-right: 20px;">
<ADropdown>
<template #overlay>
<AMenu @click="(e: any)=>{
changeLang(e.key)
}">
<AMenuItem key="zh">{{ t("landing.chinese") }}</AMenuItem>
<AMenuItem key="en">{{ t("landing.english") }}</AMenuItem>
</AMenu>
</template>
<AButton type="text" size="large">
{{ lang.lang === 'zh' ? '中文' : 'English' }}
<DownOutlined/>
</AButton>
</ADropdown>
</div>
<AButton @click="router.push('/login')" type="primary" size="large" style="margin-right: 10px;">
{{ t("landing.immediately") }}
</AButton>
</div>
</AFlex>
</div>
</div>
</template>
<script setup lang="ts">
@@ -25,10 +47,62 @@
import router from "@/router/router.ts";
import useStore from "@/store/index.ts";
import {ref} from "vue";
import {DownOutlined} from '@ant-design/icons-vue';
import {useI18n} from "vue-i18n";
const lang = useStore().lang;
const {t, locale} = useI18n();
async function changeLang(language: any) {
lang.lang = language;
locale.value = language;
}
const app = useStore().theme;
const isDarkMode = ref<boolean>(app.darkMode === "dark");
const toggleTheme = (event: any) => {
const x = event.clientX;
const y = event.clientY;
const endRadius = Math.hypot(
Math.max(x, innerWidth - x),
Math.max(y, innerHeight - y)
);
// 兼容性处理
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-expect-error
if (!document.startViewTransition) {
app.toggleDarkMode();
return;
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-expect-error
const transition = document.startViewTransition(async () => {
app.toggleDarkMode();
});
transition.ready.then(() => {
const clipPath = [
`circle(0px at ${x}px ${y}px)`,
`circle(${endRadius}px at ${x}px ${y}px)`,
];
document.documentElement.animate(
{
clipPath: app.darkMode === "dark" ? [...clipPath].reverse() : clipPath,
},
{
duration: 400,
easing: "ease-in",
pseudoElement: app.darkMode === "dark"
? "::view-transition-old(root)"
: "::view-transition-new(root)",
}
);
});
};
</script>
<style src="./index.scss" scoped>

View File

@@ -1,10 +1,13 @@
.landing-header {
height: 100px;
width: 80%;
//background-color: #767779;
width: 100%;
background-color: rgba(255, 255, 255, 0.38);
backdrop-filter: blur(20px);
display: flex;
align-items: center;
justify-content: space-between;
justify-content: center;
transition: background-color 0.3s;
z-index: 3;
.landing-header-logo {
display: inline-block;
@@ -14,6 +17,7 @@
padding: 1rem;
}
// 黑暗切换按钮
.toggle-box-label-left:empty {
margin-left: -10px;
}
@@ -115,4 +119,28 @@
color: rgba(250, 250, 250, 0.51);
font-weight: bold;
}
::view-transition-old(root),
::view-transition-new(root) {
animation: none;
mix-blend-mode: normal;
}
::view-transition-old(root) {
z-index: 1;
}
::view-transition-new(root) {
z-index: 2147483646;
}
[data-bs-theme="dark"]::view-transition-old(root) {
z-index: 2147483646;
}
[data-bs-theme="dark"]::view-transition-new(root) {
z-index: 1;
}
}

View File

@@ -0,0 +1,125 @@
.area {
background: #b9f187;
background: -webkit-linear-gradient(to left, #b9f187, #90d952, #70c13a, #52a82e) !important;
width: 100%;
height: 100vh;
z-index: -1;
overflow: hidden;
position: fixed;
top: 0;
left: 0;
}
.circles {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
.circles li {
position: absolute;
display: block;
list-style: none;
width: 20px;
height: 20px;
background: rgba(255, 255, 255, 0.5);
animation: animate 25s linear infinite;
bottom: -150px;
}
.circles li:nth-child(1) {
left: 25%;
width: 80px;
height: 80px;
animation-delay: 0s;
}
.circles li:nth-child(2) {
left: 10%;
width: 20px;
height: 20px;
animation-delay: 2s;
animation-duration: 12s;
}
.circles li:nth-child(3) {
left: 70%;
width: 20px;
height: 20px;
animation-delay: 4s;
}
.circles li:nth-child(4) {
left: 40%;
width: 60px;
height: 60px;
animation-delay: 0s;
animation-duration: 18s;
}
.circles li:nth-child(5) {
left: 65%;
width: 20px;
height: 20px;
animation-delay: 0s;
}
.circles li:nth-child(6) {
left: 75%;
width: 110px;
height: 110px;
animation-delay: 3s;
}
.circles li:nth-child(7) {
left: 35%;
width: 150px;
height: 150px;
animation-delay: 7s;
}
.circles li:nth-child(8) {
left: 50%;
width: 25px;
height: 25px;
animation-delay: 15s;
animation-duration: 45s;
}
.circles li:nth-child(9) {
left: 20%;
width: 15px;
height: 15px;
animation-delay: 2s;
animation-duration: 35s;
}
.circles li:nth-child(10) {
left: 85%;
width: 150px;
height: 150px;
animation-delay: 0s;
animation-duration: 11s;
}
@keyframes animate {
0% {
transform: translateY(0) rotate(0deg);
opacity: 1;
border-radius: 0;
}
100% {
transform: translateY(-1000px) rotate(720deg);
opacity: 0;
border-radius: 50%;
}
}

View File

@@ -1,7 +1,7 @@
<template>
<AFlex :vertical="true" align="center" justify-content="center">
<Header/>
<Content/>
<AFlex :vertical="true" align="center" justify-content="center" v-cloak>
<Header style="position: fixed;"/>
<Content style="margin-top: 100px;z-index: 2;"/>
<Footer/>
<div class="area">
<ul class="circles">
@@ -24,131 +24,6 @@ import Header from "@/layout/Landing/Header/Header.vue";
import Footer from "@/layout/Landing/Footer/Footer.vue";
import Content from "@/layout/Landing/Content/Content.vue";
</script>
<style scoped lang="scss">
.area {
background: #b9f187;
background: -webkit-linear-gradient(to left, #b9f187, #90d952,#70c13a,#52a82e);
width: 100%;
height: 100vh;
z-index: -1;
overflow: hidden;
position: fixed;
top: 0;
left: 0;
<style src="./index.scss" scoped lang="scss">
}
.circles {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
.circles li {
position: absolute;
display: block;
list-style: none;
width: 20px;
height: 20px;
background: rgba(255, 255, 255, 0.5);
animation: animate 25s linear infinite;
bottom: -150px;
}
.circles li:nth-child(1) {
left: 25%;
width: 80px;
height: 80px;
animation-delay: 0s;
}
.circles li:nth-child(2) {
left: 10%;
width: 20px;
height: 20px;
animation-delay: 2s;
animation-duration: 12s;
}
.circles li:nth-child(3) {
left: 70%;
width: 20px;
height: 20px;
animation-delay: 4s;
}
.circles li:nth-child(4) {
left: 40%;
width: 60px;
height: 60px;
animation-delay: 0s;
animation-duration: 18s;
}
.circles li:nth-child(5) {
left: 65%;
width: 20px;
height: 20px;
animation-delay: 0s;
}
.circles li:nth-child(6) {
left: 75%;
width: 110px;
height: 110px;
animation-delay: 3s;
}
.circles li:nth-child(7) {
left: 35%;
width: 150px;
height: 150px;
animation-delay: 7s;
}
.circles li:nth-child(8) {
left: 50%;
width: 25px;
height: 25px;
animation-delay: 15s;
animation-duration: 45s;
}
.circles li:nth-child(9) {
left: 20%;
width: 15px;
height: 15px;
animation-delay: 2s;
animation-duration: 35s;
}
.circles li:nth-child(10) {
left: 85%;
width: 150px;
height: 150px;
animation-delay: 0s;
animation-duration: 11s;
}
@keyframes animate {
0% {
transform: translateY(0) rotate(0deg);
opacity: 1;
border-radius: 0;
}
100% {
transform: translateY(-1000px) rotate(720deg);
opacity: 0;
border-radius: 50%;
}
}
</style>

View File

@@ -43,6 +43,21 @@ export default {
resetPasswordError: "reset password failed",
},
landing: {
immediately: 'Immediately',
english: 'English',
chinese: 'Chinese',
learnMore: 'Learn More',
title: 'Schisandra Cloud Album',
description: 'Schisandra Cloud Album is a cloud storage service that allows users to store and manage their digital assets in the cloud. It provides a simple and easy-to-use interface, and supports multiple file formats, including images, videos, documents, and audio files.',
userAgreement: 'user agreement',
privacyPolicy: 'privacy policy',
termsOfService: 'terms of service',
contactUs: 'contact us',
friends: 'friends',
helpCenter: 'help center',
copyright: '© 2021 Schisandra Cloud Album. All rights reserved.',
},
error: {
networkError: 'Network error, please try again later',
400: 'request error (400)',

View File

@@ -42,8 +42,21 @@ export default {
resetPasswordSuccess: "密码重置成功!",
resetPasswordError: "密码重置失败!",
},
landing: {
immediately: '立即进入',
english: 'English',
chinese: '中文',
learnMore: '了解更多',
title: '五味子云相册',
description: '在这个瞬息万变的世界里,我们用镜头捕捉每一个精彩瞬间。五味子云相册,为您提供一个安全、便捷的云端空间,让您的照片随时随地触手可及。 无需担心存储空间不足,无需担心照片丢失。五味子云相册,让您的每一张照片都得到妥善保管,让美好的记忆永不褪色。',
userAgreement: '用户协议',
privacyPolicy: '隐私政策',
termsOfService: '服务条款',
contactUs: '联系我们',
friends: '友情链接',
helpCenter: '帮助中心',
copyright: '版权所有 © 2021 五味子云相册',
},
error: {
networkError: '网络连接失败!',

View File

@@ -11,12 +11,9 @@ export const useThemeStore = defineStore(
() => {
const themeName = ref<string>('green'); // 主题名称
const darkMode = ref<string>('light'); // 颜色模式
const darkModeComp = computed(() => {
document.documentElement.setAttribute('data-dark', darkMode.value);
return darkMode.value;
});
const themeConfig = computed(() => {
document.documentElement.setAttribute('data-theme', themeName.value);
document.documentElement.setAttribute('data-dark', darkMode.value);
// 主题配置
return {
token: {
@@ -35,9 +32,9 @@ export const useThemeStore = defineStore(
themeName.value = value;
};
const toggleDarkMode = () => {
darkMode.value = darkMode.value === 'light' ? 'dark' : 'light';
darkMode.value = darkMode.value === "dark" ? "light" : "dark";
};
return {themeName, themeConfig, darkMode, darkModeComp, setThemeName, toggleDarkMode};
return {themeName, themeConfig, darkMode, setThemeName, toggleDarkMode};
},
{
persist: {

View File

@@ -22,15 +22,22 @@ const {onAuthRequired, onResponseRefreshToken} = createServerTokenAuthentication
// 当token过期时触发在此函数中触发刷新token
handler: async () => {
// 刷新token
const user = useStore().user;
const res: any = await refreshToken(user.user?.refreshToken || '');
if (res.code === 0 && res.data) {
const {access_token, refresh_token, uid} = res.data;
user.user.accessToken = access_token;
user.user.refreshToken = refresh_token;
user.user.uid = uid;
} else {
try {
// 刷新token
const user = useStore().user;
const res: any = await refreshToken(user.user?.refreshToken || '');
if (res.code === 0 && res.data) {
const {access_token, refresh_token, uid} = res.data;
user.user.accessToken = access_token;
user.user.refreshToken = refresh_token;
user.user.uid = uid;
} else {
message.error(i18n.global.t('error.loginExpired'));
localStorage.removeItem('user');
await router.push('/login');
}
} catch (error: any) {
console.error(error);
message.error(i18n.global.t('error.loginExpired'));
localStorage.removeItem('user');
await router.push('/login');

View File

@@ -4,7 +4,13 @@
<BoxDog/>
</div>
<div class="login-right">
<span class="login-right-title">{{ t("login.title") }}</span>
<span class="login-right-title">
<img src="@/assets/images/logo-schisandra.png" @click="()=>{
router.push('/')
}" style="width: 30px; height: 30px;cursor: pointer;" alt="">
{{ t("login.title") }}
</span>
<ACard class="login-card" bordered :hoverable="false">
<ATabs :centered="false" size="large">
<!-- 短信登录 -->
@@ -54,7 +60,8 @@
</AFormItem>
<AFormItem id="phone_login_auto" name="auto_login">
<AFlex :vertical="false" justify="space-between">
<ACheckbox v-model:checked="phoneLoginForm.auto_login">{{ t("login.autoLogin") }}
<ACheckbox id="phone_login_auto_checkbox" v-model:checked="phoneLoginForm.auto_login">
{{ t("login.autoLogin") }}
</ACheckbox>
</AFlex>
@@ -101,7 +108,8 @@
</AFormItem>
<AFormItem id="account_login_auto" name="auto_login">
<AFlex :vertical="false" justify="space-between">
<ACheckbox v-model:checked="accountLoginForm.auto_login">{{ t("login.autoLogin") }}
<ACheckbox id="account_login_auto_checkbox" v-model:checked="accountLoginForm.auto_login">
{{ t("login.autoLogin") }}
</ACheckbox>
<a @click="()=>{
router.push('/resetpass')
@@ -154,6 +162,21 @@
:events="accountLoginRotateEvent"
/>
</div>
<div class="area">
<ul class="circles">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
</div>
</template>
<script setup lang="ts">
@@ -440,6 +463,6 @@ async function sendMessageByPhone(): Promise<boolean> {
}
}
</script>
<style src="./index.scss" scoped>
@import "@/assets/styles/global.scss";
<style src="./index.scss" scoped lang="scss">
</style>

View File

@@ -4,17 +4,19 @@
width: 100vw;
height: 100vh;
/* 加载背景图 */
background-image: url("@/assets/images/background.png");
//@include useLoginTheme;
//background-image: url("@/assets/images/background.png");
/* 背景图垂直、水平均居中 */
background-position: center center;
/* 背景图不平铺 */
background-repeat: no-repeat;
/* 当内容高度大于图片高度时背景图像的位置相对于viewport固定 */
background-attachment: fixed;
/* 让背景图基于容器大小伸缩 */
background-size: cover;
//background-position: center center;
///* 背景图不平铺 */
//background-repeat: no-repeat;
///* 当内容高度大于图片高度时背景图像的位置相对于viewport固定 */
//background-attachment: fixed;
///* 让背景图基于容器大小伸缩 */
//background-size: cover;
z-index: -1;
.login-left {
width: 50%;
}
@@ -102,4 +104,131 @@
right: 0;
background-color: rgba(0, 0, 0, 0.5);
}
.area {
background: #b9f187;
background: -webkit-linear-gradient(to left, #b9f187, #90d952, #70c13a, #52a82e) !important;
width: 100%;
height: 100vh;
z-index: -1;
overflow: hidden;
position: fixed;
top: 0;
left: 0;
}
.circles {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
.circles li {
position: absolute;
display: block;
list-style: none;
width: 20px;
height: 20px;
background: rgba(255, 255, 255, 0.5);
animation: animate 25s linear infinite;
bottom: -150px;
}
.circles li:nth-child(1) {
left: 25%;
width: 80px;
height: 80px;
animation-delay: 0s;
}
.circles li:nth-child(2) {
left: 10%;
width: 20px;
height: 20px;
animation-delay: 2s;
animation-duration: 12s;
}
.circles li:nth-child(3) {
left: 70%;
width: 20px;
height: 20px;
animation-delay: 4s;
}
.circles li:nth-child(4) {
left: 40%;
width: 60px;
height: 60px;
animation-delay: 0s;
animation-duration: 18s;
}
.circles li:nth-child(5) {
left: 65%;
width: 20px;
height: 20px;
animation-delay: 0s;
}
.circles li:nth-child(6) {
left: 75%;
width: 110px;
height: 110px;
animation-delay: 3s;
}
.circles li:nth-child(7) {
left: 35%;
width: 150px;
height: 150px;
animation-delay: 7s;
}
.circles li:nth-child(8) {
left: 50%;
width: 25px;
height: 25px;
animation-delay: 15s;
animation-duration: 45s;
}
.circles li:nth-child(9) {
left: 20%;
width: 15px;
height: 15px;
animation-delay: 2s;
animation-duration: 35s;
}
.circles li:nth-child(10) {
left: 85%;
width: 150px;
height: 150px;
animation-delay: 0s;
animation-duration: 11s;
}
@keyframes animate {
0% {
transform: translateY(0) rotate(0deg);
opacity: 1;
border-radius: 0;
}
100% {
transform: translateY(-1000px) rotate(720deg);
opacity: 0;
border-radius: 50%;
}
}
}

View File

@@ -36,6 +36,20 @@
</ATooltip>
</ACard>
</div>
<div class="area">
<ul class="circles">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
</div>
</template>
<script setup lang="ts">

View File

@@ -5,15 +5,15 @@
width: 100vw;
height: 100vh;
/* 加载背景图 */
background-image: url("@/assets/images/background.png");
//background-image: url("@/assets/images/background.png");
/* 背景图垂直、水平均居中 */
background-position: center center;
/* 背景图不平铺 */
background-repeat: no-repeat;
/* 当内容高度大于图片高度时背景图像的位置相对于viewport固定 */
background-attachment: fixed;
/* 让背景图基于容器大小伸缩 */
background-size: cover;
//background-position: center center;
///* 背景图不平铺 */
//background-repeat: no-repeat;
///* 当内容高度大于图片高度时背景图像的位置相对于viewport固定 */
//background-attachment: fixed;
///* 让背景图基于容器大小伸缩 */
//background-size: cover;
z-index: -1;
.qrlogin-left {
@@ -92,8 +92,134 @@
}
.qrlogin-form-bottom-button {
color: #999ba1;
color: #999ba1 !important;
}
}
.area {
background: #b9f187;
background: -webkit-linear-gradient(to left, #b9f187, #90d952, #70c13a, #52a82e) !important;
width: 100%;
height: 100vh;
z-index: -1;
overflow: hidden;
position: fixed;
top: 0;
left: 0;
}
.circles {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
.circles li {
position: absolute;
display: block;
list-style: none;
width: 20px;
height: 20px;
background: rgba(255, 255, 255, 0.5);
animation: animate 25s linear infinite;
bottom: -150px;
}
.circles li:nth-child(1) {
left: 25%;
width: 80px;
height: 80px;
animation-delay: 0s;
}
.circles li:nth-child(2) {
left: 10%;
width: 20px;
height: 20px;
animation-delay: 2s;
animation-duration: 12s;
}
.circles li:nth-child(3) {
left: 70%;
width: 20px;
height: 20px;
animation-delay: 4s;
}
.circles li:nth-child(4) {
left: 40%;
width: 60px;
height: 60px;
animation-delay: 0s;
animation-duration: 18s;
}
.circles li:nth-child(5) {
left: 65%;
width: 20px;
height: 20px;
animation-delay: 0s;
}
.circles li:nth-child(6) {
left: 75%;
width: 110px;
height: 110px;
animation-delay: 3s;
}
.circles li:nth-child(7) {
left: 35%;
width: 150px;
height: 150px;
animation-delay: 7s;
}
.circles li:nth-child(8) {
left: 50%;
width: 25px;
height: 25px;
animation-delay: 15s;
animation-duration: 45s;
}
.circles li:nth-child(9) {
left: 20%;
width: 15px;
height: 15px;
animation-delay: 2s;
animation-duration: 35s;
}
.circles li:nth-child(10) {
left: 85%;
width: 150px;
height: 150px;
animation-delay: 0s;
animation-duration: 11s;
}
@keyframes animate {
0% {
transform: translateY(0) rotate(0deg);
opacity: 1;
border-radius: 0;
}
100% {
transform: translateY(-1000px) rotate(720deg);
opacity: 0;
border-radius: 50%;
}
}
}

View File

@@ -13,7 +13,7 @@
</ASelect>
<AButtonGroup>
<AButton type="primary">切换主题- {{ app.themeName }}</AButton>
<AButton @click="app.toggleDarkMode">切换模式{{ app.darkModeComp }}</AButton>
<AButton @click="app.toggleDarkMode">切换模式{{ app.darkMode }}</AButton>
</AButtonGroup>
<div class="test">test</div>
</AConfigProvider>