update:运动馆
This commit is contained in:
parent
a5e185e551
commit
e8ecf2c0fc
@ -7,7 +7,7 @@
|
||||
<meta name="viewport" content="width=device-width, maximum-scale=1.0, minimum-scale=1.0, initial-scale=1.0, user-scalable=no" />
|
||||
<meta name="keywords" content=".netccore,dotnet core,vue,element,element plus,vue3" />
|
||||
<meta name="description" content="智慧系统" />
|
||||
<!-- <link rel="icon" href="<%= BASE_URL %>favicon.ico"> -->
|
||||
<link rel="icon" href="favicon.ico">
|
||||
<title>智慧系统</title>
|
||||
</head>
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 195 KiB |
@ -595,6 +595,14 @@ const routes = [{
|
||||
name: 'sportsHallClass',
|
||||
component: () => import('@/views/sportsHall/classManage/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/sportHallReport', //运动馆/体测报告
|
||||
name: 'sportHallReport',
|
||||
component: () => import('@/views/sportHallReport/index.vue'),
|
||||
meta: {
|
||||
keepAlive: false
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/openReservation', //学校管理/开放预约
|
||||
name: 'openReservation',
|
||||
|
||||
841
src/views/sportHallReport/index.vue
Normal file
841
src/views/sportHallReport/index.vue
Normal file
@ -0,0 +1,841 @@
|
||||
<template>
|
||||
<div class="sport-hall-report">
|
||||
|
||||
<!-- 搜索区域 -->
|
||||
<div class="search-card">
|
||||
<div class="search-row">
|
||||
<div class="search-item">
|
||||
<span class="label">项目:</span>
|
||||
<el-select v-model="query.project" placeholder="全部" clearable style="width: 160px">
|
||||
<el-option label="全部" value="" />
|
||||
<el-option v-for="item in projectOptions" :key="item.id" :label="item.itemTypeName" :value="item.id" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<span class="label">年级-班级:</span>
|
||||
<el-cascader
|
||||
v-model="query.gradeClass"
|
||||
:options="gradeClassOptions"
|
||||
:props="{ checkStrictly: true }"
|
||||
clearable
|
||||
placeholder="全部"
|
||||
style="width: 200px"
|
||||
/>
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<span class="label">性别:</span>
|
||||
<el-select v-model="query.gender" placeholder="全部" style="width: 130px">
|
||||
<el-option label="全部" value="" />
|
||||
<el-option label="男" :value="1" />
|
||||
<el-option label="女" :value="2" />
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<span class="label">等级:</span>
|
||||
<el-select v-model="query.rank" placeholder="全部" style="width: 130px">
|
||||
<el-option label="全部" value="" />
|
||||
<el-option label="优秀" value="优秀" />
|
||||
<el-option label="良好" value="良好" />
|
||||
<el-option label="及格" value="及格" />
|
||||
<el-option label="不及格" value="不及格" />
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-row">
|
||||
<div class="search-item">
|
||||
<span class="label">测试时间:</span>
|
||||
<el-date-picker
|
||||
v-model="query.dateRange"
|
||||
type="daterange"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
range-separator="~"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
style="width: 260px"
|
||||
/>
|
||||
</div>
|
||||
<div class="search-actions">
|
||||
<el-button class="btn-reset" @click="handleReset">重置</el-button>
|
||||
<el-button class="btn-search" type="primary" @click="handleSearch">查询</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作栏 -->
|
||||
<div class="table-toolbar">
|
||||
<div class="toolbar-right">
|
||||
<el-tooltip content="将本次成绩推送至运动馆—家长端—【统计】—体测报告" placement="top">
|
||||
<el-button class="action-btn import-btn" @click="handleImport">
|
||||
导入成绩
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="本次成绩推送至运动馆—家长端—【统计】—一体测报告" placement="top">
|
||||
<el-button class="action-btn send-btn" @click="handleSendScore">
|
||||
成绩推送
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<div class="table-card">
|
||||
<el-table
|
||||
:data="tableData"
|
||||
v-loading="loading"
|
||||
style="width: 100%"
|
||||
:header-cell-style="{
|
||||
background: '#f5f7fa',
|
||||
color: '#606266',
|
||||
fontWeight: '600',
|
||||
fontSize: '13px',
|
||||
padding: '12px 0'
|
||||
}"
|
||||
:row-style="{ height: '52px' }"
|
||||
stripe
|
||||
border
|
||||
>
|
||||
<el-table-column type="index" label="序号" width="70" align="center" />
|
||||
<el-table-column prop="studentName" label="学生姓名" min-width="100" align="center" />
|
||||
<el-table-column prop="gradeAndClass" label="年级-班级" min-width="140" align="center" />
|
||||
<el-table-column prop="gender" label="性别" width="70" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.gender === 1 ? 'primary' : 'danger'" size="small" effect="light">
|
||||
{{ row.gender === 1 ? '男' : '女' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="bmi" label="体质指数(BMI)" min-width="130" align="center">
|
||||
<template #default="{ row }">
|
||||
<span>{{ row.bmi ?? '/' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="lungCapacity" label="肺活量(ml)" min-width="110" align="center">
|
||||
<template #default="{ row }">
|
||||
<span>{{ row.lungCapacity ?? '/' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="sitAndReach" label="坐位体前屈(cm)" min-width="140" align="center">
|
||||
<template #default="{ row }">
|
||||
<span>{{ row.sitAndReach ?? '/' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="ropeSkipping" label="一分钟跳绳(个)" min-width="140" align="center">
|
||||
<template #default="{ row }">
|
||||
<span>{{ row.ropeSkipping ?? '/' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="sitUp" label="一分钟仰卧起坐(个)" min-width="160" align="center">
|
||||
<template #default="{ row }">
|
||||
<span>{{ row.sitUp ?? '/' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="standingLongJump" label="立定跳远(cm)" min-width="130" align="center">
|
||||
<template #default="{ row }">
|
||||
<span>{{ row.standingLongJump ?? '/' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="testTime" label="测试时间" min-width="160" align="center" />
|
||||
<el-table-column label="操作" width="100" align="center">
|
||||
<template #default="{ row }" width="100">
|
||||
<el-button type="primary" link @click="handleEdit(row)">成绩修正</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-wrap">
|
||||
<el-pagination
|
||||
v-model:current-page="pagination.pageIndex"
|
||||
v-model:page-size="pagination.pageSize"
|
||||
:total="pagination.total"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
background
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handlePageChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 导入成绩弹窗 -->
|
||||
<el-dialog
|
||||
v-model="importDialog.visible"
|
||||
title="导入成绩"
|
||||
width="640px"
|
||||
:close-on-click-modal="false"
|
||||
class="import-dialog"
|
||||
>
|
||||
<div class="import-content">
|
||||
<!-- 说明区域 -->
|
||||
<div class="import-tips">
|
||||
<p><span class="tip-num">1.</span>上传前请先下载标准Excel模板并按照标准模板中的说明编辑文件</p>
|
||||
<p><span class="tip-num">2.</span>一次最多上传10000行数据,文件大小不能超过10M</p>
|
||||
<p><span class="tip-num">3.</span>支持上传xlsx格式文件</p>
|
||||
<p><span class="tip-num">4.</span>最新数据覆盖上次数据</p>
|
||||
</div>
|
||||
|
||||
<!-- 上传区域 -->
|
||||
<div class="upload-area">
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
class="upload-dragger"
|
||||
drag
|
||||
:action="uploadUrl"
|
||||
:headers="uploadHeaders"
|
||||
:before-upload="beforeUpload"
|
||||
:on-success="onUploadSuccess"
|
||||
:on-error="onUploadError"
|
||||
:show-file-list="false"
|
||||
accept=".xlsx"
|
||||
>
|
||||
<div class="upload-inner">
|
||||
<img src="@/assets/images/excel-icon.png" class="excel-icon" @error="onIconError" alt="Excel" />
|
||||
<div class="upload-text">
|
||||
将模板拖拽到此区域 或
|
||||
<span class="upload-link">点击上传</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-upload>
|
||||
|
||||
<div class="download-btn-wrap">
|
||||
<el-button class="btn-download" @click="downloadTemplate">
|
||||
下载标准Excel模板
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="importDialog.visible = false">关闭</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 成绩修正弹窗 -->
|
||||
<el-dialog
|
||||
v-model="editDialog.visible"
|
||||
title="成绩修正"
|
||||
width="560px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-form ref="editFormRef" :model="editForm" label-width="160px" size="default">
|
||||
<el-form-item label="学生姓名">
|
||||
<el-input :value="editForm.studentName" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item label="体质指数(BMI)">
|
||||
<el-input v-model="editForm.bmi" placeholder="请输入" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="肺活量(ml)">
|
||||
<el-input v-model="editForm.lungCapacity" placeholder="请输入" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="坐位体前屈(cm)">
|
||||
<el-input v-model="editForm.sitAndReach" placeholder="请输入" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="一分钟跳绳(个)">
|
||||
<el-input v-model="editForm.ropeSkipping" placeholder="请输入" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="一分钟仰卧起坐(个)">
|
||||
<el-input v-model="editForm.sitUp" placeholder="请输入" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="立定跳远(cm)">
|
||||
<el-input v-model="editForm.standingLongJump" placeholder="请输入" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="editDialog.visible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleEditConfirm">保存</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
|
||||
import axios from 'axios'
|
||||
|
||||
// ===================== 查询参数 =====================
|
||||
const query = reactive({
|
||||
project: '',
|
||||
gradeClass: [],
|
||||
gender: '',
|
||||
rank: '',
|
||||
dateRange: [] as string[]
|
||||
})
|
||||
|
||||
// ===================== 下拉数据 =====================
|
||||
const projectOptions = ref<any[]>([])
|
||||
const gradeClassOptions = ref<any[]>([])
|
||||
|
||||
// ===================== 表格数据 =====================
|
||||
const loading = ref(false)
|
||||
const tableData = ref<any[]>([])
|
||||
|
||||
const pagination = reactive({
|
||||
pageIndex: 1,
|
||||
pageSize: 10,
|
||||
total: 0
|
||||
})
|
||||
|
||||
// ===================== 模拟数据(接口接入后替换) =====================
|
||||
const mockData = [
|
||||
{
|
||||
id: 1, studentName: '崔政豪', gradeAndClass: '运动馆-周一班', gender: 1,
|
||||
bmi: '178/140/28', lungCapacity: 2344, sitAndReach: null, ropeSkipping: 200, sitUp: 200, standingLongJump: null, testTime: '2024-08-09 12:00'
|
||||
},
|
||||
{
|
||||
id: 2, studentName: '金辰恺', gradeAndClass: '运动馆-周一班', gender: 2,
|
||||
bmi: '178/140/28', lungCapacity: null, sitAndReach: 12, ropeSkipping: 180, sitUp: 180, standingLongJump: 12, testTime: '2024-08-09 12:00'
|
||||
},
|
||||
{
|
||||
id: 3, studentName: '樊鸣轩', gradeAndClass: '运动馆-周一班', gender: 1,
|
||||
bmi: '178/140/28', lungCapacity: 5643, sitAndReach: 10, ropeSkipping: null, sitUp: null, standingLongJump: 10, testTime: '2024-08-09 12:00'
|
||||
},
|
||||
{
|
||||
id: 4, studentName: '陈睿鸿', gradeAndClass: '运动馆-周一班', gender: 2,
|
||||
bmi: '178/140/28', lungCapacity: null, sitAndReach: null, ropeSkipping: 230, sitUp: 230, standingLongJump: null, testTime: '2024-08-09 12:00'
|
||||
},
|
||||
{
|
||||
id: 5, studentName: '俞鑫安', gradeAndClass: '运动馆-周一班', gender: 1,
|
||||
bmi: '178/140/28', lungCapacity: 2345, sitAndReach: null, ropeSkipping: 109, sitUp: 109, standingLongJump: null, testTime: '2024-08-09 12:00'
|
||||
}
|
||||
]
|
||||
|
||||
// ===================== 获取列表 =====================
|
||||
const fetchList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
// TODO: 替换为实际接口
|
||||
// const res = await getSportHallReport({ ...query, ...pagination })
|
||||
// tableData.value = res.data.datas
|
||||
// pagination.total = res.data.total
|
||||
|
||||
// 使用模拟数据
|
||||
await new Promise(resolve => setTimeout(resolve, 300))
|
||||
tableData.value = mockData
|
||||
pagination.total = 400
|
||||
} catch (e) {
|
||||
ElMessage.error('获取数据失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// ===================== 获取下拉选项 =====================
|
||||
const fetchOptions = async () => {
|
||||
try {
|
||||
// TODO: 替换为实际接口获取项目列表和年级班级列表
|
||||
gradeClassOptions.value = [
|
||||
{
|
||||
value: '1',
|
||||
label: '运动馆',
|
||||
children: [
|
||||
{ value: '1-1', label: '周一班' },
|
||||
{ value: '1-2', label: '周二班' },
|
||||
{ value: '1-3', label: '周三班' },
|
||||
]
|
||||
}
|
||||
]
|
||||
} catch (e) {
|
||||
console.error('获取下拉选项失败', e)
|
||||
}
|
||||
}
|
||||
|
||||
// ===================== 搜索/重置 =====================
|
||||
const handleSearch = () => {
|
||||
pagination.pageIndex = 1
|
||||
fetchList()
|
||||
}
|
||||
|
||||
const handleReset = () => {
|
||||
query.project = ''
|
||||
query.gradeClass = []
|
||||
query.gender = ''
|
||||
query.rank = ''
|
||||
query.dateRange = []
|
||||
pagination.pageIndex = 1
|
||||
fetchList()
|
||||
}
|
||||
|
||||
// ===================== 分页 =====================
|
||||
const handleSizeChange = (size: number) => {
|
||||
pagination.pageSize = size
|
||||
pagination.pageIndex = 1
|
||||
fetchList()
|
||||
}
|
||||
|
||||
const handlePageChange = (page: number) => {
|
||||
pagination.pageIndex = page
|
||||
fetchList()
|
||||
}
|
||||
|
||||
// ===================== 导入成绩 =====================
|
||||
const importDialog = reactive({ visible: false })
|
||||
const uploadRef = ref()
|
||||
|
||||
const uploadUrl = `${import.meta.env.VITE_APP_BASE_API || ''}/api/sportHall/importScore`
|
||||
const uploadHeaders = reactive({
|
||||
Authorization: `Bearer ${localStorage.getItem('token') || ''}`
|
||||
})
|
||||
|
||||
const handleImport = () => {
|
||||
importDialog.visible = true
|
||||
}
|
||||
|
||||
const beforeUpload = (file: File) => {
|
||||
const isXlsx = file.name.endsWith('.xlsx')
|
||||
if (!isXlsx) {
|
||||
ElMessage.error('只支持上传 .xlsx 格式文件')
|
||||
return false
|
||||
}
|
||||
const isLt10M = file.size / 1024 / 1024 < 10
|
||||
if (!isLt10M) {
|
||||
ElMessage.error('文件大小不能超过 10MB')
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
const onUploadSuccess = (response: any) => {
|
||||
if (response?.code === 200) {
|
||||
ElMessage.success('导入成功')
|
||||
importDialog.visible = false
|
||||
fetchList()
|
||||
} else {
|
||||
ElMessage.error(response?.message || '导入失败')
|
||||
}
|
||||
}
|
||||
|
||||
const onUploadError = () => {
|
||||
ElMessage.error('文件上传失败,请重试')
|
||||
}
|
||||
|
||||
const onIconError = (e: Event) => {
|
||||
const img = e.target as HTMLImageElement
|
||||
img.style.display = 'none'
|
||||
}
|
||||
|
||||
const downloadTemplate = async () => {
|
||||
try {
|
||||
// TODO: 替换为实际模板下载接口
|
||||
ElMessage.info('正在下载模板...')
|
||||
// const res = await axios.get('/api/sportHall/downloadTemplate', { responseType: 'blob' })
|
||||
// const url = window.URL.createObjectURL(new Blob([res.data]))
|
||||
// const link = document.createElement('a')
|
||||
// link.href = url
|
||||
// link.setAttribute('download', '体测成绩导入模板.xlsx')
|
||||
// document.body.appendChild(link)
|
||||
// link.click()
|
||||
// document.body.removeChild(link)
|
||||
} catch (e) {
|
||||
ElMessage.error('模板下载失败')
|
||||
}
|
||||
}
|
||||
|
||||
// ===================== 成绩推送 =====================
|
||||
const handleSendScore = () => {
|
||||
ElMessageBox.confirm(
|
||||
'确认将本次成绩推送至运动馆—家长端—【统计】—一体测报告?',
|
||||
'成绩推送',
|
||||
{
|
||||
confirmButtonText: '确认推送',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}
|
||||
).then(() => {
|
||||
// TODO: 调用推送接口
|
||||
ElMessage.success('推送成功')
|
||||
}).catch(() => {})
|
||||
}
|
||||
|
||||
// ===================== 成绩修正 =====================
|
||||
const editDialog = reactive({ visible: false })
|
||||
const editFormRef = ref()
|
||||
const editForm = reactive({
|
||||
id: null as any,
|
||||
studentName: '',
|
||||
bmi: '' as any,
|
||||
lungCapacity: '' as any,
|
||||
sitAndReach: '' as any,
|
||||
ropeSkipping: '' as any,
|
||||
sitUp: '' as any,
|
||||
standingLongJump: '' as any
|
||||
})
|
||||
|
||||
const handleEdit = (row: any) => {
|
||||
Object.assign(editForm, {
|
||||
id: row.id,
|
||||
studentName: row.studentName,
|
||||
bmi: row.bmi ?? '',
|
||||
lungCapacity: row.lungCapacity ?? '',
|
||||
sitAndReach: row.sitAndReach ?? '',
|
||||
ropeSkipping: row.ropeSkipping ?? '',
|
||||
sitUp: row.sitUp ?? '',
|
||||
standingLongJump: row.standingLongJump ?? ''
|
||||
})
|
||||
editDialog.visible = true
|
||||
}
|
||||
|
||||
const handleEditConfirm = async () => {
|
||||
try {
|
||||
// TODO: 调用成绩修正接口
|
||||
// await updateSportHallScore(editForm)
|
||||
ElMessage.success('修正成功')
|
||||
editDialog.visible = false
|
||||
fetchList()
|
||||
} catch (e) {
|
||||
ElMessage.error('操作失败,请重试')
|
||||
}
|
||||
}
|
||||
|
||||
// ===================== 初始化 =====================
|
||||
onMounted(() => {
|
||||
fetchOptions()
|
||||
fetchList()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.sport-hall-report {
|
||||
width: calc(100% - 32px);
|
||||
min-height: calc(100vh - 100px);
|
||||
margin: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
|
||||
// 面包屑
|
||||
.breadcrumb {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 14px 20px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||
|
||||
:deep(.el-breadcrumb__inner) {
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
:deep(.el-breadcrumb__item:last-child .el-breadcrumb__inner) {
|
||||
color: #303133;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索卡片
|
||||
.search-card {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 18px 20px 10px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||
|
||||
.search-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px 20px;
|
||||
margin-bottom: 12px;
|
||||
|
||||
.search-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.label {
|
||||
font-size: 13px;
|
||||
color: #606266;
|
||||
white-space: nowrap;
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.search-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-left: auto;
|
||||
|
||||
.btn-reset {
|
||||
border-radius: 6px;
|
||||
padding: 8px 20px;
|
||||
color: #606266;
|
||||
border-color: #dcdfe6;
|
||||
background: #fff;
|
||||
font-size: 13px;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
color: #409eff;
|
||||
border-color: #c6e2ff;
|
||||
background: #ecf5ff;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-search {
|
||||
border-radius: 6px;
|
||||
padding: 8px 24px;
|
||||
font-size: 13px;
|
||||
background: linear-gradient(135deg, #409eff 0%, #337ecc 100%);
|
||||
border: none;
|
||||
box-shadow: 0 2px 6px rgba(64, 158, 255, 0.4);
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
background: linear-gradient(135deg, #66b1ff 0%, #409eff 100%);
|
||||
box-shadow: 0 4px 10px rgba(64, 158, 255, 0.5);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 操作工具栏
|
||||
.table-toolbar {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
padding: 0 4px;
|
||||
|
||||
.toolbar-right {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
|
||||
.action-btn {
|
||||
position: relative;
|
||||
padding: 8px 24px 8px 30px;
|
||||
border-radius: 6px;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: all 0.25s;
|
||||
color: #fff;
|
||||
|
||||
.btn-badge {
|
||||
position: absolute;
|
||||
top: -7px;
|
||||
left: 10px;
|
||||
border-radius: 50%;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
font-size: 11px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: 700;
|
||||
border: 2px solid #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.import-btn {
|
||||
background: linear-gradient(135deg, #409eff 0%, #337ecc 100%);
|
||||
box-shadow: 0 2px 8px rgba(64, 158, 255, 0.45);
|
||||
|
||||
.btn-badge {
|
||||
background: #fff;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: linear-gradient(135deg, #66b1ff 0%, #409eff 100%);
|
||||
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.55);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.send-btn {
|
||||
background: linear-gradient(135deg, #67c23a 0%, #529b2e 100%);
|
||||
box-shadow: 0 2px 8px rgba(103, 194, 58, 0.45);
|
||||
|
||||
.btn-badge {
|
||||
background: #fff;
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: linear-gradient(135deg, #85ce61 0%, #67c23a 100%);
|
||||
box-shadow: 0 4px 12px rgba(103, 194, 58, 0.55);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 表格卡片
|
||||
.table-card {
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
|
||||
flex: 1;
|
||||
|
||||
:deep(.el-table) {
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
:deep(.el-table th) {
|
||||
background: #f5f7fa !important;
|
||||
}
|
||||
|
||||
:deep(.el-table--striped .el-table__body tr.el-table__row--striped td) {
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
:deep(.el-button.is-link) {
|
||||
color: #409eff;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
.pagination-wrap {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 16px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
}
|
||||
|
||||
// 导入弹窗
|
||||
.import-dialog {
|
||||
:deep(.el-dialog__header) {
|
||||
padding: 20px 24px 12px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
margin: 0;
|
||||
|
||||
.el-dialog__title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-dialog__body) {
|
||||
padding: 20px 24px;
|
||||
}
|
||||
|
||||
:deep(.el-dialog__footer) {
|
||||
padding: 12px 24px 20px;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
}
|
||||
}
|
||||
|
||||
.import-content {
|
||||
.import-tips {
|
||||
background: #f0f7ff;
|
||||
border-radius: 6px;
|
||||
padding: 16px 18px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
p {
|
||||
font-size: 13px;
|
||||
color: #495464;
|
||||
line-height: 2;
|
||||
margin: 0;
|
||||
|
||||
.tip-num {
|
||||
color: #409eff;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.upload-area {
|
||||
border: 1px dashed #d9d9d9;
|
||||
border-radius: 8px;
|
||||
padding: 24px;
|
||||
background: #fafafa;
|
||||
transition: border-color 0.2s;
|
||||
|
||||
&:hover {
|
||||
border-color: #409eff;
|
||||
}
|
||||
|
||||
.upload-dragger {
|
||||
width: 100%;
|
||||
|
||||
:deep(.el-upload) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.el-upload-dragger) {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
padding: 24px 0;
|
||||
border: none;
|
||||
background: transparent;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.upload-inner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
|
||||
.excel-icon {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.upload-text {
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
|
||||
.upload-link {
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.download-btn-wrap {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 16px;
|
||||
|
||||
.btn-download {
|
||||
border-radius: 20px;
|
||||
padding: 9px 24px;
|
||||
font-size: 13px;
|
||||
color: #409eff;
|
||||
border: 1px solid #c6e2ff;
|
||||
background: #ecf5ff;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
background: #409eff;
|
||||
color: #fff;
|
||||
border-color: #409eff;
|
||||
box-shadow: 0 3px 8px rgba(64, 158, 255, 0.4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Loading…
x
Reference in New Issue
Block a user