feat:change ui

This commit is contained in:
Zyronon
2025-09-30 01:48:34 +08:00
parent 85c7dff4fd
commit b8d14fdc1a
4 changed files with 128 additions and 31 deletions

View File

@@ -1,15 +1,20 @@
<script setup lang="ts">
import {Dict} from "@/types/types.ts";
import { Dict } from "@/types/types.ts";
import Progress from '@/components/base/Progress.vue'
import Checkbox from "@/components/base/checkbox/Checkbox.vue";
const props = defineProps<{
interface IProps {
item?: Partial<Dict>;
quantifier?: string
isAdd: boolean
showCheckbox?: boolean
checked?: boolean
}>()
showProgress?: boolean
}
const props = withDefaults(defineProps<IProps>(), {
showProgress: true
})
defineEmits<{
check: []
@@ -21,6 +26,7 @@ const progress = $computed(() => {
})
const studyProgress = $computed(() => {
if (!props.showProgress) return
if (props.item.complete) return props.item?.length + '/'
return props.item?.lastLearnIndex ? props.item?.lastLearnIndex + '/' : ''
})
@@ -37,7 +43,7 @@ const studyProgress = $computed(() => {
<div>{{ studyProgress }}{{ item?.length }}{{ quantifier }}</div>
</div>
<div class="absolute bottom-2 left-3 right-3">
<Progress v-if="item?.lastLearnIndex || item.complete" class="mt-1"
<Progress v-if="(item?.lastLearnIndex || item.complete) && showProgress" class="mt-1"
:percentage="progress"
:show-text="false"></Progress>
</div>

View File

@@ -1,21 +1,24 @@
<script setup lang="ts">
import {useBaseStore} from "@/stores/base.ts";
import {useRouter} from "vue-router";
import { useBaseStore } from "@/stores/base.ts";
import { useRouter } from "vue-router";
import BasePage from "@/components/BasePage.vue";
import {_getDictDataByUrl, cloneDeep, useNav} from "@/utils";
import {DictResource, DictType} from "@/types/types.ts";
import {useRuntimeStore} from "@/stores/runtime.ts";
import { _getDictDataByUrl, msToHourMinute, total, useNav } from "@/utils";
import { DictResource, DictType } from "@/types/types.ts";
import { useRuntimeStore } from "@/stores/runtime.ts";
import BaseIcon from "@/components/BaseIcon.vue";
import Book from "@/components/Book.vue";
import Progress from '@/components/base/Progress.vue';
import Toast from '@/components/base/toast/Toast.ts'
import BaseButton from "@/components/BaseButton.vue";
import PopConfirm from "@/components/PopConfirm.vue";
import {onMounted, watch} from "vue";
import {getDefaultDict} from "@/types/func.ts";
import { onMounted, watch } from "vue";
import { getDefaultDict } from "@/types/func.ts";
import DeleteIcon from "@/components/icon/DeleteIcon.vue";
import recommendBookList from "@/assets/book-list.json";
import {genArticleSectionData} from "@/hooks/article.ts";
import dayjs from "dayjs";
import isBetween from "dayjs/plugin/isBetween";
dayjs.extend(isBetween);
const {nav} = useNav()
const base = useBaseStore()
@@ -89,21 +92,96 @@ async function goBookDetail(val: DictResource) {
nav('book-detail')
}
const totalSpend = $computed(() => {
if (base.sbook.statistics?.length) {
return msToHourMinute(total(base.sbook.statistics, 'spend'))
}
return 0
})
const totalDay = $computed(() => {
if (base.sbook.statistics?.length) {
return new Set(base.sbook.statistics.map(v => dayjs(v.startDate).format('YYYY-MM-DD'))).size
}
return 0
})
const weekList = $computed(() => {
const list = Array(7).fill(false);
// 获取本周的起止时间
const startOfWeek = dayjs().startOf('week').add(1, 'day'); // 周一
const endOfWeek = dayjs().endOf('week').add(1, 'day'); // 周日
store.sbook.statistics?.forEach(item => {
const date = dayjs(item.startDate);
if (date.isBetween(startOfWeek, endOfWeek, null, '[]')) {
let idx = date.day();
// dayjs().day() 0=周日, 1=周一, ..., 6=周六
// 需要转换为 0=周一, ..., 6=周日
if (idx === 0) {
idx = 6; // 周日放到最后
} else {
idx = idx - 1; // 其余前移一位
}
list[idx] = true;
}
});
return list
})
</script>
<template>
<BasePage>
<div class="card ">
<div class="flex justify-between items-center">
<div class="bg-third p-3 gap-4 rounded-md cursor-pointer flex items-center">
<span class="text-lg font-bold"
@click="goBookDetail(base.currentBook)">{{
base.currentBook.name || '请选择书籍开始学习'
}}</span>
<BaseIcon @click="router.push('/book-list')">
<IconFluentArrowSort20Regular v-if="base.currentBook.name"/>
<IconFluentAdd16Filled v-else/>
</BaseIcon>
<div class="card flex justify-between gap-space">
<div>
<Book
v-if="base.sbook.id"
:is-add="false"
quantifier="篇"
:item="base.sbook"
:show-progress="false"
@click="goBookDetail(base.sbook)"/>
<Book v-else
:is-add="true"
@click="router.push('/book-list')"/>
</div>
<div class="flex-1">
<div class="flex items-center">
<div class="title mr-4">本周学习记录</div>
<div class="flex gap-4 color-gray">
<div
class="w-8 h-8 rounded-md center"
:class="item ? 'bg-[#409eff] color-white' : 'bg-gray-200'"
v-for="(item, i) in weekList"
:key="i"
>{{ i + 1 }}
</div>
</div>
</div>
<div class="flex gap-4 items-center mt-3 gap-space">
<div class="stat">
<div class="num">{{ totalSpend }}</div>
<div class="txt">总学习时长</div>
</div>
<div class="stat">
<div class="num">{{ totalDay }}</div>
<div class="txt">总学习天数</div>
</div>
<div class="stat">
<div class="num">{{ base.sbook?.statistics?.length || 0 }}</div>
<div class="txt">总学习次数</div>
</div>
</div>
<Progress class="mt-3"
:percentage="base.currentBookProgress"
:format="()=> `${ base.sbook?.lastLearnIndex || 0 }/${base.sbook?.length || 0}篇`"
:show-text="true"></Progress>
</div>
<div class="flex flex-col justify-between items-end">
<div class="flex gap-4 items-center" v-opacity="base.sbook.id">
<div class="color-blue cursor-pointer" @click="router.push('/book-list')">更换</div>
</div>
<BaseButton size="large"
@click="startStudy"
@@ -114,8 +192,6 @@ async function goBookDetail(val: DictResource) {
</div>
</BaseButton>
</div>
<div class="mt-5 text-sm">已学习{{ base.currentBook.lastLearnIndex }}篇文章</div>
<Progress class="mt-1" :percentage="base.currentBookProgress" :show-text="false"></Progress>
</div>
<div class="card flex flex-col">
@@ -135,7 +211,10 @@ async function goBookDetail(val: DictResource) {
</div>
</div>
<div class="flex gap-4 flex-wrap mt-4">
<Book :is-add="false" quantifier="篇" :item="item" :checked="selectIds.includes(item.id)"
<Book :is-add="false"
quantifier="篇"
:item="item"
:checked="selectIds.includes(item.id)"
@check="() => toggleSelect(item)"
:show-checkbox="isMultiple && j >= 1"
v-for="(item, j) in base.article.bookList"
@@ -163,5 +242,17 @@ async function goBookDetail(val: DictResource) {
</template>
<style scoped lang="scss">
.stat {
@apply rounded-xl p-4 box-border relative flex-1;
background: white;
border: 1px solid gainsboro;
.num {
@apply color-[#409eff] text-2xl font-bold;
}
.txt {
@apply color-gray-500;
}
}
</style>

View File

@@ -185,7 +185,7 @@ const totalSpend = $computed(() => {
<div class="font-family text-base mb-4" v-if="currentPractice.length">
<div>学习记录{{ msToHourMinute(total(currentPractice, 'spend'))}}</div>
<div class="item" v-for="i in currentPractice">
{{_dateFormat(i.startDate,'YYYY/MM/DD HH-mm')}}: {{ msToHourMinute(i.spend) }}
{{_dateFormat(i.startDate,'YYYY/MM/DD HH:mm')}}: {{ msToHourMinute(i.spend) }}
</div>
</div>
<div class="en-article-family title text-xl">

View File

@@ -120,7 +120,7 @@ function options(emitType: string) {
</div>
<div class="text-xl text-center flex flex-col justify-around">
<div>非常棒! 坚持了 <span class="color-green font-bold text-2xl">
<div>非常棒! 坚持了 <span class="color-emerald-500 font-bold text-2xl">
{{ dayjs().diff(statStore.startDate, 'm') }}</span>分钟
</div>
</div>
@@ -133,7 +133,7 @@ function options(emitType: string) {
错词
</div>
</div>
<div class="flex justify-center items-center py-3 px-10 rounded-md color-green-600 flex-col"
<div class="flex justify-center items-center py-3 px-10 rounded-md color-emerald-500 flex-col"
style="background: rgb(231,248,241)">
<div class="text-3xl">{{ statStore.total - statStore.wrong }}</div>
<div class="center gap-2">
@@ -147,8 +147,8 @@ function options(emitType: string) {
<div class="title text-align-center mb-2">本周学习记录</div>
<div class="flex gap-4 color-gray">
<div
class="w-8 h-8 rounded-full center"
:class="item ? 'bg-green color-white' : 'bg-gray-200'"
class="w-8 h-8 rounded-md center"
:class="item ? 'bg-emerald-500 color-white' : 'bg-gray-200'"
v-for="(item, i) in list"
:key="i"
>{{ i + 1 }}