fix bugs
This commit is contained in:
@@ -0,0 +1,448 @@
|
||||
<template>
|
||||
<view class="schedule-page">
|
||||
<view class="header">
|
||||
<text class="title">赛程编排管理</text>
|
||||
</view>
|
||||
|
||||
<!-- 状态显示 -->
|
||||
<view class="status-card">
|
||||
<view class="status-item">
|
||||
<text class="label">编排状态:</text>
|
||||
<text :class="['status-text', getStatusClass()]">{{ getStatusText() }}</text>
|
||||
</view>
|
||||
<view class="status-item">
|
||||
<text class="label">分组数:</text>
|
||||
<text class="value">{{ scheduleData.totalGroups || 0 }}</text>
|
||||
</view>
|
||||
<view class="status-item">
|
||||
<text class="label">参赛人数:</text>
|
||||
<text class="value">{{ scheduleData.totalParticipants || 0 }}</text>
|
||||
</view>
|
||||
<view class="status-item" v-if="scheduleData.lastAutoScheduleTime">
|
||||
<text class="label">最后编排时间:</text>
|
||||
<text class="value">{{ scheduleData.lastAutoScheduleTime }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<view class="action-buttons">
|
||||
<!-- 触发自动编排 -->
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
@click="handleAutoArrange"
|
||||
:disabled="loading || scheduleData.scheduleStatus === 2"
|
||||
>
|
||||
{{ loading ? '编排中...' : '自动编排' }}
|
||||
</button>
|
||||
|
||||
<!-- 刷新编排结果 -->
|
||||
<button
|
||||
class="btn btn-default"
|
||||
@click="loadScheduleResult"
|
||||
:disabled="loading"
|
||||
>
|
||||
刷新结果
|
||||
</button>
|
||||
|
||||
<!-- 保存并锁定 -->
|
||||
<button
|
||||
class="btn btn-success"
|
||||
@click="handleSaveAndLock"
|
||||
:disabled="loading || scheduleData.scheduleStatus === 2 || scheduleData.scheduleStatus === 0"
|
||||
>
|
||||
{{ scheduleData.scheduleStatus === 2 ? '已锁定' : '保存并锁定' }}
|
||||
</button>
|
||||
</view>
|
||||
|
||||
<!-- 编排结果列表 -->
|
||||
<view class="schedule-list" v-if="scheduleData.scheduleGroups && scheduleData.scheduleGroups.length > 0">
|
||||
<view class="list-title">编排结果</view>
|
||||
<view
|
||||
class="schedule-item"
|
||||
v-for="group in scheduleData.scheduleGroups"
|
||||
:key="group.groupId"
|
||||
>
|
||||
<view class="group-header">
|
||||
<text class="group-name">{{ group.groupName }}</text>
|
||||
<text class="participant-count">{{ group.participants.length }}人</text>
|
||||
</view>
|
||||
<view class="group-info">
|
||||
<text class="info-text">场地:{{ group.venueName }}</text>
|
||||
<text class="info-text">时间:{{ group.scheduleDate }} {{ group.scheduleTime }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view class="empty-state" v-else>
|
||||
<text class="empty-text">暂无编排数据</text>
|
||||
<text class="empty-hint">点击"自动编排"开始编排</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import scheduleAPI from '@/api/schedule.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
competitionId: null, // 赛事ID,从页面参数获取
|
||||
loading: false,
|
||||
scheduleData: {
|
||||
scheduleStatus: 0, // 0-未编排, 1-已编排, 2-已锁定
|
||||
totalGroups: 0,
|
||||
totalParticipants: 0,
|
||||
lastAutoScheduleTime: null,
|
||||
scheduleGroups: []
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
// 从页面参数获取赛事ID
|
||||
if (options.competitionId) {
|
||||
this.competitionId = parseInt(options.competitionId)
|
||||
this.loadScheduleResult()
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '缺少赛事ID',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 加载赛程编排结果
|
||||
*/
|
||||
async loadScheduleResult() {
|
||||
if (!this.competitionId) return
|
||||
|
||||
this.loading = true
|
||||
try {
|
||||
const result = await scheduleAPI.getScheduleResult(this.competitionId)
|
||||
this.scheduleData = result
|
||||
console.log('编排结果:', result)
|
||||
} catch (error) {
|
||||
console.error('加载编排结果失败:', error)
|
||||
uni.showToast({
|
||||
title: error.message || '加载失败',
|
||||
icon: 'none'
|
||||
})
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 触发自动编排
|
||||
*/
|
||||
async handleAutoArrange() {
|
||||
if (!this.competitionId) return
|
||||
|
||||
// 确认提示
|
||||
const [err, res] = await uni.showModal({
|
||||
title: '确认编排',
|
||||
content: '确定要执行自动编排吗?',
|
||||
confirmText: '确定',
|
||||
cancelText: '取消'
|
||||
})
|
||||
|
||||
if (err || !res.confirm) return
|
||||
|
||||
this.loading = true
|
||||
uni.showLoading({
|
||||
title: '编排中...',
|
||||
mask: true
|
||||
})
|
||||
|
||||
try {
|
||||
await scheduleAPI.triggerAutoArrange(this.competitionId)
|
||||
|
||||
uni.showToast({
|
||||
title: '编排成功',
|
||||
icon: 'success'
|
||||
})
|
||||
|
||||
// 延迟1秒后刷新结果
|
||||
setTimeout(() => {
|
||||
this.loadScheduleResult()
|
||||
}, 1000)
|
||||
} catch (error) {
|
||||
console.error('自动编排失败:', error)
|
||||
uni.showToast({
|
||||
title: error.message || '编排失败',
|
||||
icon: 'none'
|
||||
})
|
||||
} finally {
|
||||
this.loading = false
|
||||
uni.hideLoading()
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 保存并锁定编排
|
||||
*/
|
||||
async handleSaveAndLock() {
|
||||
if (!this.competitionId) return
|
||||
|
||||
// 确认提示
|
||||
const [err, res] = await uni.showModal({
|
||||
title: '确认锁定',
|
||||
content: '锁定后将无法再修改编排,确定要锁定吗?',
|
||||
confirmText: '确定锁定',
|
||||
cancelText: '取消'
|
||||
})
|
||||
|
||||
if (err || !res.confirm) return
|
||||
|
||||
this.loading = true
|
||||
uni.showLoading({
|
||||
title: '保存中...',
|
||||
mask: true
|
||||
})
|
||||
|
||||
try {
|
||||
await scheduleAPI.saveAndLockSchedule(this.competitionId)
|
||||
|
||||
uni.showToast({
|
||||
title: '锁定成功',
|
||||
icon: 'success'
|
||||
})
|
||||
|
||||
// 刷新结果
|
||||
setTimeout(() => {
|
||||
this.loadScheduleResult()
|
||||
}, 1000)
|
||||
} catch (error) {
|
||||
console.error('保存锁定失败:', error)
|
||||
uni.showToast({
|
||||
title: error.message || '锁定失败',
|
||||
icon: 'none'
|
||||
})
|
||||
} finally {
|
||||
this.loading = false
|
||||
uni.hideLoading()
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取状态文本
|
||||
*/
|
||||
getStatusText() {
|
||||
const statusMap = {
|
||||
0: '未编排',
|
||||
1: '已编排',
|
||||
2: '已锁定'
|
||||
}
|
||||
return statusMap[this.scheduleData.scheduleStatus] || '未知'
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取状态样式类
|
||||
*/
|
||||
getStatusClass() {
|
||||
const classMap = {
|
||||
0: 'status-pending',
|
||||
1: 'status-draft',
|
||||
2: 'status-locked'
|
||||
}
|
||||
return classMap[this.scheduleData.scheduleStatus] || ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.schedule-page {
|
||||
min-height: 100vh;
|
||||
background: #f5f5f5;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.header {
|
||||
background: #fff;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.status-card {
|
||||
background: #fff;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.status-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
min-width: 180rpx;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.status-text {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
padding: 8rpx 20rpx;
|
||||
border-radius: 8rpx;
|
||||
|
||||
&.status-pending {
|
||||
color: #999;
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
&.status-draft {
|
||||
color: #1890ff;
|
||||
background: #e6f7ff;
|
||||
}
|
||||
|
||||
&.status-locked {
|
||||
color: #52c41a;
|
||||
background: #f6ffed;
|
||||
}
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.btn {
|
||||
flex: 1;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
text-align: center;
|
||||
border-radius: 12rpx;
|
||||
font-size: 28rpx;
|
||||
border: none;
|
||||
|
||||
&.btn-primary {
|
||||
background: #1890ff;
|
||||
color: #fff;
|
||||
|
||||
&:disabled {
|
||||
background: #d9d9d9;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
&.btn-default {
|
||||
background: #fff;
|
||||
color: #333;
|
||||
border: 2rpx solid #d9d9d9;
|
||||
|
||||
&:disabled {
|
||||
background: #f5f5f5;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
&.btn-success {
|
||||
background: #52c41a;
|
||||
color: #fff;
|
||||
|
||||
&:disabled {
|
||||
background: #d9d9d9;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.schedule-list {
|
||||
background: #fff;
|
||||
padding: 30rpx;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.list-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.schedule-item {
|
||||
padding: 24rpx;
|
||||
background: #f9f9f9;
|
||||
border-radius: 12rpx;
|
||||
margin-bottom: 16rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.group-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.group-name {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.participant-count {
|
||||
font-size: 24rpx;
|
||||
color: #1890ff;
|
||||
background: #e6f7ff;
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: 6rpx;
|
||||
}
|
||||
|
||||
.group-info {
|
||||
display: flex;
|
||||
gap: 30rpx;
|
||||
}
|
||||
|
||||
.info-text {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 120rpx 0;
|
||||
background: #fff;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 32rpx;
|
||||
color: #999;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.empty-hint {
|
||||
font-size: 26rpx;
|
||||
color: #ccc;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user