feat: 支持关卡配置分享

This commit is contained in:
richarjiang
2026-04-06 17:32:32 +08:00
parent c7f52ab032
commit b489ab40f5
8 changed files with 392 additions and 24 deletions

View File

@@ -3,6 +3,7 @@ import { BaseView } from 'db://assets/scripts/core/BaseView';
import { ViewManager } from 'db://assets/scripts/core/ViewManager';
import { LevelDataManager } from 'db://assets/scripts/utils/LevelDataManager';
import { ToastManager } from 'db://assets/scripts/utils/ToastManager';
import { ShareManager } from 'db://assets/scripts/utils/ShareManager';
const { ccclass, property } = _decorator;
/**
@@ -78,6 +79,9 @@ export class PageWriteLevels extends BaseView {
/** 缓存 view 节点的 UITransform避免每次 _updateContentSize 重复查找 */
private _viewTransform: UITransform | null = null;
/** 防止重复提交 */
private _isSubmitting: boolean = false;
onViewLoad(): void {
console.log('[PageWriteLevels] onViewLoad');
this._initButtons();
@@ -92,6 +96,9 @@ export class PageWriteLevels extends BaseView {
if (this.previewBtn) {
this.previewBtn.on(Button.EventType.CLICK, this._onPreviewClick, this);
}
if (this.completeBtn) {
this.completeBtn.on(Button.EventType.CLICK, this._onCompleteClick, this);
}
}
private _initScrollView(): void {
@@ -156,7 +163,10 @@ export class PageWriteLevels extends BaseView {
onViewShow(): void {
console.log('[PageWriteLevels] onViewShow');
this._initLevelList();
// 仅首次初始化列表,从预览页返回时保留选中状态
if (this._itemNodes.length === 0) {
this._initLevelList();
}
}
private _initLevelList(): void {
@@ -276,6 +286,8 @@ export class PageWriteLevels extends BaseView {
const toggle = isSelected.getComponent(Toggle);
if (toggle) {
toggle.isChecked = this._selectedIndices.has(index);
// 禁用 Toggle 交互,仅作为视觉指示器,选中逻辑由 item Button 统一处理
toggle.interactable = false;
}
const checkmark = isSelected.getChildByName('Checkmark');
if (checkmark) {
@@ -428,14 +440,22 @@ export class PageWriteLevels extends BaseView {
ViewManager.instance.back();
}
private _onPreviewClick(): void {
/**
* 校验是否已选满关卡,未满则 Toast 提示
* @returns true 表示校验通过
*/
private _validateSelection(): boolean {
if (this._selectedIndices.size < MAX_SELECTION) {
const remaining = MAX_SELECTION - this._selectedIndices.size;
ToastManager.instance.show(`还需选择${remaining}个关卡`);
return;
return false;
}
return true;
}
private _onPreviewClick(): void {
if (!this._validateSelection()) return;
const shareTitle = this.shareTitleEditBox?.getComponent(EditBox)?.string?.trim() || '';
console.log('[PageWriteLevels] 预览按钮点击,标题:', shareTitle, '已选关卡:', Array.from(this._selectedIndices));
ViewManager.instance.open('PagePreviewLevels', {
params: {
selectedIndices: Array.from(this._selectedIndices),
@@ -444,6 +464,57 @@ export class PageWriteLevels extends BaseView {
});
}
private async _onCompleteClick(): Promise<void> {
if (!this._validateSelection()) return;
const shareTitle = this.shareTitleEditBox?.getComponent(EditBox)?.string?.trim() || '';
if (!shareTitle) {
ToastManager.instance.show('请输入分享标题');
return;
}
if (this._isSubmitting) return;
this._isSubmitting = true;
try {
const levelIds = this._getSelectedLevelIds();
if (levelIds.length !== MAX_SELECTION) {
ToastManager.instance.show('获取关卡数据失败,请重试');
return;
}
const shareCode = await ShareManager.instance.createShare(shareTitle, levelIds);
if (!shareCode) {
ToastManager.instance.show('创建分享失败,请重试');
return;
}
console.log('[PageWriteLevels] 创建分享成功, code:', shareCode);
ShareManager.instance.triggerWxShare(shareTitle, shareCode);
ToastManager.instance.show('分享创建成功!');
} catch (err) {
console.error('[PageWriteLevels] 完成按钮异常:', err);
ToastManager.instance.show('操作失败,请重试');
} finally {
this._isSubmitting = false;
}
}
/**
* 将选中的关卡索引转换为关卡 ID 数组
*/
private _getSelectedLevelIds(): string[] {
const ids: string[] = [];
const sortedIndices = Array.from(this._selectedIndices).sort((a, b) => a - b);
for (const index of sortedIndices) {
const config = LevelDataManager.instance.getLevelConfig(index);
if (config) {
ids.push(config.id);
}
}
return ids;
}
onViewHide(): void {
console.log('[PageWriteLevels] onViewHide');
}
@@ -456,6 +527,9 @@ export class PageWriteLevels extends BaseView {
if (this.previewBtn) {
this.previewBtn.off(Button.EventType.CLICK, this._onPreviewClick, this);
}
if (this.completeBtn) {
this.completeBtn.off(Button.EventType.CLICK, this._onCompleteClick, this);
}
if (this.scrollView) {
this.scrollView.off(Node.EventType.TOUCH_START, this._onTouchStart, this);
this.scrollView.off(Node.EventType.TOUCH_END, this._onTouchEnd, this);