完成番茄工作法
This commit is contained in:
parent
c98a7d70b1
commit
775ba48259
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 321 B |
|
@ -33,7 +33,7 @@ export const WidgetItem = defineComponent({
|
||||||
>
|
>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<img
|
<img
|
||||||
src={ props.content.icon}
|
src={props.content.icon}
|
||||||
class="w-[58px] h-[58px] bg-cover rounded-lg shadow-lg"
|
class="w-[58px] h-[58px] bg-cover rounded-lg shadow-lg"
|
||||||
/>
|
/>
|
||||||
<div class="px-2 w-0 flex-grow ">
|
<div class="px-2 w-0 flex-grow ">
|
||||||
|
@ -119,12 +119,19 @@ export const WidgetItem = defineComponent({
|
||||||
})
|
})
|
||||||
|
|
||||||
export default defineComponent(() => {
|
export default defineComponent(() => {
|
||||||
|
const layout = useLayoutStore()
|
||||||
return () => (
|
return () => (
|
||||||
<div class="absolute left-0 top-0 w-full h-full overflow-y-auto scrollbar-hide gap-4">
|
<div class="absolute left-0 top-0 w-full h-full overflow-y-auto scrollbar-hide gap-4">
|
||||||
<div class="w-full grid grid-cols-3 grid-flow-row-dense gap-4" style="grid-auto-rows: 120px">
|
<div class="w-full grid grid-cols-3 grid-flow-row-dense gap-4" style="grid-auto-rows: 120px">
|
||||||
{widgetList.map((el) => (
|
{
|
||||||
<WidgetItem content={el} key={el.name} />
|
layout.state.current !== 1 ?
|
||||||
))}
|
widgetList.filter(val => val.name !== 'tomato_work').map((el) => (
|
||||||
|
<WidgetItem content={el} key={el.name} />
|
||||||
|
)) :
|
||||||
|
widgetList.map((el) => (
|
||||||
|
<WidgetItem content={el} key={el.name} />
|
||||||
|
))
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { computed, defineComponent, onMounted, ref, Transition, watch } from 'vue'
|
import { computed, defineComponent, onMounted, ref, Transition, watch } from 'vue'
|
||||||
import returnImg from "~/public/icons/work/return.png"
|
import returnImg from "~/icons/work/return.png"
|
||||||
import endImg from "~/public/icons/work/tomotoIconEnd.png"
|
import endImg from "~/icons/work/tomotoIconEnd.png"
|
||||||
import playWaveGif from "~/public/icons/work/playMusicIcon.gif"
|
import playWaveGif from "~/icons/work/playMusicIcon.gif"
|
||||||
import PlayStartImg from "~/public/icons/work/start.png"
|
import PlayStartImg from "~/icons/work/start.png"
|
||||||
import musicIcon from "~/public/icons/work/musicIcon.png"
|
import musicIcon from "~/icons/work/musicIcon.png"
|
||||||
import useBackgroundStore from '../background/useBackgroundStore'
|
import useBackgroundStore from '../background/useBackgroundStore'
|
||||||
import useLayoutStore from '../useLayoutStore'
|
import useLayoutStore from '../useLayoutStore'
|
||||||
import useTomatoStore, { musicList } from '@/widgets/work/useTomatoStore'
|
import useTomatoStore, { musicList } from '@/widgets/work/useTomatoStore'
|
||||||
|
@ -84,8 +84,44 @@ export default defineComponent(() => {
|
||||||
<Transition name="modal">
|
<Transition name="modal">
|
||||||
|
|
||||||
<div class={"w-[500px] h-[500px] absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 "}>
|
<div class={"w-[500px] h-[500px] absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 "}>
|
||||||
<Modal open={showSelectModal.value}>
|
|
||||||
|
|
||||||
|
<Modal open={showSelectModal.value} footer={null} class={'bg-white p-0 rounded-lg'}
|
||||||
|
destroyOnClose
|
||||||
|
centered
|
||||||
|
onCancel={() => {
|
||||||
|
showSelectModal.value = false
|
||||||
|
}}>
|
||||||
|
<div class={"flex flex-col items-center px-4"}>
|
||||||
|
<span class={"text-[#333] font-bold text-[16px] mb-5"}>音乐选择</span>
|
||||||
|
<div class={"flex flex-col w-full gap-y-1"}>
|
||||||
|
{
|
||||||
|
musicList.map((item, idx) => (
|
||||||
|
<div
|
||||||
|
onClick={() => {
|
||||||
|
store.state.selectMusic = idx
|
||||||
|
store.setTrack(idx)
|
||||||
|
}}
|
||||||
|
class={"bg-black/[0.05] cursor-pointer rounded-lg text-[#333] text-[14px] py-2 pl-10 border-[1px] relative border-transparent hover:border-[#5955FB]"}>
|
||||||
|
{
|
||||||
|
store.state.selectMusic === idx &&
|
||||||
|
<img src={playWaveGif} class={" absolute left-2 top-1/2 -translate-y-1/2"}></img>
|
||||||
|
|
||||||
|
}
|
||||||
|
<span>{item.name}</span>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
showSelectModal.value = false
|
||||||
|
|
||||||
|
}}
|
||||||
|
class={"px-10 py-2 mt-7 font-bold text-[16px] text-white rounded-lg flex items-center justify-center cursor-pointer hover:opacity-90 duration-150"} style={{
|
||||||
|
background: 'linear-gradient(225deg,#642FFF 0%,#5162FF 100%)',
|
||||||
|
boxShadow: '0 2px 6px #00000026'
|
||||||
|
}}>确定</button>
|
||||||
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
{
|
{
|
||||||
Array.from({ length: 60 }).map((_, idx) => (
|
Array.from({ length: 60 }).map((_, idx) => (
|
||||||
|
@ -145,10 +181,15 @@ export default defineComponent(() => {
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<div class={"w-[140px] h-[44px] relative bg-[#f0f0f0] rounded-lg flex px-3 items-center justify-between cursor-pointer hover:opacity-90"}
|
<div class={"w-[140px] h-[44px] relative bg-[#f0f0f0] rounded-lg flex px-3 gap-x-2 items-center justify-between cursor-pointer hover:opacity-90"}
|
||||||
style={{
|
style={{
|
||||||
boxShadow: '0 2px 4px #0003'
|
boxShadow: '0 2px 4px #0003'
|
||||||
}}>
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
showSelectModal.value = true
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
|
||||||
{
|
{
|
||||||
store.state.isPlaying ?
|
store.state.isPlaying ?
|
||||||
<img src={playWaveGif} alt='return' class={"w-[18px] h-[18px] "}></img>
|
<img src={playWaveGif} alt='return' class={"w-[18px] h-[18px] "}></img>
|
||||||
|
@ -156,8 +197,19 @@ export default defineComponent(() => {
|
||||||
<img src={musicIcon} alt='return' class={"w-[18px] h-[18px] "}></img>
|
<img src={musicIcon} alt='return' class={"w-[18px] h-[18px] "}></img>
|
||||||
}
|
}
|
||||||
<span class={"whitespace-nowrap text-ellipsis overflow-hidden text-[#333]"}>{musicList[store.state.selectMusic].name}</span>
|
<span class={"whitespace-nowrap text-ellipsis overflow-hidden text-[#333]"}>{musicList[store.state.selectMusic].name}</span>
|
||||||
<div class={"w-[26px] h-[26px] right-[-14px] rounded-full bg-[#c0c0c0] absolute flex items-center justify-center"}>
|
<div
|
||||||
<img src={PlayStartImg} alt='start ' class={"w-[12px] h-[12px]"}></img>
|
onClick={(e) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
store.togglePlay()
|
||||||
|
}}
|
||||||
|
class={"w-[26px] h-[26px] right-[-14px] rounded-full bg-[#c0c0c0] absolute flex items-center justify-center"}>
|
||||||
|
{
|
||||||
|
store.state.isPlaying ?
|
||||||
|
<img src={endImg} alt='start ' class={"w-[12px] h-[12px]"}></img>
|
||||||
|
:
|
||||||
|
<img src={PlayStartImg} alt='start ' class={"w-[12px] h-[12px]"}></img>
|
||||||
|
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { computed, defineComponent, onMounted, ref, Transition } from 'vue'
|
import { computed, defineComponent, onMounted, ref, Transition } from 'vue'
|
||||||
import WelcomeImg from '~/public/icons/welcome/welcomeTitle.png'
|
import WelcomeImg from '~/icons/welcome/welcomeTitle.png'
|
||||||
import DivBgImg from '~/public/icons/welcome/back.png'
|
import DivBgImg from '~/icons/welcome/back.png'
|
||||||
import startUseImg from '~/public/icons/welcome/startUse.png'
|
import startUseImg from '~/icons/welcome/startUse.png'
|
||||||
import useBackgroundStore from '../background/useBackgroundStore'
|
import useBackgroundStore from '../background/useBackgroundStore'
|
||||||
import useLayoutStore from '../useLayoutStore'
|
import useLayoutStore from '../useLayoutStore'
|
||||||
export const DefaultPageSetting = [
|
export const DefaultPageSetting = [
|
||||||
|
|
|
@ -16,7 +16,10 @@ export default defineComponent({
|
||||||
const router = useRouterStore()
|
const router = useRouterStore()
|
||||||
return () => {
|
return () => {
|
||||||
const placeholder = (
|
const placeholder = (
|
||||||
<div class="w-full h-full flex justify-center items-center text-black/60">组件维护中</div>
|
<div class="w-full h-full flex justify-center items-center text-black/60" onContextmenu={(e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
menu.open(props.block)
|
||||||
|
}}>组件维护中</div>
|
||||||
)
|
)
|
||||||
const selected = widgetList.find((el) => el.name === props.block.name)
|
const selected = widgetList.find((el) => el.name === props.block.name)
|
||||||
if (!selected) return placeholder
|
if (!selected) return placeholder
|
||||||
|
|
|
@ -6,7 +6,7 @@ import asyncLoader from '@/utils/asyncLoader'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import { OhVueIcon } from 'oh-vue-icons'
|
import { OhVueIcon } from 'oh-vue-icons'
|
||||||
import { computed, defineComponent, Transition } from 'vue'
|
import { computed, defineComponent, Transition } from 'vue'
|
||||||
import SettingLineImg from '~/public/icons/settingLine.png'
|
import SettingLineImg from '~/icons/settingLine.png'
|
||||||
const Content = asyncLoader(() => import('./SettingsOverlayContent'))
|
const Content = asyncLoader(() => import('./SettingsOverlayContent'))
|
||||||
|
|
||||||
const SettingsTab = defineComponent({
|
const SettingsTab = defineComponent({
|
||||||
|
|
|
@ -2,9 +2,9 @@ import { defineComponent, onMounted, reactive, ref, Transition, watch } from 'vu
|
||||||
import useRouterStore from '@/useRouterStore'
|
import useRouterStore from '@/useRouterStore'
|
||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
import useUserStore from './useUserStore'
|
import useUserStore from './useUserStore'
|
||||||
import Logo from '~/public/logo.png'
|
import Logo from '~//logo.png'
|
||||||
import LogoIcon from '~/public/loginIcon.png'
|
import LogoIcon from '~//loginIcon.png'
|
||||||
import LogoClose from '~/public/icons/loginClose.png'
|
import LogoClose from '~/icons/loginClose.png'
|
||||||
import { message, Spin } from 'ant-design-vue'
|
import { message, Spin } from 'ant-design-vue'
|
||||||
import { v4 as uuid } from 'uuid'
|
import { v4 as uuid } from 'uuid'
|
||||||
import QrCode from 'qrcode'
|
import QrCode from 'qrcode'
|
||||||
|
|
|
@ -3,6 +3,7 @@ import request from '@/utils/request'
|
||||||
import { addIcons, OhVueIcon } from 'oh-vue-icons'
|
import { addIcons, OhVueIcon } from 'oh-vue-icons'
|
||||||
import { computed, defineComponent, onMounted, ref, watch, type CSSProperties } from 'vue'
|
import { computed, defineComponent, onMounted, ref, watch, type CSSProperties } from 'vue'
|
||||||
import { FaChevronLeft } from 'oh-vue-icons/icons'
|
import { FaChevronLeft } from 'oh-vue-icons/icons'
|
||||||
|
import PlayImg from "~/icons/game_video_bg_play.png"
|
||||||
import type { CarouselRef } from 'ant-design-vue/es/carousel'
|
import type { CarouselRef } from 'ant-design-vue/es/carousel'
|
||||||
import { randomNum } from '@/utils/tool'
|
import { randomNum } from '@/utils/tool'
|
||||||
addIcons(FaChevronLeft)
|
addIcons(FaChevronLeft)
|
||||||
|
@ -54,7 +55,9 @@ export default defineComponent(() => {
|
||||||
}, 7000)
|
}, 7000)
|
||||||
})
|
})
|
||||||
return () => (
|
return () => (
|
||||||
<div class="w-full h-full p-2 bg-[#17212d] ">
|
<div class="w-full h-full p-2 bg-[#17212d] relative ">
|
||||||
|
<img src={PlayImg} class={"absolute z-10 w-[40px] bg-[#ffffff24] rounded-lg backdrop-blur-sm left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2"}></img>
|
||||||
|
|
||||||
{
|
{
|
||||||
<div
|
<div
|
||||||
class={'w-full h-full rounded-xl relative group'}
|
class={'w-full h-full rounded-xl relative group'}
|
||||||
|
@ -65,6 +68,7 @@ export default defineComponent(() => {
|
||||||
backgroundRepeat: 'no-repeat'
|
backgroundRepeat: 'no-repeat'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class={
|
class={
|
||||||
'absolute bottom-0 left-1/2 -translate-x-1/2 pb-2 w-[300px] flex flex-col text-white '
|
'absolute bottom-0 left-1/2 -translate-x-1/2 pb-2 w-[300px] flex flex-col text-white '
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import { defineComponent } from 'vue'
|
import { defineComponent } from 'vue'
|
||||||
import { formatSeconds } from '@/utils/tool'
|
import { formatSeconds } from '@/utils/tool'
|
||||||
import PlayStartImg from "~/public/icons/work/start.png"
|
import PlayStartImg from "~/icons/work/start.png"
|
||||||
import returnImg from "~/public/icons/work/return.png"
|
import returnImg from "~/icons/work/return.png"
|
||||||
import PlusImg from "~/public/icons/work/tomatoIconAdd.png"
|
import endImg from "~/icons/work/tomotoIconEnd.png"
|
||||||
|
import PlusImg from "~/icons/work/tomatoIconAdd.png"
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { Tooltip } from 'ant-design-vue'
|
import { Tooltip } from 'ant-design-vue'
|
||||||
import useTomatoStore from './useTomatoStore'
|
import useTomatoStore from './useTomatoStore'
|
||||||
|
@ -47,10 +48,21 @@ export default defineComponent(() => {
|
||||||
<div class={"w-[42px] h-[42px] bg-white/40 backdrop-blur-md flex items-center justify-center rounded-xl"}
|
<div class={"w-[42px] h-[42px] bg-white/40 backdrop-blur-md flex items-center justify-center rounded-xl"}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
store.beginTomatoTime()
|
if (store.state.isStart) {
|
||||||
store.openFullscreen = true
|
store.stopTomatoTime()
|
||||||
|
} else {
|
||||||
|
store.beginTomatoTime()
|
||||||
|
store.openFullscreen = true
|
||||||
|
|
||||||
|
}
|
||||||
}}>
|
}}>
|
||||||
<img src={PlayStartImg} alt="start" class={"w-[18px]"}></img>
|
{
|
||||||
|
store.state.isStart ?
|
||||||
|
<img src={endImg} alt="start" class={"w-[18px]"}></img>
|
||||||
|
:
|
||||||
|
<img src={PlayStartImg} alt="start" class={"w-[18px]"}></img>
|
||||||
|
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title={"添加目标"}>
|
<Tooltip title={"添加目标"}>
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import { defineComponent, ref } from 'vue'
|
import { defineComponent, ref } from 'vue'
|
||||||
import PlusIcon from '~/public/icons/work/tomato_work_add_icon.png'
|
import PlusIcon from '~/icons/work/tomato_work_add_icon.png'
|
||||||
import DataImg from '~/public/icons/work/dataImg.png'
|
import DataImg from '~/icons/work/dataImg.png'
|
||||||
import DateImg from '~/public/icons/work/dateImg.png'
|
import DateImg from '~/icons/work/dateImg.png'
|
||||||
import ListImg from '~/public/icons/work/listImg.png'
|
import ListImg from '~/icons/work/listImg.png'
|
||||||
import AddImg from '~/public/icons/work/addTarget.png'
|
import AddImg from '~/icons/work/addTarget.png'
|
||||||
import DownImg from "~/public/icons/work/selectDown1.0.3.png"
|
import DownImg from "~/icons/work/selectDown1.0.3.png"
|
||||||
import { v4 as uuid } from "uuid"
|
import { v4 as uuid } from "uuid"
|
||||||
import List from './modal_view/list'
|
import List from './modal_view/list'
|
||||||
import { DatePicker, Modal, TimePicker } from 'ant-design-vue'
|
import { DatePicker, Modal, TimePicker } from 'ant-design-vue'
|
||||||
|
|
|
@ -3,12 +3,21 @@ import { defineComponent } from 'vue'
|
||||||
export default defineComponent(() => {
|
export default defineComponent(() => {
|
||||||
return () => (
|
return () => (
|
||||||
<div
|
<div
|
||||||
class="w-full h-full items-center pl-3 gap-x-2 flex py-3 text-white"
|
class="w-full h-full flex items-center px-3 bg-white"
|
||||||
style={{
|
|
||||||
background: 'linear-gradient(135deg,#5996ff 0%,#4862ff 100%)'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
|
|
||||||
|
>
|
||||||
|
<img class={'w-[48px] h-[48px]'} src={'/tab/icons/work/tomato_work_icon.png'}></img>
|
||||||
|
<div class={'flex-1 flex justify-center'}>
|
||||||
|
<div class="flex-col flex">
|
||||||
|
<span class={'text-[16px] text-[#333]'}>番茄时</span>
|
||||||
|
<div class={'flex items-center text-[#999] text-[12px] '}>
|
||||||
|
立即使用
|
||||||
|
<div>
|
||||||
|
<img class={"w-[7px] h-[6px] ml-1"} src="/tab/icons/work/tomoto_gt.png"></img>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,7 +2,7 @@ import asyncLoader from '@/utils/asyncLoader'
|
||||||
import type { Widget } from '..'
|
import type { Widget } from '..'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'work',
|
name: 'tomato_work',
|
||||||
label: '番茄工作法',
|
label: '番茄工作法',
|
||||||
description: '番茄记事法',
|
description: '番茄记事法',
|
||||||
icon: '/tab/icons/work/tomato_work_icon.png',
|
icon: '/tab/icons/work/tomato_work_icon.png',
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { defineComponent, onBeforeUnmount, onMounted, reactive, ref } from "vue";
|
import { computed, defineComponent, onBeforeUnmount, onMounted, reactive, ref } from "vue";
|
||||||
// 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。
|
// 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。
|
||||||
import * as echarts from 'echarts/core';
|
import * as echarts from 'echarts/core';
|
||||||
import { LineChart, PieChart, } from 'echarts/charts';
|
import { LineChart, PieChart, } from 'echarts/charts';
|
||||||
|
@ -145,12 +145,12 @@ export default defineComponent(() => {
|
||||||
}}></Progress>
|
}}></Progress>
|
||||||
<div class={"w-[65%] bg-[#F6F6F6] shadow rounded-full h-[65%] items-center justify-center absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 flex flex-col"}>
|
<div class={"w-[65%] bg-[#F6F6F6] shadow rounded-full h-[65%] items-center justify-center absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 flex flex-col"}>
|
||||||
<span class={"text-[#666]"}>相比昨天</span>
|
<span class={"text-[#666]"}>相比昨天</span>
|
||||||
<span class={"font-bold text-[#333] text-[30px]"}>+300%</span>
|
<span class={"font-bold text-[#333] text-[30px]"}>{(store.todayHour - store.yestodayHour) >= 0 ? "+" : ''}{(store.todayHour - store.yestodayHour) * 100}%</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class={"flex flex-col"}>
|
<div class={"flex flex-col items-center"}>
|
||||||
<span class={"text-[#333] text-[16px]"}>今日专注时长</span>
|
<span class={"text-[#333] text-[16px]"}>今日专注时长</span>
|
||||||
<span class={"text-[#5a6eff] font-extrabold text-[36px]"}>0.71
|
<span class={"text-[#5a6eff] font-extrabold text-[36px]"}> {(store.todayHour * 0.15).toFixed(2)}
|
||||||
<span class={"text-[20px]"}>h</span>
|
<span class={"text-[20px]"}>h</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -176,13 +176,13 @@ export default defineComponent(() => {
|
||||||
}}></Progress>
|
}}></Progress>
|
||||||
<div class={"w-[65%] bg-[#F6F6F6] shadow rounded-full h-[65%] items-center justify-center absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 flex flex-col"}>
|
<div class={"w-[65%] bg-[#F6F6F6] shadow rounded-full h-[65%] items-center justify-center absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 flex flex-col"}>
|
||||||
<span class={"text-[#666]"}>相比昨天</span>
|
<span class={"text-[#666]"}>相比昨天</span>
|
||||||
<span class={"font-bold text-[#333] text-[30px]"}>+300%</span>
|
<span class={"font-bold text-[#333] text-[30px]"}>{(store.todayFinishTarget - store.yesFinishTarget) >= 0 ? "+" : ''}{(store.todayFinishTarget - store.yesFinishTarget) * 100}%</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class={"flex flex-col"}>
|
<div class={"flex flex-col items-center"}>
|
||||||
<span class={"text-[#333] text-[16px]"}>今日专注时长</span>
|
<span class={"text-[#333] text-[16px]"}>今日完成目标数</span>
|
||||||
<span class={"text-[#5a6eff] font-extrabold text-[36px]"}>0.71
|
<span class={"text-[#5a6eff] font-extrabold text-[36px]"}>{store.todayFinishTarget}
|
||||||
<span class={"text-[20px]"}>h</span>
|
<span class={"text-[20px]"}>个</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { useCalendarStore } from "@/widgets/calendar/useCalendarStore";
|
import { useCalendarStore } from "@/widgets/calendar/useCalendarStore";
|
||||||
import { DatePicker } from "ant-design-vue";
|
import { DatePicker } from "ant-design-vue";
|
||||||
import DownImg from "~/public/icons/work/selectDown1.0.3.png"
|
import DownImg from "~/icons/work/selectDown1.0.3.png"
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { defineComponent, ref } from "vue";
|
import { defineComponent, ref } from "vue";
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { computed, defineComponent, ref } from 'vue'
|
import { computed, defineComponent, ref } from 'vue'
|
||||||
import useTomatoStore from '../useTomatoStore'
|
import useTomatoStore from '../useTomatoStore'
|
||||||
import NoDataImg from "~/public/icons/work/noData.png"
|
import NoDataImg from "~/icons/work/noData.png"
|
||||||
import StopImg from "~/public/icons/work/tomotoIconEnd.png"
|
import StopImg from "~/icons/work/tomotoIconEnd.png"
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import PlayImg from "~/public/icons/work/work_page-play.png"
|
import PlayImg from "~/icons/work/work_page-play.png"
|
||||||
export default defineComponent(() => {
|
export default defineComponent(() => {
|
||||||
const store = useTomatoStore()
|
const store = useTomatoStore()
|
||||||
const searchText = ref('')
|
const searchText = ref('')
|
||||||
|
|
|
@ -46,21 +46,17 @@ export default defineStore("work", () => {
|
||||||
isPlaying: false as boolean,
|
isPlaying: false as boolean,
|
||||||
selectMusic: 0,
|
selectMusic: 0,
|
||||||
isStart: false as boolean,
|
isStart: false as boolean,
|
||||||
beginTime: -1 as number
|
beginTime: -1 as number,
|
||||||
|
|
||||||
})
|
})
|
||||||
|
const audio = new Audio()
|
||||||
const time = useTimeStore()
|
const time = useTimeStore()
|
||||||
const remainingTime = computed(() => {
|
const remainingTime = computed(() => {
|
||||||
if (!state.isStart) {
|
if (!state.isStart) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return dayjs(state.beginTime).add(1, 'minute').diff(dayjs(time.date), 'second')
|
return dayjs(state.beginTime).add(15, 'minute').diff(dayjs(time.date), 'second')
|
||||||
})
|
})
|
||||||
const beginTomatoTime = () => {
|
|
||||||
state.beginTime = dayjs().valueOf()
|
|
||||||
state.isStart = true
|
|
||||||
playMusic()
|
|
||||||
}
|
|
||||||
const stopTomatoTime = () => {
|
const stopTomatoTime = () => {
|
||||||
state.isStart = false
|
state.isStart = false
|
||||||
state.beginTime = -1
|
state.beginTime = -1
|
||||||
|
@ -71,45 +67,65 @@ export default defineStore("work", () => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const togglePlay = () => {
|
||||||
const playAudio = computed(() => {
|
if (state.isPlaying) {
|
||||||
const audio = new Audio(musicList[state.selectMusic].music)
|
audio.pause()
|
||||||
return audio
|
} else {
|
||||||
})
|
audio.play()
|
||||||
|
}
|
||||||
// watch(() => state.isPlaying, (val) => {
|
state.isPlaying = !state.isPlaying
|
||||||
// if (val) {
|
|
||||||
// playAudio.value.play()
|
|
||||||
// } else {
|
|
||||||
// playAudio.value.pause()
|
|
||||||
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
const playMusic = () => {
|
|
||||||
state.isPlaying = true
|
|
||||||
playAudio.value.play()
|
|
||||||
}
|
}
|
||||||
|
const setTrack = (trackIndex: number) => {
|
||||||
const pauseMusic = () => {
|
state.selectMusic = trackIndex
|
||||||
state.isPlaying = false
|
audio.src = musicList[trackIndex].music
|
||||||
playAudio.value.pause()
|
audio.loop = true
|
||||||
|
audio.load()
|
||||||
|
if (state.isPlaying) {
|
||||||
|
audio.play()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const stopMusic = () => {
|
const stopMusic = () => {
|
||||||
|
audio.pause()
|
||||||
|
audio.currentTime = 0
|
||||||
state.isPlaying = false
|
state.isPlaying = false
|
||||||
playAudio.value.pause()
|
}
|
||||||
playAudio.value.currentTime = 0
|
const beginTomatoTime = () => {
|
||||||
|
state.beginTime = dayjs().valueOf()
|
||||||
|
state.isStart = true
|
||||||
|
setTrack(state.selectMusic)
|
||||||
|
togglePlay()
|
||||||
|
|
||||||
}
|
}
|
||||||
const openShowModel = ref<undefined | null | TomatoTarget>()
|
const openShowModel = ref<undefined | null | TomatoTarget>()
|
||||||
const openFullscreen = ref(false)
|
const openFullscreen = ref(false)
|
||||||
|
const todayHour = computed(() => {
|
||||||
|
return state.timeList.filter(val => dayjs(val).isSame(dayjs(), 'day')).length
|
||||||
|
})
|
||||||
|
const yestodayHour = computed(() => {
|
||||||
|
return state.timeList.filter(val => dayjs(val).isSame(dayjs().subtract(1, 'day'), 'day')).length
|
||||||
|
})
|
||||||
|
const todayFinishTarget = computed(() => {
|
||||||
|
return state.list.filter(val => dayjs(val.finishTime).isSame(dayjs(), 'day') && val.isCompleted).length
|
||||||
|
})
|
||||||
|
const yesFinishTarget = computed(() => {
|
||||||
|
return state.list.filter(val => dayjs(val.finishTime).isSame(dayjs().subtract(1, 'day'), 'day') && val.isCompleted).length
|
||||||
|
|
||||||
|
})
|
||||||
return {
|
return {
|
||||||
state,
|
state,
|
||||||
openShowModel,
|
openShowModel,
|
||||||
openFullscreen,
|
openFullscreen,
|
||||||
beginTomatoTime,
|
beginTomatoTime,
|
||||||
remainingTime,
|
remainingTime,
|
||||||
playMusic,
|
togglePlay,
|
||||||
pauseMusic,
|
|
||||||
stopMusic,
|
stopMusic,
|
||||||
stopTomatoTime
|
stopTomatoTime,
|
||||||
|
todayHour,
|
||||||
|
yestodayHour,
|
||||||
|
todayFinishTarget,
|
||||||
|
yesFinishTarget,
|
||||||
|
setTrack
|
||||||
}
|
}
|
||||||
|
}, {
|
||||||
|
persist: true
|
||||||
})
|
})
|
||||||
|
|
|
@ -31,7 +31,7 @@ export default defineConfig({
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'@': fileURLToPath(new URL('./src', import.meta.url)),
|
'@': fileURLToPath(new URL('./src', import.meta.url)),
|
||||||
'~': fileURLToPath(new URL('./', import.meta.url))
|
'~': fileURLToPath(new URL('./public', import.meta.url))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
|
|
Loading…
Reference in New Issue