fix: 选手列表去重并显示已报名标记
- loadPlayerList 添加按身份证去重逻辑 - 查询已报名选手并标记 hasRegistered - UI 显示"已报名"标签 - 选择已报名选手时弹出警告 Closes #3, Closes #4
This commit is contained in:
@@ -81,5 +81,12 @@ export default {
|
|||||||
|
|
||||||
removeContact(id) {
|
removeContact(id) {
|
||||||
return request.post('/martial/contact/remove?ids=' + id, {})
|
return request.post('/martial/contact/remove?ids=' + id, {})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取已报名选手列表(用于检查重复报名)
|
||||||
|
*/
|
||||||
|
getRegisteredAthletes(params = {}) {
|
||||||
|
return request.get('/martial/athlete/registered', params)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,13 +30,16 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="player-list">
|
<view class="player-list">
|
||||||
<view class="player-item" v-for="(item, index) in playerList" :key="index">
|
<view class="player-item" v-for="(item, index) in playerList" :key="index" :class="{ 'registered': item.hasRegistered }">
|
||||||
<view class="player-checkbox" @click="togglePlayer(item)">
|
<view class="player-checkbox" @click="togglePlayer(item)">
|
||||||
<image v-if="item.selected" class="checkbox-img" src="/static/images/选中@3x.png" mode="aspectFit"></image>
|
<image v-if="item.selected" class="checkbox-img" src="/static/images/选中@3x.png" mode="aspectFit"></image>
|
||||||
<image v-else class="checkbox-img" src="/static/images/未选中@3x.png" mode="aspectFit"></image>
|
<image v-else class="checkbox-img" src="/static/images/未选中@3x.png" mode="aspectFit"></image>
|
||||||
</view>
|
</view>
|
||||||
<view class="player-info">
|
<view class="player-info">
|
||||||
<view class="player-name">{{ item.name }}</view>
|
<view class="player-name">
|
||||||
|
{{ item.name }}
|
||||||
|
<text v-if="item.hasRegistered" class="registered-tag">已报名</text>
|
||||||
|
</view>
|
||||||
<view class="player-id">身份证:{{ item.idCard }}</view>
|
<view class="player-id">身份证:{{ item.idCard }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="player-actions">
|
<view class="player-actions">
|
||||||
@@ -426,12 +429,43 @@ export default {
|
|||||||
})
|
})
|
||||||
|
|
||||||
let list = res.records || (Array.isArray(res) ? res : [])
|
let list = res.records || (Array.isArray(res) ? res : [])
|
||||||
this.playerList = list.map(item => ({
|
|
||||||
id: item.id,
|
// Deduplicate by idCard
|
||||||
name: item.name || item.athleteName || item.playerName || '未命名',
|
const seen = new Set()
|
||||||
idCard: item.idCard || item.idCardNumber || '',
|
list = list.filter(item => {
|
||||||
selected: false
|
const key = item.idCard || item.idCardNumber || item.id
|
||||||
}))
|
if (seen.has(key)) return false
|
||||||
|
seen.add(key)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
// Get current project IDs
|
||||||
|
const projectIds = this.selectedProjects.map(p => p.id)
|
||||||
|
|
||||||
|
// Check which players have already registered for these projects
|
||||||
|
let registeredIdCards = []
|
||||||
|
if (projectIds.length > 0 && this.eventId) {
|
||||||
|
try {
|
||||||
|
const regRes = await athleteAPI.getRegisteredAthletes({
|
||||||
|
competitionId: this.eventId,
|
||||||
|
projectIds: projectIds.join(',')
|
||||||
|
})
|
||||||
|
registeredIdCards = (regRes || []).map(r => r.idCard)
|
||||||
|
} catch (e) {
|
||||||
|
console.log('查询已报名选手失败:', e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.playerList = list.map(item => {
|
||||||
|
const idCard = item.idCard || item.idCardNumber || ''
|
||||||
|
return {
|
||||||
|
id: item.id,
|
||||||
|
name: item.name || item.athleteName || item.playerName || '未命名',
|
||||||
|
idCard: idCard,
|
||||||
|
selected: false,
|
||||||
|
hasRegistered: registeredIdCards.includes(idCard)
|
||||||
|
}
|
||||||
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('加载选手列表失败:', err)
|
console.error('加载选手列表失败:', err)
|
||||||
}
|
}
|
||||||
@@ -478,6 +512,17 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
togglePlayer(item) {
|
togglePlayer(item) {
|
||||||
|
// Warn if player has already registered for this project
|
||||||
|
if (item.hasRegistered && !item.selected) {
|
||||||
|
uni.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: '该选手已报名此项目,重复报名将被系统拒绝',
|
||||||
|
confirmText: '知道了',
|
||||||
|
showCancel: false
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const index = this.playerList.findIndex(p => p.id === item.id)
|
const index = this.playerList.findIndex(p => p.id === item.id)
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
this.$set(this.playerList[index], 'selected', !this.playerList[index].selected)
|
this.$set(this.playerList[index], 'selected', !this.playerList[index].selected)
|
||||||
@@ -830,6 +875,24 @@ export default {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #333333;
|
color: #333333;
|
||||||
margin-bottom: 10rpx;
|
margin-bottom: 10rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.registered-tag {
|
||||||
|
font-size: 22rpx;
|
||||||
|
font-weight: normal;
|
||||||
|
color: #ff6600;
|
||||||
|
background: #fff3e6;
|
||||||
|
padding: 4rpx 12rpx;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
border: 1px solid #ff6600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player-item.registered {
|
||||||
|
opacity: 0.7;
|
||||||
|
background: #f9f9f9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.player-id {
|
.player-id {
|
||||||
|
|||||||
Reference in New Issue
Block a user