重构课程管理模块并更新路由选择
- 将课程管理从活动模块移至专用课程模块 - 使用新的课程管理结构更新 AdminLayout 侧边栏菜单 - 修改路由器配置以反映新的课程管理路由 - 从活动模块中删除已弃用的课程管理视图 -添加物种监测
This commit is contained in:
parent
892f6a04c8
commit
f401f40a6e
1
package-lock.json
generated
1
package-lock.json
generated
@ -1968,7 +1968,6 @@
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.6.0.tgz",
|
||||
"integrity": "sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": "2.3.0",
|
||||
"zrender": "5.6.1"
|
||||
|
30
src/api/activity/courseEnrollment.js
Normal file
30
src/api/activity/courseEnrollment.js
Normal file
@ -0,0 +1,30 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 获取课程报名列表
|
||||
* @returns {Promise} 返回报名列表数据
|
||||
*/
|
||||
export function getCourseEnrollmentList() {
|
||||
return request.get('/api/admin/course-enrollments')
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出报名记录
|
||||
* @param {Object} params - 查询参数
|
||||
* @param {number} [params.courseId] - 课程ID
|
||||
* @param {string} [params.startTime] - 开始时间
|
||||
* @param {string} [params.endTime] - 结束时间
|
||||
* @param {number} [params.status] - 状态
|
||||
* @returns {Promise} 返回文件内容
|
||||
*/
|
||||
export function exportCourseEnrollments(params = {}) {
|
||||
return request.get('/api/admin/course-enrollments/export', {
|
||||
params: {
|
||||
course_id: params.courseId,
|
||||
start_time: params.startTime,
|
||||
end_time: params.endTime,
|
||||
status: params.status === '' ? undefined : params.status
|
||||
},
|
||||
responseType: 'blob' // 设置响应类型为blob
|
||||
})
|
||||
}
|
79
src/api/monitor/species.js
Normal file
79
src/api/monitor/species.js
Normal file
@ -0,0 +1,79 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
/**
|
||||
* 查询物种列表
|
||||
* @param {Object} params - 查询参数
|
||||
* @param {number} [params.page=1] - 页码
|
||||
* @param {number} [params.page_size=10] - 每页条数
|
||||
* @param {string} [params.species_code] - 物种编号
|
||||
* @param {string} [params.chinese_name] - 中文名称
|
||||
* @param {string} [params.category] - 物种类别
|
||||
* @param {string} [params.protection_level] - 保护等级
|
||||
* @param {number} [params.status] - 状态
|
||||
* @returns {Promise} 返回物种列表数据
|
||||
*/
|
||||
export function getSpeciesList(params = {}) {
|
||||
return request.get('/api/admin/species', {
|
||||
params: {
|
||||
page: params.page || 1,
|
||||
page_size: params.page_size || 10,
|
||||
species_code: params.species_code || undefined,
|
||||
chinese_name: params.chinese_name || undefined,
|
||||
category: params.category || undefined,
|
||||
protection_level: params.protection_level || undefined,
|
||||
status: params.status === '' ? undefined : params.status
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取物种详细信息
|
||||
* @param {string|number} id - 物种ID
|
||||
* @returns {Promise} 返回物种详细信息
|
||||
*/
|
||||
export function getSpecies(id) {
|
||||
return request.get(`/api/admin/species/${id}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建物种
|
||||
* @param {Object} data - 物种数据
|
||||
* @returns {Promise} 返回创建结果
|
||||
*/
|
||||
export function addSpecies(data) {
|
||||
return request.post('/api/admin/species', data, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新物种信息
|
||||
* @param {string|number} id - 物种ID
|
||||
* @param {Object} data - 更新数据
|
||||
* @returns {Promise} 返回更新结果
|
||||
*/
|
||||
export function updateSpecies(id, data) {
|
||||
return request.put(`/api/admin/species/${id}`, data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新物种状态
|
||||
* @param {string|number} id - 物种ID
|
||||
* @param {number} status - 状态值:1-启用,0-禁用
|
||||
* @returns {Promise} 返回状态更新结果
|
||||
*/
|
||||
export function updateSpeciesStatus(id, status) {
|
||||
return request.put(`/api/admin/species/${id}/status`, {
|
||||
status: status === 1 ? 1 : 0 // 确保只发送 1 或 0
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取物种统计信息
|
||||
* @returns {Promise} 返回统计数据,包含物种类别和保护等级的统计
|
||||
*/
|
||||
export function getSpeciesStatistics() {
|
||||
return request.get('/api/admin/species/statistics/overview')
|
||||
}
|
@ -164,11 +164,19 @@ const handleLogout = () => {
|
||||
<el-icon><component :is="icons.Collection" /></el-icon>
|
||||
<span>活动管理</span>
|
||||
</template>
|
||||
<el-menu-item index="/activity/course">课程管理</el-menu-item>
|
||||
<el-menu-item index="/activity/study">研学管理</el-menu-item>
|
||||
<el-menu-item index="/activity/knowledge">知识库管理</el-menu-item>
|
||||
</el-sub-menu>
|
||||
|
||||
<el-sub-menu index="course">
|
||||
<template #title>
|
||||
<el-icon><component :is="icons.DataLine" /></el-icon>
|
||||
<span>课程管理</span>
|
||||
</template>
|
||||
<el-menu-item index="/course/index">课程管理</el-menu-item>
|
||||
<el-menu-item index="/course/application">报名管理</el-menu-item>
|
||||
</el-sub-menu>
|
||||
|
||||
<el-sub-menu index="feedback">
|
||||
<template #title>
|
||||
<el-icon><component :is="icons.DataLine" /></el-icon>
|
||||
|
@ -136,9 +136,15 @@ const router = createRouter({
|
||||
meta: { title: '轮播图管理', icon: 'picture' }
|
||||
},
|
||||
{
|
||||
path: 'activity/course',
|
||||
path: 'course/index',
|
||||
name: 'CourseManagement',
|
||||
component: () => import('../views/activity/course/index.vue')
|
||||
component: () => import('../views/course/index.vue'),
|
||||
meta: { title: '课程管理', icon: 'reading' }
|
||||
},
|
||||
{
|
||||
path: 'course/application',
|
||||
name: 'CourseApplication',
|
||||
component: () => import('../views/course/Application.vue')
|
||||
},
|
||||
{
|
||||
path: 'activity/study',
|
||||
|
@ -42,7 +42,6 @@ service.interceptors.response.use(
|
||||
}
|
||||
|
||||
const res = response.data;
|
||||
console.log('响应数据:', res)
|
||||
|
||||
// 如果响应成功
|
||||
if (res.code === 200 || res.success) {
|
||||
|
@ -37,4 +37,16 @@ export function sortArrayByField(array, field, order = 'asc') {
|
||||
});
|
||||
|
||||
return sortedArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* 反转数组顺序
|
||||
* @param {Array} array - 要反转的数组
|
||||
* @returns {Array} 反转后的新数组
|
||||
*/
|
||||
export function reverseArray(array) {
|
||||
if (!Array.isArray(array)) {
|
||||
return array;
|
||||
}
|
||||
return [...array].reverse();
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue'
|
||||
import { Plus, VideoCamera } from '@element-plus/icons-vue'
|
||||
import { Plus, VideoCamera, Loading } from '@element-plus/icons-vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { getDeviceList } from '@/api/device'
|
||||
import { createFlvPlayer, destroyFlvPlayer } from '@/utils/videoPlayer'
|
||||
@ -12,6 +12,7 @@ const mainVideoRef = ref(null)
|
||||
const mainFlvPlayer = ref(null)
|
||||
const videoRefs = ref([])
|
||||
const flvPlayers = ref([])
|
||||
const playingVideos = ref(new Set()) // 记录正在播放的视频
|
||||
|
||||
// 初始化视频播放器
|
||||
const initVideoPlayers = async () => {
|
||||
@ -28,6 +29,9 @@ const initVideoPlayers = async () => {
|
||||
})
|
||||
flvPlayers.value = []
|
||||
|
||||
// 清理播放状态
|
||||
playingVideos.value.clear()
|
||||
|
||||
// 等待DOM更新
|
||||
await nextTick()
|
||||
|
||||
@ -36,6 +40,21 @@ const initVideoPlayers = async () => {
|
||||
const deviceCode = droneList.value[currentDroneIndex.value].code
|
||||
console.log('初始化主视频播放器:', deviceCode)
|
||||
mainFlvPlayer.value = createFlvPlayer(mainVideoRef.value, deviceCode)
|
||||
|
||||
// 监听视频播放事件
|
||||
mainVideoRef.value.onplaying = () => {
|
||||
playingVideos.value.add(deviceCode)
|
||||
}
|
||||
|
||||
// 监听视频停止事件
|
||||
mainVideoRef.value.onpause = () => {
|
||||
playingVideos.value.delete(deviceCode)
|
||||
}
|
||||
|
||||
// 监听视频错误事件
|
||||
mainVideoRef.value.onerror = () => {
|
||||
playingVideos.value.delete(deviceCode)
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化列表视频播放器
|
||||
@ -45,6 +64,21 @@ const initVideoPlayers = async () => {
|
||||
console.log('初始化列表视频播放器:', index, deviceCode)
|
||||
const player = createFlvPlayer(videoRef, deviceCode)
|
||||
flvPlayers.value.push(player)
|
||||
|
||||
// 监听视频播放事件
|
||||
videoRef.onplaying = () => {
|
||||
playingVideos.value.add(deviceCode)
|
||||
}
|
||||
|
||||
// 监听视频停止事件
|
||||
videoRef.onpause = () => {
|
||||
playingVideos.value.delete(deviceCode)
|
||||
}
|
||||
|
||||
// 监听视频错误事件
|
||||
videoRef.onerror = () => {
|
||||
playingVideos.value.delete(deviceCode)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -141,6 +175,11 @@ onUnmounted(() => {
|
||||
<el-icon class="offline-icon"><VideoCamera /></el-icon>
|
||||
<span>无人机离线</span>
|
||||
</div>
|
||||
<!-- 只在视频未开始播放时显示loading -->
|
||||
<div v-if="droneList[currentDroneIndex]?.status === 'online' && !playingVideos.value.has(droneList[currentDroneIndex].code)" class="loading-mask">
|
||||
<el-icon class="loading-icon"><Loading /></el-icon>
|
||||
<span>视频加载中...</span>
|
||||
</div>
|
||||
<div class="video-info">
|
||||
<h2>{{ droneList[currentDroneIndex]?.name }}</h2>
|
||||
<div class="drone-status">
|
||||
@ -267,6 +306,32 @@ onUnmounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
.loading-mask {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
z-index: 2;
|
||||
|
||||
.loading-icon {
|
||||
font-size: 48px;
|
||||
color: #409EFF;
|
||||
margin-bottom: 16px;
|
||||
animation: rotate 1s linear infinite;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.video-info {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
|
342
src/views/course/Application.vue
Normal file
342
src/views/course/Application.vue
Normal file
@ -0,0 +1,342 @@
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted, computed } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { getCourseList } from '@/api/activity/course'
|
||||
import { getCourseEnrollmentList, exportCourseEnrollments } from '@/api/activity/courseEnrollment'
|
||||
|
||||
// 课程选项
|
||||
const courseOptions = ref([])
|
||||
|
||||
// 搜索表单数据
|
||||
const searchForm = reactive({
|
||||
courseId: '',
|
||||
enrollmentTimeRange: [],
|
||||
status: '',
|
||||
currentPage: 1,
|
||||
pageSize: 10
|
||||
})
|
||||
|
||||
// 表格数据
|
||||
const tableData = ref([])
|
||||
const total = ref(0)
|
||||
const loading = ref(false)
|
||||
|
||||
// 详情对话框显示状态
|
||||
const detailDialogVisible = ref(false)
|
||||
// 详情数据
|
||||
const detailData = ref({})
|
||||
|
||||
// 原始数据
|
||||
const originalData = ref([]);
|
||||
|
||||
// 计算属性,动态过滤数据
|
||||
const filteredData = computed(() => {
|
||||
return originalData.value.filter(item => {
|
||||
const matchCourse = searchForm.courseId ? item.userId === searchForm.courseId : true;
|
||||
const matchStatus = searchForm.status ? item.status === searchForm.status : true;
|
||||
return matchCourse && matchStatus;
|
||||
});
|
||||
});
|
||||
|
||||
// 获取课程列表
|
||||
const fetchCourseOptions = async () => {
|
||||
try {
|
||||
const res = await getCourseList() // 移除参数
|
||||
if (res.success && res.data) {
|
||||
courseOptions.value = res.data
|
||||
} else {
|
||||
courseOptions.value = []
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取课程列表失败:', error)
|
||||
ElMessage.error('获取课程列表失败')
|
||||
courseOptions.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 获取报名列表数据
|
||||
const fetchEnrollmentList = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await getCourseEnrollmentList();
|
||||
if (res.success) {
|
||||
// 存储原始数据并反转
|
||||
originalData.value = [...(res.data.list || [])].reverse().map(item => ({
|
||||
id: item.id,
|
||||
courseName: item.course_title,
|
||||
userName: item.real_name || item.username,
|
||||
userId: item.user_id,
|
||||
enrollmentTime: item.enrollment_time,
|
||||
startTime: item.start_time,
|
||||
progress: item.progress,
|
||||
status: item.status
|
||||
}));
|
||||
// 更新表格数据
|
||||
tableData.value = filteredData.value;
|
||||
total.value = res.data.pagination.total || 0;
|
||||
} else {
|
||||
console.error('获取失败:', res.message);
|
||||
ElMessage.error(res.message || '获取报名列表失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取报名列表失败:', error);
|
||||
ElMessage.error('获取报名列表失败');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 查询方法
|
||||
const handleSearch = () => {
|
||||
searchForm.currentPage = 1;
|
||||
// 更新表格数据
|
||||
tableData.value = filteredData.value;
|
||||
};
|
||||
|
||||
// 查看详情
|
||||
const handleDetail = (row) => {
|
||||
detailData.value = { ...row }
|
||||
detailDialogVisible.value = true
|
||||
}
|
||||
|
||||
// 重置表单
|
||||
const resetForm = () => {
|
||||
searchForm.courseId = '';
|
||||
searchForm.status = '';
|
||||
searchForm.currentPage = 1;
|
||||
// 重置后自动获取数据
|
||||
fetchEnrollmentList();
|
||||
};
|
||||
|
||||
// 分页方法
|
||||
const handleSizeChange = (val) => {
|
||||
searchForm.pageSize = val
|
||||
fetchEnrollmentList()
|
||||
}
|
||||
|
||||
const handleCurrentChange = (val) => {
|
||||
searchForm.currentPage = val
|
||||
fetchEnrollmentList()
|
||||
}
|
||||
|
||||
// 格式化日期时间
|
||||
const formatDateTime = (datetime) => {
|
||||
if (!datetime) return '-'
|
||||
return new Date(datetime).toLocaleString()
|
||||
}
|
||||
|
||||
// 获取状态标签类型
|
||||
const getStatusType = (status) => {
|
||||
const statusMap = {
|
||||
0: 'info',
|
||||
1: 'primary',
|
||||
2: 'success'
|
||||
}
|
||||
return statusMap[status]
|
||||
}
|
||||
|
||||
// 获取状态文本
|
||||
const getStatusText = (status) => {
|
||||
const statusMap = {
|
||||
0: '已取消',
|
||||
1: '学习中',
|
||||
2: '已完成'
|
||||
}
|
||||
return statusMap[status]
|
||||
}
|
||||
|
||||
// 导出报名记录
|
||||
const handleExport = async () => {
|
||||
try {
|
||||
const params = {
|
||||
courseId: searchForm.courseId || undefined,
|
||||
startTime: searchForm.enrollmentTimeRange?.[0],
|
||||
endTime: searchForm.enrollmentTimeRange?.[1],
|
||||
status: searchForm.status
|
||||
}
|
||||
|
||||
const res = await exportCourseEnrollments(params)
|
||||
// 创建Blob对象
|
||||
const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
|
||||
// 创建下载链接
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
// 生成文件名
|
||||
const now = new Date()
|
||||
const fileName = `报名记录_${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, '0')}${String(now.getDate()).padStart(2, '0')}.xlsx`
|
||||
link.setAttribute('download', fileName)
|
||||
// 添加到body
|
||||
document.body.appendChild(link)
|
||||
// 触发点击
|
||||
link.click()
|
||||
// 移除元素
|
||||
document.body.removeChild(link)
|
||||
// 释放URL对象
|
||||
window.URL.revokeObjectURL(url)
|
||||
|
||||
ElMessage.success('文件下载已开始')
|
||||
} catch (error) {
|
||||
console.error('导出失败:', error)
|
||||
ElMessage.error('导出失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 页面加载时获取课程列表和报名列表
|
||||
onMounted(async () => {
|
||||
await fetchCourseOptions()
|
||||
fetchEnrollmentList()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="course-application">
|
||||
<div class="search-form">
|
||||
<el-form :inline="true" :model="searchForm" class="demo-form-inline">
|
||||
<el-form-item label="课程名称">
|
||||
<el-select
|
||||
v-model="searchForm.courseId"
|
||||
placeholder="请选择课程"
|
||||
clearable
|
||||
style="width: 220px;"
|
||||
@change="handleSearch"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in courseOptions"
|
||||
:key="item.id"
|
||||
:label="item.title"
|
||||
:value="item.id"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="searchForm.status" placeholder="请选择状态" clearable style="width: 220px;" @change="handleSearch">
|
||||
<el-option label="学习中" :value="1"></el-option>
|
||||
<el-option label="已完成" :value="2"></el-option>
|
||||
<el-option label="已取消" :value="0"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button @click="handleSearch">搜索</el-button>
|
||||
<el-button @click="resetForm">重置</el-button>
|
||||
<el-button type="warning" @click="handleExport">导出</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="table-container">
|
||||
<el-table
|
||||
:data="tableData"
|
||||
border
|
||||
style="width: 100%"
|
||||
v-loading="loading"
|
||||
>
|
||||
<el-table-column prop="id" label="ID" width="80" align="center"></el-table-column>
|
||||
<el-table-column prop="courseName" label="课程名称" min-width="180" align="center"></el-table-column>
|
||||
<el-table-column prop="userName" label="学员姓名" width="120" align="center"></el-table-column>
|
||||
<el-table-column prop="enrollmentTime" label="报名时间" width="160" align="center">
|
||||
<template #default="scope">
|
||||
{{ formatDateTime(scope.row.enrollmentTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="startTime" label="开始学习时间" width="160" align="center">
|
||||
<template #default="scope">
|
||||
{{ formatDateTime(scope.row.startTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="progress" label="学习进度" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<el-progress :percentage="Number(scope.row.progress)"></el-progress>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" label="状态" width="100" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag :type="getStatusType(scope.row.status)">
|
||||
{{ getStatusText(scope.row.status) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="150" fixed="right" align="center">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
size="small"
|
||||
@click="handleDetail(scope.row)"
|
||||
>查看详情</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="pagination-container" v-if="total > 10">
|
||||
<el-pagination
|
||||
background
|
||||
layout="total, sizes, prev, pager, next"
|
||||
:total="total"
|
||||
:page-size="searchForm.pageSize"
|
||||
:current-page="searchForm.currentPage"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 详情对话框 -->
|
||||
<el-dialog
|
||||
v-model="detailDialogVisible"
|
||||
title="报名详情"
|
||||
width="600px"
|
||||
>
|
||||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item label="ID">{{ detailData.id }}</el-descriptions-item>
|
||||
<el-descriptions-item label="课程名称">{{ detailData.courseName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="学员姓名">{{ detailData.userName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="报名时间">{{ formatDateTime(detailData.enrollmentTime) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="开始学习时间">{{ formatDateTime(detailData.startTime) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="学习进度">
|
||||
<el-progress :percentage="Number(detailData.progress)"></el-progress>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="状态">
|
||||
<el-tag :type="getStatusType(detailData.status)">
|
||||
{{ getStatusText(detailData.status) }}
|
||||
</el-tag>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.course-application {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.search-form {
|
||||
background-color: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
background-color: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.el-button + .el-button {
|
||||
margin-left: 8px;
|
||||
}
|
||||
</style>
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user