diff --git a/src/Service/swimming/studentService.ts b/src/Service/swimming/studentService.ts index 9fe6b7a..14e8383 100644 --- a/src/Service/swimming/studentService.ts +++ b/src/Service/swimming/studentService.ts @@ -3,8 +3,8 @@ import { Service } from '@/Service/Service'; class studentService { private static GetStudentListPath : string = '/api/Student/GetStudentList'; /*****学生列表不分页接口*****/ - static GetStudentList() { - var result = Service.Request(this.GetStudentListPath, "GET", { }); + static GetStudentList(planId:string) { + var result = Service.Request(this.GetStudentListPath, "GET", { planId }); return result; } diff --git a/src/Service/swimming/userService.ts b/src/Service/swimming/userService.ts index 4cec73b..513ff06 100644 --- a/src/Service/swimming/userService.ts +++ b/src/Service/swimming/userService.ts @@ -24,6 +24,38 @@ class userService { } + private static GetUserListPath : string = '/api/User/GetUserList'; + /*****查询用户列表接口*****/ + static GetUserList(serch:string,page:number) { + var result = Service.Request(this.GetUserListPath, "GET", {serch,page}); + return result; + } + + + private static UpdateUserRolePath : string = '/api/User/UpdateUserRole'; + /*****更改用户权限接口*****/ + static UpdateUserRole(userId:string) { + var result = Service.Request(this.UpdateUserRolePath, "POST", {userId}); + return result; + } + + + private static GetKefuInfoPath : string = '/api/User/GetKefuInfo'; + /*****获取客服信息接口*****/ + static GetKefuInfo() { + var result = Service.Request(this.GetKefuInfoPath, "GET", {}); + return result; + } + + + private static UpdateKefuPath : string = '/api/User/UpdateKefu'; + /*****修改客服信息接口*****/ + static UpdateKefu(phone:string,name:string) { + var result = Service.Request(this.UpdateKefuPath, "POST", {phone,name}); + return result; + } + + // private static GetStudentInfoPath : string = '/api/Student/GetStudentInfo'; // /*****根据学生id查详情接口*****/ // static GetStudentInfo(studentId:string) { diff --git a/src/pages.json b/src/pages.json index f273e28..a398bcd 100644 --- a/src/pages.json +++ b/src/pages.json @@ -34,7 +34,7 @@ { "path": "swiming", "style": { - "navigationBarTitleText": "游泳项目" + "navigationBarTitleText": "计时项目" } }, { @@ -107,6 +107,18 @@ "navigationBarTitleText": "测试", "pageOrientation": "auto" } + }, + { + "path": "userPermission", + "style": { + "navigationBarTitleText": "权限管理" + } + }, + { + "path": "contactManage", + "style": { + "navigationBarTitleText": "联系方式管理" + } } ] }, { diff --git a/src/pages/dataAnalyze/Curve.vue b/src/pages/dataAnalyze/Curve.vue index df6d523..7ef0c11 100644 --- a/src/pages/dataAnalyze/Curve.vue +++ b/src/pages/dataAnalyze/Curve.vue @@ -108,7 +108,7 @@ - + @@ -133,17 +133,17 @@ const projectOptions = ref>([[]]) interface Student { - studentId: string - name: string + studentId : string + name : string } interface StudentTrainingRecord { - studentId: string - studentName: string - time: number - recordDate: string - recordFullDate: string - round: number + studentId : string + studentName : string + time : number + recordDate : string + recordFullDate : string + round : number } const projectStudents = ref([]) @@ -178,7 +178,7 @@ yAxis: { data: [{ min: 0, - format: (val: number) => val.toFixed(1) + 's' + format: (val : number) => val.toFixed(1) + 's' }] }, extra: { @@ -196,12 +196,14 @@ categories: [] as string[], series: [] as any[] }) - + + let calendar=ref(null) + onLoad(() => { getProjectData() }) - onShow(() => {}) + onShow(() => { }) const getProjectData = () => { PlanService.GetPlanListNoPage('计时项目').then(res => { @@ -213,7 +215,7 @@ }) } - const selectProcetFunc = (project: any) => { + const selectProcetFunc = (project : any) => { selectProcet.value = project.name selectId.value = project.planId showProject.value = false @@ -228,11 +230,23 @@ const openCalendar = () => { showCalendar.value = true + calendar.value.open() } - const calendarConfirm = (e: any) => { - begin.value = e[0] - end.value = e[e.length - 1] + const calendarConfirm = (e : any) => { + const newDate = e.range + if (e.range.before !== begin.value || e.range.after !== end.value ) { + selectedStudentIds.value = [] + lineChartData.value.categories = [] + lineChartData.value.series = [] + } + + begin.value = newDate.before + if( e.range.after){ + end.value = e.range.after + }else{ + end.value = e.range.before + } showCalendar.value = false } @@ -240,18 +254,18 @@ showCalendar.value = false } - const loadProjectStudents = (projectId: string) => { - studentService.GetStudentList().then(res => { + const loadProjectStudents = (projectId : string) => { + studentService.GetStudentList('').then(res => { if (res.code == 0) { projectStudents.value = res.data } else { Service.Msg(res.msg) } }) - + } - const toggleStudent = (studentId: string) => { + const toggleStudent = (studentId : string) => { const index = selectedStudentIds.value.indexOf(studentId) if (index !== -1) { selectedStudentIds.value.splice(index, 1) @@ -262,36 +276,49 @@ } selectedStudentIds.value.push(studentId) } - let studentIdList = selectedStudentIds.value.map((item) => item) - let data = { + const studentIdList = selectedStudentIds.value.map((item) => item) + const reqData = { planId: selectId.value, studentId: JSON.stringify(studentIdList), sTime: begin.value, eTime: end.value } - interface DataItem { - name: string - data: any[] - } - const xData = ref( - Array.from({ length: studentIdList.length }, () => ({ - name: '', - data: [] - })) - ) - PlanService.GetQuxianLog(data).then(res => { + PlanService.GetQuxianLog(reqData).then(res => { if (res.code == 0) { - lineChartData.value.categories = [] - res.data.list.map((item: any) => { - lineChartData.value.categories.push(item.dayTime) - item.data.map((content: any, index: any) => { - - xData.value[index].name = content.studentName - xData.value[index].data.push(content.time) + const list = res.data.list || [] + const days = list.map((item : any) => item.dayTime) + + // 按已选学生顺序初始化 series,缺省日期填充 0 + const series = studentIdList.map(id => { + const student = projectStudents.value.find(s => s.studentId === id) + return { + name: student?.name || '', + data: new Array(days.length).fill(0) + } + }) + + // 建立 studentId -> series 索引映射 + const idToIndex : Record = {} + studentIdList.forEach((id, idx) => { + idToIndex[id] = idx + }) + + // 按日期填充数据 + list.forEach((dayItem : any, dayIndex : number) => { + ; (dayItem.data || []).forEach((record : any) => { + const sIdx = idToIndex[record.studentId] + if (sIdx !== undefined) { + series[sIdx].data[dayIndex] = record.time ?? 0 + if (!series[sIdx].name && record.studentName) { + series[sIdx].name = record.studentName + } + } }) }) - lineChartData.value.series = xData.value + + lineChartData.value.categories = days + lineChartData.value.series = series } else { Service.Msg(res.msg) } @@ -689,4 +716,4 @@ color: #999; } } - + \ No newline at end of file diff --git a/src/pages/dataAnalyze/baoganAnalyze.vue b/src/pages/dataAnalyze/baoganAnalyze.vue index 8898ecd..883d760 100644 --- a/src/pages/dataAnalyze/baoganAnalyze.vue +++ b/src/pages/dataAnalyze/baoganAnalyze.vue @@ -91,8 +91,11 @@ - + + + + @@ -189,7 +192,9 @@ let showProjectPopup = ref(false) let selectProcet = ref('') let selectId = ref('') - + + let calendar=ref(null) + // 日期选择 const begin = ref('') const end = ref('') @@ -264,7 +269,7 @@ } const getStudentList = () => { - studentService.GetStudentList().then(res => { + studentService.GetStudentList('').then(res => { if (res.code == 0) { studentList.value = res.data } else { @@ -305,11 +310,17 @@ const openCalendar = () => { showCalendar.value = true + calendar.value.open() } const calendarConfirm = (e : any) => { - begin.value = e[0] - end.value = e[e.length - 1] + console.log(e); + begin.value = e.range.before + if( e.range.after){ + end.value = e.range.after + }else{ + end.value = e.range.before + } showCalendar.value = false getRecord() } diff --git a/src/pages/dataAnalyze/grades.vue b/src/pages/dataAnalyze/grades.vue index 2a8ab80..c879c9a 100644 --- a/src/pages/dataAnalyze/grades.vue +++ b/src/pages/dataAnalyze/grades.vue @@ -38,7 +38,7 @@ {{ item.studentName }} - 最快用时:{{ item.quicklyTime }}s + 最快用时:{{ formatTime(item.quicklyTime ) }} @@ -105,7 +105,7 @@ studentId: string } - const gradeList = ref([]) + const gradeList = ref>([]) const maxSpeed = computed(() => { if (gradeList.value.length === 0) return 0 @@ -143,6 +143,14 @@ } }) } + + // 格式化时间显示 + const formatTime = (seconds : number) : string => { + const mins = Math.floor(seconds / 60) + const secs = Math.floor(seconds % 60) + const ms = Math.floor((seconds % 1) * 100) + return `${mins.toString().padStart(2, '0')}′${secs.toString().padStart(2, '0')}″${ms.toString().padStart(2, '0')}` + } const handleRankingClick = (item: StudentGrade) => { console.log('点击了排名项:', item) diff --git a/src/pages/dataAnalyze/paragraphAnalyze.vue b/src/pages/dataAnalyze/paragraphAnalyze.vue index 911e4da..1e1d1fc 100644 --- a/src/pages/dataAnalyze/paragraphAnalyze.vue +++ b/src/pages/dataAnalyze/paragraphAnalyze.vue @@ -38,7 +38,8 @@ - + 选择项目 @@ -48,7 +49,8 @@ - + {{ project.name }} @@ -87,10 +89,8 @@ - + - @@ -216,12 +216,12 @@ let row = ref('') - let rowData=ref({ - studentName:'', - planName:'' + let rowData = ref({ + studentName: '', + planName: '' }) - - + + const tableData = ref([]) const projectOptions = ref>([[]]) const studentList = ref([]) @@ -268,7 +268,9 @@ } }) }) - + + let calendar=ref(null) + onLoad(() => { getProjectData() getRecordList() @@ -282,7 +284,7 @@ const getProjectData = () => { - PlanService.GetPlanListNoPage('计时项目').then(res => { + PlanService.GetPlanListNoPage('分段项目').then(res => { if (res.code == 0) { projectOptions.value[0] = res.data.list } else { @@ -292,7 +294,7 @@ } const getStudentList = () => { - studentService.GetStudentList().then(res => { + studentService.GetStudentList('').then(res => { if (res.code == 0) { studentList.value = res.data } else { @@ -303,7 +305,8 @@ const cellClick = (rows : any) => { - rowData.value=rows + rowData.value = rows + console.log(rowData.value); row.value = rows.subsection showRecordPopup.value = true } @@ -334,11 +337,16 @@ const openCalendar = () => { showCalendar.value = true + calendar.value.open() } const calendarConfirm = (e : any) => { - begin.value = e[0] - end.value = e[e.length - 1] + begin.value = e.range.before + if( e.range.after){ + end.value = e.range.after + }else{ + end.value = e.range.before + } showCalendar.value = false getRecord() } @@ -785,8 +793,8 @@ ::v-deep .sl-table__body__row:nth-child(odd) { background-color: #fff !important; } - - + + /* 项目选择弹窗 */ .project-popup-content { width: 680rpx; @@ -950,81 +958,81 @@ } /* 分段详情弹窗 */ - .segment-popup-content { - width: 90vw; - max-height: 70vh; - padding: 32rpx; + .segment-popup-content { + width: 90vw; + max-height: 70vh; + padding: 32rpx; + display: flex; + flex-direction: column; + + .popup-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 24rpx; + + .popup-title { + font-size: 34rpx; + font-weight: 700; + color: #333; + } + } + + .popup-table { + background-color: #fafafa; + border-radius: 16rpx; + overflow: hidden; display: flex; flex-direction: column; - - .popup-header { + + .popup-table-header { display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 24rpx; - - .popup-title { - font-size: 34rpx; + background: linear-gradient(135deg, #faad14 0%, #ffc53d 100%); + padding: 24rpx 0; + + .popup-th { + flex: 1; + text-align: center; + font-size: 28rpx; font-weight: 700; - color: #333; + color: #fff; } } - - .popup-table { - background-color: #fafafa; - border-radius: 16rpx; - overflow: hidden; - display: flex; - flex-direction: column; - - .popup-table-header { + + .popup-scroll { + max-height: 400rpx; + + .popup-table-row { display: flex; - background: linear-gradient(135deg, #faad14 0%, #ffc53d 100%); padding: 24rpx 0; - - .popup-th { + border-bottom: 1rpx solid #eee; + background-color: #fff; + + &:nth-child(even) { + background-color: #fafafa; + } + + .popup-td { flex: 1; text-align: center; font-size: 28rpx; - font-weight: 700; - color: #fff; + color: #333; } } - - .popup-scroll { - max-height: 400rpx; - - .popup-table-row { - display: flex; - padding: 24rpx 0; - border-bottom: 1rpx solid #eee; - background-color: #fff; - - &:nth-child(even) { - background-color: #fafafa; - } - - .popup-td { - flex: 1; - text-align: center; - font-size: 28rpx; - color: #333; - } - } - - .popup-empty { - padding: 60rpx 0; - text-align: center; - - .popup-empty-text { - font-size: 28rpx; - color: #999; - } + + .popup-empty { + padding: 60rpx 0; + text-align: center; + + .popup-empty-text { + font-size: 28rpx; + color: #999; } } } } - + } + @keyframes slideUp { from { transform: translateY(100%); diff --git a/src/pages/dataAnalyze/timingAnalze.vue b/src/pages/dataAnalyze/timingAnalze.vue index a0946a6..3997d7e 100644 --- a/src/pages/dataAnalyze/timingAnalze.vue +++ b/src/pages/dataAnalyze/timingAnalze.vue @@ -90,9 +90,9 @@ - + - + @@ -132,7 +132,7 @@ - {{ rowData.studentName +'·' + rowData.planName}} + {{ rowData.studentName +'·' + rowData.planName+' PB: '+rowData.quicklyTime}} @@ -195,7 +195,9 @@ const begin = ref('') const end = ref('') const showCalendar = ref(false) - + + let calendar=ref(null) + // 分页相关 let page = ref(1) let pageTotal = ref(10) @@ -265,7 +267,7 @@ } const getStudentList=()=>{ - studentService.GetStudentList().then(res=>{ + studentService.GetStudentList('').then(res=>{ if (res.code == 0) { studentList.value =res.data } else { @@ -276,6 +278,7 @@ const cellClick=(e:any)=>{ + console.log(e); rowData.value=e showRecordPopup.value=true } @@ -306,11 +309,18 @@ const openCalendar = () => { showCalendar.value = true + calendar.value.open() } const calendarConfirm = (e: any) => { - begin.value = e[0] - end.value = e[e.length - 1] + begin.value = e.range.before + if( e.range.after){ + end.value = e.range.after + }else{ + end.value = e.range.before + } + + showCalendar.value = false getRecord() } diff --git a/src/pages/index/index.vue b/src/pages/index/index.vue index faf3722..d7e865d 100644 --- a/src/pages/index/index.vue +++ b/src/pages/index/index.vue @@ -21,7 +21,6 @@ 计时项目 - 记录单次训练的计时数据 @@ -37,7 +36,6 @@ 包干项目 - 记录固定距离的训练成绩 @@ -53,7 +51,6 @@ 分段项目 - 记录分段训练的详细数据 @@ -69,12 +66,11 @@ 混氧项目 - 记录混氧训练的计时数据 - + 项目列表 - + @@ -147,23 +144,23 @@ // 弹窗状态 const showTimingModal = ref(false) - - - let isUse=ref(false) - + + + let isUse = ref(false) + onLoad(() => { if (!Service.GetUserToken()) { login() - }else{ + } else { isUseFunc() } }) - - onShow(()=>{ - showTimingModal.value=false + + onShow(() => { + showTimingModal.value = false uni.showTabBar() }) - + const login = () => { uni.getProvider({ service: 'oauth', @@ -190,18 +187,18 @@ } }); } - - - const isUseFunc=()=>{ - userService.IsCheakUserVerify().then(res=>{ - if(res.code==0){ - isUse.value=res.data.isCheak - }else{ + + + const isUseFunc = () => { + userService.IsCheakUserVerify().then(res => { + if (res.code == 0) { + isUse.value = res.data.isCheak + } else { Service.Msg(res.msg) } }) } - + // 获取项目列表数据 const getData = () => { @@ -213,7 +210,7 @@ // 获取项目列表 const getList = () => { - + if (status.value == 'loading' || status.value == 'nomore') { return } @@ -229,22 +226,22 @@ }) } - const goBaogan=()=>{ - if(!isUse.value){ + const goBaogan = () => { + if (!isUse.value) { Service.Msg('用户暂无权限,请等待审核!') return } Service.GoPage('/pages/userFunc/project') } - - + + // 显示计时项目列表弹窗 const showTimingProjectModal = (index : any) => { - if(!isUse.value){ + if (!isUse.value) { Service.Msg('用户暂无权限,请等待审核!') return } - + uni.hideTabBar() showTimingModal.value = true currentIndex.value = index @@ -283,7 +280,7 @@ showTimingModal.value = false Service.GoPage('/pages/userFunc/hunyang?id=' + project.planId) } - + } diff --git a/src/pages/index/user.vue b/src/pages/index/user.vue index 4054700..e8ce0fc 100644 --- a/src/pages/index/user.vue +++ b/src/pages/index/user.vue @@ -6,7 +6,8 @@ - + + + + + + + + + + + + + 权限管理 + + 管理员 + + + 管理用户权限和角色 + + + + + + + + + + + + + + + + 联系方式管理 + + 管理员 + + + 管理客服联系方式 + + + + + + + - - 客服联系人:张教练 - 138-0000-0000 + + 客服联系人:{{ kefuName }} + {{ kefuPhone }} @@ -119,44 +164,49 @@ import { Service } from '@/Service/Service' import { userService } from '@/Service/swimming/userService' - let planCount=ref(0) - let studentCount=ref(0) + let planCount = ref(0) + let studentCount = ref(0) let userInfo = ref({}) - let isUse=ref(false) + let isUse = ref(false) + let kefuName = ref('') + let kefuPhone = ref('') onLoad(() => { - + }) onShow(() => { loadUserInfo() isUseFunc() }) - - const isUseFunc=()=>{ - userService.IsCheakUserVerify().then(res=>{ - if(res.code==0){ - isUse.value=res.data.isCheak - }else{ + + const isUseFunc = () => { + userService.IsCheakUserVerify().then(res => { + if (res.code == 0) { + isUse.value = res.data.isCheak + } else { Service.Msg(res.msg) } }) } - + const loadUserInfo = () => { - userService.GetUserInfo().then((content:any) => { + userService.GetUserInfo().then((content : any) => { if (content.code == 0) { - studentCount.value=content.data.studentCount - planCount.value=content.data.planCount - userInfo.value=content.data.userInfo + studentCount.value = content.data.studentCount + planCount.value = content.data.planCount + userInfo.value = content.data.userInfo + kefuName.value = content.data.kefuName + kefuPhone.value = content.data.kefuPhone + } else { Service.Msg(content.msg) } }) } - - const goPage=(path:any)=>{ - if(!isUse.value){ + + const goPage = (path : any) => { + if (!isUse.value) { Service.Msg('用户暂无权限,请等待审核!') return } @@ -165,7 +215,7 @@ const callContact = () => { uni.makePhoneCall({ - phoneNumber: '13800000000', + phoneNumber: kefuPhone.value, fail: () => { Service.Msg('拨打电话失败') } @@ -181,7 +231,7 @@ .user-container { padding: 20rpx; padding-top: 30rpx; - padding-bottom: 140rpx; + } /* 用户信息卡片 */ @@ -328,7 +378,7 @@ display: flex; align-items: center; justify-content: center; - gap: 16rpx; + gap: 16rpx; } .stat-icon-bg { @@ -467,6 +517,16 @@ background: linear-gradient(135deg, #faad14 0%, #ffc53d 50%, #d48806 100%); } + /* 权限管理图标背景色 - 红色渐变 */ + &.admin-icon-bg { + background: linear-gradient(135deg, #f5222d 0%, #ff4d4f 50%, #cf1322 100%); + } + + /* 联系方式管理图标背景色 - 青色渐变 */ + &.contact-icon-bg { + background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 50%, #08979c 100%); + } + &.settings-icon-bg { background: linear-gradient(135deg, #1890ff 0%, #40a9ff 50%, #096dd9 100%); } @@ -523,6 +583,13 @@ color: #faad14; } + /* 管理员标签样式 - 红色 */ + &.admin-tag, + &.contact-tag { + background: linear-gradient(135deg, rgba(245, 34, 45, 0.12) 0%, rgba(245, 34, 45, 0.08) 100%); + color: #f5222d; + } + .tag-text { font-size: 20rpx; font-weight: 500; @@ -571,7 +638,6 @@ left: 0; right: 0; background-color: #fff; - border-top: 1rpx solid #eee; padding: 16rpx 0; display: flex; flex-direction: column; diff --git a/src/pages/userFunc/addHunyang.vue b/src/pages/userFunc/addHunyang.vue index 6a2227d..84037fd 100644 --- a/src/pages/userFunc/addHunyang.vue +++ b/src/pages/userFunc/addHunyang.vue @@ -359,7 +359,7 @@ } }) - console.log(projectData); + const data = { planId: planId.value, @@ -375,13 +375,24 @@ group: '' } - console.log('保存的数据:', data) + PlanService.AddPlan(data).then(res => { if (res.code == 0) { Service.Msg(planId.value?'修改成功!':'添加成功!') - setTimeout(() => { - Service.GoPageDelse('/pages/userFunc/hunyang?id=' + res.data.planId) - }, 1000) + + if(planId.value){ + setTimeout(() => { + Service.GoPageBack() + }, 1000) + + uni.$emit('change') + }else{ + setTimeout(() => { + Service.GoPageDelse('/pages/userFunc/hunyang?id=' + res.data.planId) + }, 1000) + } + + } else { diff --git a/src/pages/userFunc/contactManage.vue b/src/pages/userFunc/contactManage.vue new file mode 100644 index 0000000..beee922 --- /dev/null +++ b/src/pages/userFunc/contactManage.vue @@ -0,0 +1,187 @@ + + + + + \ No newline at end of file diff --git a/src/pages/userFunc/hunyang.vue b/src/pages/userFunc/hunyang.vue index 04945fc..698cb62 100644 --- a/src/pages/userFunc/hunyang.vue +++ b/src/pages/userFunc/hunyang.vue @@ -1,12 +1,13 @@