feat: 更新评分相关页面和API配置
- 更新环境配置文件 - 修改运动员和评分API - 优化登录、评分详情、评分列表等页面 - 更新pages.json和vue.config.js配置 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -24,9 +24,12 @@ import request from '@/utils/request.js'
|
||||
*/
|
||||
export function getMyAthletes(params) {
|
||||
return request({
|
||||
url: '/api/mini/athletes',
|
||||
url: '/mini/score/athletes',
|
||||
method: 'GET',
|
||||
params: params, // GET 请求使用 params
|
||||
params: {
|
||||
...params,
|
||||
refereeType: 2 // 普通裁判
|
||||
},
|
||||
showLoading: true
|
||||
})
|
||||
}
|
||||
@@ -44,9 +47,12 @@ export function getMyAthletes(params) {
|
||||
*/
|
||||
export function getAthletesForAdmin(params) {
|
||||
return request({
|
||||
url: '/api/mini/athletes/admin',
|
||||
url: '/mini/score/athletes',
|
||||
method: 'GET',
|
||||
params: params, // GET 请求使用 params
|
||||
params: {
|
||||
...params,
|
||||
refereeType: 1 // 裁判长
|
||||
},
|
||||
showLoading: true
|
||||
})
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import request from '@/utils/request.js'
|
||||
*/
|
||||
export function getDeductions(params) {
|
||||
return request({
|
||||
url: '/martial/deductionItem/list',
|
||||
url: '/blade-martial/deductionItem/list',
|
||||
method: 'GET',
|
||||
params: {
|
||||
...params,
|
||||
@@ -35,7 +35,7 @@ export function getDeductions(params) {
|
||||
*/
|
||||
export function submitScore(data) {
|
||||
return request({
|
||||
url: '/martial/score/submit',
|
||||
url: '/mini/score/submit',
|
||||
method: 'POST',
|
||||
data,
|
||||
showLoading: true,
|
||||
@@ -54,7 +54,7 @@ export function submitScore(data) {
|
||||
*/
|
||||
export function getScoreDetail(params) {
|
||||
return request({
|
||||
url: `/api/mini/score/detail/${params.athleteId}`,
|
||||
url: `/mini/score/detail/${params.athleteId}`,
|
||||
method: 'GET',
|
||||
showLoading: true
|
||||
})
|
||||
@@ -74,7 +74,7 @@ export function getScoreDetail(params) {
|
||||
*/
|
||||
export function modifyScore(data) {
|
||||
return request({
|
||||
url: '/api/mini/score/modify',
|
||||
url: '/mini/score/modify',
|
||||
method: 'PUT',
|
||||
data,
|
||||
showLoading: true,
|
||||
|
||||
@@ -17,11 +17,14 @@ const ENV_CONFIG = {
|
||||
dataMode: 'api',
|
||||
|
||||
// API基础路径(dataMode为'api'时使用)
|
||||
apiBaseURL: 'http://localhost:8123',
|
||||
// uni.request 不支持 devServer proxy,必须用完整地址
|
||||
apiBaseURL: 'http://142.91.105.230:8123',
|
||||
|
||||
// 请求超时时间(毫秒)
|
||||
timeout: 30000,
|
||||
|
||||
// 调试模式
|
||||
debug: true
|
||||
},
|
||||
|
||||
// 测试环境配置
|
||||
|
||||
@@ -11,7 +11,9 @@
|
||||
"path": "pages/score-list/score-list",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"navigationStyle": "custom"
|
||||
"navigationStyle": "custom",
|
||||
"enablePullDownRefresh": true,
|
||||
"onReachBottomDistance": 50
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -120,6 +120,7 @@ export default {
|
||||
|
||||
// 保存用户信息到全局数据
|
||||
getApp().globalData = {
|
||||
token, // Token(用于登录状态检查)
|
||||
userRole, // 'pub' 或 'admin'
|
||||
matchCode: this.matchCode, // 比赛编码
|
||||
inviteCode: this.inviteCode, // 邀请码(重要:用于后续API调用)
|
||||
|
||||
@@ -123,6 +123,50 @@ export default {
|
||||
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'
|
||||
})
|
||||
}, 1500)
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否是裁判长
|
||||
if (globalData.userRole !== 'admin') {
|
||||
console.warn('非裁判长用户,无权修改评分')
|
||||
uni.showToast({
|
||||
title: '无权限',
|
||||
icon: 'none',
|
||||
duration: 1500
|
||||
})
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1500)
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否有选手信息
|
||||
if (!globalData.currentAthlete || !globalData.currentAthlete.athleteId) {
|
||||
console.warn('没有选手信息,返回列表页')
|
||||
uni.showToast({
|
||||
title: '请选择选手',
|
||||
icon: 'none',
|
||||
duration: 1500
|
||||
})
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1500)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取当前选手信息(从 score-list-multi 页面传递)
|
||||
const currentAthlete = globalData.currentAthlete || {}
|
||||
|
||||
@@ -238,12 +282,11 @@ export default {
|
||||
|
||||
// 🔥 关键改动:使用 dataAdapter 修改评分
|
||||
// Mock模式:调用 mock/score.js 的 modifyScore 函数
|
||||
// API模式:调用 api/score.js 的 modifyScore 函数(PUT /api/mini/score/modify)
|
||||
// API模式:调用 api/score.js 的 modifyScore 函数(PUT /mini/score/modify)
|
||||
const response = await dataAdapter.getData('modifyScore', {
|
||||
athleteId: this.athleteInfo.athleteId,
|
||||
modifierId: this.modifierId,
|
||||
modifiedScore: this.currentScore,
|
||||
note: this.note
|
||||
newScore: this.currentScore,
|
||||
reason: this.note
|
||||
})
|
||||
|
||||
uni.hideLoading()
|
||||
|
||||
@@ -120,6 +120,36 @@ export default {
|
||||
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'
|
||||
})
|
||||
}, 1500)
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否有选手信息
|
||||
if (!globalData.currentAthlete || !globalData.currentAthlete.athleteId) {
|
||||
console.warn('没有选手信息,返回列表页')
|
||||
uni.showToast({
|
||||
title: '请选择选手',
|
||||
icon: 'none',
|
||||
duration: 1500
|
||||
})
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1500)
|
||||
return
|
||||
}
|
||||
|
||||
// 加载当前选手信息(从 score-list 页面传递)
|
||||
const currentAthlete = globalData.currentAthlete || {}
|
||||
this.player = {
|
||||
@@ -161,14 +191,22 @@ export default {
|
||||
try {
|
||||
// 🔥 关键改动:使用 dataAdapter 获取扣分项列表
|
||||
// Mock模式:调用 mock/score.js 的 getDeductions 函数
|
||||
// API模式:调用 api/score.js 的 getDeductions 函数(GET /martial/deductionItem/list)
|
||||
// API模式:调用 api/score.js 的 getDeductions 函数(GET /blade-martial/deductionItem/list)
|
||||
const response = await dataAdapter.getData('getDeductions', {
|
||||
projectId: this.projectId
|
||||
})
|
||||
|
||||
// 为每个扣分项添加 checked 状态
|
||||
this.deductions = (response.data || []).map(item => ({
|
||||
...item,
|
||||
// 获取返回数据(兼容分页和非分页格式)
|
||||
const responseData = response.data || {}
|
||||
const records = responseData.records || response.data || []
|
||||
|
||||
// 为每个扣分项添加 checked 状态,并映射字段名
|
||||
// 后端字段: id, itemName
|
||||
// 前端字段: deductionId, deductionName
|
||||
this.deductions = (Array.isArray(records) ? records : []).map(item => ({
|
||||
deductionId: item.deductionId || item.id,
|
||||
deductionName: item.deductionName || item.itemName,
|
||||
deductionPoint: item.deductionPoint || 0,
|
||||
checked: false
|
||||
}))
|
||||
|
||||
@@ -216,10 +254,10 @@ export default {
|
||||
return
|
||||
}
|
||||
|
||||
// 收集选中的扣分项ID
|
||||
// 收集选中的扣分项ID(转为数字类型,后端期望 List<Long>)
|
||||
const selectedDeductions = this.deductions
|
||||
.filter(item => item.checked)
|
||||
.map(item => item.deductionId)
|
||||
.map(item => Number(item.deductionId))
|
||||
|
||||
try {
|
||||
uni.showLoading({
|
||||
@@ -229,13 +267,19 @@ export default {
|
||||
|
||||
// 🔥 关键改动:使用 dataAdapter 提交评分
|
||||
// Mock模式:调用 mock/score.js 的 submitScore 函数
|
||||
// API模式:调用 api/score.js 的 submitScore 函数(POST /martial/score/submit)
|
||||
// API模式:调用 api/score.js 的 submitScore 函数(POST /mini/score/submit)
|
||||
const app = getApp()
|
||||
const globalData = app.globalData || {}
|
||||
const response = await dataAdapter.getData('submitScore', {
|
||||
athleteId: this.player.athleteId,
|
||||
judgeId: this.judgeId,
|
||||
athleteId: Number(this.player.athleteId),
|
||||
judgeId: Number(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,
|
||||
deductions: selectedDeductions,
|
||||
note: this.note
|
||||
note: this.note || ''
|
||||
})
|
||||
|
||||
uni.hideLoading()
|
||||
|
||||
@@ -116,6 +116,31 @@ export default {
|
||||
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'
|
||||
})
|
||||
}, 1500)
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否是裁判长
|
||||
if (globalData.userRole !== 'admin') {
|
||||
console.warn('非裁判长用户,跳转到普通评分页')
|
||||
uni.reLaunch({
|
||||
url: '/pages/score-list/score-list'
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 加载比赛信息
|
||||
this.matchInfo = {
|
||||
id: globalData.matchId,
|
||||
@@ -207,8 +232,11 @@ export default {
|
||||
|
||||
// 🔥 关键改动:使用 dataAdapter 获取选手列表(裁判长视图)
|
||||
// Mock模式:调用 mock/athlete.js 的 getAthletesForAdmin 函数
|
||||
// API模式:调用 api/athlete.js 的 getAthletesForAdmin 函数(GET /api/mini/athletes/admin)
|
||||
// API模式:调用 api/athlete.js 的 getAthletesForAdmin 函数(GET /mini/score/athletes)
|
||||
const app = getApp()
|
||||
const globalData = app.globalData || {}
|
||||
const response = await dataAdapter.getData('getAthletesForAdmin', {
|
||||
judgeId: globalData.judgeId,
|
||||
competitionId: this.competitionId,
|
||||
venueId: this.currentVenue,
|
||||
projectId: this.currentProject
|
||||
|
||||
@@ -73,6 +73,24 @@
|
||||
<view class="info-item">编号:{{ player.number }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载状态 -->
|
||||
<view class="loading-status" v-if="players.length > 0">
|
||||
<view v-if="isLoading" class="loading-more">
|
||||
<text>加载中...</text>
|
||||
</view>
|
||||
<view v-else-if="!hasMore" class="no-more">
|
||||
<text>— 没有更多了 —</text>
|
||||
</view>
|
||||
<view v-else class="load-more-tip">
|
||||
<text>上拉加载更多</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view class="empty-state" v-if="!isLoading && players.length === 0">
|
||||
<text class="empty-text">暂无选手数据</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
@@ -101,7 +119,15 @@ export default {
|
||||
currentProjectIndex: 0, // 当前选中的项目索引
|
||||
players: [],
|
||||
scoredCount: 0,
|
||||
totalCount: 0
|
||||
totalCount: 0,
|
||||
// 分页相关
|
||||
pagination: {
|
||||
current: 1, // 当前页码
|
||||
size: 10, // 每页条数
|
||||
total: 0 // 总条数
|
||||
},
|
||||
isLoading: false, // 是否正在加载
|
||||
hasMore: true // 是否还有更多数据
|
||||
}
|
||||
},
|
||||
|
||||
@@ -110,6 +136,22 @@ export default {
|
||||
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'
|
||||
})
|
||||
}, 1500)
|
||||
return
|
||||
}
|
||||
|
||||
// 加载比赛信息
|
||||
this.matchInfo = {
|
||||
name: globalData.matchName || '比赛名称',
|
||||
@@ -141,35 +183,69 @@ export default {
|
||||
})
|
||||
}
|
||||
|
||||
// 加载选手列表
|
||||
await this.loadPlayers()
|
||||
// 加载选手列表(第一页)
|
||||
await this.loadPlayers(true)
|
||||
},
|
||||
|
||||
// 下拉刷新
|
||||
async onPullDownRefresh() {
|
||||
if (config.debug) {
|
||||
console.log('下拉刷新')
|
||||
}
|
||||
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: {
|
||||
async loadPlayers() {
|
||||
try {
|
||||
uni.showLoading({
|
||||
title: '加载中...',
|
||||
mask: true
|
||||
})
|
||||
/**
|
||||
* 加载选手列表
|
||||
* @param {Boolean} refresh - 是否刷新(重置分页)
|
||||
*/
|
||||
async loadPlayers(refresh = false) {
|
||||
// 如果正在加载,直接返回
|
||||
if (this.isLoading) return
|
||||
|
||||
// 🔥 关键改动:使用 dataAdapter 获取选手列表
|
||||
// Mock模式:调用 mock/athlete.js 的 getMyAthletes 函数
|
||||
// API模式:调用 api/athlete.js 的 getMyAthletes 函数(GET /api/mini/athletes)
|
||||
try {
|
||||
this.isLoading = true
|
||||
|
||||
// 刷新时重置分页
|
||||
if (refresh) {
|
||||
this.pagination.current = 1
|
||||
this.hasMore = true
|
||||
}
|
||||
|
||||
// 首次加载显示loading
|
||||
if (refresh) {
|
||||
uni.showLoading({
|
||||
title: '加载中...',
|
||||
mask: true
|
||||
})
|
||||
}
|
||||
|
||||
// 构建请求参数
|
||||
// 优先使用 matchCode(比赛编码),这样后端可以根据邀请码关联查询
|
||||
const app = getApp()
|
||||
const globalData = app.globalData || {}
|
||||
|
||||
const params = {
|
||||
// 方案1:使用比赛编码(推荐,后端可以根据邀请码关联)
|
||||
// 比赛编码
|
||||
matchCode: globalData.matchCode,
|
||||
|
||||
// 方案2:使用具体的ID(作为备选)
|
||||
// 具体的ID
|
||||
judgeId: this.judgeId,
|
||||
venueId: this.venueInfo.id,
|
||||
projectId: this.projectInfo.id
|
||||
projectId: this.projectInfo.id,
|
||||
// 分页参数
|
||||
current: this.pagination.current,
|
||||
size: this.pagination.size
|
||||
}
|
||||
|
||||
// 移除无效参数
|
||||
@@ -186,21 +262,42 @@ export default {
|
||||
|
||||
const response = await dataAdapter.getData('getMyAthletes', params)
|
||||
|
||||
uni.hideLoading()
|
||||
if (refresh) {
|
||||
uni.hideLoading()
|
||||
}
|
||||
|
||||
// 保存选手列表
|
||||
this.players = response.data || []
|
||||
// 获取返回数据
|
||||
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.totalCount = this.players.length
|
||||
this.scoredCount = this.players.filter(p => p.scored).length
|
||||
|
||||
// 判断是否还有更多数据
|
||||
const loadedCount = this.players.length
|
||||
this.hasMore = loadedCount < total
|
||||
|
||||
// 调试信息
|
||||
if (config.debug) {
|
||||
console.log('选手列表加载成功:', {
|
||||
total: this.totalCount,
|
||||
scored: this.scoredCount,
|
||||
players: this.players
|
||||
page: this.pagination.current,
|
||||
size: this.pagination.size,
|
||||
total: total,
|
||||
loaded: loadedCount,
|
||||
hasMore: this.hasMore,
|
||||
scored: this.scoredCount
|
||||
})
|
||||
}
|
||||
|
||||
@@ -212,9 +309,29 @@ export default {
|
||||
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()
|
||||
@@ -265,8 +382,8 @@ export default {
|
||||
})
|
||||
}
|
||||
|
||||
// 重新加载选手列表
|
||||
await this.loadPlayers()
|
||||
// 重新加载选手列表(刷新)
|
||||
await this.loadPlayers(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -522,4 +639,32 @@ export default {
|
||||
color: #666666;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* 加载状态 */
|
||||
.loading-status {
|
||||
padding: 30rpx 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.loading-more,
|
||||
.no-more,
|
||||
.load-more-tip {
|
||||
font-size: 26rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.loading-more {
|
||||
color: #1B7C5E;
|
||||
}
|
||||
|
||||
/* 空状态 */
|
||||
.empty-state {
|
||||
padding: 100rpx 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user