feat: 支持通关字段上报

This commit is contained in:
richarjiang
2026-04-07 15:46:22 +08:00
parent b489ab40f5
commit e05a6a1f8c
3 changed files with 37 additions and 8 deletions

View File

@@ -691,7 +691,8 @@ export class PageLevel extends BaseView {
// 通关奖励:分享模式下不增加积分 // 通关奖励:分享模式下不增加积分
if (!this._isShareMode) { if (!this._isShareMode) {
const levelId = this._currentConfig?.id ?? ''; const levelId = this._currentConfig?.id ?? '';
await UserAssetsManager.instance.earnPoint(levelId); const timeSpent = 60 - this._countdown;
await UserAssetsManager.instance.earnPoint(levelId, timeSpent);
this.updatePointsLabel(); this.updatePointsLabel();
} }

View File

@@ -243,6 +243,13 @@ export class PageWriteLevels extends BaseView {
// 设置默认名称和选中状态(封面由 _loadAndRefreshCover 异步填充) // 设置默认名称和选中状态(封面由 _loadAndRefreshCover 异步填充)
this._initItemState(item, index); this._initItemState(item, index);
// 禁用 Button 组件,防止它拦截触摸事件导致 ScrollView 无法滑动
const button = item.getComponent(Button);
if (button) {
button.enabled = false;
}
this._setupItemClick(item, index); this._setupItemClick(item, index);
return item; return item;
@@ -323,14 +330,32 @@ export class PageWriteLevels extends BaseView {
} }
private _setupItemClick(item: Node, index: number): void { private _setupItemClick(item: Node, index: number): void {
// 只用 Button click 统一处理选中/取消,避免 Toggle 事件与 Button 事件同时触发导致双重调用 // 用触摸事件代替 Button区分点击和滑动
const button = item.getComponent(Button); // 短距离松手 = 点击(切换选中),长距离 = 滑动(交给 ScrollView
if (button) { let touchStartPos: Vec2 | null = null;
button.node.on(Button.EventType.CLICK, () => {
item.on(Node.EventType.TOUCH_START, (event: EventTouch) => {
touchStartPos = event.getUILocation();
}, this);
item.on(Node.EventType.TOUCH_END, (event: EventTouch) => {
if (!touchStartPos) return;
const endPos = event.getUILocation();
const dx = endPos.x - touchStartPos.x;
const dy = endPos.y - touchStartPos.y;
const distance = Math.sqrt(dx * dx + dy * dy);
touchStartPos = null;
// 滑动距离小于阈值才算点击
if (distance < 20) {
const isCurrentlySelected = this._selectedIndices.has(index); const isCurrentlySelected = this._selectedIndices.has(index);
this._onItemToggle(index, !isCurrentlySelected); this._onItemToggle(index, !isCurrentlySelected);
}, this); }
} }, this);
item.on(Node.EventType.TOUCH_CANCEL, () => {
touchStartPos = null;
}, this);
} }
/** /**

View File

@@ -85,9 +85,11 @@ export class UserAssetsManager {
/** /**
* 获得积分(通关奖励) * 获得积分(通关奖励)
* @param levelId 关卡ID
* @param timeSpent 通关耗时(秒)
* @returns 获得后的积分数 * @returns 获得后的积分数
*/ */
async earnPoint(levelId: string): Promise<number> { async earnPoint(levelId: string, timeSpent: number): Promise<number> {
if (!AuthManager.instance.isLoggedIn) { if (!AuthManager.instance.isLoggedIn) {
StorageManager.addPoint(); StorageManager.addPoint();
return StorageManager.getPoints(); return StorageManager.getPoints();
@@ -99,6 +101,7 @@ export class UserAssetsManager {
{ {
reason: POINT_REASONS.LEVEL_COMPLETE, reason: POINT_REASONS.LEVEL_COMPLETE,
levelId, levelId,
timeSpent,
}, },
API_TIMEOUT.SHORT API_TIMEOUT.SHORT
); );