feat: 更新评分相关页面和API配置

- 更新环境配置文件
- 修改运动员和评分API
- 优化登录、评分详情、评分列表等页面
- 更新pages.json和vue.config.js配置

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
DevOps
2025-12-19 14:43:16 +08:00
parent 736aa08fba
commit 7620d9bf96
12 changed files with 346 additions and 52 deletions

View File

@@ -17,7 +17,11 @@ const ENV_CONFIG = {
dataMode: 'api',
// API基础路径dataMode为'api'时使用)
apiBaseURL: 'http://localhost:8123',
// uni.request 不支持 devServer proxy必须用完整地址
apiBaseURL: 'http://142.91.105.230:8123',
// 调试模式
debug: true,
// 请求超时时间(毫秒)
timeout: 30000,

7
postcss.config.js.bak Normal file
View File

@@ -0,0 +1,7 @@
const autoprefixer = require('autoprefixer')
module.exports = {
plugins: [
autoprefixer()
]
}

View File

@@ -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
})
}

View File

@@ -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,

View File

@@ -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
},
// 测试环境配置

View File

@@ -11,7 +11,9 @@
"path": "pages/score-list/score-list",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom"
"navigationStyle": "custom",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{

View File

@@ -120,6 +120,7 @@ export default {
// 保存用户信息到全局数据
getApp().globalData = {
token, // Token用于登录状态检查
userRole, // 'pub' 或 'admin'
matchCode: this.matchCode, // 比赛编码
inviteCode: this.inviteCode, // 邀请码重要用于后续API调用

View File

@@ -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()

View File

@@ -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()

View File

@@ -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

View File

@@ -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>

View File

@@ -20,10 +20,21 @@ module.exports = {
// 开发服务器配置
devServer: {
port: 8080,
host: '0.0.0.0',
open: true,
overlay: {
warnings: false,
errors: true
},
proxy: {
'/mini': {
target: 'http://localhost:8123',
changeOrigin: true
},
'/martial': {
target: 'http://localhost:8123',
changeOrigin: true
}
}
},