From 47fc5544ca4119290c6e02daa8cd156778e56548 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=85=E6=88=BF?= Date: Fri, 26 Dec 2025 10:20:46 +0800 Subject: [PATCH] fix bugs --- .claude/settings.local.json | 15 +- api/competition.js | 23 + package-lock.json | 45 + package.json | 1 + pages/attachment-view/attachment-view.vue | 880 +++++++++++++++++ pages/event-detail/event-detail.vue | 23 +- pages/event-list/event-list.vue | 2 +- pages/home/home.vue | 2 +- pages/my-registration/my-registration.vue | 2 +- pages/schedule/schedule-example.vue | 2 +- src/api/competition.js | 23 + src/components/pdf-viewer/pdf-viewer.vue | 508 ++++++++++ src/pages.json | 16 + src/pages/attachment-view/attachment-view.vue | 903 ++++++++++++++++++ src/pages/event-detail/event-detail.vue | 23 +- src/pages/event-list/event-list.vue | 2 +- src/pages/event-photos/event-photos.vue | 43 + src/pages/home/home.vue | 2 +- src/pages/my-registration/my-registration.vue | 120 +-- src/pages/schedule/schedule-example.vue | 2 +- 20 files changed, 2559 insertions(+), 78 deletions(-) create mode 100644 pages/attachment-view/attachment-view.vue create mode 100644 src/components/pdf-viewer/pdf-viewer.vue create mode 100644 src/pages/attachment-view/attachment-view.vue create mode 100644 src/pages/event-photos/event-photos.vue diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 2aac387..575cafa 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -19,7 +19,20 @@ "Bash(\"D:\\Program Files\\mysql-8.0.32-winx64\\bin\\mysql.exe\" -h localhost -P 3306 -u root -p123456 -D martial_db -e \"SHOW TABLES;\")", "Bash(\"D:\\Program Files\\mysql-8.0.32-winx64\\bin\\mysql.exe\" -h localhost -P 3306 -u root -p123456 -D martial_db -e \"DESCRIBE athlete;\")", "Bash(tree:*)", - "Bash(find:*)" + "Bash(find:*)", + "Bash(\"D:\\\\Program Files\\\\mysql-8.0.32-winx64\\\\bin\\\\mysql.exe\" -h localhost -P 3306 -u root -p123456 -D martial_db -e \"SHOW TABLES LIKE ''%attachment%'';\")", + "Bash(\"D:\\\\Program Files\\\\mysql-8.0.32-winx64\\\\bin\\\\mysql.exe\" -h localhost -P 3306 -u root -p123456 -D martial_db -e \"DESCRIBE martial_competition_rules_attachment;\")", + "Bash(ls -la \"d:\\\\workspace\\\\31.比赛项目\\\\project\\\\martial-mini\\\\src\\\\pages\\\\attachment-view\"\" 2>/dev/null && ls -la \"d:workspace31.比赛项目projectmartial-minisrcpagesevent-photos\"\")", + "Bash(npm install:*)", + "Bash(npm uninstall:*)", + "Bash(\"D:\\\\Program Files\\\\mysql-8.0.32-winx64\\\\bin\\\\mysql.exe\" -h localhost -P 3306 -u root -p123456 -D martial_db -e \"SELECT id, name FROM martial_competition LIMIT 5;\")", + "Bash(\"D:\\\\Program Files\\\\mysql-8.0.32-winx64\\\\bin\\\\mysql.exe\" -h localhost -P 3306 -u root -p123456 -D martial_db -e \"DESCRIBE martial_competition;\")", + "Bash(\"D:\\\\Program Files\\\\mysql-8.0.32-winx64\\\\bin\\\\mysql.exe\" -h localhost -P 3306 -u root -p123456 -D martial_db -e \"SELECT id, competition_name, total_participants FROM martial_competition WHERE is_deleted = 0 LIMIT 5;\")", + "Bash(\"D:\\\\Program Files\\\\mysql-8.0.32-winx64\\\\bin\\\\mysql.exe\" -h localhost -P 3306 -u root -p123456 -D martial_db -e \"DESCRIBE martial_registration_order;\")", + "Bash(\"D:\\\\Program Files\\\\mysql-8.0.32-winx64\\\\bin\\\\mysql.exe\":*)", + "Bash(\"D:\\\\Program Files\\\\mysql-8.0.32-winx64\\\\bin\\\\mysql.exe\" -h localhost -P 3306 -u root -p123456 -D martial_db -e \"SELECT id, competition_name, total_participants FROM martial_competition WHERE id = 200;\")", + "Bash(\"D:\\\\Program Files\\\\mysql-8.0.32-winx64\\\\bin\\\\mysql.exe\" -h localhost -P 3306 -u root -p123456 -D martial_db -e \"SELECT competition_id, COUNT\\(*\\) as order_count, SUM\\(total_participants\\) as total_people, is_deleted FROM martial_registration_order WHERE competition_id = 200 GROUP BY competition_id, is_deleted;\")", + "Bash(\"D:\\\\Program Files\\\\mysql-8.0.32-winx64\\\\bin\\\\mysql.exe\" -h localhost -P 3306 -u root -p123456 -D martial_db -e \"SELECT id, competition_name, total_participants, is_deleted FROM martial_competition WHERE id = 200;\")" ], "deny": [], "ask": [] diff --git a/api/competition.js b/api/competition.js index 7c2433c..dc2a77e 100644 --- a/api/competition.js +++ b/api/competition.js @@ -61,5 +61,28 @@ export default { */ getCompetitionRules(competitionId) { return request.get('/martial/competition/rules', { competitionId }) + }, + + /** + * 获取赛事附件列表 + * @param {Object} params { competitionId, type } + * type: info-信息发布, rules-赛事规程, schedule-活动日程, + * results-成绩, medals-奖牌榜, photos-图片直播 + * @returns {Promise} + */ + getAttachments(params = {}) { + return request.get('/martial/competition/attachment/getByType', { + competitionId: params.competitionId, + attachmentType: params.type + }) + }, + + /** + * 获取赛事所有附件 + * @param {String|Number} competitionId 赛事ID + * @returns {Promise} + */ + getAllAttachments(competitionId) { + return request.get('/martial/competition/attachment/getByCompetition', { competitionId }) } } diff --git a/package-lock.json b/package-lock.json index 18944af..75466f2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "@dcloudio/uni-migration": "^2.0.2-4080720251210002", "cache-loader": "^4.1.0", "html-webpack-plugin": "^4.5.2", + "pdfjs-dist": "^2.16.105", "vue": "^2.6.14" }, "devDependencies": { @@ -76,6 +77,7 @@ "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", + "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -2854,6 +2856,7 @@ "resolved": "https://registry.npmjs.org/@vue/cli-service/-/cli-service-4.5.19.tgz", "integrity": "sha512-+Wpvj8fMTCt9ZPOLu5YaLkFCQmB4MrZ26aRmhhKiCQ/4PMoL6mLezfqdt6c+m2htM+1WV5RunRo+0WHl2DfwZA==", "dev": true, + "peer": true, "dependencies": { "@intervolga/optimize-cssnano-plugin": "^1.0.5", "@soda/friendly-errors-webpack-plugin": "^1.7.1", @@ -3514,6 +3517,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -4410,6 +4414,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -5329,6 +5334,7 @@ "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.2.tgz", "integrity": "sha512-Uh7crJAco3AjBvgAy9Z75CjK8IG+gxaErro71THQ+vv/bl4HaQcpkexAY8KVW/T6D2W2IRr+couF/knIRkZMIQ==", "dev": true, + "peer": true, "dependencies": { "cacache": "^12.0.3", "find-cache-dir": "^2.1.0", @@ -6425,6 +6431,13 @@ "url": "https://github.com/fb55/domhandler?sponsor=1" } }, + "node_modules/dommatrix": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dommatrix/-/dommatrix-1.0.3.tgz", + "integrity": "sha512-l32Xp/TLgWb8ReqbVJAFIvXmY7go4nTxxlWiAFyhoQw9RKEOHBZNnyGvJWqDVSPmq3Y9HlM4npqF/T6VMOXhww==", + "deprecated": "dommatrix is no longer maintained. Please use @thednp/dommatrix.", + "license": "MIT" + }, "node_modules/domutils": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", @@ -7369,6 +7382,7 @@ "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-4.3.0.tgz", "integrity": "sha512-aKrYPYjF1yG3oX0kWRrqrSMfgftm7oJW5M+m4owoldH5C51C0RkIwB++JbRvEW3IU6/ZG5n8UvEcdgwOt2UOWA==", "dev": true, + "peer": true, "dependencies": { "loader-utils": "^1.2.3", "schema-utils": "^2.5.0" @@ -8440,6 +8454,7 @@ "version": "4.5.2", "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.5.2.tgz", "integrity": "sha512-q5oYdzjKUIPQVjOosjgvCHQOv9Ett9CYYHlgvJeXG0qQvdSojnBq4vAdQBwn1+yGveAwHCoe/rMR86ozX3+c2A==", + "peer": true, "dependencies": { "@types/html-minifier-terser": "^5.0.0", "@types/tapable": "^1.0.5", @@ -11295,6 +11310,24 @@ } ] }, + "node_modules/pdfjs-dist": { + "version": "2.16.105", + "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.16.105.tgz", + "integrity": "sha512-J4dn41spsAwUxCpEoVf6GVoz908IAA3mYiLmNxg8J9kfRXc2jxpbUepcP0ocp0alVNLFthTAM8DZ1RaHh8sU0A==", + "license": "Apache-2.0", + "dependencies": { + "dommatrix": "^1.0.3", + "web-streams-polyfill": "^3.2.1" + }, + "peerDependencies": { + "worker-loader": "^3.0.8" + }, + "peerDependenciesMeta": { + "worker-loader": { + "optional": true + } + } + }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -11403,6 +11436,7 @@ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", "dev": true, + "peer": true, "dependencies": { "picocolors": "^0.2.1", "source-map": "^0.6.1" @@ -13029,6 +13063,7 @@ "resolved": "https://registry.npmjs.org/sass/-/sass-1.96.0.tgz", "integrity": "sha512-8u4xqqUeugGNCYwr9ARNtQKTOj4KmYiJAVKXf2CTIivTCR51j96htbMKWDru8H5SaQWpyVgTfOF8Ylyf5pun1Q==", "dev": true, + "peer": true, "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.0.2", @@ -16032,10 +16067,20 @@ "defaults": "^1.0.3" } }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, "node_modules/webpack": { "version": "4.47.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.47.0.tgz", "integrity": "sha512-td7fYwgLSrky3fI1EuU5cneU4+pbH6GgOfuKNS1tNPcfdGinGELAqsb/BP4nnvZyKSG2i/xFGU7+n2PvZA8HJQ==", + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.9.0", "@webassemblyjs/helper-module-context": "1.9.0", diff --git a/package.json b/package.json index 89effb3..54d58ad 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "@dcloudio/uni-migration": "^2.0.2-4080720251210002", "cache-loader": "^4.1.0", "html-webpack-plugin": "^4.5.2", + "pdfjs-dist": "^2.16.105", "vue": "^2.6.14" }, "devDependencies": { diff --git a/pages/attachment-view/attachment-view.vue b/pages/attachment-view/attachment-view.vue new file mode 100644 index 0000000..5bcd9c4 --- /dev/null +++ b/pages/attachment-view/attachment-view.vue @@ -0,0 +1,880 @@ + + + + + diff --git a/pages/event-detail/event-detail.vue b/pages/event-detail/event-detail.vue index b39c423..76db7a2 100644 --- a/pages/event-detail/event-detail.vue +++ b/pages/event-detail/event-detail.vue @@ -125,7 +125,7 @@ export default { res.registerTime || res.registrationPeriod || '待定', matchTime: this.formatTimeRange(startTime, endTime) || res.matchTime || res.competitionTime || '待定', - registerCount: res.registrationCount || res.registerCount || res.signUpCount || '0', + registerCount: res.registrationCount || res.registerCount || res.signUpCount || res.totalParticipants || '0', status: this.getStatus(res.status) } @@ -169,16 +169,23 @@ export default { }, handleFunction(type) { + // 需要跳转到附件展示页面的类型 + const attachmentTypes = ['info', 'rules', 'schedule', 'score', 'awards', 'photos'] + + if (attachmentTypes.includes(type)) { + // 跳转到通用附件展示页面 + const name = encodeURIComponent(this.eventInfo.title) + uni.navigateTo({ + url: `/pages/attachment-view/attachment-view?type=${type}&competitionId=${this.eventId}&name=${name}` + }) + return + } + + // 其他功能页面的路由映射 const routeMap = { - 'info': '/pages/event-info/event-info', - 'rules': '/pages/event-rules/event-rules', - 'schedule': '/pages/event-schedule/event-schedule', 'players': '/pages/event-players/event-players', 'match': '/pages/event-live/event-live', - 'lineup': '/pages/event-lineup/event-lineup', - 'score': '/pages/event-score/event-score', - 'awards': '/pages/event-medals/event-medals', - 'photos': '' // 图片直播暂未实现 + 'lineup': '/pages/event-lineup/event-lineup' }; const url = routeMap[type]; diff --git a/pages/event-list/event-list.vue b/pages/event-list/event-list.vue index d90e407..230a68a 100644 --- a/pages/event-list/event-list.vue +++ b/pages/event-list/event-list.vue @@ -228,7 +228,7 @@ export default { item.registerTime || item.registrationPeriod || '待定', matchTime: this.formatTimeRange(startTime, endTime) || item.matchTime || item.competitionTime || '待定', - registerCount: item.registrationCount || item.registerCount || item.signUpCount || '0', + registerCount: item.registrationCount || item.registerCount || item.signUpCount || item.totalParticipants || '0', status: this.getStatus(item.status) } }) diff --git a/pages/home/home.vue b/pages/home/home.vue index ed39682..3082e06 100644 --- a/pages/home/home.vue +++ b/pages/home/home.vue @@ -137,7 +137,7 @@ export default { item.registerTime || item.registrationPeriod || '待定', matchTime: this.formatTimeRange(startTime, endTime) || item.matchTime || item.competitionTime || '待定', - registerCount: item.registrationCount || item.registerCount || item.signUpCount || '0', + registerCount: item.registrationCount || item.registerCount || item.signUpCount || item.totalParticipants || '0', status: this.getStatus(item.status) } }) diff --git a/pages/my-registration/my-registration.vue b/pages/my-registration/my-registration.vue index 39d932d..1d79ec6 100644 --- a/pages/my-registration/my-registration.vue +++ b/pages/my-registration/my-registration.vue @@ -243,7 +243,7 @@ export default { matchTime: '', projects: '', contact: orderItem.contactPhone || '', - participants: `${orderItem.totalParticipants || 0}人` + participants: `${orderItem.registerCount || 0}人` } } }, diff --git a/pages/schedule/schedule-example.vue b/pages/schedule/schedule-example.vue index 334b70b..6d19c1c 100644 --- a/pages/schedule/schedule-example.vue +++ b/pages/schedule/schedule-example.vue @@ -16,7 +16,7 @@ 参赛人数: - {{ scheduleData.totalParticipants || 0 }} + {{ scheduleData.registerCount || 0 }} 最后编排时间: diff --git a/src/api/competition.js b/src/api/competition.js index 7c2433c..dc2a77e 100644 --- a/src/api/competition.js +++ b/src/api/competition.js @@ -61,5 +61,28 @@ export default { */ getCompetitionRules(competitionId) { return request.get('/martial/competition/rules', { competitionId }) + }, + + /** + * 获取赛事附件列表 + * @param {Object} params { competitionId, type } + * type: info-信息发布, rules-赛事规程, schedule-活动日程, + * results-成绩, medals-奖牌榜, photos-图片直播 + * @returns {Promise} + */ + getAttachments(params = {}) { + return request.get('/martial/competition/attachment/getByType', { + competitionId: params.competitionId, + attachmentType: params.type + }) + }, + + /** + * 获取赛事所有附件 + * @param {String|Number} competitionId 赛事ID + * @returns {Promise} + */ + getAllAttachments(competitionId) { + return request.get('/martial/competition/attachment/getByCompetition', { competitionId }) } } diff --git a/src/components/pdf-viewer/pdf-viewer.vue b/src/components/pdf-viewer/pdf-viewer.vue new file mode 100644 index 0000000..d0de97f --- /dev/null +++ b/src/components/pdf-viewer/pdf-viewer.vue @@ -0,0 +1,508 @@ + + + + + + + diff --git a/src/pages.json b/src/pages.json index 2ef98ea..757cf81 100644 --- a/src/pages.json +++ b/src/pages.json @@ -189,6 +189,22 @@ "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white" } + }, + { + "path": "pages/attachment-view/attachment-view", + "style": { + "navigationBarTitleText": "附件查看", + "navigationBarBackgroundColor": "#C93639", + "navigationBarTextStyle": "white" + } + }, + { + "path": "pages/event-photos/event-photos", + "style": { + "navigationBarTitleText": "图片直播", + "navigationBarBackgroundColor": "#C93639", + "navigationBarTextStyle": "white" + } } ], "globalStyle": { diff --git a/src/pages/attachment-view/attachment-view.vue b/src/pages/attachment-view/attachment-view.vue new file mode 100644 index 0000000..4c01623 --- /dev/null +++ b/src/pages/attachment-view/attachment-view.vue @@ -0,0 +1,903 @@ + + + + + diff --git a/src/pages/event-detail/event-detail.vue b/src/pages/event-detail/event-detail.vue index b39c423..76db7a2 100644 --- a/src/pages/event-detail/event-detail.vue +++ b/src/pages/event-detail/event-detail.vue @@ -125,7 +125,7 @@ export default { res.registerTime || res.registrationPeriod || '待定', matchTime: this.formatTimeRange(startTime, endTime) || res.matchTime || res.competitionTime || '待定', - registerCount: res.registrationCount || res.registerCount || res.signUpCount || '0', + registerCount: res.registrationCount || res.registerCount || res.signUpCount || res.totalParticipants || '0', status: this.getStatus(res.status) } @@ -169,16 +169,23 @@ export default { }, handleFunction(type) { + // 需要跳转到附件展示页面的类型 + const attachmentTypes = ['info', 'rules', 'schedule', 'score', 'awards', 'photos'] + + if (attachmentTypes.includes(type)) { + // 跳转到通用附件展示页面 + const name = encodeURIComponent(this.eventInfo.title) + uni.navigateTo({ + url: `/pages/attachment-view/attachment-view?type=${type}&competitionId=${this.eventId}&name=${name}` + }) + return + } + + // 其他功能页面的路由映射 const routeMap = { - 'info': '/pages/event-info/event-info', - 'rules': '/pages/event-rules/event-rules', - 'schedule': '/pages/event-schedule/event-schedule', 'players': '/pages/event-players/event-players', 'match': '/pages/event-live/event-live', - 'lineup': '/pages/event-lineup/event-lineup', - 'score': '/pages/event-score/event-score', - 'awards': '/pages/event-medals/event-medals', - 'photos': '' // 图片直播暂未实现 + 'lineup': '/pages/event-lineup/event-lineup' }; const url = routeMap[type]; diff --git a/src/pages/event-list/event-list.vue b/src/pages/event-list/event-list.vue index d90e407..230a68a 100644 --- a/src/pages/event-list/event-list.vue +++ b/src/pages/event-list/event-list.vue @@ -228,7 +228,7 @@ export default { item.registerTime || item.registrationPeriod || '待定', matchTime: this.formatTimeRange(startTime, endTime) || item.matchTime || item.competitionTime || '待定', - registerCount: item.registrationCount || item.registerCount || item.signUpCount || '0', + registerCount: item.registrationCount || item.registerCount || item.signUpCount || item.totalParticipants || '0', status: this.getStatus(item.status) } }) diff --git a/src/pages/event-photos/event-photos.vue b/src/pages/event-photos/event-photos.vue new file mode 100644 index 0000000..a8549dc --- /dev/null +++ b/src/pages/event-photos/event-photos.vue @@ -0,0 +1,43 @@ + + + + + diff --git a/src/pages/home/home.vue b/src/pages/home/home.vue index ed39682..3082e06 100644 --- a/src/pages/home/home.vue +++ b/src/pages/home/home.vue @@ -137,7 +137,7 @@ export default { item.registerTime || item.registrationPeriod || '待定', matchTime: this.formatTimeRange(startTime, endTime) || item.matchTime || item.competitionTime || '待定', - registerCount: item.registrationCount || item.registerCount || item.signUpCount || '0', + registerCount: item.registrationCount || item.registerCount || item.signUpCount || item.totalParticipants || '0', status: this.getStatus(item.status) } }) diff --git a/src/pages/my-registration/my-registration.vue b/src/pages/my-registration/my-registration.vue index 7512a3e..b07da32 100644 --- a/src/pages/my-registration/my-registration.vue +++ b/src/pages/my-registration/my-registration.vue @@ -131,8 +131,7 @@ export default { const res = await registrationAPI.getRegistrationList(params) - console.log('=== 我的报名列表 - 后端返回的原始数据 ===') - console.log('完整响应:', res) + console.log('=== 我的报名列表 ===', res) let list = [] let total = 0 @@ -146,18 +145,18 @@ export default { total = res.length } - // 为每条报名记录获取详情(包含关联数据) - const detailPromises = list.map(item => this.getRegistrationDetailData(item)) - const mappedList = await Promise.all(detailPromises) + // 优化:先收集所有不重复的赛事ID,批量获取赛事信息(使用缓存) + const competitionIds = [...new Set(list.map(item => item.competitionId).filter(Boolean))] + const competitionMap = await this.batchGetCompetitionInfo(competitionIds) - // 过滤掉获取失败的记录 - const validList = mappedList.filter(item => item !== null) + // 映射数据(不再单独请求赛事详情) + const mappedList = list.map(item => this.mapRegistrationItem(item, competitionMap)) // 刷新或加载更多 if (refresh || !loadMore) { - this.eventList = validList + this.eventList = mappedList } else { - this.eventList = [...this.eventList, ...validList] + this.eventList = [...this.eventList, ...mappedList] } // 判断是否还有更多数据 @@ -174,56 +173,69 @@ export default { }, /** - * 获取单条报名记录的详细信息 - * @param {Object} orderItem 订单基本信息 - * @returns {Promise} 包含完整信息的记录 + * 批量获取赛事信息(带缓存,避免重复请求) + * @param {Array} competitionIds 赛事ID数组 + * @returns {Promise} 赛事信息Map {id: info} */ - async getRegistrationDetailData(orderItem) { - try { - console.log('=== 获取报名详情 ===', orderItem.id) + async batchGetCompetitionInfo(competitionIds) { + const competitionMap = {} - // 获取报名详情 - const detail = await registrationAPI.getRegistrationDetail(orderItem.id) - console.log('报名详情:', detail) + // 初始化缓存 + if (!this.competitionCache) { + this.competitionCache = {} + } - // 获取赛事详情 - let competitionInfo = null - if (orderItem.competitionId || detail.competitionId) { - const competitionId = orderItem.competitionId || detail.competitionId - competitionInfo = await competitionAPI.getCompetitionDetail(competitionId) - console.log('赛事详情:', competitionInfo) - } + // 过滤出未缓存的赛事ID + const uncachedIds = competitionIds.filter(id => !this.competitionCache[id]) - // 构建映射数据 - const mapped = { - id: orderItem.id, - status: this.getStatus(orderItem.status), - title: competitionInfo?.name || detail.competitionName || '未知赛事', - location: competitionInfo?.location || competitionInfo?.address || detail.location || '', - matchTime: this.formatTimeRange( - competitionInfo?.startTime || detail.startTime, - competitionInfo?.endTime || detail.endTime - ) || '', - projects: detail.projectNames || this.formatProjects(detail.projects || detail.projectList) || '', - contact: orderItem.contactPhone || detail.contactPhone || '', - participants: detail.athleteNames || this.formatParticipants(detail.athletes || detail.athleteList) || '' - } + // 只请求未缓存的赛事(去重后通常只有1-2个) + if (uncachedIds.length > 0) { + console.log('需要请求的赛事ID(去重后):', uncachedIds) - console.log('映射后的数据:', mapped) - return mapped - } catch (err) { - console.error('获取报名详情失败:', err, orderItem.id) - // 返回基本信息,避免整个记录丢失 - return { - id: orderItem.id, - status: this.getStatus(orderItem.status), - title: '获取详情失败', - location: '', - matchTime: '', - projects: '', - contact: orderItem.contactPhone || '', - participants: `${orderItem.totalParticipants || 0}人` - } + // 并行请求所有未缓存的赛事详情 + const promises = uncachedIds.map(async (id) => { + try { + const info = await competitionAPI.getCompetitionDetail(id) + this.competitionCache[id] = info + } catch (err) { + console.error('获取赛事详情失败:', id, err) + this.competitionCache[id] = null + } + }) + + await Promise.all(promises) + } + + // 从缓存中获取所有赛事信息 + competitionIds.forEach(id => { + competitionMap[id] = this.competitionCache[id] || null + }) + + return competitionMap + }, + + /** + * 映射单条报名记录(使用已缓存的赛事信息) + * @param {Object} item 订单信息 + * @param {Object} competitionMap 赛事信息Map + * @returns {Object} 映射后的数据 + */ + mapRegistrationItem(item, competitionMap) { + const competitionInfo = competitionMap[item.competitionId] || {} + + return { + id: item.id, + competitionId: item.competitionId, + status: this.getStatus(item.status), + title: competitionInfo.competitionName || competitionInfo.name || item.competitionName || '未知赛事', + location: competitionInfo.location || competitionInfo.address || item.location || '', + matchTime: this.formatTimeRange( + competitionInfo.competitionStartTime || competitionInfo.startTime, + competitionInfo.competitionEndTime || competitionInfo.endTime + ) || '', + projects: item.projectNames || this.formatProjects(item.projects) || '', + contact: item.contactPhone || item.contactPerson || '', + participants: item.athleteNames || `${item.totalParticipants || 0}人` } }, diff --git a/src/pages/schedule/schedule-example.vue b/src/pages/schedule/schedule-example.vue index 334b70b..6d19c1c 100644 --- a/src/pages/schedule/schedule-example.vue +++ b/src/pages/schedule/schedule-example.vue @@ -16,7 +16,7 @@ 参赛人数: - {{ scheduleData.totalParticipants || 0 }} + {{ scheduleData.registerCount || 0 }} 最后编排时间: