feat:change ui
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
Reference in New Issue
Block a user