闫增涛
2025-04-14 d7e53e63dd6c435e226d9f08cde31ca35131c911
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
<template>
  <el-dialog v-model="dialogVisable" title="番茄闹钟" width="500" >
    <div class="ring-box">
      <span class="title-txt">响铃时长</span>
      <el-switch v-model="pageData.isRing" :disabled="isRuning" />
      <el-input-number v-model="pageData.ringTime" :disabled="isRuning" :min="1" step-strictly />
    </div>
    <p class="prompt-txt ring-title">以秒为单位</p>
    <div class="border" ></div>
    <ul class="sustain-box">
      <li>
        <span class="title-txt">持续时间</span>
        <span class="label-txt" >专注时间</span>
        <el-input-number v-model="pageData.workTime" :disabled="isRuning" :min="1" step-strictly />
      </li>
      <li>
        <span class="title-txt"></span>
        <span class="label-txt">短休息</span>
        <el-input-number v-model="pageData.shortTime" :disabled="isRuning" :min="0" step-strictly />
      </li>
      <li>
        <span class="title-txt"></span>
        <span class="label-txt">长休息</span>
        <el-input-number v-model="pageData.longTime" :disabled="isRuning" :min="0" step-strictly />
      </li>
    </ul>
    <p  class="prompt-txt ring-title" >以分钟为单位</p>
    <div class="border" ></div>
    <div>
      <el-button type="primary" @click="startFun" >开始</el-button>
      <el-button type="primary" @click="pauseFun" >停止</el-button>
      <el-button @click="resetFun">重置</el-button>
      <el-button @click="handleRestFun(false)" >长休息</el-button>
      <el-button @click="handleRestFun(true)">短休息</el-button>
    </div>
    {{ formatTime(pageData.currentTime) }}
  </el-dialog>
  <!-- <video src="../../assets/audio/买辣椒也用券.mp3"  ref="audioRef"></video> -->
</template>
 
<script setup lang="ts">
import { ElMessage } from 'element-plus'
import { ref, reactive, defineExpose ,watchEffect } from 'vue'
import {useFormatData} from '@/hooks/public'
const isShow =ref<boolean>(false)  // 悬浮框是否显示 
const audioRef = ref<HTMLAudioElement>()  // 音频实例
const dialogVisable = ref<boolean>(false)  // 弹窗状态
const timerInterval = ref<any>(null)  // 计时器实例
const isRuning = ref<boolean>(false)  // 计时器是否运行
const isBreak = ref<boolean>(false)  // true 休息  false 工作
const isShortTime = ref<boolean>(false)  // 长短休息模式
const pageData = reactive({
  isRing: true, // 是否响铃
  ringTime: 5, // 响铃时长  秒
  workTime: 25, // 工作时长  分钟
  saveWorkTime: 0,  // 剩余工作时间
  shortTime: 5, // 短休息
  longTime: 5, // 长休息
  currentTime:0,  // 显示时间  秒
})
const { formatTime } = useFormatData()
watchEffect(() => {
  pageData.currentTime = pageData.workTime * 60
})
watchEffect(() => {
  if(!isBreak.value) pageData.saveWorkTime = pageData.currentTime
})
const setDialogVisable = (value: boolean) => {
  dialogVisable.value = value
}
  // 开始计时
const startFun = () => {
  isShow.value = true
  isRuning.value = true
  timerInterval.value = setInterval(() => {
    if(pageData.currentTime > 0) {
      pageData.currentTime--
    } else {
      playAudio()
      if(isBreak.value) {
        // 工作时间赋值
        isBreak.value = false
        if( pageData.saveWorkTime) {
          pageData.currentTime =  pageData.saveWorkTime
          ElMessage.success('休息结束,开始学习吧!')
        } else {
          clearInterval(timerInterval.value)
          isRuning.value = false
          ElMessage.success('学习结束')
        }
 
      } else {
        // 休息时间赋值
        isBreak.value = true
        pageData.currentTime = isShortTime.value ? pageData.shortTime * 60 : pageData.longTime * 60
        ElMessage.success('休息一下吧!')
      }
    }
    
  }, 1000)
  dialogVisable.value = false
}
// 暂停计时
const pauseFun = () => {
  isRuning.value =  false
  if(timerInterval.value) {
    clearInterval(timerInterval.value)
  }
}
// 重置计时器
const resetFun = () =>  {
  isRuning.value = false
  isBreak.value = false
  pauseFun()
  pageData.currentTime = pageData.workTime * 60
}
// 休息按钮
const startBreak = () => {
  if(isRuning.value && !isBreak.value) {
    if(pageData.shortTime || pageData.longTime) {
      pageData.saveWorkTime = pageData.currentTime
      isBreak.value = true
      pageData.currentTime = isShortTime.value ? pageData.shortTime * 60 : pageData.longTime * 60
      ElMessage.success('开始休息')
    } else {
      ElMessage.warning('暂未设置休息时间')
    }
  }
}
// 开始响铃
const playAudio = () => {
  audioRef.value!.currentTime = 0
  audioRef.value?.play()
  setTimeout(() => {
    pauseAudio()
  },pageData.ringTime * 1000)
}
 // 暂停响铃
const pauseAudio = () => {
  audioRef.value?.pause()
}
 
// 长短休息
const handleRestFun = (value:boolean) => {
  isShortTime.value = value
  startBreak()
}
 
defineExpose({
  isShow,
  isRuning,
  pageData,
  setDialogVisable,
  startFun,
  pauseFun,
  resetFun,
  handleRestFun
})
</script>
 
<style lang="less" scoped>
.prompt-txt {
  margin-top: 10px;
  font-size: 12px;
  color: #b7b7b7;
}
.title-txt {
  color: #2c2c2c;
  width: 4em;
}
.label-txt {
  width: 4em;
  color:#707070 ;
}
.ring-box {
  width: 300px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.ring-title {
  padding-left: 150px;
}
.sustain-box {
  width: 300px;
  li {
    display: flex;
    justify-content: space-between;
    margin-bottom: 10px;
  }
}
.border {
  height: 1px;
  background-color:#cecece ;
  margin: 10px 0;
}
</style>