保存数据

This commit is contained in:
Ls
2026-04-11 17:47:28 +08:00
parent f682c0316b
commit c9aeba0949
35 changed files with 5658 additions and 3544 deletions

View File

@@ -29,7 +29,7 @@
</view>
<!-- 包干项目模块 -->
<view @click="showTimingProjectModal(2)" class="create-card package-card">
<view @click="Service.GoPage('/pages/userFunc/project')" 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>
@@ -45,7 +45,7 @@
</view>
<!-- 分段项目模块 -->
<view @click="createSegmentProject" class="create-card segment-card">
<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>
@@ -59,6 +59,22 @@
<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>
<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>
@@ -66,15 +82,14 @@
<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>
<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 v-if="currentIndex!==2" class="add-btn" @click="createTimingProject">
<view class="add-btn" @click="createTimingProject">
<u-icon name="plus" size="18" color="#1890ff"></u-icon>
<text class="add-btn-text">新增项目</text>
</view>
@@ -83,8 +98,8 @@
<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 v-for="project in projects" :key="project.planId" class="project-item"
@click="handleProjectClick(project)">
<view class="item-icon">
<view class="icon-bg">
<text class="icon-text">{{ project.name.charAt(0) }}</text>
@@ -92,7 +107,7 @@
</view>
<view class="item-info">
<text class="item-name">{{ project.name }}</text>
<text class="item-count">{{ project.studentCount }}</text>
<text v-if="currentIndex!==3" class="item-count">{{ project.users.length }}</text>
</view>
</view>
</view>
@@ -103,140 +118,131 @@
</view>
</view>
</view>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { Service } from '@/Service/Service'
import { onLoad } from '@dcloudio/uni-app'
import { loginService } from '@/Service/swimming/loginService'
import { PlanService } from '@/Service/swimming/PlanService'
// 项目类型
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)
let currentIndex=ref(0)
// 分页相关
let page = ref(1)
let status = ref('loadmore')
// 模拟项目数据
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 projects = ref<Array<any>>([])
// 弹窗状态
const showTimingModal = ref(false)
const showDetailModal = ref(false)
const currentProject = ref<Project | null>(null)
// 生命周期
onMounted(() => {
// TODO: 实际应从接口获取项目列表
onLoad(() => {
if (!Service.GetUserToken()) {
login()
}
})
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)
} else {
Service.Msg(content.msg)
}
})
},
fail: function (error) {
}
});
}
});
}
onUnmounted(() => {
// 清理
})
// 获取项目列表数据
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 showTimingProjectModal = (index:any) => {
const showTimingProjectModal = (index : any) => {
uni.hideTabBar()
showTimingModal.value = true
currentIndex.value=index
currentIndex.value = index
getData()
}
// 关闭计时项目列表弹窗
const closeTimingProjectModal = () => {
showTimingModal.value = false
uni.showTabBar()
}
// 创建计时项目
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')
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>
@@ -447,6 +453,11 @@
&.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 {
@@ -483,7 +494,7 @@
line-height: 1.4;
}
.card-arrow {
flex-shrink: 0;
@@ -550,7 +561,7 @@
}
}
/* 计时项目列表弹窗 */
.project-list-modal {
@@ -934,4 +945,75 @@
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>