|
@@ -0,0 +1,537 @@
|
|
|
|
|
+//index.js
|
|
|
|
|
+const app = getApp()
|
|
|
|
|
+const util = require('../../utils/util.js')
|
|
|
|
|
+
|
|
|
|
|
+Page({
|
|
|
|
|
+ data: {
|
|
|
|
|
+ userInfo:{},
|
|
|
|
|
+ hasUserInfo:false,
|
|
|
|
|
+ clockShow: false,
|
|
|
|
|
+ clockHeight: 0,
|
|
|
|
|
+ time: '25',
|
|
|
|
|
+ mTime: 1500000,
|
|
|
|
|
+ timeStr: '25:00',
|
|
|
|
|
+ rate: '',
|
|
|
|
|
+ timer: null,
|
|
|
|
|
+ cateArr: [
|
|
|
|
|
+ { icon: 'work', text: '工作' },
|
|
|
|
|
+ { icon: 'study', text: "学习" },
|
|
|
|
|
+ { icon: 'think', text: '思考' },
|
|
|
|
|
+ { icon: 'write', text: '写作' },
|
|
|
|
|
+ { icon: 'sport', text: '运动' },
|
|
|
|
|
+ { icon: 'read', text: "阅读" }
|
|
|
|
|
+ ],
|
|
|
|
|
+ cateActive: null,
|
|
|
|
|
+ okShow: false,
|
|
|
|
|
+ pauseShow: true,
|
|
|
|
|
+ continueCancleShow: false,
|
|
|
|
|
+ customTask: '',
|
|
|
|
|
+ showCustomInput: false,
|
|
|
|
|
+ plans: [],
|
|
|
|
|
+ selectedPlan: null,
|
|
|
|
|
+ editMode: false,
|
|
|
|
|
+ editPlanId: null,
|
|
|
|
|
+ currentTask: '',
|
|
|
|
|
+ userInfo: null,
|
|
|
|
|
+ isLoggedIn: false,
|
|
|
|
|
+ theme: {},
|
|
|
|
|
+ containerStyle: '',
|
|
|
|
|
+ buttonStyle: '', // 按钮动态样式
|
|
|
|
|
+ timerStyle: '', // 计时器动态样式
|
|
|
|
|
+ progressStyle: '', // 进度条动态样式
|
|
|
|
|
+ photoPath: '',
|
|
|
|
|
+ isTimerRunning: false, // 新增:计时器是否正在运行
|
|
|
|
|
+ startTime: 0, // 新增:开始时间戳
|
|
|
|
|
+ endTime: 0, // 新增:结束时间戳
|
|
|
|
|
+ remainingTime: 0 // 新增:剩余时间(毫秒)
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ onLoad: function () {
|
|
|
|
|
+ const res = wx.getSystemInfoSync();
|
|
|
|
|
+ const rate = 750 / res.windowWidth;
|
|
|
|
|
+ this.setData({
|
|
|
|
|
+ rate: rate,
|
|
|
|
|
+ clockHeight: res.windowHeight * 2,
|
|
|
|
|
+ time: '25',
|
|
|
|
|
+ mTime: 25 * 60 * 1000,
|
|
|
|
|
+ timeStr: '25:00'
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ const plans = wx.getStorageSync('plans') || [];
|
|
|
|
|
+ this.setData({ plans });
|
|
|
|
|
+
|
|
|
|
|
+ if (app.globalData.userInfo) {
|
|
|
|
|
+ this.setData({
|
|
|
|
|
+ userInfo: app.globalData.userInfo,
|
|
|
|
|
+ hasUserInfo: true,
|
|
|
|
|
+ isLoggedIn: true
|
|
|
|
|
+ });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 没有用户信息,引导用户授权
|
|
|
|
|
+ wx.showModal({
|
|
|
|
|
+ title: '授权提示',
|
|
|
|
|
+ content: '需要获取您的用户信息以提供更好的服务,请授权登录',
|
|
|
|
|
+ success: res => {
|
|
|
|
|
+ if (res.confirm) {
|
|
|
|
|
+ wx.getUserProfile({
|
|
|
|
|
+ desc: '用于完善用户资料',
|
|
|
|
|
+ success: res => {
|
|
|
|
|
+ app.globalData.userInfo = res.userInfo;
|
|
|
|
|
+ this.setData({
|
|
|
|
|
+ userInfo: res.userInfo,
|
|
|
|
|
+ hasUserInfo: true,
|
|
|
|
|
+ isLoggedIn: true
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ if (app.eventBus) {
|
|
|
|
|
+ app.eventBus.on('userInfoChange', (userInfo) => {
|
|
|
|
|
+ this.setData({
|
|
|
|
|
+ userInfo: userInfo,
|
|
|
|
|
+ isLoggedIn: !!userInfo
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ app.eventBus.on('themeChange', (theme) => {
|
|
|
|
|
+ this.setData({ theme });
|
|
|
|
|
+ this.updateThemeStyles();
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this.setData({
|
|
|
|
|
+ userInfo: app.globalData.userInfo,
|
|
|
|
|
+ isLoggedIn: !!app.globalData.userInfo,
|
|
|
|
|
+ theme: app.globalData.theme
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ this.updateThemeStyles();
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ onShow: function() {
|
|
|
|
|
+ this.updateNavigationBarColor();
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ onUnload: function() {
|
|
|
|
|
+ if (this.data.timer) {
|
|
|
|
|
+ clearInterval(this.data.timer);
|
|
|
|
|
+ this.setData({ timer: null });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (app.eventBus) {
|
|
|
|
|
+ app.eventBus.off('userInfoChange');
|
|
|
|
|
+ app.eventBus.off('themeChange');
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ updateNavigationBarColor: function() {
|
|
|
|
|
+ const { theme } = this.data;
|
|
|
|
|
+ if (theme && theme.primaryColor && theme.textColor) {
|
|
|
|
|
+ wx.setNavigationBarColor({
|
|
|
|
|
+ frontColor: theme.textColor === '#333' ? '#000000' : '#ffffff',
|
|
|
|
|
+ backgroundColor: theme.primaryColor,
|
|
|
|
|
+ animation: {
|
|
|
|
|
+ duration: 300,
|
|
|
|
|
+ timingFunc: 'easeIn'
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ updateThemeStyles: function () {
|
|
|
|
|
+ const { theme } = this.data;
|
|
|
|
|
+ const { bgColor, textColor, primaryColor } = theme;
|
|
|
|
|
+
|
|
|
|
|
+ this.setData({
|
|
|
|
|
+ containerStyle: `background-color: ${bgColor}; color: ${textColor};`,
|
|
|
|
|
+ buttonStyle: `background-color: ${primaryColor}; color: ${textColor};`,
|
|
|
|
|
+ timerStyle: `color: ${primaryColor};`,
|
|
|
|
|
+ progressStyle: primaryColor,
|
|
|
|
|
+ sliderStyle: primaryColor // 新增滑块主题色
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ this.updateNavigationBarColor();
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ slideChange: function (e) {
|
|
|
|
|
+ const minutes = e.detail.value;
|
|
|
|
|
+ this.setData({
|
|
|
|
|
+ time: minutes.toString(),
|
|
|
|
|
+ timeStr: minutes >= 10 ? minutes + ':00' : '0' + minutes + ':00',
|
|
|
|
|
+ mTime: minutes * 60 * 1000
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ clickCate: function (e) {
|
|
|
|
|
+ this.setData({
|
|
|
|
|
+ cateActive: e.currentTarget.dataset.index,
|
|
|
|
|
+ showCustomInput: false,
|
|
|
|
|
+ selectedPlan: null,
|
|
|
|
|
+ editMode: false
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ showCustomTaskInput: function() {
|
|
|
|
|
+ this.setData({
|
|
|
|
|
+ showCustomInput: true,
|
|
|
|
|
+ cateActive: null,
|
|
|
|
|
+ selectedPlan: null,
|
|
|
|
|
+ customTask: '',
|
|
|
|
|
+ editMode: false
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ inputCustomTask: function(e) {
|
|
|
|
|
+ this.setData({ customTask: e.detail.value });
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ savePlan: function() {
|
|
|
|
|
+ if (!this.data.customTask.trim()) {
|
|
|
|
|
+ wx.showToast({ title: '请输入任务内容', icon: 'none' });
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ let updatedPlans = [];
|
|
|
|
|
+
|
|
|
|
|
+ if (this.data.editMode) {
|
|
|
|
|
+ updatedPlans = this.data.plans.map(plan => {
|
|
|
|
|
+ if (plan.id === this.data.editPlanId) {
|
|
|
|
|
+ return { ...plan, content: this.data.customTask, time: this.data.time };
|
|
|
|
|
+ }
|
|
|
|
|
+ return plan;
|
|
|
|
|
+ });
|
|
|
|
|
+ wx.showToast({ title: '计划更新成功', icon: 'success' });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ const newPlan = {
|
|
|
|
|
+ id: Date.now(),
|
|
|
|
|
+ content: this.data.customTask,
|
|
|
|
|
+ time: this.data.time,
|
|
|
|
|
+ createdAt: new Date().toISOString()
|
|
|
|
|
+ };
|
|
|
|
|
+ updatedPlans = [...this.data.plans, newPlan];
|
|
|
|
|
+ wx.showToast({ title: '计划添加成功', icon: 'success' });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this.setData({
|
|
|
|
|
+ plans: updatedPlans,
|
|
|
|
|
+ customTask: '',
|
|
|
|
|
+ showCustomInput: false,
|
|
|
|
|
+ editMode: false,
|
|
|
|
|
+ editPlanId: null
|
|
|
|
|
+ });
|
|
|
|
|
+ wx.setStorageSync('plans', updatedPlans);
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ selectPlan: function(e) {
|
|
|
|
|
+ const { index } = e.currentTarget.dataset;
|
|
|
|
|
+ const selectedPlan = this.data.plans[index];
|
|
|
|
|
+ this.setData({
|
|
|
|
|
+ time: selectedPlan.time,
|
|
|
|
|
+ customTask: selectedPlan.content,
|
|
|
|
|
+ cateActive: null,
|
|
|
|
|
+ showCustomInput: false,
|
|
|
|
|
+ selectedPlan: selectedPlan,
|
|
|
|
|
+ editMode: false
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ editPlan: function(e) {
|
|
|
|
|
+ const { index } = e.currentTarget.dataset;
|
|
|
|
|
+ const planToEdit = this.data.plans[index];
|
|
|
|
|
+ this.setData({
|
|
|
|
|
+ time: planToEdit.time,
|
|
|
|
|
+ customTask: planToEdit.content,
|
|
|
|
|
+ showCustomInput: true,
|
|
|
|
|
+ editMode: true,
|
|
|
|
|
+ editPlanId: planToEdit.id,
|
|
|
|
|
+ selectedPlan: null
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ deletePlan: function(e) {
|
|
|
|
|
+ const { index } = e.currentTarget.dataset;
|
|
|
|
|
+ const planToDelete = this.data.plans[index];
|
|
|
|
|
+ wx.showModal({
|
|
|
|
|
+ title: '确认删除',
|
|
|
|
|
+ content: `确定要删除计划"${planToDelete.content}"吗?`,
|
|
|
|
|
+ success: (res) => {
|
|
|
|
|
+ if (res.confirm) {
|
|
|
|
|
+ const updatedPlans = this.data.plans.filter((_, i) => i !== index);
|
|
|
|
|
+ this.setData({ plans: updatedPlans, selectedPlan: null });
|
|
|
|
|
+ wx.setStorageSync('plans', updatedPlans);
|
|
|
|
|
+ wx.showToast({ title: '计划已删除', icon: 'success' });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ start: function () {
|
|
|
|
|
+ let taskContent = '';
|
|
|
|
|
+ let time = parseInt(this.data.time);
|
|
|
|
|
+ let categoryIndex = this.data.cateActive;
|
|
|
|
|
+
|
|
|
|
|
+ if (this.data.selectedPlan) {
|
|
|
|
|
+ taskContent = this.data.selectedPlan.content;
|
|
|
|
|
+ time = parseInt(this.data.selectedPlan.time);
|
|
|
|
|
+ } else if (this.data.showCustomInput && this.data.customTask) {
|
|
|
|
|
+ taskContent = this.data.customTask;
|
|
|
|
|
+ categoryIndex = null;
|
|
|
|
|
+ } else if (this.data.cateActive !== null) {
|
|
|
|
|
+ taskContent = this.data.cateArr[this.data.cateActive].text;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ wx.showToast({ title: '请选择一个任务', icon: 'none' });
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ this.setData({
|
|
|
|
|
+ clockShow: true,
|
|
|
|
|
+ mTime: time * 60 * 1000,
|
|
|
|
|
+ timeStr: time >= 10 ? time + ':00' : '0' + time + ':00',
|
|
|
|
|
+ time: time.toString(),
|
|
|
|
|
+ currentTask: taskContent,
|
|
|
|
|
+ cateActive: categoryIndex
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ this.drawBg();
|
|
|
|
|
+ this.drawActive();
|
|
|
|
|
+ this.showPhotoConfirm();
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ drawBg: function () {
|
|
|
|
|
+ const lineWidth = 6 / this.data.rate;
|
|
|
|
|
+ const ctx = wx.createCanvasContext('progress_bg');
|
|
|
|
|
+ const center = 250 / this.data.rate;
|
|
|
|
|
+ const radius = center - 2 * lineWidth;
|
|
|
|
|
+
|
|
|
|
|
+ ctx.setLineWidth(lineWidth);
|
|
|
|
|
+ ctx.setStrokeStyle('#f0f0f0');
|
|
|
|
|
+ ctx.setLineCap('round');
|
|
|
|
|
+ ctx.beginPath();
|
|
|
|
|
+ ctx.arc(center, center, radius, 0, 2 * Math.PI, false);
|
|
|
|
|
+ ctx.stroke();
|
|
|
|
|
+ ctx.draw();
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ drawActive: function () {
|
|
|
|
|
+ const _this = this;
|
|
|
|
|
+ const lineWidth = 6 / this.data.rate;
|
|
|
|
|
+ const center = 250 / this.data.rate;
|
|
|
|
|
+ const radius = center - 2 * lineWidth;
|
|
|
|
|
+
|
|
|
|
|
+ const timer = setInterval(function () {
|
|
|
|
|
+ const angle = 1.5 + 2 * (_this.data.time * 60 * 1000 - _this.data.mTime) / (_this.data.time * 60 * 1000);
|
|
|
|
|
+ const currentTime = _this.data.mTime - 100;
|
|
|
|
|
+ _this.setData({ mTime: currentTime });
|
|
|
|
|
+
|
|
|
|
|
+ if (angle < 3.5) {
|
|
|
|
|
+ if (currentTime % 1000 == 0) {
|
|
|
|
|
+ let timeStr1 = currentTime / 1000;
|
|
|
|
|
+ let timeStr2 = parseInt(timeStr1 / 60);
|
|
|
|
|
+ let timeStr3 = (timeStr1 - timeStr2 * 60) >= 10 ?
|
|
|
|
|
+ (timeStr1 - timeStr2 * 60) : '0' + (timeStr1 - timeStr2 * 60);
|
|
|
|
|
+ timeStr2 = timeStr2 >= 10 ? timeStr2 : '0' + timeStr2;
|
|
|
|
|
+ _this.setData({ timeStr: timeStr2 + ':' + timeStr3 });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const ctx = wx.createCanvasContext('progress_active');
|
|
|
|
|
+ ctx.setLineWidth(lineWidth);
|
|
|
|
|
+ ctx.setStrokeStyle(_this.data.theme.primaryColor);
|
|
|
|
|
+ ctx.setLineCap('round');
|
|
|
|
|
+ ctx.beginPath();
|
|
|
|
|
+ ctx.arc(center, center, radius, 1.5 * Math.PI, angle * Math.PI, false);
|
|
|
|
|
+ ctx.stroke();
|
|
|
|
|
+ ctx.draw();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ const logs = wx.getStorageSync('logs') || [];
|
|
|
|
|
+ logs.unshift({
|
|
|
|
|
+ date: util.formatTime(new Date),
|
|
|
|
|
+ task: _this.data.currentTask,
|
|
|
|
|
+ cate: _this.data.cateActive,
|
|
|
|
|
+ time: _this.data.time
|
|
|
|
|
+ });
|
|
|
|
|
+ wx.setStorageSync('logs', logs);
|
|
|
|
|
+ _this.setData({
|
|
|
|
|
+ timeStr: '00:00',
|
|
|
|
|
+ okShow: true,
|
|
|
|
|
+ pauseShow: false,
|
|
|
|
|
+ continueCancleShow: false
|
|
|
|
|
+ });
|
|
|
|
|
+ clearInterval(timer);
|
|
|
|
|
+ }
|
|
|
|
|
+ }, 100);
|
|
|
|
|
+ _this.setData({ timer: timer });
|
|
|
|
|
+ },
|
|
|
|
|
+ showPhotoConfirm: function() {
|
|
|
|
|
+ wx.showModal({
|
|
|
|
|
+ title: '打卡拍照',
|
|
|
|
|
+ content: '开始专注前需要拍照打卡确认',
|
|
|
|
|
+ confirmText: '拍照',
|
|
|
|
|
+ cancelText: '暂不',
|
|
|
|
|
+ success: (res) => {
|
|
|
|
|
+ if (res.confirm) {
|
|
|
|
|
+ this.checkCameraPermission();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 取消拍照则重置界面
|
|
|
|
|
+ this.resetTimerUI();
|
|
|
|
|
+ wx.showToast({ title: '拍照打卡已取消', icon: 'none' });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ checkCameraPermission: function() {
|
|
|
|
|
+ wx.getSetting({
|
|
|
|
|
+ success: (res) => {
|
|
|
|
|
+ if (!res.authSetting['scope.camera']) {
|
|
|
|
|
+ wx.authorize({
|
|
|
|
|
+ scope: 'scope.camera',
|
|
|
|
|
+ success: () => this.takePhoto(),
|
|
|
|
|
+ fail: () => {
|
|
|
|
|
+ wx.showModal({
|
|
|
|
|
+ title: '权限申请',
|
|
|
|
|
+ content: '需要授予相机权限才能拍照打卡',
|
|
|
|
|
+ success: (res) => {
|
|
|
|
|
+ if (res.confirm) wx.openSetting();
|
|
|
|
|
+ else this.resetTimerUI(); // 拒绝权限则重置界面
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.takePhoto();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ takePhoto: function () {
|
|
|
|
|
+ wx.chooseImage({
|
|
|
|
|
+ count: 1,
|
|
|
|
|
+ sourceType: ['camera'],
|
|
|
|
|
+ success: (res) => {
|
|
|
|
|
+ const photoPath = res.tempFilePaths[0];
|
|
|
|
|
+ this.setData({ photoPath });
|
|
|
|
|
+ wx.setStorageSync('checkInPhoto', photoPath);
|
|
|
|
|
+ wx.showToast({ title: '拍照成功' });
|
|
|
|
|
+
|
|
|
|
|
+ // 拍照成功后才开始计时
|
|
|
|
|
+ this.startTimer();
|
|
|
|
|
+ },
|
|
|
|
|
+ fail: (err) => {
|
|
|
|
|
+ console.error('拍照失败', err);
|
|
|
|
|
+ wx.showToast({ title: '拍照失败', icon: 'none' });
|
|
|
|
|
+ this.resetTimerUI(); // 拍照失败则重置界面
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ startTimer: function() {
|
|
|
|
|
+ // 记录开始时间和预计结束时间
|
|
|
|
|
+ const now = Date.now();
|
|
|
|
|
+ this.setData({
|
|
|
|
|
+ isTimerRunning: true,
|
|
|
|
|
+ startTime: now,
|
|
|
|
|
+ endTime: now + this.data.remainingTime
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 更新计时器显示
|
|
|
|
|
+ this.updateTimer();
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ updateTimer: function() {
|
|
|
|
|
+ if (!this.data.isTimerRunning) return;
|
|
|
|
|
+
|
|
|
|
|
+ const now = Date.now();
|
|
|
|
|
+ let remaining = this.data.endTime - now;
|
|
|
|
|
+
|
|
|
|
|
+ // 处理计时结束
|
|
|
|
|
+ if (remaining <= 0) {
|
|
|
|
|
+ this.finishTimer();
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 更新剩余时间显示
|
|
|
|
|
+ const minutes = Math.floor(remaining / 60000);
|
|
|
|
|
+ const seconds = Math.floor((remaining % 60000) / 1000);
|
|
|
|
|
+ const timeStr = `${minutes >= 10 ? minutes : '0' + minutes}:${seconds >= 10 ? seconds : '0' + seconds}`;
|
|
|
|
|
+
|
|
|
|
|
+ this.setData({
|
|
|
|
|
+ remainingTime: remaining,
|
|
|
|
|
+ timeStr: timeStr
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 更新进度环
|
|
|
|
|
+ this.drawActive();
|
|
|
|
|
+
|
|
|
|
|
+ // 每秒更新一次
|
|
|
|
|
+ this.timerInterval = setTimeout(() => {
|
|
|
|
|
+ this.updateTimer();
|
|
|
|
|
+ }, 1000);
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ // 重置计时器UI
|
|
|
|
|
+ resetTimerUI: function() {
|
|
|
|
|
+ this.setData({
|
|
|
|
|
+ clockShow: false,
|
|
|
|
|
+ isTimerRunning: false,
|
|
|
|
|
+ photoPath: ''
|
|
|
|
|
+ });
|
|
|
|
|
+ clearTimeout(this.timerInterval);
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ // 完成计时
|
|
|
|
|
+ finishTimer: function() {
|
|
|
|
|
+ this.setData({
|
|
|
|
|
+ isTimerRunning: false,
|
|
|
|
|
+ timeStr: '00:00'
|
|
|
|
|
+ });
|
|
|
|
|
+ clearTimeout(this.timerInterval);
|
|
|
|
|
+
|
|
|
|
|
+ // 显示完成提示
|
|
|
|
|
+ wx.showToast({
|
|
|
|
|
+ title: '专注完成!',
|
|
|
|
|
+ icon: 'success',
|
|
|
|
|
+ duration: 2000
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+ pause: function () {
|
|
|
|
|
+ clearInterval(this.data.timer);
|
|
|
|
|
+ this.setData({
|
|
|
|
|
+ pauseShow: false,
|
|
|
|
|
+ continueCancleShow: true,
|
|
|
|
|
+ okShow: false
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ continue: function () {
|
|
|
|
|
+ this.drawActive();
|
|
|
|
|
+ this.setData({
|
|
|
|
|
+ pauseShow: true,
|
|
|
|
|
+ continueCancleShow: false,
|
|
|
|
|
+ okShow: false
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ cancle: function () {
|
|
|
|
|
+ clearInterval(this.data.timer);
|
|
|
|
|
+ this.setData({
|
|
|
|
|
+ pauseShow: true,
|
|
|
|
|
+ continueCancleShow: false,
|
|
|
|
|
+ okShow: false,
|
|
|
|
|
+ clockShow: false
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ ok: function () {
|
|
|
|
|
+ clearInterval(this.data.timer);
|
|
|
|
|
+ this.setData({
|
|
|
|
|
+ pauseShow: true,
|
|
|
|
|
+ continueCancleShow: false,
|
|
|
|
|
+ okShow: false,
|
|
|
|
|
+ clockShow: false
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+})
|