1060 lines
21 KiB
Vue
1060 lines
21 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>
|
||
</view>
|
||
<view class="card-arrow">
|
||
<u-icon name="arrow-right" size="20" color="#1890ff"></u-icon>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 包干项目模块 -->
|
||
<view @click=" goBaogan()" 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>
|
||
</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 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>
|
||
</view>
|
||
<view class="card-arrow">
|
||
<u-icon name="arrow-right" size="20" color="#1890ff"></u-icon>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 混氧项目模块 -->
|
||
<view @click="showTimingProjectModal(3)" class="create-card hunyang-card">
|
||
<view class="card-icon">
|
||
<view class="icon-circle hunyang-icon">
|
||
<u-icon name="grid" size="40" color="#fff"></u-icon>
|
||
</view>
|
||
</view>
|
||
<view class="card-info">
|
||
<text class="card-title">混氧项目</text>
|
||
</view>
|
||
<view class="card-arrow">
|
||
<u-icon name="arrow-right" size="20" color="#1890ff"></u-icon>
|
||
</view>
|
||
|
||
</view>
|
||
</view>
|
||
<!-- <view @click="Service.GoPage('/pages/userFunc/cs')" class="">
|
||
cs
|
||
</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"> {{ currentIndex==1?"计时项目":(currentIndex==2?"分段项目":"混氧项目") }} </text>
|
||
<view class="modal-close" @click="closeTimingProjectModal">
|
||
<u-icon name="close" size="20" color="#999"></u-icon>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="modal-content">
|
||
<view 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>
|
||
<scroll-view v-if="projects.length > 0" scroll-y="true" @scrolltolower='getList()'
|
||
class="list-container">
|
||
<view v-for="(project,index) in projects" :key="project.planId" class="project-item"
|
||
@click="handleProjectClick(project)">
|
||
<view class="item-icon">
|
||
<view class="icon-bg">
|
||
<text class="icon-text">{{ index+1 }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="item-info">
|
||
<text class="item-name">{{ project.name }}</text>
|
||
<text v-if="currentIndex!==3" class="item-count">{{ project.users.length }}人</text>
|
||
</view>
|
||
</view>
|
||
</scroll-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'
|
||
import { onLoad, onShow } from '@dcloudio/uni-app'
|
||
import { loginService } from '@/Service/swimming/loginService'
|
||
import { PlanService } from '@/Service/swimming/PlanService'
|
||
import { userService } from '@/Service/swimming/userService'
|
||
|
||
|
||
|
||
let currentIndex = ref(0)
|
||
|
||
// 分页相关
|
||
let page = ref(1)
|
||
let status = ref('loadmore')
|
||
|
||
// 模拟项目数据
|
||
const projects = ref<Array<any>>([])
|
||
|
||
// 弹窗状态
|
||
const showTimingModal = ref(false)
|
||
|
||
|
||
let isUse = ref(false)
|
||
|
||
onLoad(() => {
|
||
if (!Service.GetUserToken()) {
|
||
login()
|
||
} else {
|
||
isUseFunc()
|
||
}
|
||
})
|
||
|
||
onShow(() => {
|
||
showTimingModal.value = false
|
||
uni.showTabBar()
|
||
})
|
||
|
||
const login = () => {
|
||
uni.getProvider({
|
||
service: 'oauth',
|
||
success: function (res : any) {
|
||
uni.login({
|
||
onlyAuthorize: true,
|
||
provider: res.provider,
|
||
success: function (loginRes) {
|
||
loginService.Login(
|
||
loginRes.code,
|
||
).then(content => {
|
||
if (content.code == 0) {
|
||
Service.SetUserToken(content.data.token)
|
||
isUseFunc()
|
||
} else {
|
||
Service.Msg(content.msg)
|
||
}
|
||
})
|
||
},
|
||
fail: function (error) {
|
||
|
||
}
|
||
});
|
||
}
|
||
});
|
||
}
|
||
|
||
|
||
const isUseFunc = () => {
|
||
userService.IsCheakUserVerify().then(res => {
|
||
if (res.code == 0) {
|
||
isUse.value = res.data.isCheak
|
||
} else {
|
||
Service.Msg(res.msg)
|
||
}
|
||
})
|
||
}
|
||
|
||
|
||
// 获取项目列表数据
|
||
const getData = () => {
|
||
projects.value = []
|
||
page.value = 1
|
||
status.value = 'loadmore'
|
||
getList()
|
||
}
|
||
|
||
// 获取项目列表
|
||
const getList = () => {
|
||
|
||
if (status.value == 'loading' || status.value == 'nomore') {
|
||
return
|
||
}
|
||
status.value = 'loading'
|
||
PlanService.GetPlanList(currentIndex.value == 1 ? '计时项目' : (currentIndex.value == 2 ? '分段项目' : '混氧项目'), page.value.toString()).then(res => {
|
||
if (res.code == 0) {
|
||
projects.value = [...projects.value, ...res.data]
|
||
status.value = res.data.length == 10 ? 'loadmore' : 'nomore'
|
||
page.value++
|
||
} else {
|
||
Service.Msg(res.msg)
|
||
}
|
||
})
|
||
}
|
||
|
||
const goBaogan = () => {
|
||
if (!isUse.value) {
|
||
Service.Msg('用户暂无权限,请等待审核!')
|
||
return
|
||
}
|
||
Service.GoPage('/pages/userFunc/project')
|
||
}
|
||
|
||
|
||
// 显示计时项目列表弹窗
|
||
const showTimingProjectModal = (index : any) => {
|
||
if (!isUse.value) {
|
||
Service.Msg('用户暂无权限,请等待审核!')
|
||
return
|
||
}
|
||
|
||
uni.hideTabBar()
|
||
showTimingModal.value = true
|
||
currentIndex.value = index
|
||
getData()
|
||
}
|
||
|
||
// 关闭计时项目列表弹窗
|
||
const closeTimingProjectModal = () => {
|
||
showTimingModal.value = false
|
||
uni.showTabBar()
|
||
}
|
||
|
||
// 创建计时项目
|
||
const createTimingProject = () => {
|
||
if (currentIndex.value == 3) {
|
||
Service.GoPage('/pages/userFunc/addHunyang')
|
||
} else {
|
||
Service.GoPage('/pages/userFunc/setCourse?type=' + currentIndex.value)
|
||
}
|
||
|
||
|
||
}
|
||
|
||
// 处理项目点击事件
|
||
const handleProjectClick = (project : any) => {
|
||
if (currentIndex.value === 1) {
|
||
showTimingModal.value = false
|
||
Service.GoPage('/pages/userFunc/swiming?id=' + project.planId)
|
||
|
||
}
|
||
else if (currentIndex.value === 2) {
|
||
showTimingModal.value = false
|
||
Service.GoPage('/pages/userFunc/segmentation?id=' + project.planId)
|
||
}
|
||
else {
|
||
showTimingModal.value = false
|
||
Service.GoPage('/pages/userFunc/hunyang?id=' + project.planId)
|
||
}
|
||
|
||
}
|
||
</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%);
|
||
}
|
||
|
||
/* 混氧图标 - 紫色渐变 */
|
||
&.hunyang-icon {
|
||
background: linear-gradient(135deg, #722ed1 0%, #9254de 50%, #531dab 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;
|
||
height: 100vh;
|
||
}
|
||
|
||
.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;
|
||
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;
|
||
max-height: 800rpx;
|
||
}
|
||
|
||
.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%);
|
||
}
|
||
}
|
||
|
||
/* 包干项目选项样式 */
|
||
.package-options {
|
||
margin-bottom: 36rpx;
|
||
}
|
||
|
||
.form-group {
|
||
margin-bottom: 32rpx;
|
||
}
|
||
|
||
.form-label {
|
||
display: block;
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
color: #333;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.radio-group {
|
||
display: flex;
|
||
gap: 20rpx;
|
||
}
|
||
|
||
.radio-item {
|
||
flex: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12rpx;
|
||
padding: 24rpx 20rpx;
|
||
background: #f5f5f5;
|
||
border-radius: 16rpx;
|
||
border: 2rpx solid transparent;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.radio-item.active {
|
||
background: linear-gradient(135deg, #e6f7ff 0%, #bae7ff 100%);
|
||
border-color: #1890ff;
|
||
}
|
||
|
||
.radio-item:active {
|
||
transform: scale(0.98);
|
||
}
|
||
|
||
.radio-circle {
|
||
width: 36rpx;
|
||
height: 36rpx;
|
||
border-radius: 50%;
|
||
border: 3rpx solid #d9d9d9;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.radio-item.active .radio-circle {
|
||
border-color: #1890ff;
|
||
}
|
||
|
||
.radio-dot {
|
||
width: 18rpx;
|
||
height: 18rpx;
|
||
border-radius: 50%;
|
||
background: #1890ff;
|
||
}
|
||
|
||
.radio-label {
|
||
font-size: 28rpx;
|
||
font-weight: 500;
|
||
color: #333;
|
||
}
|
||
</style> |