diff --git a/index.html b/index.html index ed26777..0efad59 100644 --- a/index.html +++ b/index.html @@ -3,6 +3,7 @@ + @@ -11,6 +12,7 @@ diff --git a/pages/modify-score/modify-score.vue b/pages/modify-score/modify-score.vue index a4f32b9..0fea6b5 100644 --- a/pages/modify-score/modify-score.vue +++ b/pages/modify-score/modify-score.vue @@ -50,13 +50,12 @@ + -0.001 @@ -67,22 +66,17 @@ 可不改 + +0.001 - - @@ -129,7 +123,14 @@ export default { note: '', minScore: 5.0, maxScore: 10.0, - isProcessing: false + // 防止双击的状态管理 + isTouching: false, + touchTimer: null, + lastTouchTime: 0, + // 长按相关 + longPressTimer: null, + longPressInterval: null, + isLongPressing: false } }, @@ -139,7 +140,7 @@ export default { const globalData = app.globalData || {} // 获取当前选手信息(从 score-list-multi 页面传递) - const currentAthlete = globalData.currentAthlete || {} + const currentAthlete = globalData.currentAthlete || // 获取裁判长ID this.modifierId = globalData.judgeId @@ -156,9 +157,151 @@ export default { if (currentAthlete.athleteId) { await this.loadScoreDetail(currentAthlete.athleteId) } + + // H5 平台特殊处理:禁用双击缩放 + // #ifdef H5 + this.disableDoubleTapZoom() + // #endif + }, + + onUnload() { + // 清理定时器 + this.clearAllTimers() }, methods: { + // #ifdef H5 + disableDoubleTapZoom() { + // 在 H5 环境下,添加额外的事件监听来防止双击缩放 + this.$nextTick(() => { + const decreaseBtn = document.querySelector('.control-btn.decrease') + const increaseBtn = document.querySelector('.control-btn.increase') + + const preventZoom = (e) => { + e.preventDefault() + e.stopPropagation() + e.stopImmediatePropagation() + return false + } + + if (decreaseBtn) { + decreaseBtn.addEventListener('touchstart', preventZoom, { passive: false, capture: true }) + decreaseBtn.addEventListener('touchend', preventZoom, { passive: false, capture: true }) + decreaseBtn.addEventListener('touchmove', preventZoom, { passive: false, capture: true }) + decreaseBtn.addEventListener('click', preventZoom, { passive: false, capture: true }) + } + + if (increaseBtn) { + increaseBtn.addEventListener('touchstart', preventZoom, { passive: false, capture: true }) + increaseBtn.addEventListener('touchend', preventZoom, { passive: false, capture: true }) + increaseBtn.addEventListener('touchmove', preventZoom, { passive: false, capture: true }) + increaseBtn.addEventListener('click', preventZoom, { passive: false, capture: true }) + } + }) + }, + // #endif + + clearAllTimers() { + if (this.touchTimer) { + clearTimeout(this.touchTimer) + this.touchTimer = null + } + if (this.longPressTimer) { + clearTimeout(this.longPressTimer) + this.longPressTimer = null + } + if (this.longPressInterval) { + clearInterval(this.longPressInterval) + this.longPressInterval = null + } + }, + + // 减分按钮 - touchstart + onDecreaseStart(e) { + e.preventDefault() + e.stopPropagation() + + const now = Date.now() + + // 防止快速连续触摸(300ms内的触摸被忽略) + if (now - this.lastTouchTime < 300) { + return + } + + this.lastTouchTime = now + this.isTouching = true + + // 立即执行一次减分 + this.decreaseScore() + + // 设置长按定时器(500ms后开始连续减分) + this.longPressTimer = setTimeout(() => { + this.isLongPressing = true + // 每100ms执行一次减分 + this.longPressInterval = setInterval(() => { + this.decreaseScore() + }, 100) + }, 500) + }, + + // 减分按钮 - touchend + onDecreaseEnd(e) { + e.preventDefault() + e.stopPropagation() + + this.isTouching = false + this.isLongPressing = false + this.clearAllTimers() + }, + + // 加分按钮 - touchstart + onIncreaseStart(e) { + e.preventDefault() + e.stopPropagation() + + const now = Date.now() + + // 防止快速连续触摸(300ms内的触摸被忽略) + if (now - this.lastTouchTime < 300) { + return + } + + this.lastTouchTime = now + this.isTouching = true + + // 立即执行一次加分 + this.increaseScore() + + // 设置长按定时器(500ms后开始连续加分) + this.longPressTimer = setTimeout(() => { + this.isLongPressing = true + // 每100ms执行一次加分 + this.longPressInterval = setInterval(() => { + this.increaseScore() + }, 100) + }, 500) + }, + + // 加分按钮 - touchend + onIncreaseEnd(e) { + e.preventDefault() + e.stopPropagation() + + this.isTouching = false + this.isLongPressing = false + this.clearAllTimers() + }, + + // 触摸取消 + onTouchCancel(e) { + e.preventDefault() + e.stopPropagation() + + this.isTouching = false + this.isLongPressing = false + this.clearAllTimers() + }, + async loadScoreDetail(athleteId) { try { uni.showLoading({ @@ -166,9 +309,6 @@ export default { mask: true }) - // 🔥 关键改动:使用 dataAdapter 获取评分详情 - // Mock模式:调用 mock/score.js 的 getScoreDetail 函数 - // API模式:调用 api/score.js 的 getScoreDetail 函数(GET /api/mini/score/detail/{athleteId}) const response = await dataAdapter.getData('getScoreDetail', { athleteId: athleteId }) @@ -214,54 +354,29 @@ export default { uni.navigateBack() }, - // 空操作函数,用于阻止事件 - noop() { - // 什么都不做 - }, - - handleDecrease(e) { - // 防止重复处理 - if (this.isProcessing) { - return - } - - this.isProcessing = true - - // 执行减分逻辑 - this.decreaseScore() - - // 使用 requestAnimationFrame 确保在下一帧重置状态 - requestAnimationFrame(() => { - this.isProcessing = false - }) - }, - - handleIncrease(e) { - // 防止重复处理 - if (this.isProcessing) { - return - } - - this.isProcessing = true - - // 执行加分逻辑 - this.increaseScore() - - // 使用 requestAnimationFrame 确保在下一帧重置状态 - requestAnimationFrame(() => { - this.isProcessing = false - }) - }, - decreaseScore() { if (this.currentScore > this.minScore) { this.currentScore = parseFloat((this.currentScore - 0.001).toFixed(3)) + + // 添加触觉反馈(仅在支持的平台) + // #ifndef H5 + uni.vibrateShort({ + type: 'light' + }) + // #endif } }, increaseScore() { if (this.currentScore < this.maxScore) { this.currentScore = parseFloat((this.currentScore + 0.001).toFixed(3)) + + // 添加触觉反馈(仅在支持的平台) + // #ifndef H5 + uni.vibrateShort({ + type: 'light' + }) + // #endif } }, @@ -290,9 +405,6 @@ export default { mask: true }) - // 🔥 关键改动:使用 dataAdapter 修改评分 - // Mock模式:调用 mock/score.js 的 modifyScore 函数 - // API模式:调用 api/score.js 的 modifyScore 函数(PUT /api/mini/score/modify) const response = await dataAdapter.getData('modifyScore', { athleteId: this.athleteInfo.athleteId, modifierId: this.modifierId, @@ -513,41 +625,22 @@ export default { } .control-btn { - /* 关键:完全禁用所有触摸行为 */ - touch-action: none !important; - -webkit-tap-highlight-color: transparent !important; - -webkit-touch-callout: none !important; - -webkit-user-select: none !important; - -moz-user-select: none !important; - -ms-user-select: none !important; - user-select: none !important; - /* 防止长按菜单 */ - -webkit-touch-callout: none !important; - /* 防止文本选择 */ - pointer-events: auto !important; - width: 140rpx; height: 140rpx; display: flex; flex-direction: column; align-items: center; justify-content: center; - background-color: #F5F5F5; border-radius: 12rpx; cursor: pointer; position: relative; - overflow: hidden; -} - -.control-btn::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: transparent; - z-index: 1; + + /* 关键:禁用所有可能导致缩放的触摸行为 */ + touch-action: none; + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + -webkit-user-select: none; + user-select: none; } .control-btn.decrease { @@ -561,9 +654,7 @@ export default { .btn-symbol { font-size: 48rpx; font-weight: 300; - pointer-events: none !important; - user-select: none !important; - -webkit-user-select: none !important; + pointer-events: none; } .control-btn.decrease .btn-symbol { @@ -577,9 +668,7 @@ export default { .btn-value { font-size: 24rpx; margin-top: 8rpx; - pointer-events: none !important; - user-select: none !important; - -webkit-user-select: none !important; + pointer-events: none; } .control-btn.decrease .btn-value { @@ -608,13 +697,6 @@ export default { margin-top: 8rpx; } -.modify-tip { - font-size: 24rpx; - color: #FF4D6A; - line-height: 1.6; - text-align: center; -} - /* 备注 */ .note-section { margin: 30rpx;