Compare commits
8
Commits
3b05e7fc28
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
56a1897b7d | ||
|
|
5f68218079 | ||
|
|
82deb8b4f9 | ||
|
|
076aa287bd | ||
|
|
d8c255d69d | ||
|
|
7c4507c3ed | ||
|
|
412069524e | ||
|
|
53cc4600a8 |
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-2
@@ -10,7 +10,7 @@ import request from '@/utils/request.js'
|
|||||||
*/
|
*/
|
||||||
export function getScheduleResult(competitionId) {
|
export function getScheduleResult(competitionId) {
|
||||||
return request.get('/martial/schedule/result', {
|
return request.get('/martial/schedule/result', {
|
||||||
params: { competitionId }
|
competitionId
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,6 +91,27 @@ export function saveDispatch(data) {
|
|||||||
return request.post('/martial/schedule/save-dispatch', data)
|
return request.post('/martial/schedule/save-dispatch', data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取编排状态(小程序用)
|
||||||
|
* @param {Number} competitionId - 赛事ID
|
||||||
|
*/
|
||||||
|
export function getScheduleStatus(competitionId) {
|
||||||
|
return request.get('/mini/schedule/status', {
|
||||||
|
competitionId
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取出场顺序(小程序用)
|
||||||
|
* @param {Number} competitionId - 赛事ID
|
||||||
|
* @param {Number} projectId - 项目ID (可选)
|
||||||
|
*/
|
||||||
|
export function getLineup(competitionId, projectId, orderId) {
|
||||||
|
return request.get('/mini/schedule/lineup', {
|
||||||
|
competitionId, projectId, orderId
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
getScheduleResult,
|
getScheduleResult,
|
||||||
triggerAutoArrange,
|
triggerAutoArrange,
|
||||||
@@ -99,5 +120,7 @@ export default {
|
|||||||
moveScheduleGroup,
|
moveScheduleGroup,
|
||||||
getDispatchData,
|
getDispatchData,
|
||||||
adjustOrder,
|
adjustOrder,
|
||||||
saveDispatch
|
saveDispatch,
|
||||||
|
getScheduleStatus,
|
||||||
|
getLineup
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,6 +124,36 @@ export default {
|
|||||||
try {
|
try {
|
||||||
await athleteAPI.saveContact(this.formData);
|
await athleteAPI.saveContact(this.formData);
|
||||||
uni.showToast({ title: '保存成功', icon: 'success' });
|
uni.showToast({ title: '保存成功', icon: 'success' });
|
||||||
|
|
||||||
|
// Set flag to notify previous page
|
||||||
|
uni.setStorageSync('contactListNeedRefresh', true);
|
||||||
|
|
||||||
|
// Notify previous page to refresh contact list
|
||||||
|
try {
|
||||||
|
const pages = getCurrentPages();
|
||||||
|
console.log('页面栈长度:', pages.length);
|
||||||
|
console.log('页面栈:', pages);
|
||||||
|
if (pages.length >= 2) {
|
||||||
|
const prevPage = pages[pages.length - 2];
|
||||||
|
console.log('上一页:', prevPage);
|
||||||
|
// Try different ways to access the component
|
||||||
|
const vm = prevPage.$vm || prevPage;
|
||||||
|
console.log('vm:', vm);
|
||||||
|
if (vm && typeof vm.loadContactList === 'function') {
|
||||||
|
console.log('调用 loadContactList');
|
||||||
|
vm.loadContactList();
|
||||||
|
} else if (vm && vm.$refs && vm.$refs.page && typeof vm.$refs.page.loadContactList === 'function') {
|
||||||
|
console.log('通过 $refs 调用');
|
||||||
|
vm.$refs.page.loadContactList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('通知上一页失败:', e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also emit event as backup
|
||||||
|
uni.$emit('contactAdded');
|
||||||
|
|
||||||
setTimeout(() => { uni.navigateBack(); }, 1500);
|
setTimeout(() => { uni.navigateBack(); }, 1500);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('保存联系人失败:', err);
|
console.error('保存联系人失败:', err);
|
||||||
|
|||||||
@@ -109,7 +109,8 @@ export default {
|
|||||||
const res = await athleteAPI.getAthleteList({
|
const res = await athleteAPI.getAthleteList({
|
||||||
current: 1,
|
current: 1,
|
||||||
size: 100,
|
size: 100,
|
||||||
createUser: userInfo.userId
|
createUser: userInfo.userId,
|
||||||
|
registrationStatus: 0 // Only query player info records
|
||||||
})
|
})
|
||||||
|
|
||||||
let list = []
|
let list = []
|
||||||
@@ -119,6 +120,15 @@ export default {
|
|||||||
list = res
|
list = res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deduplicate by id
|
||||||
|
const seen = new Set()
|
||||||
|
list = list.filter(item => {
|
||||||
|
const key = item.id
|
||||||
|
if (seen.has(key)) return false
|
||||||
|
seen.add(key)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
this.playerList = list.map(item => ({
|
this.playerList = list.map(item => ({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
name: item.name || item.playerName
|
name: item.name || item.playerName
|
||||||
|
|||||||
@@ -168,7 +168,15 @@ export default {
|
|||||||
})
|
})
|
||||||
|
|
||||||
let list = res.records || (Array.isArray(res) ? res : [])
|
let list = res.records || (Array.isArray(res) ? res : [])
|
||||||
this.playerList = list.map(item => ({
|
// Deduplicate by idCard
|
||||||
|
const seen = new Set()
|
||||||
|
const uniqueList = list.filter(item => {
|
||||||
|
const idCard = item.idCard || item.idCardNumber
|
||||||
|
if (idCard && seen.has(idCard)) return false
|
||||||
|
if (idCard) seen.add(idCard)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
this.playerList = uniqueList.map(item => ({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
name: item.name || item.playerName,
|
name: item.name || item.playerName,
|
||||||
idCard: item.idCard || item.idCardNumber,
|
idCard: item.idCard || item.idCardNumber,
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
eventId: '',
|
eventId: '',
|
||||||
|
orderId: '',
|
||||||
eventInfo: {
|
eventInfo: {
|
||||||
id: '',
|
id: '',
|
||||||
title: '',
|
title: '',
|
||||||
@@ -96,6 +97,7 @@ export default {
|
|||||||
onLoad(options) {
|
onLoad(options) {
|
||||||
if (options.id) {
|
if (options.id) {
|
||||||
this.eventId = options.id
|
this.eventId = options.id
|
||||||
|
this.orderId = options.orderId || null
|
||||||
this.loadEventDetail(options.id)
|
this.loadEventDetail(options.id)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -192,7 +194,7 @@ export default {
|
|||||||
if (url) {
|
if (url) {
|
||||||
// 跳转时传递赛事ID
|
// 跳转时传递赛事ID
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: `${url}?eventId=${this.eventId}`
|
url: `${url}?eventId=${this.eventId}&orderId=${this.orderId || ""}`
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
|
|||||||
@@ -1,135 +1,135 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="event-lineup-page">
|
<view class="event-lineup-page">
|
||||||
<!-- 组别选择 -->
|
<view v-if="loading" class="loading-container">
|
||||||
<view class="group-tabs">
|
<text>加载中...</text>
|
||||||
<view
|
|
||||||
class="group-tab"
|
|
||||||
v-for="(group, index) in groups"
|
|
||||||
:key="index"
|
|
||||||
:class="{ active: currentGroup === index }"
|
|
||||||
@click="currentGroup = index"
|
|
||||||
>
|
|
||||||
{{ group }}
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 出场顺序列表 -->
|
<view v-else-if="!isScheduleCompleted" class="not-ready">
|
||||||
<view class="lineup-list">
|
<view class="not-ready-icon">📋</view>
|
||||||
<view class="lineup-item" v-for="(item, index) in currentLineup" :key="index">
|
<text class="not-ready-text">赛程编排尚未完成</text>
|
||||||
<view class="lineup-order">
|
<text class="not-ready-hint">请等待赛事组织方完成编排后查看</text>
|
||||||
<view class="order-number">{{ item.order }}</view>
|
</view>
|
||||||
<text class="order-text">号</text>
|
|
||||||
</view>
|
<template v-else>
|
||||||
<view class="lineup-info">
|
<!-- 组别选择 -->
|
||||||
<view class="lineup-name">{{ item.name }}</view>
|
<view class="group-tabs">
|
||||||
<view class="lineup-detail">
|
<view
|
||||||
<text class="detail-item">{{ item.team }}</text>
|
class="group-tab"
|
||||||
<text class="divider">|</text>
|
v-for="(group, index) in groups"
|
||||||
<text class="detail-item">{{ item.time }}</text>
|
:key="index"
|
||||||
</view>
|
:class="{ active: currentGroupIndex === index }"
|
||||||
</view>
|
@click="currentGroupIndex = index"
|
||||||
<view class="lineup-status" :class="item.status">
|
>
|
||||||
{{ item.statusText }}
|
{{ group.groupName }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
|
||||||
|
<!-- 出场顺序列表 -->
|
||||||
|
<view class="lineup-list" v-if="currentGroup">
|
||||||
|
<view class="group-header">
|
||||||
|
<text class="group-venue">{{ currentGroup.venueName }}</text>
|
||||||
|
<text class="group-time">{{ currentGroup.timeSlot }}</text>
|
||||||
|
<text class="group-table">表号: {{ currentGroup.tableNo }}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="lineup-item" v-for="(item, index) in currentGroup.participants" :key="index">
|
||||||
|
<view class="lineup-order">
|
||||||
|
<view class="order-number">{{ item.order }}</view>
|
||||||
|
<text class="order-text">号</text>
|
||||||
|
</view>
|
||||||
|
<view class="lineup-info">
|
||||||
|
<view class="lineup-name">{{ item.playerName }}</view>
|
||||||
|
<view class="lineup-detail">
|
||||||
|
<text class="detail-item">{{ item.organization }}</text>
|
||||||
|
<text class="detail-divider" v-if="item.estimatedTime"> | </text>
|
||||||
|
<text class="detail-item" v-if="item.estimatedTime">{{ item.estimatedTime }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="lineup-status" :class="item.status">
|
||||||
|
{{ getStatusText(item.status) }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="!currentGroup.participants || currentGroup.participants.length === 0" class="empty-list">
|
||||||
|
<text>暂无参赛者信息</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { getScheduleStatus, getLineup } from '@/api/schedule.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
currentGroup: 0,
|
eventId: '',
|
||||||
groups: ['男子A组', '男子B组', '女子A组'],
|
orderId: '',
|
||||||
lineups: {
|
loading: true,
|
||||||
0: [
|
isScheduleCompleted: false,
|
||||||
{
|
currentGroupIndex: 0,
|
||||||
order: 1,
|
groups: []
|
||||||
name: '张三',
|
}
|
||||||
team: '北京队',
|
|
||||||
time: '09:00',
|
|
||||||
status: 'finished',
|
|
||||||
statusText: '已完成'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
order: 2,
|
|
||||||
name: '李四',
|
|
||||||
team: '上海队',
|
|
||||||
time: '09:15',
|
|
||||||
status: 'finished',
|
|
||||||
statusText: '已完成'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
order: 3,
|
|
||||||
name: '王五',
|
|
||||||
team: '广东队',
|
|
||||||
time: '09:30',
|
|
||||||
status: 'ongoing',
|
|
||||||
statusText: '进行中'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
order: 4,
|
|
||||||
name: '赵六',
|
|
||||||
team: '天津队',
|
|
||||||
time: '09:45',
|
|
||||||
status: 'waiting',
|
|
||||||
statusText: '待出场'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
order: 5,
|
|
||||||
name: '刘七',
|
|
||||||
team: '江苏队',
|
|
||||||
time: '10:00',
|
|
||||||
status: 'waiting',
|
|
||||||
statusText: '待出场'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
1: [
|
|
||||||
{
|
|
||||||
order: 1,
|
|
||||||
name: '孙八',
|
|
||||||
team: '浙江队',
|
|
||||||
time: '10:30',
|
|
||||||
status: 'waiting',
|
|
||||||
statusText: '待出场'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
order: 2,
|
|
||||||
name: '周九',
|
|
||||||
team: '湖北队',
|
|
||||||
time: '10:45',
|
|
||||||
status: 'waiting',
|
|
||||||
statusText: '待出场'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
2: [
|
|
||||||
{
|
|
||||||
order: 1,
|
|
||||||
name: '小红',
|
|
||||||
team: '四川队',
|
|
||||||
time: '14:00',
|
|
||||||
status: 'waiting',
|
|
||||||
statusText: '待出场'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
order: 2,
|
|
||||||
name: '小芳',
|
|
||||||
team: '河南队',
|
|
||||||
time: '14:15',
|
|
||||||
status: 'waiting',
|
|
||||||
statusText: '待出场'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
currentLineup() {
|
currentGroup() {
|
||||||
return this.lineups[this.currentGroup] || [];
|
return this.groups[this.currentGroupIndex] || null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onLoad(options) {
|
||||||
|
if (options.eventId) {
|
||||||
|
this.eventId = options.eventId
|
||||||
|
this.orderId = options.orderId || null
|
||||||
|
this.checkScheduleStatus()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
async checkScheduleStatus() {
|
||||||
|
try {
|
||||||
|
const res = await getScheduleStatus(this.eventId)
|
||||||
|
if (res) {
|
||||||
|
this.isScheduleCompleted = res.isCompleted
|
||||||
|
if (this.isScheduleCompleted) {
|
||||||
|
await this.loadLineup()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('检查编排状态失败:', error)
|
||||||
|
uni.showToast({ title: '加载失败', icon: 'none' })
|
||||||
|
} finally {
|
||||||
|
this.loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async loadLineup() {
|
||||||
|
try {
|
||||||
|
const res = await getLineup(this.eventId, null, this.orderId)
|
||||||
|
if (res && res.groups) {
|
||||||
|
this.groups = res.groups
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载出场顺序失败:', error)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getStatusText(status) {
|
||||||
|
const map = {
|
||||||
|
'waiting': '待出场',
|
||||||
|
'未签到': '待出场',
|
||||||
|
'已完成': '已完成',
|
||||||
|
'进行中': '进行中',
|
||||||
|
'异常': '异常',
|
||||||
|
'ongoing': '进行中',
|
||||||
|
'finished': '已完成'
|
||||||
|
}
|
||||||
|
return map[status] || '待出场'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@@ -138,6 +138,38 @@ export default {
|
|||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.loading-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 300rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.not-ready {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 100rpx 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.not-ready-icon {
|
||||||
|
font-size: 80rpx;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.not-ready-text {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.not-ready-hint {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
.group-tabs {
|
.group-tabs {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -166,6 +198,21 @@ export default {
|
|||||||
padding: 0 30rpx 20rpx;
|
padding: 0 30rpx 20rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.group-header {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-venue, .group-time, .group-table {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
.lineup-item {
|
.lineup-item {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
@@ -216,10 +263,6 @@ export default {
|
|||||||
color: #666666;
|
color: #666666;
|
||||||
}
|
}
|
||||||
|
|
||||||
.divider {
|
|
||||||
margin: 0 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lineup-status {
|
.lineup-status {
|
||||||
padding: 8rpx 20rpx;
|
padding: 8rpx 20rpx;
|
||||||
border-radius: 8rpx;
|
border-radius: 8rpx;
|
||||||
@@ -227,18 +270,28 @@ export default {
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lineup-status.finished {
|
.lineup-status.finished,
|
||||||
|
.lineup-status.已完成 {
|
||||||
background-color: #E8F5E9;
|
background-color: #E8F5E9;
|
||||||
color: #4CAF50;
|
color: #4CAF50;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lineup-status.ongoing {
|
.lineup-status.ongoing,
|
||||||
|
.lineup-status.进行中 {
|
||||||
background-color: #FFF3E0;
|
background-color: #FFF3E0;
|
||||||
color: #FF9800;
|
color: #FF9800;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lineup-status.waiting {
|
.lineup-status.waiting,
|
||||||
|
.lineup-status.未签到 {
|
||||||
background-color: #F5F5F5;
|
background-color: #F5F5F5;
|
||||||
color: #999999;
|
color: #999999;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.empty-list {
|
||||||
|
text-align: center;
|
||||||
|
padding: 60rpx;
|
||||||
|
color: #999;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -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">
|
||||||
@@ -63,13 +66,16 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="player-list">
|
<view class="player-list">
|
||||||
<view class="player-item" v-for="(item, index) in teamList" :key="index">
|
<view class="player-item" v-for="(item, index) in teamList" :key="index" :class="{ 'registered': item.hasRegistered }">
|
||||||
<view class="player-checkbox" @click="toggleTeam(item)">
|
<view class="player-checkbox" @click="toggleTeam(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.memberCount || 0 }}人</view>
|
<view class="player-id">成员数:{{ item.memberCount || 0 }}人</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="player-actions">
|
<view class="player-actions">
|
||||||
@@ -282,6 +288,11 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLoad(options) {
|
onLoad(options) {
|
||||||
|
// Listen for contact added event
|
||||||
|
uni.$on('contactAdded', () => {
|
||||||
|
console.log('=== 收到 contactAdded 事件 ===')
|
||||||
|
this.loadContactList()
|
||||||
|
})
|
||||||
if (options.eventId) {
|
if (options.eventId) {
|
||||||
this.eventId = options.eventId
|
this.eventId = options.eventId
|
||||||
this.loadEventDetail(options.eventId)
|
this.loadEventDetail(options.eventId)
|
||||||
@@ -309,7 +320,21 @@ export default {
|
|||||||
this.loadPlayerList()
|
this.loadPlayerList()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onUnload() {
|
||||||
|
uni.$off('contactAdded')
|
||||||
|
},
|
||||||
onShow() {
|
onShow() {
|
||||||
|
console.log('=== onShow 被触发 ===')
|
||||||
|
// Check if contact list needs refresh
|
||||||
|
const needRefresh = uni.getStorageSync('contactListNeedRefresh')
|
||||||
|
if (needRefresh) {
|
||||||
|
console.log('检测到需要刷新联系人列表')
|
||||||
|
uni.removeStorageSync('contactListNeedRefresh')
|
||||||
|
this.loadContactList()
|
||||||
|
} else {
|
||||||
|
// Always refresh contact list when page shows
|
||||||
|
this.loadContactList()
|
||||||
|
}
|
||||||
if (this.currentStep === 1) {
|
if (this.currentStep === 1) {
|
||||||
if (this.isTeamProject) {
|
if (this.isTeamProject) {
|
||||||
this.loadTeamList()
|
this.loadTeamList()
|
||||||
@@ -322,13 +347,19 @@ export default {
|
|||||||
// Contact methods
|
// Contact methods
|
||||||
async loadContactList() {
|
async loadContactList() {
|
||||||
try {
|
try {
|
||||||
|
console.log('=== 开始加载联系人列表 ===')
|
||||||
const res = await athleteAPI.getContactList({ current: 1, size: 100 })
|
const res = await athleteAPI.getContactList({ current: 1, size: 100 })
|
||||||
this.contactList = (res.records || []).map(item => ({
|
console.log('联系人API返回:', res)
|
||||||
|
const records = res.records || res.data?.records || []
|
||||||
|
console.log('联系人记录:', records)
|
||||||
|
this.contactList = records.map(item => ({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
name: item.name,
|
name: item.name,
|
||||||
phone: item.phone,
|
phone: item.phone,
|
||||||
idCard: item.idCard
|
idCard: item.idCard,
|
||||||
|
isDefault: item.isDefault
|
||||||
}))
|
}))
|
||||||
|
console.log('处理后的联系人列表:', this.contactList)
|
||||||
// Auto select default contact if exists
|
// Auto select default contact if exists
|
||||||
if (!this.selectedContact && this.contactList.length > 0) {
|
if (!this.selectedContact && this.contactList.length > 0) {
|
||||||
const defaultContact = this.contactList.find(c => c.isDefault) || this.contactList[0]
|
const defaultContact = this.contactList.find(c => c.isDefault) || this.contactList[0]
|
||||||
@@ -397,16 +428,48 @@ export default {
|
|||||||
const res = await athleteAPI.getAthleteList({
|
const res = await athleteAPI.getAthleteList({
|
||||||
current: 1,
|
current: 1,
|
||||||
size: 100,
|
size: 100,
|
||||||
createUser: userInfo.userId
|
createUser: userInfo.userId,
|
||||||
|
registrationStatus: 0 // Only query player info records, not registration records
|
||||||
})
|
})
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
@@ -423,12 +486,43 @@ export default {
|
|||||||
})
|
})
|
||||||
|
|
||||||
let list = res.records || (Array.isArray(res) ? res : [])
|
let list = res.records || (Array.isArray(res) ? res : [])
|
||||||
this.teamList = list.map(item => ({
|
|
||||||
id: item.id,
|
// Deduplicate by id
|
||||||
name: item.teamName || item.name,
|
const seen = new Set()
|
||||||
memberCount: item.memberCount || 0,
|
list = list.filter(item => {
|
||||||
selected: false
|
const key = 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 teams have already registered for these projects
|
||||||
|
let registeredTeamNames = []
|
||||||
|
if (projectIds.length > 0 && this.eventId) {
|
||||||
|
try {
|
||||||
|
const regRes = await athleteAPI.getRegisteredAthletes({
|
||||||
|
competitionId: this.eventId,
|
||||||
|
projectIds: projectIds.join(',')
|
||||||
|
})
|
||||||
|
registeredTeamNames = (regRes || []).filter(r => r.teamName).map(r => r.teamName)
|
||||||
|
} catch (e) {
|
||||||
|
console.log('查询已报名集体失败:', e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.teamList = list.map(item => {
|
||||||
|
const teamName = item.teamName || item.name
|
||||||
|
return {
|
||||||
|
id: item.id,
|
||||||
|
name: teamName,
|
||||||
|
memberCount: item.memberCount || 0,
|
||||||
|
selected: false,
|
||||||
|
hasRegistered: registeredTeamNames.includes(teamName)
|
||||||
|
}
|
||||||
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('加载集体列表失败:', err)
|
console.error('加载集体列表失败:', err)
|
||||||
this.teamList = []
|
this.teamList = []
|
||||||
@@ -453,6 +547,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)
|
||||||
@@ -460,6 +565,17 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
toggleTeam(item) {
|
toggleTeam(item) {
|
||||||
|
// Warn if team has already registered for this project
|
||||||
|
if (item.hasRegistered && !item.selected) {
|
||||||
|
uni.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: '该集体已报名此项目,重复报名将被系统拒绝',
|
||||||
|
confirmText: '知道了',
|
||||||
|
showCancel: false
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const index = this.teamList.findIndex(t => t.id === item.id)
|
const index = this.teamList.findIndex(t => t.id === item.id)
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
this.$set(this.teamList[index], 'selected', !this.teamList[index].selected)
|
this.$set(this.teamList[index], 'selected', !this.teamList[index].selected)
|
||||||
@@ -564,6 +680,12 @@ export default {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 强制验证联系人是否已选择
|
||||||
|
if (!this.selectedContact) {
|
||||||
|
uni.showToast({ title: '请选择联系人', icon: 'none' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const now = new Date()
|
const now = new Date()
|
||||||
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')}`
|
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')}`
|
||||||
|
|
||||||
@@ -799,6 +921,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 {
|
||||||
|
|||||||
@@ -341,7 +341,7 @@ export default {
|
|||||||
},
|
},
|
||||||
goToEventDetail(item) {
|
goToEventDetail(item) {
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: '/pages/event-detail/event-detail?id=' + item.competitionId
|
url: '/pages/event-detail/event-detail?id=' + item.competitionId + '&orderId=' + item.id
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleViewCert(item) {
|
handleViewCert(item) {
|
||||||
|
|||||||
Reference in New Issue
Block a user