- 将同一单位的选手合并为一个队伍行 - 多选手队伍可展开查看具体选手 - 队伍状态根据所有选手状态计算(已签到/未签到/部分签到/部分异常) - 上移/下移操作移动整个队伍 - 异常标记:单人队伍在主行标记,多人队伍需展开后标记单个选手 - 修复语法错误(转义字符和字符串引号) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -86,13 +86,44 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-table :data="group.items" border stripe size="small">
|
<el-table :data="groupItemsByTeam(group.items)" border stripe size="small" row-key="id">
|
||||||
|
<!-- 展开列 -->
|
||||||
|
<el-table-column type="expand" width="30">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<div v-if="row.players.length > 1" class="player-expand-list">
|
||||||
|
<div v-for="player in row.players" :key="player.id" class="player-row">
|
||||||
|
<span class="player-name">{{ player.playerName }}</span>
|
||||||
|
<el-tag :type="player.status === '已签到' ? 'success' : player.status === '异常' ? 'danger' : 'info'" size="small">
|
||||||
|
{{ player.status || '未签到' }}
|
||||||
|
</el-tag>
|
||||||
|
<el-button
|
||||||
|
v-if="(player.status || '未签到') === '未签到'"
|
||||||
|
link
|
||||||
|
size="small"
|
||||||
|
@click="markPlayerAsException(group, player)"
|
||||||
|
:disabled="isScheduleCompleted"
|
||||||
|
style="color: #f56c6c;"
|
||||||
|
>
|
||||||
|
异常
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else class="player-expand-list">
|
||||||
|
<span style="color: #909399;">单人队伍</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="序号" type="index" width="60" align="center"></el-table-column>
|
<el-table-column label="序号" type="index" width="60" align="center"></el-table-column>
|
||||||
<el-table-column prop="schoolUnit" label="学校/单位" min-width="200"></el-table-column>
|
<el-table-column prop="schoolUnit" label="学校/单位" min-width="150"></el-table-column>
|
||||||
<el-table-column prop="status" label="状态" width="100" align="center">
|
<el-table-column label="选手" min-width="120">
|
||||||
<template #default="scope">
|
<template #default="{ row }">
|
||||||
<el-tag :type="scope.row.status === '已签到' ? 'success' : scope.row.status === '异常' ? 'danger' : 'info'" size="small">
|
{{ row.players.map(p => p.playerName).join('、') }}
|
||||||
{{ scope.row.status || '未签到' }}
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="状态" width="100" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-tag :type="getTeamStatusType(row)" size="small">
|
||||||
|
{{ getTeamStatus(row) }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -101,7 +132,7 @@
|
|||||||
<el-button
|
<el-button
|
||||||
link
|
link
|
||||||
size="small"
|
size="small"
|
||||||
@click="handleMoveUp(group, scope.$index)"
|
@click="handleTeamMoveUp(group, scope.$index)"
|
||||||
:disabled="scope.$index === 0 || isScheduleCompleted"
|
:disabled="scope.$index === 0 || isScheduleCompleted"
|
||||||
title="上移"
|
title="上移"
|
||||||
class="move-btn"
|
class="move-btn"
|
||||||
@@ -111,18 +142,18 @@
|
|||||||
<el-button
|
<el-button
|
||||||
link
|
link
|
||||||
size="small"
|
size="small"
|
||||||
@click="handleMoveDown(group, scope.$index)"
|
@click="handleTeamMoveDown(group, scope.$index)"
|
||||||
:disabled="scope.$index === group.items.length - 1 || isScheduleCompleted"
|
:disabled="scope.$index === groupItemsByTeam(group.items).length - 1 || isScheduleCompleted"
|
||||||
title="下移"
|
title="下移"
|
||||||
class="move-btn"
|
class="move-btn"
|
||||||
>
|
>
|
||||||
<img src="/img/图标 4@3x.png" class="move-icon" alt="下移" />
|
<img src="/img/图标 4@3x.png" class="move-icon" alt="下移" />
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
v-if="(scope.row.status || '未签到') === '未签到'"
|
v-if="scope.row.players.length === 1 && (scope.row.players[0].status || '未签到') === '未签到'"
|
||||||
link
|
link
|
||||||
size="small"
|
size="small"
|
||||||
@click="markAsException(group, scope.$index)"
|
@click="markPlayerAsException(group, scope.row.players[0])"
|
||||||
:disabled="isScheduleCompleted"
|
:disabled="isScheduleCompleted"
|
||||||
style="color: #f56c6c;"
|
style="color: #f56c6c;"
|
||||||
>
|
>
|
||||||
@@ -372,6 +403,146 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 将选手按学校/单位分组为队伍
|
||||||
|
groupItemsByTeam(items) {
|
||||||
|
if (!items || items.length === 0) return []
|
||||||
|
const teamMap = new Map()
|
||||||
|
items.forEach(item => {
|
||||||
|
const key = item.schoolUnit
|
||||||
|
if (!teamMap.has(key)) {
|
||||||
|
teamMap.set(key, {
|
||||||
|
id: `team_${item.id}`,
|
||||||
|
schoolUnit: key,
|
||||||
|
players: [],
|
||||||
|
playerIds: []
|
||||||
|
})
|
||||||
|
}
|
||||||
|
teamMap.get(key).players.push(item)
|
||||||
|
teamMap.get(key).playerIds.push(item.id)
|
||||||
|
})
|
||||||
|
return Array.from(teamMap.values())
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取队伍状态
|
||||||
|
getTeamStatus(team) {
|
||||||
|
if (!team || !team.players) return '未签到'
|
||||||
|
const statuses = team.players.map(p => p.status || '未签到')
|
||||||
|
if (statuses.every(s => s === '已签到')) return '已签到'
|
||||||
|
if (statuses.every(s => s === '未签到')) return '未签到'
|
||||||
|
if (statuses.some(s => s === '异常')) return '部分异常'
|
||||||
|
return '部分签到'
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取队伍状态类型
|
||||||
|
getTeamStatusType(team) {
|
||||||
|
const status = this.getTeamStatus(team)
|
||||||
|
switch(status) {
|
||||||
|
case '已签到': return 'success'
|
||||||
|
case '部分异常': return 'danger'
|
||||||
|
case '部分签到': return 'warning'
|
||||||
|
default: return 'info'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 队伍上移
|
||||||
|
handleTeamMoveUp(group, teamIndex) {
|
||||||
|
const teams = this.groupItemsByTeam(group.items)
|
||||||
|
if (teamIndex === 0 || this.isScheduleCompleted) return
|
||||||
|
|
||||||
|
const currentTeam = teams[teamIndex]
|
||||||
|
const prevTeam = teams[teamIndex - 1]
|
||||||
|
|
||||||
|
// 找到两个队伍在原数组中的位置范围
|
||||||
|
const currentPlayerIds = currentTeam.playerIds
|
||||||
|
const prevPlayerIds = prevTeam.playerIds
|
||||||
|
|
||||||
|
// 重新排序:将当前队伍的所有选手移到前一个队伍之前
|
||||||
|
const newItems = []
|
||||||
|
let addedCurrent = false
|
||||||
|
|
||||||
|
for (const item of group.items) {
|
||||||
|
if (prevPlayerIds.includes(item.id) && !addedCurrent) {
|
||||||
|
// 先添加当前队伍的所有选手
|
||||||
|
for (const cItem of group.items) {
|
||||||
|
if (currentPlayerIds.includes(cItem.id)) {
|
||||||
|
newItems.push(cItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addedCurrent = true
|
||||||
|
}
|
||||||
|
if (!currentPlayerIds.includes(item.id)) {
|
||||||
|
newItems.push(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
group.items = newItems
|
||||||
|
this.$message.success('上移成功')
|
||||||
|
},
|
||||||
|
|
||||||
|
// 队伍下移
|
||||||
|
handleTeamMoveDown(group, teamIndex) {
|
||||||
|
const teams = this.groupItemsByTeam(group.items)
|
||||||
|
if (teamIndex === teams.length - 1 || this.isScheduleCompleted) return
|
||||||
|
|
||||||
|
const currentTeam = teams[teamIndex]
|
||||||
|
const nextTeam = teams[teamIndex + 1]
|
||||||
|
|
||||||
|
const currentPlayerIds = currentTeam.playerIds
|
||||||
|
const nextPlayerIds = nextTeam.playerIds
|
||||||
|
|
||||||
|
// 重新排序:将当前队伍的所有选手移到下一个队伍之后
|
||||||
|
const newItems = []
|
||||||
|
let addedCurrent = false
|
||||||
|
|
||||||
|
for (const item of group.items) {
|
||||||
|
if (!currentPlayerIds.includes(item.id)) {
|
||||||
|
newItems.push(item)
|
||||||
|
}
|
||||||
|
if (nextPlayerIds.includes(item.id)) {
|
||||||
|
// 检查是否是下一个队伍的最后一个选手
|
||||||
|
const isLastOfNext = item.id === nextPlayerIds[nextPlayerIds.length - 1]
|
||||||
|
if (isLastOfNext && !addedCurrent) {
|
||||||
|
// 在下一个队伍最后一个选手之后添加当前队伍
|
||||||
|
for (const cItem of group.items) {
|
||||||
|
if (currentPlayerIds.includes(cItem.id)) {
|
||||||
|
newItems.push(cItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addedCurrent = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
group.items = newItems
|
||||||
|
this.$message.success('下移成功')
|
||||||
|
},
|
||||||
|
|
||||||
|
// 标记单个选手为异常
|
||||||
|
markPlayerAsException(group, player) {
|
||||||
|
if (this.isScheduleCompleted) {
|
||||||
|
this.$message.warning('编排已完成,无法标记异常')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在 group.items 中找到该选手并修改状态
|
||||||
|
const item = group.items.find(i => i.id === player.id)
|
||||||
|
if (item) {
|
||||||
|
item.status = '异常'
|
||||||
|
|
||||||
|
// 添加到异常列表
|
||||||
|
this.exceptionList.push({
|
||||||
|
groupId: group.id,
|
||||||
|
groupTitle: group.title,
|
||||||
|
participantId: player.id,
|
||||||
|
schoolUnit: player.schoolUnit,
|
||||||
|
playerName: player.playerName,
|
||||||
|
status: '异常'
|
||||||
|
})
|
||||||
|
|
||||||
|
this.$message.success(`已将 ${player.playerName} 标记为异常`)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
goBack() {
|
goBack() {
|
||||||
this.$router.go(-1)
|
this.$router.go(-1)
|
||||||
},
|
},
|
||||||
@@ -505,6 +676,7 @@ export default {
|
|||||||
items: (group.participants || []).map(p => ({
|
items: (group.participants || []).map(p => ({
|
||||||
id: p.id,
|
id: p.id,
|
||||||
schoolUnit: p.schoolUnit,
|
schoolUnit: p.schoolUnit,
|
||||||
|
playerName: p.playerName,
|
||||||
status: p.status || '未签到',
|
status: p.status || '未签到',
|
||||||
sortOrder: p.sortOrder
|
sortOrder: p.sortOrder
|
||||||
}))
|
}))
|
||||||
@@ -1014,4 +1186,28 @@ export default {
|
|||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 展开行样式
|
||||||
|
.player-expand-list {
|
||||||
|
padding: 10px 20px 10px 60px;
|
||||||
|
background: #fafafa;
|
||||||
|
|
||||||
|
.player-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 15px;
|
||||||
|
padding: 8px 0;
|
||||||
|
border-bottom: 1px dashed #eee;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player-name {
|
||||||
|
min-width: 80px;
|
||||||
|
color: #606266;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user