Codex Assistant
1 天以前 ba94ceae1315174798ae1967ef62268c6d16cd5b
web/src/views/activity-list.vue
@@ -19,6 +19,20 @@
          @keyup.enter="handleSearch"
          @clear="handleClear"
        />
        <el-select
          v-model="searchForm.state"
          placeholder="比赛状态"
          style="width: 160px"
          clearable
          @change="handleStateChange"
        >
          <el-option
            v-for="option in stateOptions"
            :key="option.value"
            :label="option.label"
            :value="option.value"
          />
        </el-select>
        <el-button type="primary" @click="handleSearch">
          <el-icon><Search /></el-icon>
          查询
@@ -43,18 +57,18 @@
        <el-table-column label="操作" width="120" fixed="right" align="center">
          <template #default="{ row }">
            <div class="table-actions">
              <el-button
                text
                :icon="Edit"
                size="small"
              <el-button
                text
                :icon="Edit"
                size="small"
                @click="handleEdit(row)"
                class="action-btn edit-btn"
                title="编辑"
              />
              <el-button
                text
                :icon="Delete"
                size="small"
              <el-button
                text
                :icon="Delete"
                size="small"
                @click="handleDelete(row)"
                class="action-btn delete-btn"
                title="删除"
@@ -81,19 +95,28 @@
</template>
<script setup lang="ts">
import { reactive, ref, onMounted } from 'vue'
import { reactive, ref, onMounted, onActivated, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { useRouter } from 'vue-router'
import { getActivities } from '@/api/activity'
import { getActivities, updateActivityState } from '@/api/activity'
import { Search, Plus, Edit, Delete } from '@element-plus/icons-vue'
console.log('=== activity-list.vue 组件开始加载 ===')
const loading = ref(false)
const router = useRouter()
// 搜索表单
const searchForm = reactive({
  name: ''
  name: '',
  state: ''
})
const stateOptions = [
  { label: '未发布', value: 0 },
  { label: '发布', value: 1 },
  { label: '关闭', value: 2 }
]
// 分页信息
const pagination = reactive({
@@ -105,13 +128,26 @@
// 表格数据
const tableData = ref([])
// 调试用途:监听表格数据变化
watch(
  tableData,
  newVal => {
    console.log('=== tableData 发生变化 ===', newVal)
    console.log('tableData.value.length:', newVal.length)
  },
  { deep: true }
)
// 获取状态标签类型
const getStatusType = (status: string) => {
  const typeMap: Record<string, string> = {
    '进行中': 'success',
    '报名中': 'warning',
    '待开始': 'info',
    '已结束': 'info'
    已发布: 'success',
    发布: 'success',
    进行中: 'success',
    报名中: 'warning',
    待开始: 'info',
    已结束: 'info',
    关闭: 'danger'
  }
  return typeMap[status] || 'info'
}
@@ -122,35 +158,45 @@
  loadData()
}
const handleStateChange = () => {
  pagination.page = 1
  loadData()
}
// 清空搜索
const handleClear = () => {
  searchForm.name = ''
  loadData()
}
 // 新增比赛
// 新增比赛
const handleAdd = () => {
  router.push('/activity/new')
}
 // 编辑比赛
// 编辑比赛
const handleEdit = (row: any) => {
  router.push(`/activity/edit/${row.id}`)
}
 // 删除比赛
// 删除比赛
const handleDelete = async (row: any) => {
  try {
    await ElMessageBox.confirm(`确定要删除比赛"${row.name}"吗?`, '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
    await ElMessageBox.confirm(
      `确定要删除比赛 “${row.name}” 吗?`,
      '提示',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )
    await updateActivityState(row.id, 2)
    ElMessage.success('删除成功')
    loadData()
  } catch {
    // 用户取消
    // 用户取消操作
  }
}
@@ -170,17 +216,37 @@
const loadData = async () => {
  loading.value = true
  try {
    const data = await getActivities(pagination.page - 1, pagination.size, searchForm.name || '')
    tableData.value = (data && data.content) ? data.content : []
    pagination.total = (data && data.totalElements) ? data.totalElements : 0
  } catch (e) {
    ElMessage.error((e && e.message) ? e.message : '加载比赛列表失败')
    const keyword = (searchForm.name || '').trim()
    const data = await getActivities(
      pagination.page - 1,
      pagination.size,
      keyword,
      searchForm.state
    )
    // 数据映射:将 API 返回字段转换为表格需要的字段
    const mappedData = (data?.content || []).map(item => ({
      ...item,
      playerCount: item.playerCount || 0,
      stateName: item.stateName || ''
    }))
    tableData.value = mappedData
    pagination.total = data?.totalElements || 0
  } catch (e: any) {
    console.error('加载数据失败:', e)
    ElMessage.error(e?.message || '加载比赛列表失败')
  } finally {
    loading.value = false
  }
}
onMounted(() => {
  loadData()
})
// 页面激活时重新加载数据(解决从新增/编辑返回后列表不同步的问题)
onActivated(() => {
  loadData()
})
</script>
@@ -242,7 +308,7 @@
  margin-bottom: 20px;
}
/* 搜索框样式 */
/* 搜索按钮 */
.search-icon {
  color: #999;
}
@@ -298,15 +364,15 @@
    align-items: stretch;
    gap: 16px;
  }
  .toolbar {
    flex-wrap: wrap;
    gap: 8px;
  }
  .toolbar .el-input {
    width: 100% !important;
    max-width: 280px;
  }
}
</style>
</style>