feat: 收敛玩法运行时配置并加入故障恢复

This commit is contained in:
2026-04-01 13:04:26 +08:00
parent 1635a11780
commit 3ef841ecc7
73 changed files with 8820 additions and 2122 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -73,25 +73,26 @@
</view>
</view>
<view
class="game-content-card game-content-card--{{contentCardTemplate}} {{contentCardFxClass}}"
wx:if="{{contentCardVisible}}"
catchtap="handleContentCardTap"
>
<view class="game-content-card__title">{{contentCardTitle}}</view>
<view class="game-content-card__body">{{contentCardBody}}</view>
<view class="game-content-card__action-row {{contentCardActions.length ? 'game-content-card__action-row--split' : ''}}">
<view class="game-content-card__cta-group" wx:if="{{contentCardActions.length}}">
<view
wx:for="{{contentCardActions}}"
wx:key="key"
class="game-content-card__action"
data-type="{{item.type}}"
data-key="{{item.key}}"
catchtap="handleOpenContentCardAction"
>{{item.label}}</view>
<view class="game-content-card-layer" wx:if="{{contentCardVisible}}" bindtap="handleDismissTransientContentCard">
<view
class="game-content-card game-content-card--{{contentCardTemplate}} {{contentCardFxClass}}"
catchtap="handleContentCardTap"
>
<view class="game-content-card__title">{{contentCardTitle}}</view>
<view class="game-content-card__body">{{contentCardBody}}</view>
<view wx:if="{{contentCardActions.length}}" class="game-content-card__action-row game-content-card__action-row--split">
<view class="game-content-card__cta-group" wx:if="{{contentCardActions.length}}">
<view
wx:for="{{contentCardActions}}"
wx:key="key"
class="game-content-card__action"
data-type="{{item.type}}"
data-key="{{item.key}}"
catchtap="handleOpenContentCardAction"
>{{item.label}}</view>
</view>
<view class="game-content-card__close" catchtap="handleCloseContentCard">关闭</view>
</view>
<view class="game-content-card__close" catchtap="handleCloseContentCard">关闭</view>
</view>
</view>
@@ -118,7 +119,7 @@
</view>
</view>
<view class="game-punch-hint" wx:if="{{!showResultScene && showPunchHintBanner && punchHintText}}" style="top: {{topInsetHeight}}px;" catchtouchstart="handlePunchHintTap" catchtouchmove="handlePunchHintTap" catchtouchend="handlePunchHintTap">
<view class="game-punch-hint {{punchHintFxClass}}" wx:if="{{!showResultScene && !contentCardVisible && !contentQuizVisible && showPunchHintBanner && punchHintText}}" style="top: {{topInsetHeight}}px;" catchtouchstart="handlePunchHintTap" catchtouchmove="handlePunchHintTap" catchtouchend="handlePunchHintTap">
<view class="game-punch-hint__text">{{punchHintText}}</view>
<view class="game-punch-hint__close" catchtouchstart="handlePunchHintTap" catchtouchmove="handlePunchHintTap" catchtouchend="handlePunchHintTap" catchtap="handleClosePunchHint">×</view>
</view>
@@ -187,12 +188,15 @@
<view class="race-panel__grid">
<view class="race-panel__cell race-panel__cell--action">
<view class="race-panel__action-button"><!-- status only -->
<view class="race-panel__action-button-text">{{punchButtonText}}</view>
<view class="race-panel__action-stack">
<view class="race-panel__action-button {{punchButtonEnabled ? 'race-panel__action-button--active' : ''}}"><!-- status only -->
<view class="race-panel__action-button-text">{{punchButtonText}}</view>
</view>
<text class="race-panel__action-summary">{{panelTargetSummaryText}}</text>
</view>
</view>
<view class="race-panel__cell race-panel__cell--timer">
<text class="race-panel__timer {{panelTimerFxClass}}">{{panelTimerText}}</text>
<text class="race-panel__timer {{panelTimerFxClass}} {{panelTimerMode === 'countdown' ? 'race-panel__timer--countdown' : ''}}">{{panelTimerText}}</text>
</view>
<view class="race-panel__cell race-panel__cell--mileage">
<view class="race-panel__mileage-wrap {{panelMileageFxClass}}">
@@ -244,7 +248,7 @@
</view>
</view>
<view class="race-panel__cell race-panel__cell--timer">
<text class="race-panel__timer {{panelTimerFxClass}}">{{panelTimerText}}</text>
<text class="race-panel__timer {{panelTimerFxClass}} {{panelTimerMode === 'countdown' ? 'race-panel__timer--countdown' : ''}}">{{panelTimerText}}</text>
</view>
<view class="race-panel__cell race-panel__cell--mileage">
<view class="race-panel__metric-group race-panel__metric-group--right race-panel__metric-group--panel">
@@ -364,8 +368,8 @@
<view class="debug-section__title">01. 动画性能</view>
<view class="debug-section__desc">根据设备性能切换动画强度,低端机建议精简</view>
</view>
<view class="debug-section__lock {{lockAnimationLevel ? 'debug-section__lock--active' : ''}}" data-key="lockAnimationLevel" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockAnimationLevel ? '已锁' : '可改'}}</text>
<view class="debug-section__lock {{lockAnimationLevel ? 'debug-section__lock--active' : ''}}">
<text class="debug-section__lock-text">{{lockAnimationLevel ? '配置锁定' : '允许调整'}}</text>
</view>
</view>
</view>
@@ -386,8 +390,8 @@
<view class="debug-section__title">02. 轨迹选项</view>
<view class="debug-section__desc">控制不显示、彗尾拖尾、全轨迹三种显示方式</view>
</view>
<view class="debug-section__lock {{lockTrackMode ? 'debug-section__lock--active' : ''}}" data-key="lockTrackMode" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockTrackMode ? '已锁' : '可改'}}</text>
<view class="debug-section__lock {{lockTrackMode ? 'debug-section__lock--active' : ''}}">
<text class="debug-section__lock-text">{{lockTrackMode ? '配置锁定' : '允许调整'}}</text>
</view>
</view>
</view>
@@ -411,8 +415,8 @@
<view class="debug-section__title">03. 轨迹尾巴</view>
<view class="debug-section__desc">拖尾模式下控制尾巴长短,跑得越快会在此基础上再拉长</view>
</view>
<view class="debug-section__lock {{lockTrackTailLength ? 'debug-section__lock--active' : ''}}" data-key="lockTrackTailLength" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockTrackTailLength ? '已锁' : '可改'}}</text>
<view class="debug-section__lock {{lockTrackTailLength ? 'debug-section__lock--active' : ''}}">
<text class="debug-section__lock-text">{{lockTrackTailLength ? '配置锁定' : '允许调整'}}</text>
</view>
</view>
</view>
@@ -436,8 +440,8 @@
<view class="debug-section__title">04. 轨迹颜色</view>
<view class="debug-section__desc">亮色轨迹调色盘,运行中会按速度和心率张力自动提亮</view>
</view>
<view class="debug-section__lock {{lockTrackColor ? 'debug-section__lock--active' : ''}}" data-key="lockTrackColor" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockTrackColor ? '已锁' : '可改'}}</text>
<view class="debug-section__lock {{lockTrackColor ? 'debug-section__lock--active' : ''}}">
<text class="debug-section__lock-text">{{lockTrackColor ? '配置锁定' : '允许调整'}}</text>
</view>
</view>
</view>
@@ -468,8 +472,8 @@
<view class="debug-section__title">05. 轨迹风格</view>
<view class="debug-section__desc">切换经典线条和流光轨迹风格,默认推荐流光</view>
</view>
<view class="debug-section__lock {{lockTrackStyle ? 'debug-section__lock--active' : ''}}" data-key="lockTrackStyle" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockTrackStyle ? '已锁' : '可改'}}</text>
<view class="debug-section__lock {{lockTrackStyle ? 'debug-section__lock--active' : ''}}">
<text class="debug-section__lock-text">{{lockTrackStyle ? '配置锁定' : '允许调整'}}</text>
</view>
</view>
</view>
@@ -490,8 +494,8 @@
<view class="debug-section__title">06. GPS点显示</view>
<view class="debug-section__desc">控制地图上的 GPS 定位点显示与隐藏</view>
</view>
<view class="debug-section__lock {{lockGpsMarkerVisible ? 'debug-section__lock--active' : ''}}" data-key="lockGpsMarkerVisible" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockGpsMarkerVisible ? '已锁' : '可改'}}</text>
<view class="debug-section__lock {{lockGpsMarkerVisible ? 'debug-section__lock--active' : ''}}">
<text class="debug-section__lock-text">{{lockGpsMarkerVisible ? '配置锁定' : '允许调整'}}</text>
</view>
</view>
</view>
@@ -512,8 +516,8 @@
<view class="debug-section__title">07. GPS点大小</view>
<view class="debug-section__desc">控制定位点本体和朝向小三角的整体尺寸</view>
</view>
<view class="debug-section__lock {{lockGpsMarkerSize ? 'debug-section__lock--active' : ''}}" data-key="lockGpsMarkerSize" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockGpsMarkerSize ? '已锁' : '可改'}}</text>
<view class="debug-section__lock {{lockGpsMarkerSize ? 'debug-section__lock--active' : ''}}">
<text class="debug-section__lock-text">{{lockGpsMarkerSize ? '配置锁定' : '允许调整'}}</text>
</view>
</view>
</view>
@@ -535,8 +539,8 @@
<view class="debug-section__title">08. GPS点颜色</view>
<view class="debug-section__desc">切换定位点主色,默认使用青绿高亮色</view>
</view>
<view class="debug-section__lock {{lockGpsMarkerColor ? 'debug-section__lock--active' : ''}}" data-key="lockGpsMarkerColor" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockGpsMarkerColor ? '已锁' : '可改'}}</text>
<view class="debug-section__lock {{lockGpsMarkerColor ? 'debug-section__lock--active' : ''}}">
<text class="debug-section__lock-text">{{lockGpsMarkerColor ? '配置锁定' : '允许调整'}}</text>
</view>
</view>
</view>
@@ -567,8 +571,8 @@
<view class="debug-section__title">09. GPS点风格</view>
<view class="debug-section__desc">切换定位点底座风格,影响本体与外圈表现</view>
</view>
<view class="debug-section__lock {{lockGpsMarkerStyle ? 'debug-section__lock--active' : ''}}" data-key="lockGpsMarkerStyle" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockGpsMarkerStyle ? '已锁' : '可改'}}</text>
<view class="debug-section__lock {{lockGpsMarkerStyle ? 'debug-section__lock--active' : ''}}">
<text class="debug-section__lock-text">{{lockGpsMarkerStyle ? '配置锁定' : '允许调整'}}</text>
</view>
</view>
</view>
@@ -591,8 +595,8 @@
<view class="debug-section__title">10. 按钮习惯</view>
<view class="debug-section__desc">切换功能按钮显示在左侧还是右侧,适配左手/右手操作习惯</view>
</view>
<view class="debug-section__lock {{lockSideButtonPlacement ? 'debug-section__lock--active' : ''}}" data-key="lockSideButtonPlacement" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockSideButtonPlacement ? '已锁' : '可改'}}</text>
<view class="debug-section__lock {{lockSideButtonPlacement ? 'debug-section__lock--active' : ''}}">
<text class="debug-section__lock-text">{{lockSideButtonPlacement ? '配置锁定' : '允许调整'}}</text>
</view>
</view>
</view>
@@ -613,8 +617,8 @@
<view class="debug-section__title">11. 自动转图</view>
<view class="debug-section__desc">控制地图是否跟随朝向自动旋转,外部按钮与这里保持同步</view>
</view>
<view class="debug-section__lock {{lockAutoRotate ? 'debug-section__lock--active' : ''}}" data-key="lockAutoRotate" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockAutoRotate ? '已锁' : '可改'}}</text>
<view class="debug-section__lock {{lockAutoRotate ? 'debug-section__lock--active' : ''}}">
<text class="debug-section__lock-text">{{lockAutoRotate ? '配置锁定' : '允许调整'}}</text>
</view>
</view>
</view>
@@ -635,8 +639,8 @@
<view class="debug-section__title">12. 指北针响应</view>
<view class="debug-section__desc">切换指针的平滑与跟手程度,影响指北针响应手感</view>
</view>
<view class="debug-section__lock {{lockCompassTuning ? 'debug-section__lock--active' : ''}}" data-key="lockCompassTuning" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockCompassTuning ? '已锁' : '可改'}}</text>
<view class="debug-section__lock {{lockCompassTuning ? 'debug-section__lock--active' : ''}}">
<text class="debug-section__lock-text">{{lockCompassTuning ? '配置锁定' : '允许调整'}}</text>
</view>
</view>
</view>
@@ -658,8 +662,8 @@
<view class="debug-section__title">13. 比例尺显示</view>
<view class="debug-section__desc">控制比例尺显示与否,默认沿用你的本地偏好</view>
</view>
<view class="debug-section__lock {{lockScaleRulerVisible ? 'debug-section__lock--active' : ''}}" data-key="lockScaleRulerVisible" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockScaleRulerVisible ? '已锁' : '可改'}}</text>
<view class="debug-section__lock {{lockScaleRulerVisible ? 'debug-section__lock--active' : ''}}">
<text class="debug-section__lock-text">{{lockScaleRulerVisible ? '配置锁定' : '允许调整'}}</text>
</view>
</view>
</view>
@@ -680,8 +684,8 @@
<view class="debug-section__title">14. 比例尺基准点</view>
<view class="debug-section__desc">设置比例尺零点锚定位置,可跟随屏幕中心或指北针圆心</view>
</view>
<view class="debug-section__lock {{lockScaleRulerAnchor ? 'debug-section__lock--active' : ''}}" data-key="lockScaleRulerAnchor" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockScaleRulerAnchor ? '已锁' : '可改'}}</text>
<view class="debug-section__lock {{lockScaleRulerAnchor ? 'debug-section__lock--active' : ''}}">
<text class="debug-section__lock-text">{{lockScaleRulerAnchor ? '配置锁定' : '允许调整'}}</text>
</view>
</view>
</view>
@@ -702,8 +706,8 @@
<view class="debug-section__title">15. 北参考</view>
<view class="debug-section__desc">切换磁北/真北作为地图与指北针参考</view>
</view>
<view class="debug-section__lock {{lockNorthReference ? 'debug-section__lock--active' : ''}}" data-key="lockNorthReference" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockNorthReference ? '已锁' : '可改'}}</text>
<view class="debug-section__lock {{lockNorthReference ? 'debug-section__lock--active' : ''}}">
<text class="debug-section__lock-text">{{lockNorthReference ? '配置锁定' : '允许调整'}}</text>
</view>
</view>
</view>
@@ -724,8 +728,8 @@
<view class="debug-section__title">16. 心率设备</view>
<view class="debug-section__desc">清除已记住的首选心率带设备,下次重新选择</view>
</view>
<view class="debug-section__lock {{lockHeartRateDevice ? 'debug-section__lock--active' : ''}}" data-key="lockHeartRateDevice" bindtap="handleToggleSettingLock">
<text class="debug-section__lock-text">{{lockHeartRateDevice ? '已锁' : '可改'}}</text>
<view class="debug-section__lock {{lockHeartRateDevice ? 'debug-section__lock--active' : ''}}">
<text class="debug-section__lock-text">{{lockHeartRateDevice ? '配置锁定' : '允许调整'}}</text>
</view>
</view>
</view>
@@ -801,6 +805,21 @@
<view class="control-chip control-chip--primary" bindtap="handleConnectAllMockSources">一键连接开发调试源</view>
<view class="control-chip control-chip--secondary" bindtap="handleOpenWebViewTest">测试 H5</view>
</view>
<view class="info-panel__row info-panel__row--stack">
<text class="info-panel__label">模拟通道号</text>
<view class="debug-inline-stack">
<input
class="debug-input"
value="{{mockChannelIdDraft}}"
placeholder="default / runner-a"
bindinput="handleMockChannelIdInput"
/>
<view class="control-row control-row--compact">
<view class="control-chip control-chip--secondary" bindtap="handleSaveMockChannelId">保存通道号</view>
</view>
</view>
<text class="info-panel__hint">当前通道:{{mockChannelIdText}}</text>
</view>
<view class="debug-group-title">定位模拟</view>
<view class="info-panel__row">
<text class="info-panel__label">GPS</text>
@@ -907,7 +926,7 @@
<input
class="debug-input"
value="{{mockHeartRateBridgeUrlDraft}}"
placeholder="ws://192.168.x.x:17865/mock-gps"
placeholder="ws://192.168.x.x:17865/mock-hr"
bindinput="handleMockHeartRateBridgeUrlInput"
/>
<view class="control-row control-row--compact">
@@ -932,7 +951,7 @@
<input
class="debug-input"
value="{{mockDebugLogBridgeUrlDraft}}"
placeholder="ws://192.168.x.x:17865/mock-gps"
placeholder="ws://192.168.x.x:17865/debug-log"
bindinput="handleMockDebugLogBridgeUrlInput"
/>
<view class="control-row control-row--compact">
@@ -1025,6 +1044,19 @@
<text class="info-panel__label">Accuracy</text>
<text class="info-panel__value">{{panelAccuracyValueText}} {{panelAccuracyUnitText}}</text>
</view>
<view class="info-panel__row">
<text class="info-panel__label">Timer</text>
<text class="info-panel__value">{{panelTimerText}}</text>
</view>
<view class="info-panel__row">
<text class="info-panel__label">Timer Mode</text>
<text class="info-panel__value">{{panelTimerMode === 'countdown' ? '倒计时' : '正计时'}}</text>
</view>
<view class="control-row control-row--triple">
<view class="control-chip control-chip--secondary" bindtap="handleDebugSetSessionRemainingWarning">剩10分钟</view>
<view class="control-chip control-chip--secondary" bindtap="handleDebugSetSessionRemainingOneMinute">剩1分钟</view>
<view class="control-chip control-chip--secondary" bindtap="handleDebugTimeoutSession">立即超时</view>
</view>
<view class="control-row control-row--triple">
<view class="control-chip control-chip--secondary" bindtap="handleDebugHeartRateBlue">蓝</view>
<view class="control-chip control-chip--secondary" bindtap="handleDebugHeartRatePurple">紫</view>

