feat: 接入我参与的挑战接口以及UI

This commit is contained in:
richarjiang
2026-05-14 16:55:26 +08:00
parent dcbd32b0cd
commit 40f7be5200
6 changed files with 470 additions and 99 deletions

View File

@@ -37,20 +37,20 @@
"__id__": 180
},
{
"__id__": 266
"__id__": 272
}
],
"_active": true,
"_components": [
{
"__id__": 282
"__id__": 288
},
{
"__id__": 284
"__id__": 290
}
],
"_prefab": {
"__id__": 286
"__id__": 292
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -4347,20 +4347,20 @@
"__id__": 197
},
{
"__id__": 257
"__id__": 263
}
],
"_active": true,
"_components": [
{
"__id__": 263
"__id__": 269
},
{
"__id__": 194
}
],
"_prefab": {
"__id__": 265
"__id__": 271
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -4417,7 +4417,7 @@
}
],
"_prefab": {
"__id__": 256
"__id__": 262
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -4724,11 +4724,11 @@
"_active": true,
"_components": [
{
"__id__": 253
"__id__": 259
}
],
"_prefab": {
"__id__": 255
"__id__": 261
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -4937,27 +4937,27 @@
{
"__id__": 206
},
{
"__id__": 230
},
{
"__id__": 236
},
{
"__id__": 242
},
{
"__id__": 248
}
],
"_active": true,
"_components": [
{
"__id__": 248
"__id__": 254
},
{
"__id__": 250
"__id__": 256
}
],
"_prefab": {
"__id__": 252
"__id__": 258
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -5005,19 +5005,22 @@
},
{
"__id__": 219
},
{
"__id__": 225
}
],
"_active": true,
"_components": [
{
"__id__": 225
"__id__": 231
},
{
"__id__": 227
"__id__": 233
}
],
"_prefab": {
"__id__": 229
"__id__": 235
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -5456,6 +5459,165 @@
"targetOverrides": null,
"nestedPrefabInstanceRoots": null
},
{
"__type__": "cc.Node",
"_name": "RankNumber",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": {
"__id__": 206
},
"_children": [],
"_active": false,
"_components": [
{
"__id__": 226
},
{
"__id__": 228
}
],
"_prefab": {
"__id__": 230
},
"_lpos": {
"__type__": "cc.Vec3",
"x": -9.887,
"y": 0,
"z": 0
},
"_lrot": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_lscale": {
"__type__": "cc.Vec3",
"x": 2.387,
"y": 2.387,
"z": 2.387
},
"_mobility": 0,
"_layer": 1073741824,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": ""
},
{
"__type__": "cc.UITransform",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 225
},
"_enabled": true,
"__prefab": {
"__id__": 227
},
"_contentSize": {
"__type__": "cc.Size",
"width": 65.615234375,
"height": 136
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "afc2A9N6FGc7UuXiK197iF"
},
{
"__type__": "cc.Label",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 225
},
"_enabled": true,
"__prefab": {
"__id__": 229
},
"_customMaterial": null,
"_srcBlendFactor": 2,
"_dstBlendFactor": 4,
"_color": {
"__type__": "cc.Color",
"r": 236,
"g": 236,
"b": 236,
"a": 255
},
"_string": "4",
"_horizontalAlign": 1,
"_verticalAlign": 1,
"_actualFontSize": 100,
"_fontSize": 100,
"_fontFamily": "Arial",
"_lineHeight": 100,
"_overflow": 0,
"_enableWrapText": true,
"_font": null,
"_isSystemFontUsed": true,
"_spacingX": 0,
"_isItalic": false,
"_isBold": true,
"_isUnderline": false,
"_underlineHeight": 2,
"_cacheMode": 0,
"_enableOutline": true,
"_outlineColor": {
"__type__": "cc.Color",
"r": 0,
"g": 0,
"b": 0,
"a": 255
},
"_outlineWidth": 5,
"_enableShadow": false,
"_shadowColor": {
"__type__": "cc.Color",
"r": 0,
"g": 0,
"b": 0,
"a": 255
},
"_shadowOffset": {
"__type__": "cc.Vec2",
"x": 2,
"y": 2
},
"_shadowBlur": 2,
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "59LYxrApZB/bVeRXmT+WzJ"
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "afXTpxGqpP+IgoyzMhucMS",
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": null
},
{
"__type__": "cc.UITransform",
"_name": "",
@@ -5466,7 +5628,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 226
"__id__": 232
},
"_contentSize": {
"__type__": "cc.Size",
@@ -5494,7 +5656,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 228
"__id__": 234
},
"_customMaterial": null,
"_srcBlendFactor": 2,
@@ -5554,14 +5716,14 @@
"_active": true,
"_components": [
{
"__id__": 231
"__id__": 237
},
{
"__id__": 233
"__id__": 239
}
],
"_prefab": {
"__id__": 235
"__id__": 241
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -5598,15 +5760,15 @@
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 230
"__id__": 236
},
"_enabled": true,
"__prefab": {
"__id__": 232
"__id__": 238
},
"_contentSize": {
"__type__": "cc.Size",
"width": 490,
"width": 549.0625,
"height": 88.2
},
"_anchorPoint": {
@@ -5626,11 +5788,11 @@
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 230
"__id__": 236
},
"_enabled": true,
"__prefab": {
"__id__": 234
"__id__": 240
},
"_customMaterial": null,
"_srcBlendFactor": 2,
@@ -5642,15 +5804,15 @@
"b": 29,
"a": 255
},
"_string": "西瓜太郎的挑战",
"_horizontalAlign": 1,
"_string": "西瓜太郎12",
"_horizontalAlign": 0,
"_verticalAlign": 1,
"_actualFontSize": 70,
"_fontSize": 70,
"_fontFamily": "Arial",
"_lineHeight": 70,
"_overflow": 0,
"_enableWrapText": true,
"_overflow": 1,
"_enableWrapText": false,
"_font": {
"__uuid__": "fb4acba6-6bc7-4eb3-be34-8f2ac9823a80",
"__expectedType__": "cc.TTFFont"
@@ -5716,14 +5878,14 @@
"_active": true,
"_components": [
{
"__id__": 237
"__id__": 243
},
{
"__id__": 239
"__id__": 245
}
],
"_prefab": {
"__id__": 241
"__id__": 247
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -5760,11 +5922,11 @@
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 236
"__id__": 242
},
"_enabled": true,
"__prefab": {
"__id__": 238
"__id__": 244
},
"_contentSize": {
"__type__": "cc.Size",
@@ -5788,11 +5950,11 @@
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 236
"__id__": 242
},
"_enabled": true,
"__prefab": {
"__id__": 240
"__id__": 246
},
"_customMaterial": null,
"_srcBlendFactor": 2,
@@ -5852,14 +6014,14 @@
"_active": true,
"_components": [
{
"__id__": 243
"__id__": 249
},
{
"__id__": 245
"__id__": 251
}
],
"_prefab": {
"__id__": 247
"__id__": 253
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -5896,11 +6058,11 @@
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 242
"__id__": 248
},
"_enabled": true,
"__prefab": {
"__id__": 244
"__id__": 250
},
"_contentSize": {
"__type__": "cc.Size",
@@ -5924,11 +6086,11 @@
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 242
"__id__": 248
},
"_enabled": true,
"__prefab": {
"__id__": 246
"__id__": 252
},
"_customMaterial": null,
"_srcBlendFactor": 2,
@@ -6012,7 +6174,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 249
"__id__": 255
},
"_contentSize": {
"__type__": "cc.Size",
@@ -6040,7 +6202,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 251
"__id__": 257
},
"_customMaterial": null,
"_srcBlendFactor": 2,
@@ -6098,7 +6260,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 254
"__id__": 260
},
"_contentSize": {
"__type__": "cc.Size",
@@ -6154,14 +6316,14 @@
"_active": true,
"_components": [
{
"__id__": 258
"__id__": 264
},
{
"__id__": 260
"__id__": 266
}
],
"_prefab": {
"__id__": 262
"__id__": 268
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -6198,11 +6360,11 @@
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 257
"__id__": 263
},
"_enabled": true,
"__prefab": {
"__id__": 259
"__id__": 265
},
"_contentSize": {
"__type__": "cc.Size",
@@ -6226,11 +6388,11 @@
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 257
"__id__": 263
},
"_enabled": true,
"__prefab": {
"__id__": 261
"__id__": 267
},
"_customMaterial": null,
"_srcBlendFactor": 2,
@@ -6288,7 +6450,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 264
"__id__": 270
},
"_contentSize": {
"__type__": "cc.Size",
@@ -6329,26 +6491,26 @@
},
"_children": [
{
"__id__": 267
"__id__": 273
}
],
"_active": true,
"_components": [
{
"__id__": 273
},
{
"__id__": 275
},
{
"__id__": 277
},
{
"__id__": 279
},
{
"__id__": 281
},
{
"__id__": 283
},
{
"__id__": 285
}
],
"_prefab": {
"__id__": 281
"__id__": 287
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -6385,20 +6547,20 @@
"_objFlags": 0,
"__editorExtras__": {},
"_parent": {
"__id__": 266
"__id__": 272
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 268
"__id__": 274
},
{
"__id__": 270
"__id__": 276
}
],
"_prefab": {
"__id__": 272
"__id__": 278
},
"_lpos": {
"__type__": "cc.Vec3",
@@ -6435,11 +6597,11 @@
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 267
"__id__": 273
},
"_enabled": true,
"__prefab": {
"__id__": 269
"__id__": 275
},
"_contentSize": {
"__type__": "cc.Size",
@@ -6463,11 +6625,11 @@
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 267
"__id__": 273
},
"_enabled": true,
"__prefab": {
"__id__": 271
"__id__": 277
},
"_customMaterial": null,
"_srcBlendFactor": 2,
@@ -6547,11 +6709,11 @@
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 266
"__id__": 272
},
"_enabled": true,
"__prefab": {
"__id__": 274
"__id__": 280
},
"_contentSize": {
"__type__": "cc.Size",
@@ -6575,11 +6737,11 @@
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 266
"__id__": 272
},
"_enabled": true,
"__prefab": {
"__id__": 276
"__id__": 282
},
"_customMaterial": null,
"_srcBlendFactor": 2,
@@ -6620,11 +6782,11 @@
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 266
"__id__": 272
},
"_enabled": true,
"__prefab": {
"__id__": 278
"__id__": 284
},
"_alignFlags": 20,
"_target": null,
@@ -6656,11 +6818,11 @@
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 266
"__id__": 272
},
"_enabled": true,
"__prefab": {
"__id__": 280
"__id__": 286
},
"clickEvents": [],
"_interactable": true,
@@ -6700,7 +6862,7 @@
"_duration": 0.1,
"_zoomScale": 1.2,
"_target": {
"__id__": 266
"__id__": 272
},
"_id": ""
},
@@ -6731,7 +6893,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 283
"__id__": 289
},
"_contentSize": {
"__type__": "cc.Size",
@@ -6759,10 +6921,10 @@
},
"_enabled": true,
"__prefab": {
"__id__": 285
"__id__": 291
},
"backBtn": {
"__id__": 266
"__id__": 272
},
"createdListContent": {
"__id__": 54
@@ -6770,6 +6932,12 @@
"createdListItemTemplate": {
"__id__": 63
},
"participatedListContent": {
"__id__": 196
},
"participatedListItemTemplate": {
"__id__": 205
},
"_id": ""
},
{

View File

@@ -1,7 +1,7 @@
import { _decorator, Node, Button, instantiate, Label, ScrollView, UITransform, Sprite, SpriteFrame, Texture2D, ImageAsset, assetManager } from 'cc';
import { BaseView } from 'db://assets/scripts/core/BaseView';
import { ViewManager } from 'db://assets/scripts/core/ViewManager';
import { CreatedShareItem, ShareParticipantRankSummary } from 'db://assets/scripts/types/ApiTypes';
import { CreatedShareItem, ParticipatedShareItem, ShareParticipantRankSummary } from 'db://assets/scripts/types/ApiTypes';
import { ShareManager } from 'db://assets/scripts/utils/ShareManager';
import { ToastManager } from 'db://assets/scripts/utils/ToastManager';
const { ccclass, property } = _decorator;
@@ -11,6 +11,9 @@ export class PagePKData extends BaseView {
private static readonly CREATED_ITEM_TOP_PADDING = 20;
private static readonly CREATED_ITEM_BOTTOM_PADDING = 20;
private static readonly CREATED_ITEM_SPACING = 20;
private static readonly PARTICIPATED_ITEM_TOP_PADDING = 20;
private static readonly PARTICIPATED_ITEM_BOTTOM_PADDING = 20;
private static readonly PARTICIPATED_ITEM_SPACING = 20;
@property({ type: Node, tooltip: '返回按钮' })
backBtn: Node | null = null;
@@ -21,8 +24,16 @@ export class PagePKData extends BaseView {
@property({ type: Node, tooltip: '我创建的挑战列表条目模板 FriendsPKRankListItem' })
createdListItemTemplate: Node | null = null;
@property({ type: Node, tooltip: '我参与的挑战列表 content 节点' })
participatedListContent: Node | null = null;
@property({ type: Node, tooltip: '我参与的挑战列表条目模板 MyPKListItem' })
participatedListItemTemplate: Node | null = null;
private _createdShares: CreatedShareItem[] = [];
private _participatedShares: ParticipatedShareItem[] = [];
private _createdItemNodes: Node[] = [];
private _participatedItemNodes: Node[] = [];
private _createdButtonBindings: Array<{ node: Node; handler: () => void }> = [];
private _isLoading: boolean = false;
private _renderVersion: number = 0;
@@ -33,36 +44,44 @@ export class PagePKData extends BaseView {
this.backBtn.on(Button.EventType.CLICK, this._onBackClick, this);
}
this._hideCreatedItemTemplate();
this._hideParticipatedItemTemplate();
}
onViewShow(): void {
this._resolveNodes();
void this._loadCreatedShares();
void this._loadShareLists();
}
onViewHide(): void {
this._renderVersion++;
}
private _onBackClick(): void {
ViewManager.instance.back();
}
private async _loadCreatedShares(): Promise<void> {
private async _loadShareLists(): Promise<void> {
if (this._isLoading) {
return;
}
this._isLoading = true;
try {
const items = await ShareManager.instance.fetchCreatedShares();
if (!items) {
const [createdItems, participatedItems] = await Promise.all([
ShareManager.instance.fetchCreatedShares(),
ShareManager.instance.fetchParticipatedShares(),
]);
if (!createdItems || !participatedItems) {
ToastManager.instance.show('获取挑战列表失败,请稍后重试');
return;
}
this._createdShares = items;
this._createdShares = createdItems ?? [];
this._participatedShares = participatedItems ?? [];
console.log('[PagePKData] 我创建的挑战列表:', this._createdShares);
console.log('[PagePKData] 我参与的挑战列表:', this._participatedShares);
this._renderCreatedShares();
this._renderParticipatedShares();
} finally {
this._isLoading = false;
}
@@ -73,6 +92,7 @@ export class PagePKData extends BaseView {
this.backBtn.off(Button.EventType.CLICK, this._onBackClick, this);
}
this._clearCreatedItems();
this._clearParticipatedItems();
}
private _resolveNodes(): void {
@@ -87,12 +107,25 @@ export class PagePKData extends BaseView {
?? this.createdListContent?.getChildByName('FriendsPKRankListItem')
?? null;
const participatedList = this.node.getChildByName('MyPKList');
const participatedView = participatedList?.getChildByName('view');
this.participatedListContent = this.participatedListContent ?? participatedView?.getChildByName('content') ?? null;
this.participatedListItemTemplate = this.participatedListItemTemplate
?? this.participatedListContent?.getChildByName('MyPKListItem')
?? null;
if (!this.createdListContent) {
console.warn('[PagePKData] 未找到 FriendsPKRankList/content 节点');
}
if (!this.createdListItemTemplate) {
console.warn('[PagePKData] 未找到 FriendsPKRankListItem 模板节点');
}
if (!this.participatedListContent) {
console.warn('[PagePKData] 未找到 MyPKList/content 节点');
}
if (!this.participatedListItemTemplate) {
console.warn('[PagePKData] 未找到 MyPKListItem 模板节点');
}
}
private _renderCreatedShares(): void {
@@ -119,6 +152,29 @@ export class PagePKData extends BaseView {
this._scrollCreatedListToTop();
}
private _renderParticipatedShares(): void {
this._clearParticipatedItems();
if (!this.participatedListContent || !this.participatedListItemTemplate) {
return;
}
this._layoutParticipatedList(this._participatedShares.length);
this._hideParticipatedItemTemplate();
this._participatedShares.forEach((share, index) => {
const item = instantiate(this.participatedListItemTemplate!);
item.name = `MyPKListItem_${index + 1}`;
item.active = true;
this.participatedListContent!.addChild(item);
this._participatedItemNodes.push(item);
this._positionParticipatedItem(item, index);
this._applyParticipatedShare(item, share);
});
this._scrollParticipatedListToTop();
}
private _applyCreatedShare(item: Node, share: CreatedShareItem, version: number): void {
this._setLabel(this._findLabelIn(item, 'Name'), share.title || '未命名挑战');
this._setLabel(this._findLabelIn(item, 'ParticipateLabel'), `${share.participantCount ?? 0}人参与`);
@@ -146,6 +202,12 @@ export class PagePKData extends BaseView {
}
}
private _applyParticipatedShare(item: Node, share: ParticipatedShareItem): void {
this._setLabel(this._findLabelIn(item, 'ChallangeName'), share.title || '未命名挑战');
this._setLabel(this._findLabelIn(item, 'ParticipateLabel'), `${share.participantCount ?? 0}人参与`);
this._applyParticipatedRank(item, share.userRank);
}
private _openShareDetail(share: CreatedShareItem): void {
if (!share.shareCode) {
ToastManager.instance.show('挑战数据异常,请稍后重试');
@@ -200,6 +262,34 @@ export class PagePKData extends BaseView {
);
}
private _layoutParticipatedList(itemCount: number): void {
if (!this.participatedListContent || !this.participatedListItemTemplate) {
return;
}
const contentTransform = this.participatedListContent.getComponent(UITransform);
const viewTransform = this.participatedListContent.parent?.getComponent(UITransform) ?? null;
const itemTransform = this.participatedListItemTemplate.getComponent(UITransform);
if (!contentTransform || !viewTransform || !itemTransform) {
return;
}
const contentHeight = Math.max(
viewTransform.height,
PagePKData.PARTICIPATED_ITEM_TOP_PADDING
+ PagePKData.PARTICIPATED_ITEM_BOTTOM_PADDING
+ itemCount * itemTransform.height
+ Math.max(0, itemCount - 1) * PagePKData.PARTICIPATED_ITEM_SPACING,
);
contentTransform.setContentSize(contentTransform.width, contentHeight);
this.participatedListContent.setPosition(
this.participatedListContent.position.x,
viewTransform.height / 2,
this.participatedListContent.position.z,
);
}
private _positionCreatedItem(item: Node, index: number): void {
const itemTransform = item.getComponent(UITransform);
if (!itemTransform) {
@@ -212,11 +302,55 @@ export class PagePKData extends BaseView {
item.setPosition(0, y, item.position.z);
}
private _positionParticipatedItem(item: Node, index: number): void {
const itemTransform = item.getComponent(UITransform);
if (!itemTransform) {
return;
}
const y = -PagePKData.PARTICIPATED_ITEM_TOP_PADDING
- itemTransform.height / 2
- index * (itemTransform.height + PagePKData.PARTICIPATED_ITEM_SPACING);
item.setPosition(0, y, item.position.z);
}
private _scrollCreatedListToTop(): void {
const scrollView = this.node.getChildByName('FriendsPKRankList')?.getComponent(ScrollView);
scrollView?.scrollToTop(0);
}
private _scrollParticipatedListToTop(): void {
const scrollView = this.node.getChildByName('MyPKList')?.getComponent(ScrollView);
scrollView?.scrollToTop(0);
}
private _applyParticipatedRank(item: Node, rank: number | null): void {
const rankRoot = this._findChild(item, 'Rank');
if (!rankRoot) {
return;
}
const rank1Badge = this._findChild(rankRoot, 'rank1badge');
const rank2Badge = this._findChild(rankRoot, 'rank2badge');
const rank3Badge = this._findChild(rankRoot, 'rank3badge');
const rankNumberNode = this._findChild(rankRoot, 'RankNumber');
const normalizedRank = rank && rank > 0 ? rank : null;
if (rank1Badge) {
rank1Badge.active = normalizedRank === 1;
}
if (rank2Badge) {
rank2Badge.active = normalizedRank === 2;
}
if (rank3Badge) {
rank3Badge.active = normalizedRank === 3;
}
if (rankNumberNode) {
rankNumberNode.active = normalizedRank !== 1 && normalizedRank !== 2 && normalizedRank !== 3;
this._setLabel(rankNumberNode.getComponent(Label), normalizedRank ? `${normalizedRank}` : '-');
}
}
private _findAvatarSprite(item: Node): Sprite | null {
const headNode = this._findChild(item, 'Head');
return headNode?.children[0]?.getComponent(Sprite) ?? headNode?.getComponent(Sprite) ?? null;
@@ -256,6 +390,18 @@ export class PagePKData extends BaseView {
this._hideCreatedItemTemplate();
}
private _clearParticipatedItems(): void {
for (const item of this._participatedItemNodes) {
if (item.isValid) {
item.removeFromParent();
item.destroy();
}
}
this._participatedItemNodes = [];
this._hideParticipatedItemTemplate();
}
private _unbindCreatedButtons(): void {
for (const binding of this._createdButtonBindings) {
if (binding.node.isValid) {
@@ -271,6 +417,12 @@ export class PagePKData extends BaseView {
}
}
private _hideParticipatedItemTemplate(): void {
if (this.participatedListItemTemplate?.isValid) {
this.participatedListItemTemplate.active = false;
}
}
private _setLabel(label: Label | null, text: string): void {
if (label) {
label.string = text;

View File

@@ -178,7 +178,7 @@ export class PagePKDetail extends BaseView {
return;
}
this._setLabel(this._findLabelIn(panel, 'UserName'), this._getParticipantName(champion) || '暂无参与');
this._setLabel(this._findLabelIn(panel, 'UserName'), this._getParticipantDisplayName(champion, '暂无参与'));
this._setLabel(this._findLabelIn(panel, 'RightInfo'), this._formatCorrectText(champion, shareInfo));
this._setLabel(this._findLabelIn(panel, 'UsedTime'), this._formatTimeText(champion, shareInfo));
this._loadAvatar(champion?.avatarUrl ?? '', this._findAvatarSprite(panel), version);
@@ -222,7 +222,7 @@ export class PagePKDetail extends BaseView {
this._setLabel(rankNumberNode.getComponent(Label), rank > 0 ? `${rank}` : '-');
}
this._setLabel(this._findLabelIn(item, 'UserName'), this._getParticipantName(participant) || '微信用户');
this._setLabel(this._findLabelIn(item, 'UserName'), this._getParticipantDisplayName(participant, '微信用户'));
this._setLabel(this._findLabelIn(item, 'RightInfo'), this._formatCorrectText(participant, null));
this._setLabel(this._findLabelIn(item, 'UsedTime'), this._formatTimeText(participant));
this._loadAvatar(participant.avatarUrl ?? '', this._findAvatarSprite(item), version);
@@ -312,13 +312,23 @@ export class PagePKDetail extends BaseView {
return participant?.nickname || participant?.nickName || '';
}
private _getParticipantDisplayName(
participant: ShareParticipantRankSummary | null,
emptyParticipantFallback: string,
): string {
if (!participant) {
return emptyParticipantFallback;
}
return this._getParticipantName(participant) || '微信用户';
}
private _loadAvatar(url: string, sprite: Sprite | null, version: number): void {
if (!sprite) {
return;
}
if (!url) {
sprite.spriteFrame = null;
return;
}

View File

@@ -19,6 +19,7 @@ export const API_ENDPOINTS = {
/** 分享相关 */
SHARE_CREATE: `${API_BASE}/share`,
SHARE_CREATED: `${API_BASE}/share/created`,
SHARE_PARTICIPATED: `${API_BASE}/share/participated`,
/** 用户信息 */
USER_INFO: `${API_BASE}/user/info`,
/** 用户所有已通关的关卡(成就墙 / 关卡回看) */

View File

@@ -194,6 +194,18 @@ export interface CreatedShareListData {
items: CreatedShareItem[];
}
/** 我参与的分享挑战条目 */
export interface ParticipatedShareItem {
title: string;
participantCount: number;
userRank: number | null;
}
/** 我参与的分享挑战列表响应 */
export interface ParticipatedShareListData {
items: ParticipatedShareItem[];
}
/** 分享挑战详情响应 */
export interface ShareDetailData {
id: string;

View File

@@ -9,6 +9,8 @@ import {
ShareLevelData,
CreatedShareItem,
CreatedShareListData,
ParticipatedShareItem,
ParticipatedShareListData,
ShareDetailData,
SubmitShareData,
SubmitShareLevel,
@@ -31,6 +33,7 @@ export class ShareManager {
private _shareTitle: string = '';
private _shareCode: string | null = null;
private _createdShares: CreatedShareItem[] = [];
private _participatedShares: ParticipatedShareItem[] = [];
/** 图片缓存URL -> SpriteFrame */
private _imageCache: Map<string, SpriteFrame> = new Map();
@@ -52,6 +55,10 @@ export class ShareManager {
return [...this._createdShares];
}
get participatedShares(): ParticipatedShareItem[] {
return [...this._participatedShares];
}
get shareCode(): string | null {
return this._shareCode;
}
@@ -158,6 +165,27 @@ export class ShareManager {
}
}
async fetchParticipatedShares(): Promise<ParticipatedShareItem[] | null> {
try {
const response = await HttpUtil.get<ApiEnvelope<ParticipatedShareListData>>(
API_ENDPOINTS.SHARE_PARTICIPATED,
API_TIMEOUT.DEFAULT,
);
if (!response.success || !response.data) {
console.error('[ShareManager] 获取我参与的挑战列表失败:', response.message);
return null;
}
this._participatedShares = response.data.items ?? [];
console.log(`[ShareManager] 获取我参与的挑战列表成功: ${this._participatedShares.length}`);
return this.participatedShares;
} catch (err) {
console.error('[ShareManager] 获取我参与的挑战列表异常:', err);
return null;
}
}
async fetchShareDetail(code: string): Promise<ShareDetailData | null> {
try {
const response = await HttpUtil.get<ApiEnvelope<ShareDetailData>>(