937 lines
19 KiB
Vue
937 lines
19 KiB
Vue
<template>
|
||
<view class="home-container">
|
||
|
||
|
||
<!-- 空状态 -->
|
||
<view class="empty-state-container">
|
||
<!-- 标题区域 -->
|
||
<view class="title-section">
|
||
<text class="main-title">暂无项目</text>
|
||
<text class="sub-title">您还没有创建任何训练项目,开始您的第一次游泳训练记录吧</text>
|
||
</view>
|
||
|
||
<!-- 创建项目模块列表 -->
|
||
<view class="create-modules">
|
||
<!-- 计时项目模块 -->
|
||
<view @click="showTimingProjectModal(1)" class="create-card timing-card">
|
||
<view class="card-icon">
|
||
<view class="icon-circle timing-icon">
|
||
<u-icon name="clock" size="40" color="#fff"></u-icon>
|
||
</view>
|
||
</view>
|
||
<view class="card-info">
|
||
<text class="card-title">计时项目</text>
|
||
<text class="card-desc">记录单次训练的计时数据</text>
|
||
</view>
|
||
<view class="card-arrow">
|
||
<u-icon name="arrow-right" size="20" color="#1890ff"></u-icon>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 包干项目模块 -->
|
||
<view @click="showTimingProjectModal(2)" class="create-card package-card">
|
||
<view class="card-icon">
|
||
<view class="icon-circle package-icon">
|
||
<u-icon name="grid" size="40" color="#fff"></u-icon>
|
||
</view>
|
||
</view>
|
||
<view class="card-info">
|
||
<text class="card-title">包干项目</text>
|
||
<text class="card-desc">记录固定距离的训练成绩</text>
|
||
</view>
|
||
<view class="card-arrow">
|
||
<u-icon name="arrow-right" size="20" color="#1890ff"></u-icon>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 分段项目模块 -->
|
||
<view @click="createSegmentProject" class="create-card segment-card">
|
||
<view class="card-icon">
|
||
<view class="icon-circle segment-icon">
|
||
<u-icon name="list" size="40" color="#fff"></u-icon>
|
||
</view>
|
||
</view>
|
||
<view class="card-info">
|
||
<text class="card-title">分段项目</text>
|
||
<text class="card-desc">记录分段训练的详细数据</text>
|
||
</view>
|
||
<view class="card-arrow">
|
||
<u-icon name="arrow-right" size="20" color="#1890ff"></u-icon>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 计时项目列表弹窗 -->
|
||
<view v-if="showTimingModal" class="modal-overlay" @click="closeTimingProjectModal"></view>
|
||
<view v-if="showTimingModal" class="project-list-modal">
|
||
<view class="modal-header">
|
||
<text class="modal-title">计时项目</text>
|
||
<view class="modal-close" @click="closeTimingProjectModal">
|
||
<u-icon name="close" size="20" color="#999"></u-icon>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="modal-content">
|
||
<!-- 新增按钮 -->
|
||
<view v-if="currentIndex!==2" class="add-btn" @click="createTimingProject">
|
||
<u-icon name="plus" size="18" color="#1890ff"></u-icon>
|
||
<text class="add-btn-text">新增项目</text>
|
||
</view>
|
||
|
||
<!-- 项目列表 -->
|
||
<view class="project-list">
|
||
<text class="list-title" v-if="projects.length > 0">项目列表</text>
|
||
<view v-if="projects.length > 0" class="list-container">
|
||
<view v-for="project in projects" :key="project.id" class="project-item"
|
||
@click=" goPageFunc() ">
|
||
<view class="item-icon">
|
||
<view class="icon-bg">
|
||
<text class="icon-text">{{ project.name.charAt(0) }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="item-info">
|
||
<text class="item-name">{{ project.name }}</text>
|
||
<text class="item-count">{{ project.studentCount }}人</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view v-else class="empty-project">
|
||
<text class="empty-text">暂无项目</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, onMounted, onUnmounted } from 'vue'
|
||
import { Service } from '@/Service/Service'
|
||
|
||
// 项目类型
|
||
interface Project {
|
||
id : string
|
||
name : string
|
||
startType : string // together | interval
|
||
intervalSeconds : string
|
||
laneType : string // single | multi
|
||
laneCount : string
|
||
lanePersonCount : string
|
||
studentCount : number
|
||
students : {
|
||
id : string
|
||
name : string
|
||
gender : string
|
||
age : string
|
||
}[]
|
||
}
|
||
|
||
let currentIndex=ref(0)
|
||
|
||
// 模拟项目数据
|
||
const projects = ref<Project[]>([
|
||
{
|
||
id: '001',
|
||
name: '自由泳500米',
|
||
startType: 'together',
|
||
intervalSeconds: '',
|
||
laneType: 'multi',
|
||
laneCount: '4',
|
||
lanePersonCount: '2',
|
||
studentCount: 8,
|
||
students: [
|
||
{ id: 's1', name: '张三', gender: '男', age: '12' },
|
||
{ id: 's2', name: '李四', gender: '女', age: '13' },
|
||
{ id: 's3', name: '王五', gender: '男', age: '11' },
|
||
{ id: 's4', name: '赵六', gender: '女', age: '12' },
|
||
{ id: 's5', name: '钱七', gender: '男', age: '14' },
|
||
{ id: 's6', name: '孙八', gender: '女', age: '10' },
|
||
{ id: 's7', name: '周九', gender: '男', age: '13' },
|
||
{ id: 's8', name: '吴十', gender: '女', age: '12' }
|
||
]
|
||
|
||
},
|
||
{
|
||
id: '002',
|
||
name: '蛙泳200米',
|
||
startType: 'interval',
|
||
intervalSeconds: '30',
|
||
laneType: 'single',
|
||
laneCount: '',
|
||
lanePersonCount: '',
|
||
studentCount: 5,
|
||
students: [
|
||
{ id: 's1', name: '陈十一', gender: '男', age: '14' },
|
||
{ id: 's2', name: '林十二', gender: '女', age: '12' },
|
||
{ id: 's3', name: '黄十三', gender: '男', age: '11' },
|
||
{ id: 's4', name: '周十四', gender: '女', age: '13' },
|
||
{ id: 's5', name: '吴十五', gender: '男', age: '10' }
|
||
]
|
||
}
|
||
])
|
||
|
||
// 弹窗状态
|
||
const showTimingModal = ref(false)
|
||
const showDetailModal = ref(false)
|
||
const currentProject = ref<Project | null>(null)
|
||
|
||
|
||
// 生命周期
|
||
onMounted(() => {
|
||
// TODO: 实际应从接口获取项目列表
|
||
})
|
||
|
||
onUnmounted(() => {
|
||
// 清理
|
||
})
|
||
|
||
// 显示计时项目列表弹窗
|
||
const showTimingProjectModal = (index:any) => {
|
||
showTimingModal.value = true
|
||
currentIndex.value=index
|
||
}
|
||
|
||
// 关闭计时项目列表弹窗
|
||
const closeTimingProjectModal = () => {
|
||
showTimingModal.value = false
|
||
}
|
||
|
||
// 创建计时项目
|
||
const createTimingProject = () => {
|
||
Service.GoPage('/pages/userFunc/setCourse')
|
||
}
|
||
|
||
// 创建包干项目
|
||
const createPackageProject = () => {
|
||
Service.GoPage('/pages/userFunc/setCourse')
|
||
}
|
||
|
||
// 创建分段项目
|
||
const createSegmentProject = () => {
|
||
Service.GoPage('/pages/userFunc/setCourse')
|
||
}
|
||
|
||
// 显示项目详情
|
||
const showProjectDetail = (project : Project) => {
|
||
currentProject.value = project
|
||
showTimingModal.value = false
|
||
showDetailModal.value = true
|
||
}
|
||
|
||
// 关闭弹窗
|
||
const closeDetailModal = () => {
|
||
showDetailModal.value = false
|
||
currentProject.value = null
|
||
}
|
||
|
||
|
||
const goPageFunc=()=>{
|
||
if(currentIndex.value==1){
|
||
Service.GoPage('/pages/userFunc/swiming')
|
||
}else{
|
||
Service.GoPage('/pages/userFunc/project')
|
||
}
|
||
|
||
}
|
||
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
page {
|
||
background-color: #f5f5f5;
|
||
}
|
||
|
||
.home-container {
|
||
padding: 20rpx;
|
||
}
|
||
|
||
/* 项目列表区域 */
|
||
.projects-section {
|
||
padding: 20rpx 0;
|
||
}
|
||
|
||
/* 计时器卡片 */
|
||
.timer-card {
|
||
background-color: #fff;
|
||
border-radius: 24rpx;
|
||
padding: 30rpx;
|
||
margin-bottom: 20rpx;
|
||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
|
||
|
||
.timer-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 30rpx;
|
||
|
||
.timer-title {
|
||
font-size: 32rpx;
|
||
font-weight: 700;
|
||
color: #333;
|
||
}
|
||
|
||
.task-count {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
|
||
.timer-content {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 30rpx;
|
||
|
||
&:active {
|
||
transform: scale(0.98);
|
||
}
|
||
}
|
||
|
||
.timer-circle {
|
||
position: relative;
|
||
}
|
||
|
||
.circle-progress {
|
||
width: 120rpx;
|
||
height: 120rpx;
|
||
position: relative;
|
||
}
|
||
|
||
.progress-ring {
|
||
width: 100%;
|
||
height: 100%;
|
||
border-radius: 50%;
|
||
background: conic-gradient(#1890ff 0deg, #40a9ff 360deg, #1890ff 100%);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
animation: progress 1.5s ease-in-out infinite;
|
||
}
|
||
|
||
.ring-inner {
|
||
width: 85%;
|
||
height: 85%;
|
||
background: radial-gradient(circle, #fff 30%, transparent 70%);
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
box-shadow: 0 4rpx 12rpx rgba(24, 144, 255, 0.15);
|
||
transition: all 0.3s ease;
|
||
|
||
&:active {
|
||
transform: scale(0.95);
|
||
}
|
||
}
|
||
}
|
||
|
||
@keyframes progress {
|
||
0% {
|
||
background: #40a9ff;
|
||
}
|
||
|
||
100% {
|
||
background: #1890ff;
|
||
}
|
||
}
|
||
|
||
|
||
.timer-info {
|
||
flex: 1;
|
||
|
||
.timer-name {
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
color: #333;
|
||
margin-bottom: 8rpx;
|
||
display: block;
|
||
}
|
||
|
||
.timer-time {
|
||
font-size: 24rpx;
|
||
color: #666;
|
||
}
|
||
}
|
||
|
||
|
||
/* 空状态 */
|
||
.empty-state-container {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
padding: 40rpx 20rpx;
|
||
}
|
||
|
||
/* 标题区域 */
|
||
.title-section {
|
||
text-align: center;
|
||
margin-bottom: 60rpx;
|
||
|
||
.main-title {
|
||
font-size: 42rpx;
|
||
font-weight: 700;
|
||
color: #333;
|
||
display: block;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.sub-title {
|
||
font-size: 26rpx;
|
||
color: #999;
|
||
line-height: 1.6;
|
||
}
|
||
}
|
||
|
||
/* 创建项目模块列表 */
|
||
.create-modules {
|
||
width: 100%;
|
||
max-width: 600rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 20rpx;
|
||
}
|
||
|
||
/* 创建项目卡片 */
|
||
.create-card {
|
||
background-color: #fff;
|
||
border-radius: 24rpx;
|
||
padding: 32rpx 28rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 30rpx;
|
||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
|
||
position: relative;
|
||
overflow: hidden;
|
||
transition: all 0.3s ease;
|
||
|
||
&:active {
|
||
transform: scale(0.98);
|
||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
|
||
}
|
||
|
||
.card-icon {
|
||
flex-shrink: 0;
|
||
margin-right: 24rpx;
|
||
}
|
||
|
||
.icon-circle {
|
||
width: 96rpx;
|
||
height: 96rpx;
|
||
border-radius: 22rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
box-shadow: 0 6rpx 16rpx rgba(0, 0, 0, 0.12);
|
||
transition: all 0.3s ease;
|
||
position: relative;
|
||
overflow: hidden;
|
||
|
||
&:active {
|
||
transform: scale(0.9);
|
||
}
|
||
|
||
/* 计时图标 - 蓝色渐变 */
|
||
&.timing-icon {
|
||
background: linear-gradient(135deg, #1890ff 0%, #40a9ff 50%, #096dd9 100%);
|
||
}
|
||
|
||
/* 包干图标 - 橙色渐变 */
|
||
&.package-icon {
|
||
background: linear-gradient(135deg, #faad14 0%, #ffc53d 50%, #d48806 100%);
|
||
}
|
||
|
||
/* 分段图标 - 绿色渐变 */
|
||
&.segment-icon {
|
||
background: linear-gradient(135deg, #52c41a 0%, #73d13d 50%, #389e0d 100%);
|
||
}
|
||
}
|
||
|
||
&::after {
|
||
content: '';
|
||
position: absolute;
|
||
top: 6rpx;
|
||
right: 6rpx;
|
||
width: 18rpx;
|
||
height: 18rpx;
|
||
background: rgba(255, 255, 255, 0.3);
|
||
border-radius: 50%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
}
|
||
|
||
|
||
.card-info {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
|
||
.card-title {
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
color: #333;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
|
||
.card-desc {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
line-height: 1.4;
|
||
}
|
||
|
||
|
||
|
||
.card-arrow {
|
||
flex-shrink: 0;
|
||
width: 56rpx;
|
||
height: 56rpx;
|
||
border-radius: 50%;
|
||
background: linear-gradient(135deg, rgba(24, 144, 255, 0.1) 0%, rgba(24, 144, 255, 0.05) 100%);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
transition: all 0.3s ease;
|
||
|
||
&:active {
|
||
transform: scale(1.1);
|
||
}
|
||
}
|
||
|
||
|
||
/* 弹窗通用通用样式 */
|
||
.modal-overlay {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background: linear-gradient(180deg, rgba(0, 0, 0, 0.6) 0%, rgba(0, 0, 0, 0.4) 100%);
|
||
backdrop-filter: blur(10rpx);
|
||
z-index: 998;
|
||
animation: fadeIn 0.3s ease;
|
||
}
|
||
|
||
.modal-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 36rpx 32rpx 28rpx;
|
||
background: linear-gradient(180deg, #fafbfc 0%, #fff 100%);
|
||
border-bottom: 1rpx solid rgba(0, 0, 0, 0.06);
|
||
|
||
.modal-title {
|
||
font-size: 36rpx;
|
||
font-weight: 700;
|
||
background: linear-gradient(135deg, #1890ff 0%, #40a9ff 100%);
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
background-clip: text;
|
||
}
|
||
|
||
.modal-close {
|
||
width: 60rpx;
|
||
height: 60rpx;
|
||
border-radius: 50%;
|
||
background: linear-gradient(135deg, #f5f5f5 0%, #f0f0f0 100%);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.08);
|
||
|
||
&:active {
|
||
background: linear-gradient(135deg, #e8e8e8 0%, #e0e0e0 100%);
|
||
transform: scale(0.92);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/* 计时项目列表弹窗 */
|
||
.project-list-modal {
|
||
position: fixed;
|
||
top: 50%;
|
||
left: 50%;
|
||
transform: translate(-50%, -50%);
|
||
width: 90%;
|
||
max-width: 680rpx;
|
||
max-height: 80vh;
|
||
background: linear-gradient(180deg, #fafbfc 0%, #fff 100%);
|
||
border-radius: 32rpx;
|
||
z-index: 999;
|
||
animation: slideUp 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||
box-shadow: 0 24rpx 80rpx rgba(0, 0, 0, 0.25), 0 0 0 1rpx rgba(0, 0, 0, 0.04);
|
||
overflow: hidden;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.modal-content {
|
||
flex: 1;
|
||
padding: 24rpx 28rpx;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
/* 新增按钮 */
|
||
.add-btn {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 16rpx;
|
||
width: 100%;
|
||
height: 96rpx;
|
||
background: linear-gradient(135deg, #1890ff 0%, #40a9ff 50%, #36cfc9 100%);
|
||
background-size: 200% 200%;
|
||
border-radius: 20rpx;
|
||
margin-bottom: 36rpx;
|
||
box-shadow: 0 8rpx 24rpx rgba(24, 144, 255, 0.35), 0 0 0 1rpx rgba(255, 255, 255, 0.5) inset;
|
||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||
position: relative;
|
||
overflow: hidden;
|
||
|
||
&::before {
|
||
content: '';
|
||
position: absolute;
|
||
top: 0;
|
||
left: -100%;
|
||
width: 100%;
|
||
height: 100%;
|
||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
|
||
animation: shimmer 2s infinite;
|
||
}
|
||
|
||
&:active {
|
||
transform: scale(0.97);
|
||
box-shadow: 0 4rpx 12rpx rgba(24, 144, 255, 0.25);
|
||
}
|
||
|
||
.add-btn-text {
|
||
font-size: 32rpx;
|
||
color: #fff;
|
||
font-weight: 600;
|
||
letter-spacing: 2rpx;
|
||
position: relative;
|
||
z-index: 1;
|
||
}
|
||
}
|
||
|
||
/* 项目列表 */
|
||
.project-list {
|
||
margin-bottom: 20rpx;
|
||
|
||
.list-title {
|
||
font-size: 30rpx;
|
||
font-weight: 700;
|
||
color: #333;
|
||
display: block;
|
||
margin-bottom: 24rpx;
|
||
padding-left: 12rpx;
|
||
border-left: 4rpx solid #1890ff;
|
||
background: linear-gradient(90deg, rgba(24, 144, 255, 0.05) 0%, transparent 100%);
|
||
padding: 8rpx 12rpx;
|
||
border-radius: 0 8rpx 8rpx 0;
|
||
}
|
||
|
||
.list-container {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 16rpx;
|
||
}
|
||
|
||
.project-item {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 20rpx;
|
||
padding: 28rpx 24rpx;
|
||
background: linear-gradient(135deg, #fff 0%, #fafbfc 100%);
|
||
border-radius: 20rpx;
|
||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06), 0 0 0 1rpx rgba(0, 0, 0, 0.04) inset;
|
||
position: relative;
|
||
overflow: hidden;
|
||
|
||
&::after {
|
||
content: '';
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
width: 4rpx;
|
||
height: 100%;
|
||
background: linear-gradient(180deg, #1890ff 0%, #40a9ff 100%);
|
||
opacity: 0;
|
||
transition: opacity 0.3s ease;
|
||
}
|
||
|
||
|
||
.item-icon {
|
||
flex-shrink: 0;
|
||
|
||
.icon-bg {
|
||
width: 72rpx;
|
||
height: 72rpx;
|
||
background: linear-gradient(135deg, #1890ff 0%, #40a9ff 50%, #36cfc9 100%);
|
||
border-radius: 16rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
box-shadow: 0 4rpx 12rpx rgba(24, 144, 255, 0.25);
|
||
position: relative;
|
||
|
||
&::before {
|
||
content: '';
|
||
position: absolute;
|
||
top: 8rpx;
|
||
right: 8rpx;
|
||
width: 12rpx;
|
||
height: 12rpx;
|
||
background: rgba(255, 255, 255, 0.3);
|
||
border-radius: 50%;
|
||
}
|
||
|
||
.icon-text {
|
||
font-size: 34rpx;
|
||
color: #fff;
|
||
font-weight: 700;
|
||
letter-spacing: 2rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.item-info {
|
||
flex: 1;
|
||
min-width: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 8rpx;
|
||
|
||
.item-name {
|
||
font-size: 30rpx;
|
||
font-weight: 600;
|
||
color: #333;
|
||
letter-spacing: 1rpx;
|
||
}
|
||
|
||
.item-count {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
|
||
.item-arrow {
|
||
flex-shrink: 0;
|
||
width: 52rpx;
|
||
height: 52rpx;
|
||
border-radius: 50%;
|
||
background: linear-gradient(135deg, rgba(24, 144, 255, 0.1) 0%, rgba(64, 169, 255, 0.05) 100%);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
transition: all 0.3s ease;
|
||
}
|
||
}
|
||
|
||
.empty-project {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 100rpx 20rpx;
|
||
gap: 16rpx;
|
||
|
||
.empty-text {
|
||
font-size: 28rpx;
|
||
color: #999;
|
||
font-weight: 500;
|
||
}
|
||
|
||
&::before {
|
||
content: '';
|
||
width: 120rpx;
|
||
height: 120rpx;
|
||
background: linear-gradient(135deg, rgba(24, 144, 255, 0.08) 0%, rgba(64, 169, 255, 0.03) 100%);
|
||
border-radius: 28rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-bottom: 8rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 项目详情弹窗 */
|
||
.project-detail-modal {
|
||
position: fixed;
|
||
top: 50%;
|
||
left: 50%;
|
||
transform: translate(-50%, -50%);
|
||
width: 90%;
|
||
max-width: 680rpx;
|
||
max-height: 80vh;
|
||
background-color: #fff;
|
||
border-radius: 28rpx;
|
||
z-index: 999;
|
||
animation: slideUp 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||
box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.2);
|
||
overflow: hidden;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.detail-section {
|
||
padding: 24rpx 0;
|
||
margin-bottom: 24rpx;
|
||
|
||
.detail-title {
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
color: #666;
|
||
margin-bottom: 16rpx;
|
||
display: block;
|
||
padding-left: 8rpx;
|
||
border-left: 3rpx solid #1890ff;
|
||
}
|
||
|
||
.detail-item {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-bottom: 16rpx;
|
||
|
||
.detail-label {
|
||
font-size: 26rpx;
|
||
color: #666;
|
||
min-width: 100rpx;
|
||
}
|
||
|
||
.detail-value {
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
font-weight: 500;
|
||
flex: 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
.detail-count {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
margin-bottom: 16rpx;
|
||
display: block;
|
||
}
|
||
|
||
|
||
.student-scroll {
|
||
max-height: 400rpx;
|
||
overflow-y: auto;
|
||
|
||
.student-item {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 16rpx;
|
||
padding: 16rpx 20rpx;
|
||
background-color: #f5f5f5;
|
||
border-radius: 16rpx;
|
||
margin-bottom: 12rpx;
|
||
|
||
.student-index {
|
||
width: 48rpx;
|
||
height: 48rpx;
|
||
background: linear-gradient(135deg, #1890ff 0%, #096dd9 100%);
|
||
color: #fff;
|
||
border-radius: 50%;
|
||
font-size: 22rpx;
|
||
font-weight: 600;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.student-avatar {
|
||
width: 56rpx;
|
||
height: 56rpx;
|
||
background: linear-gradient(135deg, #52c41a 0%, #73d13d 100%);
|
||
border-radius: 14rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
flex-shrink: 0;
|
||
|
||
.avatar-text {
|
||
color: #fff;
|
||
font-size: 26rpx;
|
||
font-weight: 700;
|
||
}
|
||
}
|
||
|
||
.student-info {
|
||
flex: 1;
|
||
min-width: 0;
|
||
gap: 8rpx;
|
||
}
|
||
|
||
.student-name {
|
||
font-size: 26rpx;
|
||
font-weight: 600;
|
||
color: #333;
|
||
}
|
||
|
||
.student-meta {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12rpx;
|
||
|
||
.gender-badge {
|
||
font-size: 22rpx;
|
||
padding: 4rpx 10rpx;
|
||
border-radius: 8rpx;
|
||
font-weight: 500;
|
||
|
||
&.male {
|
||
color: #1890ff;
|
||
background-color: #e6f7ff;
|
||
}
|
||
|
||
&.female {
|
||
color: #fa8c16;
|
||
background-color: #fff7e6;
|
||
}
|
||
}
|
||
|
||
.age-text {
|
||
font-size: 22rpx;
|
||
color: #999;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/* 动画 */
|
||
@keyframes fadeIn {
|
||
from {
|
||
opacity: 0;
|
||
}
|
||
|
||
to {
|
||
opacity: 1;
|
||
}
|
||
}
|
||
|
||
@keyframes slideUp {
|
||
from {
|
||
opacity: 0;
|
||
transform: translate(-50%, -45%);
|
||
}
|
||
|
||
to {
|
||
opacity: 1;
|
||
transform: translate(-50%, -50%);
|
||
}
|
||
}
|
||
</style> |