diff --git a/pages/score-detail/score-detail.vue b/pages/score-detail/score-detail.vue
index 50da31c..d4aa58c 100644
--- a/pages/score-detail/score-detail.vue
+++ b/pages/score-detail/score-detail.vue
@@ -31,28 +31,22 @@
-
-
-
+
{{ currentScore.toFixed(3) }}
+ 点击编辑
+
-
-
-
@@ -82,12 +76,35 @@
v-model="note"
maxlength="200"
/>
-
+
+
+
+
+
+
+
+ 分数范围:{{ minScore }} - {{ maxScore }},保留3位小数
+
+
+
+
@@ -113,16 +130,16 @@ export default {
note: '',
minScore: 5.0,
maxScore: 10.0,
- deductions: []
+ deductions: [],
+ showInputModal: false,
+ inputScore: ''
}
},
async onLoad() {
- // 获取全局数据
const app = getApp()
const globalData = app.globalData || {}
- // 加载当前选手信息(从 score-list 页面传递)
const currentAthlete = globalData.currentAthlete || {}
this.player = {
athleteId: currentAthlete.athleteId || '',
@@ -132,18 +149,15 @@ export default {
number: currentAthlete.number || ''
}
- // 如果选手已评分,加载其原有评分
if (currentAthlete.scored && currentAthlete.myScore) {
this.currentScore = currentAthlete.myScore
}
- // 加载评委ID和项目ID
this.judgeId = globalData.judgeId
this.projectId = globalData.currentProjectId || ''
this.competitionId = globalData.matchId || globalData.matchCode || ''
this.venueId = globalData.currentVenueId || globalData.venueId || ''
- // 调试信息
if (config.debug) {
console.log('评分详情页加载:', {
athlete: this.player,
@@ -155,22 +169,17 @@ export default {
})
}
- // 加载扣分项列表
await this.loadDeductions()
},
methods: {
async loadDeductions() {
try {
- // 🔥 关键改动:使用 dataAdapter 获取扣分项列表
- // Mock模式:调用 mock/score.js 的 getDeductions 函数
- // API模式:调用 api/score.js 的 getDeductions 函数(GET /martial/deductionItem/list)
const response = await dataAdapter.getData('getDeductions', {
projectId: this.projectId
})
- // 为每个扣分项添加 checked 状态,并映射字段名
- const records = response.data?.records || []
+ const records = response.data && response.data.records ? response.data.records : []
this.deductions = records.map(item => ({
deductionId: item.id,
deductionName: item.itemName,
@@ -178,7 +187,6 @@ export default {
checked: false
}))
- // 调试信息
if (config.debug) {
console.log('扣分项加载成功:', this.deductions)
}
@@ -201,7 +209,6 @@ export default {
delta: 1,
fail: (err) => {
console.error('返回失败:', err)
- // 如果返回失败,尝试跳转到评分列表页
uni.redirectTo({
url: '/pages/score-list/score-list'
})
@@ -221,12 +228,44 @@ export default {
}
},
+ showScoreInput() {
+ this.inputScore = this.currentScore.toFixed(3)
+ this.showInputModal = true
+ },
+
+ hideScoreInput() {
+ this.showInputModal = false
+ this.inputScore = ''
+ },
+
+ confirmScoreInput() {
+ const score = parseFloat(this.inputScore)
+
+ if (isNaN(score)) {
+ uni.showToast({
+ title: '请输入有效的数字',
+ icon: 'none'
+ })
+ return
+ }
+
+ if (score < this.minScore || score > this.maxScore) {
+ uni.showToast({
+ title: `分数必须在${this.minScore}-${this.maxScore}之间`,
+ icon: 'none'
+ })
+ return
+ }
+
+ this.currentScore = parseFloat(score.toFixed(3))
+ this.hideScoreInput()
+ },
+
toggleDeduction(index) {
this.deductions[index].checked = !this.deductions[index].checked
},
async handleSubmit() {
- // 验证评分范围
if (this.currentScore < this.minScore || this.currentScore > this.maxScore) {
uni.showToast({
title: `评分必须在${this.minScore}-${this.maxScore}分之间`,
@@ -235,7 +274,6 @@ export default {
return
}
- // 验证必需字段
if (!this.competitionId) {
uni.showToast({
title: '缺少比赛ID,请重新登录',
@@ -252,7 +290,6 @@ export default {
return
}
- // 收集选中的扣分项ID
const selectedDeductions = this.deductions
.filter(item => item.checked)
.map(item => item.deductionId)
@@ -263,7 +300,6 @@ export default {
mask: true
})
- // 准备提交数据
const submitData = {
athleteId: this.player.athleteId,
judgeId: this.judgeId,
@@ -275,19 +311,14 @@ export default {
note: this.note
}
- // 调试日志:打印提交数据
if (config.debug) {
console.log('准备提交评分数据:', submitData)
}
- // 🔥 关键改动:使用 dataAdapter 提交评分
- // Mock模式:调用 mock/score.js 的 submitScore 函数
- // API模式:调用 api/score.js 的 submitScore 函数(POST /martial/score/submit)
const response = await dataAdapter.getData('submitScore', submitData)
uni.hideLoading()
- // 调试信息
if (config.debug) {
console.log('评分提交成功:', {
athleteId: this.player.athleteId,
@@ -297,14 +328,12 @@ export default {
})
}
- // 显示成功提示
uni.showToast({
title: '提交成功',
icon: 'success',
duration: 1500
})
- // 返回上一页
setTimeout(() => {
uni.navigateBack()
}, 1500)
@@ -485,6 +514,14 @@ export default {
display: flex;
flex-direction: column;
align-items: center;
+ cursor: pointer;
+ padding: 20rpx;
+ border-radius: 16rpx;
+ transition: background-color 0.2s;
+}
+
+.score-display:active {
+ background-color: rgba(27, 124, 94, 0.1);
}
.current-score {
@@ -493,6 +530,12 @@ export default {
color: #1B7C5E;
}
+.edit-hint {
+ font-size: 22rpx;
+ color: #999999;
+ margin-top: 8rpx;
+}
+
.judge-tip {
padding: 0 30rpx;
font-size: 24rpx;
@@ -628,4 +671,95 @@ export default {
.submit-btn:active {
opacity: 0.9;
}
+
+/* 分数输入弹窗 */
+.modal-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.5);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 1000;
+}
+
+.modal-content {
+ width: 600rpx;
+ background-color: #FFFFFF;
+ border-radius: 24rpx;
+ overflow: hidden;
+}
+
+.modal-header {
+ padding: 40rpx 30rpx 20rpx;
+ text-align: center;
+}
+
+.modal-title {
+ font-size: 34rpx;
+ font-weight: 600;
+ color: #333333;
+}
+
+.modal-body {
+ padding: 20rpx 30rpx 30rpx;
+}
+
+.score-input {
+ width: 100%;
+ height: 90rpx;
+ border: 2rpx solid #E0E0E0;
+ border-radius: 12rpx;
+ padding: 0 24rpx;
+ font-size: 36rpx;
+ text-align: center;
+ color: #1B7C5E;
+ font-weight: 600;
+}
+
+.score-input:focus {
+ border-color: #1B7C5E;
+}
+
+.input-hint {
+ display: block;
+ margin-top: 16rpx;
+ font-size: 24rpx;
+ color: #999999;
+ text-align: center;
+}
+
+.modal-footer {
+ display: flex;
+ border-top: 1rpx solid #E0E0E0;
+}
+
+.modal-btn {
+ flex: 1;
+ height: 100rpx;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 32rpx;
+ background: none;
+ border: none;
+ border-radius: 0;
+}
+
+.modal-btn.cancel {
+ color: #666666;
+ border-right: 1rpx solid #E0E0E0;
+}
+
+.modal-btn.confirm {
+ color: #1B7C5E;
+ font-weight: 600;
+}
+
+.modal-btn:active {
+ background-color: #F5F5F5;
+}
diff --git a/src/pages/score-detail/score-detail.vue b/src/pages/score-detail/score-detail.vue
index a38714b..d4aa58c 100644
--- a/src/pages/score-detail/score-detail.vue
+++ b/src/pages/score-detail/score-detail.vue
@@ -31,28 +31,22 @@
-
-
-
+
{{ currentScore.toFixed(3) }}
+ 点击编辑
+
-
-
-
@@ -82,12 +76,35 @@
v-model="note"
maxlength="200"
/>
-
+
+
+
+
+
+
+
+ 分数范围:{{ minScore }} - {{ maxScore }},保留3位小数
+
+
+
+
@@ -107,50 +124,22 @@ export default {
},
judgeId: '',
projectId: '',
+ competitionId: '',
+ venueId: '',
currentScore: 8.000,
note: '',
minScore: 5.0,
maxScore: 10.0,
- deductions: []
+ deductions: [],
+ showInputModal: false,
+ inputScore: ''
}
},
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'
- })
- }, 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 = {
athleteId: currentAthlete.athleteId || '',
@@ -160,57 +149,44 @@ export default {
number: currentAthlete.number || ''
}
- // 如果选手已评分,加载其原有评分
if (currentAthlete.scored && currentAthlete.myScore) {
this.currentScore = currentAthlete.myScore
}
- // 加载评委ID和项目ID
this.judgeId = globalData.judgeId
- const projects = globalData.projects || []
- const currentIndex = globalData.currentProjectIndex || 0
- const currentProject = projects[currentIndex] || {}
- this.projectId = currentProject.projectId
+ this.projectId = globalData.currentProjectId || ''
+ this.competitionId = globalData.matchId || globalData.matchCode || ''
+ this.venueId = globalData.currentVenueId || globalData.venueId || ''
- // 调试信息
if (config.debug) {
console.log('评分详情页加载:', {
athlete: this.player,
judgeId: this.judgeId,
projectId: this.projectId,
+ competitionId: this.competitionId,
+ venueId: this.venueId,
initialScore: this.currentScore
})
}
- // 加载扣分项列表
await this.loadDeductions()
},
methods: {
async loadDeductions() {
try {
- // 🔥 关键改动:使用 dataAdapter 获取扣分项列表
- // Mock模式:调用 mock/score.js 的 getDeductions 函数
- // API模式:调用 api/score.js 的 getDeductions 函数(GET /blade-martial/deductionItem/list)
const response = await dataAdapter.getData('getDeductions', {
projectId: this.projectId
})
- // 获取返回数据(兼容分页和非分页格式)
- 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,
+ const records = response.data && response.data.records ? response.data.records : []
+ this.deductions = records.map(item => ({
+ deductionId: item.id,
+ deductionName: item.itemName,
+ deductionScore: parseFloat(item.deductionPoint || 0),
checked: false
}))
- // 调试信息
if (config.debug) {
console.log('扣分项加载成功:', this.deductions)
}
@@ -225,7 +201,19 @@ export default {
},
goBack() {
- uni.navigateBack()
+ if (config.debug) {
+ console.log('返回上一页')
+ }
+
+ uni.navigateBack({
+ delta: 1,
+ fail: (err) => {
+ console.error('返回失败:', err)
+ uni.redirectTo({
+ url: '/pages/score-list/score-list'
+ })
+ }
+ })
},
decreaseScore() {
@@ -240,12 +228,44 @@ export default {
}
},
+ showScoreInput() {
+ this.inputScore = this.currentScore.toFixed(3)
+ this.showInputModal = true
+ },
+
+ hideScoreInput() {
+ this.showInputModal = false
+ this.inputScore = ''
+ },
+
+ confirmScoreInput() {
+ const score = parseFloat(this.inputScore)
+
+ if (isNaN(score)) {
+ uni.showToast({
+ title: '请输入有效的数字',
+ icon: 'none'
+ })
+ return
+ }
+
+ if (score < this.minScore || score > this.maxScore) {
+ uni.showToast({
+ title: `分数必须在${this.minScore}-${this.maxScore}之间`,
+ icon: 'none'
+ })
+ return
+ }
+
+ this.currentScore = parseFloat(score.toFixed(3))
+ this.hideScoreInput()
+ },
+
toggleDeduction(index) {
this.deductions[index].checked = !this.deductions[index].checked
},
async handleSubmit() {
- // 验证评分范围
if (this.currentScore < this.minScore || this.currentScore > this.maxScore) {
uni.showToast({
title: `评分必须在${this.minScore}-${this.maxScore}分之间`,
@@ -254,10 +274,25 @@ export default {
return
}
- // 收集选中的扣分项ID(转为数字类型,后端期望 List)
+ if (!this.competitionId) {
+ uni.showToast({
+ title: '缺少比赛ID,请重新登录',
+ icon: 'none'
+ })
+ return
+ }
+
+ if (!this.projectId) {
+ uni.showToast({
+ title: '缺少项目ID,请返回重新选择',
+ icon: 'none'
+ })
+ return
+ }
+
const selectedDeductions = this.deductions
.filter(item => item.checked)
- .map(item => String(item.deductionId))
+ .map(item => item.deductionId)
try {
uni.showLoading({
@@ -265,26 +300,25 @@ export default {
mask: true
})
- // 🔥 关键改动:使用 dataAdapter 提交评分
- // Mock模式:调用 mock/score.js 的 submitScore 函数
- // API模式:调用 api/score.js 的 submitScore 函数(POST /mini/score/submit)
- const app = getApp()
- const globalData = app.globalData || {}
- const response = await dataAdapter.getData('submitScore', {
- athleteId: String(this.player.athleteId),
- judgeId: String(this.judgeId),
+ const submitData = {
+ athleteId: this.player.athleteId,
+ judgeId: this.judgeId,
+ projectId: this.projectId,
+ competitionId: this.competitionId,
+ venueId: this.venueId,
score: this.currentScore,
- 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 || ''
- })
+ note: this.note
+ }
+
+ if (config.debug) {
+ console.log('准备提交评分数据:', submitData)
+ }
+
+ const response = await dataAdapter.getData('submitScore', submitData)
uni.hideLoading()
- // 调试信息
if (config.debug) {
console.log('评分提交成功:', {
athleteId: this.player.athleteId,
@@ -294,14 +328,12 @@ export default {
})
}
- // 显示成功提示
uni.showToast({
title: '提交成功',
icon: 'success',
duration: 1500
})
- // 返回上一页
setTimeout(() => {
uni.navigateBack()
}, 1500)
@@ -341,12 +373,19 @@ export default {
.nav-left {
position: absolute;
- left: 30rpx;
- width: 60rpx;
- height: 60rpx;
+ left: 0;
+ top: 0;
+ width: 120rpx;
+ height: 90rpx;
display: flex;
align-items: center;
justify-content: center;
+ z-index: 10;
+ cursor: pointer;
+}
+
+.nav-left:active {
+ opacity: 0.6;
}
.back-icon {
@@ -475,6 +514,14 @@ export default {
display: flex;
flex-direction: column;
align-items: center;
+ cursor: pointer;
+ padding: 20rpx;
+ border-radius: 16rpx;
+ transition: background-color 0.2s;
+}
+
+.score-display:active {
+ background-color: rgba(27, 124, 94, 0.1);
}
.current-score {
@@ -483,6 +530,12 @@ export default {
color: #1B7C5E;
}
+.edit-hint {
+ font-size: 22rpx;
+ color: #999999;
+ margin-top: 8rpx;
+}
+
.judge-tip {
padding: 0 30rpx;
font-size: 24rpx;
@@ -618,4 +671,95 @@ export default {
.submit-btn:active {
opacity: 0.9;
}
+
+/* 分数输入弹窗 */
+.modal-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.5);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 1000;
+}
+
+.modal-content {
+ width: 600rpx;
+ background-color: #FFFFFF;
+ border-radius: 24rpx;
+ overflow: hidden;
+}
+
+.modal-header {
+ padding: 40rpx 30rpx 20rpx;
+ text-align: center;
+}
+
+.modal-title {
+ font-size: 34rpx;
+ font-weight: 600;
+ color: #333333;
+}
+
+.modal-body {
+ padding: 20rpx 30rpx 30rpx;
+}
+
+.score-input {
+ width: 100%;
+ height: 90rpx;
+ border: 2rpx solid #E0E0E0;
+ border-radius: 12rpx;
+ padding: 0 24rpx;
+ font-size: 36rpx;
+ text-align: center;
+ color: #1B7C5E;
+ font-weight: 600;
+}
+
+.score-input:focus {
+ border-color: #1B7C5E;
+}
+
+.input-hint {
+ display: block;
+ margin-top: 16rpx;
+ font-size: 24rpx;
+ color: #999999;
+ text-align: center;
+}
+
+.modal-footer {
+ display: flex;
+ border-top: 1rpx solid #E0E0E0;
+}
+
+.modal-btn {
+ flex: 1;
+ height: 100rpx;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 32rpx;
+ background: none;
+ border: none;
+ border-radius: 0;
+}
+
+.modal-btn.cancel {
+ color: #666666;
+ border-right: 1rpx solid #E0E0E0;
+}
+
+.modal-btn.confirm {
+ color: #1B7C5E;
+ font-weight: 600;
+}
+
+.modal-btn:active {
+ background-color: #F5F5F5;
+}