diff --git a/src/api/athlete.js b/src/api/athlete.js
index 56f3ca3..0b5d125 100644
--- a/src/api/athlete.js
+++ b/src/api/athlete.js
@@ -7,8 +7,6 @@ import request from '@/utils/request.js'
export default {
/**
* 获取选手列表
- * @param {Object} params 查询参数 { current, size, competitionId, name }
- * @returns {Promise}
*/
getAthleteList(params = {}) {
return request.get('/martial/athlete/list', {
@@ -20,8 +18,6 @@ export default {
/**
* 获取选手详情
- * @param {String|Number} id 选手ID
- * @returns {Promise}
*/
getAthleteDetail(id) {
return request.get('/martial/athlete/detail', { id })
@@ -29,8 +25,6 @@ export default {
/**
* 新增或修改选手
- * @param {Object} data 选手数据
- * @returns {Promise}
*/
submitAthlete(data) {
return request.post('/martial/athlete/submit', data)
@@ -38,12 +32,44 @@ export default {
/**
* 删除选手
- * @param {String|Array} ids 选手ID或ID数组
- * @returns {Promise}
*/
removeAthlete(ids) {
return request.post('/martial/athlete/remove', {
ids: Array.isArray(ids) ? ids.join(',') : ids
})
+ },
+
+ // ========== 集体/团队相关 API ==========
+
+ /**
+ * 获取集体列表
+ */
+ getTeamList(params = {}) {
+ return request.get('/martial/team/list', {
+ current: params.current || 1,
+ size: params.size || 100,
+ ...params
+ })
+ },
+
+ /**
+ * 获取集体详情
+ */
+ getTeamDetail(id) {
+ return request.get('/martial/team/detail', { id })
+ },
+
+ /**
+ * 保存集体
+ */
+ saveTeam(data) {
+ return request.post('/martial/team/submit', data)
+ },
+
+ /**
+ * 删除集体
+ */
+ removeTeam(id) {
+ return request.post('/martial/team/remove', null, { params: { id } })
}
}
diff --git a/src/pages/event-register/event-register.vue b/src/pages/event-register/event-register.vue
index 454cdd9..8e37571 100644
--- a/src/pages/event-register/event-register.vue
+++ b/src/pages/event-register/event-register.vue
@@ -4,7 +4,7 @@
- 选择选手信息
+ {{ isTeamProject ? '选择集体' : '选择选手信息' }}
@@ -18,37 +18,73 @@
-
+
- 已选:{{ selectedCount }} 人
+
+
+ 已选:{{ selectedCount }} 人
-
- ⊕
- 新增选手
-
+
+ ⊕
+ 新增选手
+
-
-
-
-
-
-
-
- {{ item.name }}
- 身份证:{{ item.idCard }}
-
-
-
-
- 编辑
+
+
+
+
+
-
-
- 删除
+
+ {{ item.name }}
+ 身份证:{{ item.idCard }}
+
+
+
+
+ 编辑
+
+
+
+ 删除
+
-
+
+
+
+
+ 已选:{{ selectedTeamCount }} 个集体
+
+
+ ⊕
+ 新增集体
+
+
+
+
+
+
+
+
+
+ {{ item.name }}
+ 成员数:{{ item.memberCount || 0 }}人
+
+
+
+
+ 删除
+
+
+
+
+
+
+ 暂无集体,请先新增
+
+
下一步
@@ -81,11 +117,11 @@
(注意是否用此号码接收信息)
- 参赛选手:
+ {{ isTeamProject ? '参赛集体:' : '参赛选手:' }}
- {{ eventInfo.participants || '未选择选手' }}
+ {{ eventInfo.participants || (isTeamProject ? '未选择集体' : '未选择选手') }}
-
+
查看证件
›
@@ -94,8 +130,8 @@
- 人数:
- {{ selectedCount }}
+ {{ isTeamProject ? '集体数:' : '人数:' }}
+ {{ isTeamProject ? selectedTeamCount : selectedCount }}
合计:
@@ -132,14 +168,25 @@
{{ eventInfo.contact }}
- 参赛选手:{{ selectedPlayers.length }}人
-
-
- {{ item.name }}
- 身份证:{{ item.idCard }}
- 编号:{{ item.number }}
+
+ 参赛选手:{{ selectedPlayers.length }}人
+
+
+ {{ item.name }}
+ 身份证:{{ item.idCard }}
+ 编号:{{ item.number }}
+
-
+
+
+ 参赛集体:{{ selectedTeams.length }}个
+
+
+ {{ item.name }}
+ 成员数:{{ item.memberCount }}人
+
+
+
@@ -179,6 +226,7 @@ export default {
currentStep: 1,
eventId: '',
selectedProjects: [],
+ isTeamProject: false,
eventInfo: {
title: '',
location: '',
@@ -188,7 +236,9 @@ export default {
participants: ''
},
playerList: [],
+ teamList: [],
selectedPlayers: [],
+ selectedTeams: [],
showPlayerModal: false,
totalPrice: 0,
registrationId: ''
@@ -198,11 +248,8 @@ export default {
selectedCount() {
return this.playerList.filter(item => item.selected).length
},
- participantsText() {
- return this.playerList
- .filter(item => item.selected)
- .map(item => item.name)
- .join('、')
+ selectedTeamCount() {
+ return this.teamList.filter(item => item.selected).length
}
},
onLoad(options) {
@@ -213,47 +260,44 @@ export default {
if (options.projects) {
try {
- // 尝试解码(可能被双重编码)
let projectsStr = decodeURIComponent(options.projects)
-
- // 如果还包含 %,说明被双重编码了,再解码一次
if (projectsStr.includes('%')) {
projectsStr = decodeURIComponent(projectsStr)
}
-
this.selectedProjects = JSON.parse(projectsStr)
+
+ // Check if any project is team type (type === 2)
+ this.isTeamProject = this.selectedProjects.some(p => p.type === 2 || p.type === '2')
} catch (err) {
console.error('解析项目数据失败:', err)
}
}
- // 加载选手列表
- this.loadPlayerList()
- },
- onShow() {
- // 从新增/编辑页面返回时重新加载列表
- if (this.currentStep === 1) {
+ // Load list based on project type
+ if (this.isTeamProject) {
+ this.loadTeamList()
+ } else {
this.loadPlayerList()
}
},
+ onShow() {
+ if (this.currentStep === 1) {
+ if (this.isTeamProject) {
+ this.loadTeamList()
+ } else {
+ this.loadPlayerList()
+ }
+ }
+ },
methods: {
- /**
- * 加载赛事详情
- */
async loadEventDetail(id) {
try {
const res = await competitionAPI.getCompetitionDetail(id)
-
- // 尝试多个可能的时间字段名
const startTime = res.startTime || res.competitionStartTime || res.beginTime || res.startDate
const endTime = res.endTime || res.competitionEndTime || res.finishTime || res.endDate
-
- // 如果没有时间字段,尝试使用其他字段
let matchTime = this.formatTimeRange(startTime, endTime)
if (!matchTime && res.matchTime) {
matchTime = res.matchTime
- } else if (!matchTime && res.competitionTime) {
- matchTime = res.competitionTime
} else if (!matchTime) {
matchTime = '待定'
}
@@ -270,7 +314,6 @@ export default {
}
} catch (err) {
console.error('加载赛事详情失败:', err)
- // 设置默认值,防止页面显示空白
this.eventInfo = {
title: '未命名赛事',
location: '待定',
@@ -282,111 +325,105 @@ export default {
}
},
- /**
- * 加载选手列表
- */
async loadPlayerList() {
try {
- // 获取当前用户信息
const userInfo = getUserInfo()
if (!userInfo || !userInfo.userId) {
- uni.showToast({
- title: '请先登录',
- icon: 'none'
- })
+ uni.showToast({ title: '请先登录', icon: 'none' })
return
}
- // 只查询当前用户创建的选手
const res = await athleteAPI.getAthleteList({
current: 1,
size: 100,
createUser: userInfo.userId
})
- let list = []
- if (res.records) {
- list = res.records
- } else if (Array.isArray(res)) {
- list = res
- }
-
- // 数据映射 - 尝试多个可能的字段名
+ let list = res.records || (Array.isArray(res) ? res : [])
this.playerList = list.map(item => ({
id: item.id,
- // 尝试多个可能的姓名字段
- name: item.name || item.athleteName || item.playerName || item.realName || item.userName || '未命名',
- // 尝试多个可能的身份证字段
- idCard: item.idCard || item.idCardNumber || item.idCardNo || item.identityCard || '',
+ name: item.name || item.athleteName || item.playerName || '未命名',
+ idCard: item.idCard || item.idCardNumber || '',
selected: false
}))
} catch (err) {
console.error('加载选手列表失败:', err)
- uni.showToast({
- title: '加载选手列表失败',
- icon: 'none'
- })
}
},
- /**
- * 格式化时间范围
- */
+ async loadTeamList() {
+ try {
+ const userInfo = getUserInfo()
+ if (!userInfo || !userInfo.userId) return
+
+ const res = await athleteAPI.getTeamList({
+ current: 1,
+ size: 100
+ })
+
+ let list = res.records || (Array.isArray(res) ? res : [])
+ this.teamList = list.map(item => ({
+ id: item.id,
+ name: item.teamName || item.name,
+ memberCount: item.memberCount || 0,
+ selected: false
+ }))
+ } catch (err) {
+ console.error('加载集体列表失败:', err)
+ this.teamList = []
+ }
+ },
+
formatTimeRange(startTime, endTime) {
if (!startTime || !endTime) return ''
-
const formatDate = (dateStr) => {
if (!dateStr) return ''
const date = new Date(dateStr)
- const year = date.getFullYear()
- const month = String(date.getMonth() + 1).padStart(2, '0')
- const day = String(date.getDate()).padStart(2, '0')
- return `${year}.${month}.${day}`
+ return `${date.getFullYear()}.${String(date.getMonth() + 1).padStart(2, '0')}.${String(date.getDate()).padStart(2, '0')}`
}
-
return `${formatDate(startTime)}-${formatDate(endTime)}`
},
- /**
- * 计算总价
- */
calculateTotalPrice() {
- const count = this.selectedCount
-
- if (!this.selectedProjects || this.selectedProjects.length === 0) {
- return 0
- }
-
- // 计算所有项目的总价(将字符串转换为数字)
- const pricePerProject = this.selectedProjects.reduce((sum, p) => {
- const price = parseFloat(p.price || 0)
- return sum + price
- }, 0)
-
- const total = count * pricePerProject
-
- return total.toFixed(2)
+ const count = this.isTeamProject ? this.selectedTeamCount : this.selectedCount
+ if (!this.selectedProjects || this.selectedProjects.length === 0) return 0
+ const pricePerProject = this.selectedProjects.reduce((sum, p) => sum + parseFloat(p.price || 0), 0)
+ return (count * pricePerProject).toFixed(2)
},
togglePlayer(item) {
const index = this.playerList.findIndex(p => p.id === item.id)
if (index !== -1) {
- const newValue = !this.playerList[index].selected
- this.$set(this.playerList[index], 'selected', newValue)
+ this.$set(this.playerList[index], 'selected', !this.playerList[index].selected)
}
},
+
+ toggleTeam(item) {
+ const index = this.teamList.findIndex(t => t.id === item.id)
+ if (index !== -1) {
+ this.$set(this.teamList[index], 'selected', !this.teamList[index].selected)
+ }
+ },
+
goToAddPlayer() {
- // 传递赛事ID和项目ID到新增选手页面
const projectIds = this.selectedProjects.map(p => p.id).join(',')
uni.navigateTo({
url: `/pages/add-player/add-player?competitionId=${this.eventId}&projectIds=${projectIds}`
- });
+ })
},
+
+ goToAddTeam() {
+ uni.navigateTo({
+ url: '/pages/add-team/add-team'
+ })
+ },
+
handleEdit(item) {
uni.navigateTo({
url: '/pages/edit-player/edit-player?id=' + item.id
- });
+ })
},
+
async handleDelete(item) {
try {
const confirmRes = await new Promise((resolve) => {
@@ -399,167 +436,146 @@ export default {
if (confirmRes.confirm) {
await athleteAPI.removeAthlete(item.id)
-
- const index = this.playerList.findIndex(p => p.id === item.id);
- if (index > -1) {
- this.playerList.splice(index, 1);
- }
-
- uni.showToast({
- title: '删除成功',
- icon: 'success'
- })
+ const index = this.playerList.findIndex(p => p.id === item.id)
+ if (index > -1) this.playerList.splice(index, 1)
+ uni.showToast({ title: '删除成功', icon: 'success' })
}
} catch (err) {
console.error('删除选手失败:', err)
- uni.showToast({
- title: '删除失败',
- icon: 'none'
- })
+ uni.showToast({ title: '删除失败', icon: 'none' })
}
},
+
+ async handleDeleteTeam(item) {
+ try {
+ const confirmRes = await new Promise((resolve) => {
+ uni.showModal({
+ title: '删除集体',
+ content: '确定要删除该集体吗?',
+ success: (res) => resolve(res)
+ })
+ })
+
+ if (confirmRes.confirm) {
+ await athleteAPI.removeTeam(item.id)
+ const index = this.teamList.findIndex(t => t.id === item.id)
+ if (index > -1) this.teamList.splice(index, 1)
+ uni.showToast({ title: '删除成功', icon: 'success' })
+ }
+ } catch (err) {
+ console.error('删除集体失败:', err)
+ uni.showToast({ title: '删除失败', icon: 'none' })
+ }
+ },
+
goToStep2() {
- const selected = this.playerList.filter(item => item.selected)
-
- if (selected.length === 0) {
- uni.showToast({
- title: '请至少选择一名选手',
- icon: 'none'
- })
- return
+ if (this.isTeamProject) {
+ const selected = this.teamList.filter(item => item.selected)
+ if (selected.length === 0) {
+ uni.showToast({ title: '请至少选择一个集体', icon: 'none' })
+ return
+ }
+ this.$set(this.eventInfo, 'participants', selected.map(t => t.name).join('、'))
+ this.selectedTeams = selected
+ } else {
+ const selected = this.playerList.filter(item => item.selected)
+ if (selected.length === 0) {
+ uni.showToast({ title: '请至少选择一名选手', icon: 'none' })
+ return
+ }
+ this.$set(this.eventInfo, 'participants', selected.map(p => p.name).join('、'))
}
-
- // 更新参赛选手信息
- const participantsText = selected.map(p => p.name).join('、')
-
- // 使用 $set 确保响应式更新
- this.$set(this.eventInfo, 'participants', participantsText)
+
this.totalPrice = this.calculateTotalPrice()
-
- // 延迟切换步骤,确保数据更新完成
- this.$nextTick(() => {
- this.currentStep = 2
- })
+ this.$nextTick(() => { this.currentStep = 2 })
},
+
async goToStep3() {
try {
- // 获取选中的选手
- const selected = this.playerList.filter(item => item.selected)
-
- // 检查必填字段
if (!this.eventId) {
- uni.showToast({
- title: '赛事ID缺失',
- icon: 'none'
- })
+ uni.showToast({ title: '赛事ID缺失', icon: 'none' })
return
}
if (!this.selectedProjects || this.selectedProjects.length === 0) {
- uni.showToast({
- title: '请选择报名项目',
- icon: 'none'
- })
+ uni.showToast({ title: '请选择报名项目', icon: 'none' })
return
}
- if (selected.length === 0) {
- uni.showToast({
- title: '请选择参赛选手',
- icon: 'none'
- })
- return
- }
-
- // 生成订单号:格式 BMyyyyMMddHHmmss + 随机4位数
const now = new Date()
- const year = now.getFullYear()
- const month = String(now.getMonth() + 1).padStart(2, '0')
- const day = String(now.getDate()).padStart(2, '0')
- const hours = String(now.getHours()).padStart(2, '0')
- const minutes = String(now.getMinutes()).padStart(2, '0')
- const seconds = String(now.getSeconds()).padStart(2, '0')
- const random = String(Math.floor(Math.random() * 10000)).padStart(4, '0')
- const orderNo = `BM${year}${month}${day}${hours}${minutes}${seconds}${random}`
+ const orderNo = `BM${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, '0')}${String(now.getDate()).padStart(2, '0')}${String(now.getHours()).padStart(2, '0')}${String(now.getMinutes()).padStart(2, '0')}${String(now.getSeconds()).padStart(2, '0')}${String(Math.floor(Math.random() * 10000)).padStart(4, '0')}`
- // 构建提交数据 - 确保ID都是数字类型
- const submitData = {
- orderNo: orderNo,
- competitionId: String(this.eventId),
- projectIds: this.selectedProjects.map(p => String(p.id)),
- athleteIds: selected.map(p => String(p.id)),
- contactPhone: this.eventInfo.contact || '',
- totalAmount: parseFloat(this.totalPrice) || 0
+ let submitData
+ if (this.isTeamProject) {
+ const selected = this.teamList.filter(item => item.selected)
+ if (selected.length === 0) {
+ uni.showToast({ title: '请选择参赛集体', icon: 'none' })
+ return
+ }
+ submitData = {
+ orderNo: orderNo,
+ competitionId: String(this.eventId),
+ projectIds: this.selectedProjects.map(p => String(p.id)),
+ teamIds: selected.map(t => String(t.id)),
+ athleteIds: [],
+ contactPhone: this.eventInfo.contact || '',
+ totalAmount: parseFloat(this.totalPrice) || 0
+ }
+ } else {
+ const selected = this.playerList.filter(item => item.selected)
+ if (selected.length === 0) {
+ uni.showToast({ title: '请选择参赛选手', icon: 'none' })
+ return
+ }
+ submitData = {
+ orderNo: orderNo,
+ competitionId: String(this.eventId),
+ projectIds: this.selectedProjects.map(p => String(p.id)),
+ athleteIds: selected.map(p => String(p.id)),
+ contactPhone: this.eventInfo.contact || '',
+ totalAmount: parseFloat(this.totalPrice) || 0
+ }
}
- console.log('=== 提交报名数据 ===')
- console.log('订单号:', submitData.orderNo)
- console.log('完整提交数据:', submitData)
- console.log('赛事ID:', submitData.competitionId, typeof submitData.competitionId)
- console.log('项目IDs:', submitData.projectIds)
- console.log('选手IDs:', submitData.athleteIds)
- console.log('联系电话:', submitData.contactPhone)
- console.log('总金额:', submitData.totalAmount, typeof submitData.totalAmount)
-
- // 提交报名订单
+ console.log('提交报名数据:', submitData)
const res = await registrationAPI.submitRegistration(submitData)
+ this.registrationId = res.id || res.registrationId || orderNo
- console.log('=== 报名响应数据 ===')
- console.log('完整响应:', res)
- console.log('响应数据:', res.data)
-
- // 保存报名ID - 尝试多个可能的字段
- this.registrationId = res.id || res.registrationId || res.data?.id || res.data?.registrationId || orderNo
-
- console.log('报名ID:', this.registrationId)
-
- // 更新选中的选手列表(包含编号)
- this.selectedPlayers = selected.map((item, index) => {
- // 生成编号:使用报名ID或订单号 + 选手索引
- const playerNumber = item.playerNo || item.number || `${this.registrationId}-${String(index + 1).padStart(6, '0')}`
-
- return {
+ if (this.isTeamProject) {
+ this.selectedTeams = this.teamList.filter(item => item.selected).map(item => ({
+ name: item.name,
+ memberCount: item.memberCount
+ }))
+ } else {
+ const selected = this.playerList.filter(item => item.selected)
+ this.selectedPlayers = selected.map((item, index) => ({
name: item.name,
idCard: item.idCard,
- number: playerNumber
- }
- })
+ number: `${this.registrationId}-${String(index + 1).padStart(6, '0')}`
+ }))
+ }
- this.currentStep = 3;
-
- uni.showToast({
- title: '报名成功',
- icon: 'success'
- })
+ this.currentStep = 3
+ uni.showToast({ title: '报名成功', icon: 'success' })
} catch (err) {
console.error('提交报名失败:', err)
- uni.showToast({
- title: '报名失败,请重试',
- icon: 'none'
- })
+ uni.showToast({ title: '报名失败,请重试', icon: 'none' })
}
},
+
showPlayers() {
- // 更新选中的选手列表
this.selectedPlayers = this.playerList
.filter(item => item.selected)
- .map(item => ({
- name: item.name,
- idCard: item.idCard,
- number: ''
- }))
-
- this.showPlayerModal = true;
+ .map(item => ({ name: item.name, idCard: item.idCard, number: '' }))
+ this.showPlayerModal = true
},
+
handleClose() {
- uni.navigateBack({
- delta: 3
- });
+ uni.navigateBack({ delta: 3 })
}
}
-};
+}
-
+
+.empty-state {
+ padding: 100rpx 0;
+ text-align: center;
+}
+
+.empty-text {
+ font-size: 28rpx;
+ color: #999999;
+}