View File

@@ -849,6 +849,12 @@
text-shadow: 0 2rpx 0 rgba(255, 255, 255, 0.2);
}
.race-panel__timer--countdown {
color: #ffe082;
text-shadow: 0 0 14rpx rgba(255, 176, 32, 0.42);
animation: race-panel-timer-countdown 1.15s ease-in-out infinite;
}
.race-panel__timer--fx-tick {
animation: race-panel-timer-tick 0.32s cubic-bezier(0.24, 0.86, 0.3, 1) 1;
}
@@ -973,6 +979,12 @@
100% { transform: translateY(0) scale(1); opacity: 1; }
}
@keyframes race-panel-timer-countdown {
0% { opacity: 0.88; transform: scale(1); }
50% { opacity: 1; transform: scale(1.03); }
100% { opacity: 0.88; transform: scale(1); }
}
@keyframes race-panel-mileage-update {
0% { transform: translateX(-16rpx) scale(1); opacity: 0.94; }
40% { transform: translateX(-16rpx) scale(1.05); opacity: 1; }
@@ -1612,6 +1624,7 @@
border-radius: 999rpx;
background: rgba(233, 242, 228, 0.92);
box-shadow: inset 0 0 0 1rpx rgba(22, 48, 32, 0.08);
pointer-events: none;
}
.debug-section__lock--active {
@@ -1942,6 +1955,10 @@
pointer-events: auto;
}
.game-punch-hint--fx-enter {
animation: game-punch-hint-enter 0.42s cubic-bezier(0.22, 0.88, 0.28, 1) 1;
}
.game-punch-hint__text {
flex: 1;
min-width: 0;
@@ -1961,6 +1978,26 @@
background: rgba(255, 255, 255, 0.08);
}
@keyframes game-punch-hint-enter {
0% {
opacity: 0;
transform: translateX(-50%) translateY(-16rpx) scale(0.96);
box-shadow: 0 0 0 0 rgba(120, 255, 210, 0);
}
58% {
opacity: 1;
transform: translateX(-50%) translateY(0) scale(1.02);
box-shadow: 0 0 0 12rpx rgba(120, 255, 210, 0.12);
}
100% {
opacity: 1;
transform: translateX(-50%) translateY(0) scale(1);
box-shadow: 0 0 0 0 rgba(120, 255, 210, 0);
}
}
.game-punch-feedback {
position: absolute;
left: 50%;
@@ -2002,6 +2039,13 @@
animation: feedback-toast-warning 0.56s ease-out;
}
.game-content-card-layer {
position: absolute;
inset: 0;
z-index: 34;
pointer-events: auto;
}
.game-content-card {
position: absolute;
left: 50%;
@@ -2014,7 +2058,7 @@
background: rgba(248, 251, 244, 0.96);
box-shadow: 0 18rpx 48rpx rgba(22, 48, 32, 0.18);
box-sizing: border-box;
z-index: 33;
z-index: 35;
pointer-events: auto;
}
@@ -2233,6 +2277,24 @@
color: rgba(236, 241, 246, 0.86);
}
.race-panel__action-stack {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 10rpx;
max-width: 100%;
}
.race-panel__action-summary {
max-width: 220rpx;
font-size: 18rpx;
line-height: 1.2;
color: rgba(233, 241, 248, 0.68);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.race-panel__action-button--active .race-panel__action-button-text {
color: #775000;
}