diff --git a/src/pages/score-detail/score-detail.vue b/src/pages/score-detail/score-detail.vue index 7dbe092..a38714b 100644 --- a/src/pages/score-detail/score-detail.vue +++ b/src/pages/score-detail/score-detail.vue @@ -257,7 +257,7 @@ export default { // 收集选中的扣分项ID(转为数字类型,后端期望 List) const selectedDeductions = this.deductions .filter(item => item.checked) - .map(item => Number(item.deductionId)) + .map(item => String(item.deductionId)) try { uni.showLoading({ @@ -271,13 +271,13 @@ export default { const app = getApp() const globalData = app.globalData || {} const response = await dataAdapter.getData('submitScore', { - athleteId: Number(this.player.athleteId), - judgeId: Number(this.judgeId), + athleteId: String(this.player.athleteId), + judgeId: String(this.judgeId), score: this.currentScore, - projectId: Number(this.projectId), - competitionId: globalData.matchId ? Number(globalData.matchId) : null, - venueId: globalData.venueId ? Number(globalData.venueId) : null, - scheduleId: globalData.scheduleId ? Number(globalData.scheduleId) : null, + projectId: String(this.projectId), + competitionId: globalData.matchId ? String(globalData.matchId) : null, + venueId: globalData.venueId ? String(globalData.venueId) : null, + scheduleId: globalData.scheduleId ? String(globalData.scheduleId) : null, deductions: selectedDeductions, note: this.note || '' }) diff --git a/src/pages/score-list/score-list.vue b/src/pages/score-list/score-list.vue index 54a17cd..40d4506 100644 --- a/src/pages/score-list/score-list.vue +++ b/src/pages/score-list/score-list.vue @@ -4,87 +4,102 @@ 评分系统 - ··· - + ··· + {{ matchInfo.name }} - 比赛时间:{{ matchInfo.time }} + 比赛时间:{{ formatDateTime(matchInfo.time) }} - - + + + - {{ venueInfo.name }} + {{ venueInfo.name }} + 刷新 - - - {{ project.projectName }} - + + + + + + {{ project.projectName }} + + + - + - 已评分: - {{ scoredCount }}/{{ totalCount }} + 已评分: + {{ scoredCount }}/{{ totalCount }} - + - - {{ player.name }} - - - - 我的评分:{{ player.myScore }} - 总分:{{ player.totalScore }} + + - - - + + - - 身份证:{{ player.idCard }} - 队伍:{{ player.team }} - 编号:{{ player.number }} + + + + 身份证:{{ player.idCard }} + + + 队伍:{{ player.team }} + + + 编号:{{ player.number }} + - - 加载中... - - - — 没有更多了 — - - - 上拉加载更多 - + 加载中... + — 没有更多了 — @@ -115,236 +130,209 @@ export default { name: '' }, judgeId: '', - projects: [], // 所有分配的项目列表 - currentProjectIndex: 0, // 当前选中的项目索引 + projects: [], + currentProjectIndex: 0, players: [], scoredCount: 0, totalCount: 0, - // 分页相关 pagination: { - current: 1, // 当前页码 - size: 10, // 每页条数 - total: 0 // 总条数 + current: 1, + size: 10, + total: 0 }, - isLoading: false, // 是否正在加载 - hasMore: true // 是否还有更多数据 + isLoading: false, + hasMore: true, + isFirstLoad: true } }, async onLoad() { - // 获取全局数据 const app = getApp() const globalData = app.globalData || {} - // 检查登录状态 if (!globalData.judgeId || !globalData.token) { - console.warn('用户未登录,跳转到登录页') uni.showToast({ title: '请先登录', icon: 'none', duration: 1500 }) setTimeout(() => { - uni.reLaunch({ - url: '/pages/login/login' - }) + uni.reLaunch({ url: '/pages/login/login' }) }, 1500) return } - // 加载比赛信息 this.matchInfo = { name: globalData.matchName || '比赛名称', - time: globalData.matchTime || '比赛时间' + time: globalData.matchTime || '' } - // 加载场地信息 this.venueInfo = { id: globalData.venueId, - name: globalData.venueName || '场地' + name: globalData.venueName || '第一场地' } - // 加载项目列表 this.projects = globalData.projects || [] this.currentProjectIndex = globalData.currentProjectIndex || 0 - - // 设置当前项目信息 this.updateCurrentProject() - this.judgeId = globalData.judgeId - // 调试信息 if (config.debug) { console.log('评分列表页加载:', { judgeId: this.judgeId, venueId: this.venueInfo.id, - projectId: this.projectInfo.id, - projectsCount: this.projects.length + projectId: this.projectInfo.id }) } - // 加载选手列表(第一页) await this.loadPlayers(true) + this.isFirstLoad = false }, - // 下拉刷新 - async onPullDownRefresh() { - if (config.debug) { - console.log('下拉刷新') + async onShow() { + // 从评分详情页返回时刷新数据 + if (!this.isFirstLoad) { + if (config.debug) { + console.log('页面显示,刷新数据') + } + await this.loadPlayers(true) } + }, + + async onPullDownRefresh() { await this.loadPlayers(true) uni.stopPullDownRefresh() }, - // 上拉加载更多 async onReachBottom() { - if (config.debug) { - console.log('上拉加载更多, hasMore:', this.hasMore, 'isLoading:', this.isLoading) - } if (this.hasMore && !this.isLoading) { await this.loadMore() } }, methods: { - /** - * 加载选手列表 - * @param {Boolean} refresh - 是否刷新(重置分页) - */ - async loadPlayers(refresh = false) { - // 如果正在加载,直接返回 - if (this.isLoading) return + formatDateTime(dateTimeStr) { + if (!dateTimeStr) return '' + try { + const date = new Date(dateTimeStr) + if (isNaN(date.getTime())) return dateTimeStr + const year = date.getFullYear() + const month = date.getMonth() + 1 + const day = date.getDate() + const hours = date.getHours() + const minutes = date.getMinutes() + const paddedMinutes = minutes < 10 ? '0' + minutes : minutes + return year + '年' + month + '月' + day + '日 ' + hours + ':' + paddedMinutes + } catch (error) { + return dateTimeStr + } + }, + formatScore(score) { + // 处理 null、undefined、-1 等无效值 + if (score === null || score === undefined || score === -1 || score === '-1') { + return '--' + } + // 如果是字符串类型的数字,直接返回 + if (typeof score === 'string' && !isNaN(parseFloat(score))) { + return score + } + // 如果是数字类型,保留3位小数 + if (typeof score === 'number') { + return score.toFixed(3) + } + return score + }, + + async handleRefresh() { + if (this.isLoading) return + uni.showToast({ title: '刷新中...', icon: 'loading', duration: 1000 }) + await this.loadPlayers(true) + uni.showToast({ title: '刷新成功', icon: 'success', duration: 1000 }) + }, + + async loadPlayers(refresh = false) { + if (this.isLoading) return try { this.isLoading = true - - // 刷新时重置分页 if (refresh) { this.pagination.current = 1 this.hasMore = true } - - // 首次加载显示loading - if (refresh) { - uni.showLoading({ - title: '加载中...', - mask: true - }) + if (refresh && this.isFirstLoad) { + uni.showLoading({ title: '加载中...', mask: true }) } - - // 构建请求参数 const app = getApp() const globalData = app.globalData || {} - const params = { - // 比赛编码 matchCode: globalData.matchCode, - // 具体的ID judgeId: this.judgeId, venueId: this.venueInfo.id, projectId: this.projectInfo.id, - // 分页参数 current: this.pagination.current, size: this.pagination.size } - - // 移除无效参数 Object.keys(params).forEach(key => { if (params[key] === undefined || params[key] === null || params[key] === '') { delete params[key] } }) - // 调试信息 if (config.debug) { - console.log('请求运动员列表参数:', params) + console.log('请求选手列表参数:', params) } const response = await dataAdapter.getData('getMyAthletes', params) - if (refresh) { - uni.hideLoading() + if (config.debug) { + console.log('选手列表响应:', response) } - // 获取返回数据 + if (refresh && this.isFirstLoad) { + uni.hideLoading() + } const responseData = response.data || {} const records = responseData.records || response.data || [] const total = responseData.total || records.length - - // 更新分页信息 this.pagination.total = total this.totalCount = total - - // 刷新时替换数据,否则追加数据 if (refresh) { this.players = records } else { this.players = [...this.players, ...records] } - - // 计算评分统计 this.scoredCount = this.players.filter(p => p.scored).length + this.hasMore = this.players.length < total - // 判断是否还有更多数据 - const loadedCount = this.players.length - this.hasMore = loadedCount < total - - // 调试信息 if (config.debug) { - console.log('选手列表加载成功:', { - page: this.pagination.current, - size: this.pagination.size, + console.log('选手列表处理结果:', { total: total, - loaded: loadedCount, - hasMore: this.hasMore, - scored: this.scoredCount + loaded: this.players.length, + scored: this.scoredCount, + players: this.players }) } - } catch (error) { uni.hideLoading() console.error('加载选手列表失败:', error) - - uni.showToast({ - title: error.message || '加载失败', - icon: 'none' - }) + uni.showToast({ title: error.message || '加载失败', icon: 'none' }) } finally { this.isLoading = false } }, - /** - * 加载更多 - */ async loadMore() { if (!this.hasMore || this.isLoading) return - - // 页码+1 this.pagination.current++ - - // 调试信息 - if (config.debug) { - console.log('加载更多, 页码:', this.pagination.current) - } - - // 加载下一页 await this.loadPlayers(false) }, goToScoreDetail(player) { - // 保存当前选手信息到全局数据 const app = getApp() app.globalData.currentAthlete = player - - uni.navigateTo({ - url: '/pages/score-detail/score-detail' - }) + uni.navigateTo({ url: '/pages/score-detail/score-detail' }) }, - /** - * 更新当前项目信息 - */ updateCurrentProject() { const currentProject = this.projects[this.currentProjectIndex] || {} this.projectInfo = { @@ -353,36 +341,12 @@ export default { } }, - /** - * 切换项目 - * @param {Number} index - 项目索引 - */ async switchProject(index) { - // 如果点击的是当前项目,不做处理 - if (index === this.currentProjectIndex) { - return - } - - // 更新当前项目索引 + if (index === this.currentProjectIndex) return this.currentProjectIndex = index - - // 更新全局数据中的项目索引 const app = getApp() app.globalData.currentProjectIndex = index - - // 更新当前项目信息 this.updateCurrentProject() - - // 调试信息 - if (config.debug) { - console.log('切换项目:', { - index: index, - projectId: this.projectInfo.id, - projectName: this.projectInfo.name - }) - } - - // 重新加载选手列表(刷新) await this.loadPlayers(true) } } @@ -396,7 +360,7 @@ export default { padding-bottom: 40rpx; } -/* 导航栏 */ +/* ==================== 导航栏 ==================== */ .nav-bar { height: 90rpx; background: linear-gradient(135deg, #1B7C5E 0%, #2A9D7E 100%); @@ -411,7 +375,6 @@ export default { font-size: 36rpx; font-weight: 600; color: #FFFFFF; - letter-spacing: 2rpx; } .nav-right { @@ -419,24 +382,15 @@ export default { right: 30rpx; display: flex; align-items: center; - gap: 30rpx; + gap: 20rpx; } -.icon-menu, -.icon-close { - width: 60rpx; - height: 60rpx; - background-color: rgba(255, 255, 255, 0.25); - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; +.nav-dots, .nav-circle { font-size: 32rpx; color: #FFFFFF; - font-weight: bold; } -/* 比赛信息 */ +/* ==================== 比赛信息 ==================== */ .match-info { padding: 30rpx; background-color: #F5F5F5; @@ -445,121 +399,94 @@ export default { .match-title { font-size: 32rpx; font-weight: 600; - color: #333333; - line-height: 1.6; - margin-bottom: 10rpx; -} - -.tip-text { - font-size: 24rpx; - color: #FF4D6A; - margin-bottom: 10rpx; + color: #1B7C5E; + line-height: 1.5; + margin-bottom: 8rpx; } .match-time { font-size: 28rpx; - color: #666666; + color: #333333; } -/* 场地和项目区域 */ -.venue-section { +/* ==================== 场地卡片 ==================== */ +.venue-card { + margin: 0 30rpx 20rpx; background-color: #FFFFFF; - margin: 20rpx 30rpx; border-radius: 16rpx; padding: 30rpx; - box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08); + box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06); } .venue-header { display: flex; align-items: center; justify-content: space-between; - margin-bottom: 30rpx; - padding-bottom: 20rpx; + padding-bottom: 24rpx; border-bottom: 4rpx solid #1B7C5E; + margin-bottom: 24rpx; } -.venue-tab { +.venue-name { font-size: 32rpx; font-weight: 600; color: #333333; - position: relative; } -.venue-tab.active::after { - content: ''; - position: absolute; - bottom: -24rpx; - left: 0; - right: 0; - height: 4rpx; - background-color: #1B7C5E; +.refresh-link { + font-size: 26rpx; + color: #4A90D9; } -.refresh-hint { - font-size: 24rpx; - color: #FF4D6A; -} - -.project-section { +.project-row { display: flex; - align-items: center; - flex-wrap: wrap; + flex-direction: column; +} + +.project-scroll { + white-space: nowrap; +} + +.project-chips { + display: inline-flex; gap: 20rpx; } -.project-btn { - padding: 20rpx 40rpx; - background-color: #FFFFFF; +.project-chip { + display: inline-block; + padding: 16rpx 32rpx; border: 2rpx solid #1B7C5E; border-radius: 8rpx; font-size: 28rpx; color: #1B7C5E; - font-weight: 500; - cursor: pointer; - transition: all 0.3s ease; + background-color: #FFFFFF; } -.project-btn:active { - opacity: 0.7; -} - -.project-btn.active { +.project-chip.active { background-color: #1B7C5E; color: #FFFFFF; } -.project-tip { - font-size: 22rpx; - color: #FF4D6A; - flex: 1; - margin-left: 20rpx; - line-height: 1.5; -} - -/* 评分统计 */ +/* ==================== 评分统计 ==================== */ .score-stats { padding: 20rpx 30rpx; + display: flex; + align-items: center; +} + +.stats-label { font-size: 28rpx; color: #333333; } -.stats-text { - color: #666666; -} - -.stats-number { +.stats-value { + font-size: 32rpx; color: #1B7C5E; font-weight: 600; + margin-left: 8rpx; } -.warning-tip { - padding: 0 30rpx 20rpx; - font-size: 24rpx; - color: #FF4D6A; -} - -/* 选手列表 */ +/* ==================== 选手卡片 ==================== */ .player-list { padding: 0 30rpx; } @@ -567,14 +494,14 @@ export default { .player-card { background-color: #FFFFFF; border-radius: 16rpx; - padding: 30rpx; + padding: 24rpx; margin-bottom: 20rpx; - box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08); + box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06); } -.player-header { +.card-header { display: flex; - align-items: center; + align-items: flex-start; justify-content: space-between; margin-bottom: 20rpx; } @@ -585,34 +512,36 @@ export default { color: #333333; } -.player-scores { +/* ==================== 已评分标签 ==================== */ +.score-tags { display: flex; - flex-direction: column; - align-items: flex-end; - gap: 8rpx; + gap: 16rpx; } -.my-score { - font-size: 26rpx; +.score-tag { + display: flex; + align-items: center; + padding: 12rpx 20rpx; + background-color: #F5F5F5; + border-radius: 8rpx; + border: 2rpx solid #E5E5E5; +} + +.tag-label { + font-size: 24rpx; color: #666666; } -.total-score { - font-size: 26rpx; +.tag-value { + font-size: 28rpx; color: #333333; - font-weight: 600; + font-weight: 500; } -.action-area { +/* ==================== 未评分操作 ==================== */ +.action-row { display: flex; - flex-direction: column; - align-items: flex-end; - gap: 8rpx; -} - -.chief-hint { - font-size: 24rpx; - color: #FF4D6A; + align-items: center; } .score-btn { @@ -622,42 +551,43 @@ export default { font-size: 28rpx; color: #FFFFFF; font-weight: 500; + border: none; + line-height: 1.4; } -.score-btn:active { - opacity: 0.9; -} - -.player-info { +/* ==================== 选手详情 ==================== */ +.player-details { display: flex; flex-direction: column; - gap: 12rpx; + gap: 8rpx; } -.info-item { +.detail-row { + line-height: 1.6; +} + +.detail-text { font-size: 26rpx; color: #666666; - line-height: 1.5; } -/* 加载状态 */ +/* ==================== 加载状态 ==================== */ .loading-status { padding: 30rpx 0; text-align: center; } -.loading-more, -.no-more, -.load-more-tip { +.loading-text { + font-size: 26rpx; + color: #1B7C5E; +} + +.no-more-text { font-size: 26rpx; color: #999999; } -.loading-more { - color: #1B7C5E; -} - -/* 空状态 */ +/* ==================== 空状态 ==================== */ .empty-state { padding: 100rpx 0; text-align: center;