feat:save

This commit is contained in:
zyronon
2025-07-11 20:05:52 +08:00
parent e1cf6ce98f
commit 6bf6d8638e
8 changed files with 61 additions and 191 deletions

8
pnpm-lock.yaml generated
View File

@@ -38,6 +38,9 @@ importers:
git-last-commit:
specifier: ^1.0.1
version: 1.0.1
gsap:
specifier: ^3.13.0
version: 3.13.0
hover.css:
specifier: ^2.3.2
version: 2.3.2
@@ -2208,6 +2211,9 @@ packages:
resolution: {integrity: sha512-rXunEHF9M9EkMydTBux7+IryYXEZinRk6g8OBOGDBzo/qWJjhTxy86i5q7lQYpCLHN8Sqv1XX3OIOc7ka2gtvQ==}
engines: {node: '>=8.0.0'}
gsap@3.13.0:
resolution: {integrity: sha512-QL7MJ2WMjm1PHWsoFrAQH/J8wUeqZvMtHO58qdekHpCfhvhSL4gSiz6vJf5EeMP0LOn3ZCprL2ki/gjED8ghVw==}
gulp-cli@2.3.0:
resolution: {integrity: sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==}
engines: {node: '>= 0.10'}
@@ -6167,6 +6173,8 @@ snapshots:
grad-school@0.0.5: {}
gsap@3.13.0: {}
gulp-cli@2.3.0:
dependencies:
ansi-colors: 1.1.0

View File

@@ -3,7 +3,6 @@ import {onMounted, watch} from "vue";
import {BaseState, useBaseStore} from "@/stores/base.ts";
import {useRuntimeStore} from "@/stores/runtime.ts";
import {useSettingStore} from "@/stores/setting.ts";
import Backgorund from "@/pages/pc/components/Backgorund.vue";
import useTheme from "@/hooks/theme.ts";
import * as localforage from "localforage";
import SettingDialog from "@/pages/pc/components/dialog/SettingDialog.vue";
@@ -69,7 +68,6 @@ watch(() => route.path, (to, from) => {
</script>
<template>
<Backgorund/>
<router-view v-slot="{ Component }">
<transition :name="transitionName">
<keep-alive :exclude="runtimeStore.excludeRoutes">
@@ -83,14 +81,4 @@ watch(() => route.path, (to, from) => {
<style scoped lang="scss">
.main-page {
position: relative;
z-index: 1;
width: 100%;
height: 100%;
overflow: hidden;
font-size: 14rem;
display: flex;
justify-content: center;
}
</style>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -5,9 +5,12 @@ import "vue-activity-calendar/style.css";
import {useRouter} from "vue-router";
import {enArticle} from "@/assets/dictionary.ts";
import BasePage from "@/pages/pc/components/BasePage.vue";
import {useNav} from "@/utils";
const {nav} = useNav()
const base = useBaseStore()
const router = useRouter()
const store = useBaseStore()
function clickEvent(e) {
console.log('e', e)
@@ -52,6 +55,23 @@ function clickEvent(e) {
</div>
</div>
</div>
<div class="card flex flex-col">
<div class="title">
我的词典
</div>
<div class="grid grid-cols-6 gap-4 mt-4">
<div class="my-dict" @click="nav('edit-word-dict',{type:0})">
<span>收藏</span>
<div class="absolute bottom-4 right-4">{{ store.collectWord.words.length }}个词</div>
</div>
<div class="my-dict" @click="nav('edit-word-dict',{type:1})">
<span>错词本</span>
<div class="absolute bottom-4 right-4">{{ store.wrong.words.length }}个词</div>
</div>
</div>
</div>
<div class="mt-4">
<div class="title">文章</div>
<div class="mt-4 flex gap-4">
@@ -82,4 +102,7 @@ function clickEvent(e) {
.title {
@apply text-lg font-medium;
}
.my-dict {
@apply p-4 rounded-md bg-slate-200 relative cursor-pointer h-40;
}
</style>

View File

@@ -1,110 +0,0 @@
<template>
<div id="background" class="anim">
<img src="../../../assets/img/moon.png" alt="" id="moon" style="display:none">
<Transition name="fade">
<canvas ref="canvas" v-show="settingStore.theme === 'dark'"/>
</Transition>
</div>
</template>
<script setup lang="ts">
import {onMounted} from "vue"
import {useSettingStore} from "@/stores/setting.ts";
const canvas = $ref<HTMLCanvasElement>()
const settingStore = useSettingStore()
onMounted(() => {
// console.log('canvas;', canvas)
let ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
let maxRadius = 1,
stars = [];
let Star = function (x: number, y: number, r: number) {
this.x = x;
this.y = y;
this.r = r;
};
Star.prototype = {
paint: function () {
ctx.save();
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
ctx.fillStyle = "rgba(255,255,255," + this.r + ")";
ctx.fill();
ctx.restore();
},
};
function drawBg() {
for (let i = 0; i < 1000; i++) {
let r = Math.random() * maxRadius;
let x = Math.random() * canvas.width;
let y = Math.random() * 2 * canvas.height - canvas.height;
let star = new Star(x, y, r);
stars.push(star);
star.paint();
}
}
drawBg()
function drawMoon() {
let moon: HTMLImageElement = document.getElementById("moon");
let centerX = canvas.width - 200,
centerY = 100,
width = 80;
let index = 0;
for (let i = 0; i < 10; i++) {
ctx.save();
ctx.beginPath();
ctx.arc(
centerX + width / 2,
centerY + width / 2,
width / 2 + index,
0,
2 * Math.PI
);
ctx.fillStyle = "rgba(240,219,120,0.05)";
index += 2;
ctx.fill();
ctx.restore();
}
if (moon.complete) {
ctx.drawImage(moon, centerX, centerY, width, width);
} else {
moon.onload = function () {
ctx.drawImage(moon, centerX, centerY, width, width);
};
}
}
drawMoon()
})
</script>
<style scoped lang="scss">
#background {
position: fixed;
width: 100vw;
height: 100vh;
left: 0;
top: 0;
background-color: var(--color-main-bg);
canvas {
width: 100vw;
height: 100vh;
opacity: 0;
}
}
</style>

View File

@@ -3,8 +3,6 @@
import {ShortcutKey} from "@/types.ts";
import Logo from "@/pages/pc/components/Logo.vue";
import {Icon} from "@iconify/vue";
import {usePracticeStore} from "@/stores/practice.ts";
import {useBaseStore} from "@/stores/base.ts";
import {useSettingStore} from "@/stores/setting.ts";
import {useRuntimeStore} from "@/stores/runtime.ts";
import {useRouter} from "vue-router";
@@ -13,50 +11,50 @@ import Tooltip from "@/pages/pc/components/Tooltip.vue";
import useTheme from "@/hooks/theme.ts";
import BaseIcon from "@/components/BaseIcon.vue";
const statisticsStore = usePracticeStore()
const store = useBaseStore()
const settingStore = useSettingStore()
const runtimeStore = useRuntimeStore()
const router = useRouter()
const {toggleTheme} = useTheme()
let show = $ref(false)
</script>
<template>
<div class="layout">
<div class="aside" :class="{'hide':settingStore.showSide}">
<div class="aside" :class="{'expand':settingStore.sideExpand}">
<div class="top">
<Logo/>
<Logo v-if="settingStore.sideExpand"/>
<div class="row" @click="router.push('/home')">
<Icon icon="iconoir:home"/>
<span>主页</span>
<span v-if="settingStore.sideExpand">主页</span>
</div>
<div class="row" @click="router.push('/word')">
<Icon icon="material-symbols-light:dictionary-outline-sharp"/>
<!-- <Icon icon="streamline:dictionary-language-book"/>-->
<span>单词</span>
<span v-if="settingStore.sideExpand">单词</span>
</div>
<div class="row" @click="router.push('/article')">
<Icon icon="ph:article-ny-times"/>
<span>文章</span>
<span v-if="settingStore.sideExpand">文章</span>
</div>
<div class="row" @click="router.push('/article2')">
<Icon icon="healthicons:i-exam-multiple-choice-outline"/>
<span>试卷</span>
<span v-if="settingStore.sideExpand">试卷</span>
</div>
<div class="row">
<Icon icon="mdi-light:forum"/>
<span>社区</span>
<span v-if="settingStore.sideExpand">社区</span>
</div>
</div>
<div class="bottom flex justify-evenly ">
<BaseIcon
:title="`收起(${settingStore.shortcutKeyMap[ShortcutKey.OpenSetting]})`"
@click="settingStore.showSide = !settingStore.showSide"
icon="formkit:left"/>
@click="settingStore.sideExpand = !settingStore.sideExpand"
:icon="settingStore.sideExpand?'formkit:left':'formkit:right'"/>
<Tooltip
:title="`切换主题(${settingStore.shortcutKeyMap[ShortcutKey.ToggleTheme]})`"
v-if="settingStore.sideExpand"
>
<IconWrapper>
<Icon icon="ep:moon" v-if="settingStore.theme === 'dark'"
@@ -65,48 +63,12 @@ let show = $ref(false)
</IconWrapper>
</Tooltip>
<BaseIcon
v-if="settingStore.sideExpand"
:title="`设置(${settingStore.shortcutKeyMap[ShortcutKey.OpenSetting]})`"
@click="runtimeStore.showSettingModal = true"
icon="uil:setting"/>
</div>
</div>
<div class="fixed top-8 left-8 z-9">
<BaseIcon
title="菜单"
@click="show = !show"
icon="hugeicons:menu-square"/>
<div class="menus flex flex-col" v-if="show">
<BaseIcon
title="单词"
@click="router.push('/word')"
icon="material-symbols-light:dictionary-outline-sharp"/>
<BaseIcon
title="文章"
@click="router.push('/article')"
icon="ph:article-ny-times"/>
<BaseIcon
title="试卷"
icon="healthicons:i-exam-multiple-choice-outline"/>
<BaseIcon
title="展开"
@click="settingStore.showSide = !settingStore.showSide"
icon="formkit:right"/>
<Tooltip
:title="`切换主题(${settingStore.shortcutKeyMap[ShortcutKey.ToggleTheme]})`"
>
<IconWrapper>
<Icon icon="ep:moon" v-if="settingStore.theme === 'dark'"
@click="toggleTheme"/>
<Icon icon="tabler:sun" v-else @click="toggleTheme"/>
</IconWrapper>
</Tooltip>
<BaseIcon
:title="`设置(${settingStore.shortcutKeyMap[ShortcutKey.OpenSetting]})`"
@click="runtimeStore.showSettingModal = true"
icon="uil:setting"/>
</div>
</div>
<div class="flex-1 z-1">
<router-view></router-view>
</div>
@@ -118,44 +80,43 @@ let show = $ref(false)
width: 100%;
height: 100%;
display: flex;
background: var(--color-background);
}
.aside {
background: var(--color-second-bg);
position: fixed;
z-index: 999;
top: 0;
left: 0;
height: 100vh;
width: var(--aside-width);
padding: 1rem 1rem;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-between;
box-shadow: rgb(0 0 0 / 3%) 0px 0px 12px 0px;
transition: all .3s;
width: 4.5rem;
transition: all 0.3s;
z-index: 2;
.row {
@apply cursor-pointer rounded-md text p-2 my-2 flex items-center gap-2;
transition: all .5s;
flex-shrink: 0;
&:hover {
background: var(--color-primary);
color: white;
}
span{
flex-shrink: 0;
}
svg {
font-size: 1.5rem;
flex-shrink: 0;
font-size: 1.5rem!important;
}
}
&.hide {
transform: translateX(-12rem);
&.expand {
width: var(--aside-width);
}
}
.content {
flex: 1;
}
</style>
</style>

View File

@@ -262,4 +262,4 @@ function changePerDayStudyNumber() {
color: var(--color-font-1);
}
</style>
</style>

View File

@@ -36,7 +36,7 @@ export interface SettingState {
wordTranslateFontSize: number,
},
showPanel: boolean,
showSide: boolean,
sideExpand: boolean,
theme: string,
collapse: boolean,
chapterWordNumber: number,
@@ -49,7 +49,7 @@ export const DefaultSettingState = (): SettingState => ({
showToolbar: true,
show: false,
showPanel: true,
showSide: true,
sideExpand: true,
allSound: true,
wordSound: true,
@@ -109,4 +109,4 @@ export const useSettingStore = defineStore('setting', {
})
}
}
})
})