1
This commit is contained in:
		
							parent
							
								
									c7bbf42e96
								
							
						
					
					
						commit
						cd569f2881
					
				| @ -35,7 +35,7 @@ export default defineUniPages({ | |||||||
|       { |       { | ||||||
|         iconPath: 'static/tabbar/document.svg', |         iconPath: 'static/tabbar/document.svg', | ||||||
|         selectedIconPath: 'static/tabbar/documentHL.svg', |         selectedIconPath: 'static/tabbar/documentHL.svg', | ||||||
|         pagePath: 'pages/fate/fate', |         pagePath: 'pages/exam/my', | ||||||
|         text: '考试', |         text: '考试', | ||||||
|       }, |       }, | ||||||
|     ], |     ], | ||||||
|  | |||||||
| @ -32,7 +32,7 @@ | |||||||
|       { |       { | ||||||
|         "iconPath": "static/tabbar/document.svg", |         "iconPath": "static/tabbar/document.svg", | ||||||
|         "selectedIconPath": "static/tabbar/documentHL.svg", |         "selectedIconPath": "static/tabbar/documentHL.svg", | ||||||
|         "pagePath": "pages/fate/fate", |         "pagePath": "pages/exam/my", | ||||||
|         "text": "考试" |         "text": "考试" | ||||||
|       } |       } | ||||||
|     ] |     ] | ||||||
| @ -45,6 +45,13 @@ | |||||||
|         "navigationBarTitleText": "" |         "navigationBarTitleText": "" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     { | ||||||
|  |       "path": "pages/exam/my", | ||||||
|  |       "type": "home", | ||||||
|  |       "style": { | ||||||
|  |         "navigationBarTitleText": "" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     { |     { | ||||||
|       "path": "pages/exam/detail", |       "path": "pages/exam/detail", | ||||||
|       "type": "home", |       "type": "home", | ||||||
| @ -86,7 +93,7 @@ | |||||||
|       "type": "page", |       "type": "page", | ||||||
|       "layout": "default", |       "layout": "default", | ||||||
|       "style": { |       "style": { | ||||||
|         "navigationBarTitleText": "红娘" |         "navigationBarTitleText": "" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|  | |||||||
							
								
								
									
										282
									
								
								src/pages/exam/my.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										282
									
								
								src/pages/exam/my.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,282 @@ | |||||||
|  | <!-- 使用 type="home" 属性设置首页,其他页面不需要设置,默认为page;推荐使用json5,更强大,且允许注释 --> | ||||||
|  | <route lang="json5" type="home"> | ||||||
|  | { | ||||||
|  |   style: { | ||||||
|  |     navigationBarTitleText: '', | ||||||
|  |   }, | ||||||
|  | } | ||||||
|  | </route> | ||||||
|  | <template> | ||||||
|  |   <view class="px-4 py-3" @click="closeUserMenu"> | ||||||
|  |     <!-- 顶部栏 --> | ||||||
|  |     <view class="flex items-center justify-between mb-6"> | ||||||
|  |       <text class="text-lg font-bold">我的考试</text> | ||||||
|  |     </view> | ||||||
|  | 
 | ||||||
|  |     <!-- 考试列表 --> | ||||||
|  |     <view class="space-y-6"> | ||||||
|  |       <view | ||||||
|  |         v-for="exam in examList" | ||||||
|  |         :key="exam.id" | ||||||
|  |         class="bg-white rounded-lg shadow-xl p-4 border-2 border-gray-400 relative transition-all duration-300 hover:shadow-2xl hover:-translate-y-1 hover:border-gray-500 cursor-pointer" | ||||||
|  |         style=" | ||||||
|  |           box-shadow: | ||||||
|  |             0 8px 16px -4px rgba(0, 0, 0, 0.15), | ||||||
|  |             0 4px 8px -2px rgba(0, 0, 0, 0.1), | ||||||
|  |             inset 0 1px 0 rgba(255, 255, 255, 0.1); | ||||||
|  |           padding-top: 2.5rem; | ||||||
|  |         " | ||||||
|  |         @mouseenter="handleCardHover(exam.id)" | ||||||
|  |         @mouseleave="handleCardLeave(exam.id)" | ||||||
|  |       > | ||||||
|  |         <!-- 状态标签 --> | ||||||
|  |         <view | ||||||
|  |           :class="[ | ||||||
|  |             'absolute left-4 top-4 px-3 py-1 rounded-full text-xs font-bold', | ||||||
|  |             statusClass(exam.status), | ||||||
|  |           ]" | ||||||
|  |         > | ||||||
|  |           {{ statusText(exam.status) }} | ||||||
|  |         </view> | ||||||
|  |         <view class="h-4"></view> | ||||||
|  |         <!-- 第一行:考试名称 --> | ||||||
|  |         <view class="mb-2"> | ||||||
|  |           <text class="text-xl font-bold text-gray-800">{{ exam.examName }}</text> | ||||||
|  |         </view> | ||||||
|  | 
 | ||||||
|  |         <!-- 第二行:考试时间 --> | ||||||
|  |         <view class="mb-2"> | ||||||
|  |           <text class="text-base text-gray-600"> | ||||||
|  |             {{ formatExamTime(exam.examDate, exam.startTime, exam.endTime) }} | ||||||
|  |           </text> | ||||||
|  |         </view> | ||||||
|  | 
 | ||||||
|  |         <!-- 第三行:考试地点 --> | ||||||
|  |         <view class="mb-2"> | ||||||
|  |           <text class="text-base text-gray-600"> | ||||||
|  |             {{ | ||||||
|  |               formatExamLocation(exam.provinceName, exam.cityName, exam.address, exam.locationName) | ||||||
|  |             }} | ||||||
|  |           </text> | ||||||
|  |         </view> | ||||||
|  | 
 | ||||||
|  |         <!-- 第四、五行:空白间距 --> | ||||||
|  |         <view class="h-4"></view> | ||||||
|  |         <view class="h-4"></view> | ||||||
|  | 
 | ||||||
|  |         <!-- 第六行:报名截止信息 --> | ||||||
|  |         <view class="mb-4"> | ||||||
|  |           <text class="text-sm text-gray-500">报名截止:{{ exam.registrationDeadline }}</text> | ||||||
|  |         </view> | ||||||
|  |       </view> | ||||||
|  |     </view> | ||||||
|  | 
 | ||||||
|  |     <!-- 加载状态 --> | ||||||
|  |     <view v-if="loading" class="text-center py-8"> | ||||||
|  |       <text class="text-gray-500">加载中...</text> | ||||||
|  |     </view> | ||||||
|  | 
 | ||||||
|  |     <!-- 空状态 --> | ||||||
|  |     <view v-if="!loading && examList.length === 0" class="text-center py-8"> | ||||||
|  |       <text class="text-gray-500">暂无可报名的考试</text> | ||||||
|  |     </view> | ||||||
|  |   </view> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <script lang="ts" setup> | ||||||
|  | import { ref } from 'vue' | ||||||
|  | import { getAlreadyBookExamList } from '@/service/exam' | ||||||
|  | import { onLoad, onShow } from '@dcloudio/uni-app' | ||||||
|  | 
 | ||||||
|  | defineOptions({ | ||||||
|  |   name: 'Home', | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | const userName = ref('') | ||||||
|  | const showUserMenu = ref(false) | ||||||
|  | const examList = ref([]) | ||||||
|  | const loading = ref(false) | ||||||
|  | 
 | ||||||
|  | // 获取考试列表 | ||||||
|  | const getExamList = async () => { | ||||||
|  |   loading.value = true | ||||||
|  |   try { | ||||||
|  |     const res = await getAlreadyBookExamList() | ||||||
|  |     examList.value = res.data.list || [] | ||||||
|  |   } catch (error) { | ||||||
|  |     console.error('获取考试列表失败:', error) | ||||||
|  |     uni.showToast({ | ||||||
|  |       title: '获取考试列表失败', | ||||||
|  |       icon: 'none', | ||||||
|  |     }) | ||||||
|  |   } finally { | ||||||
|  |     loading.value = false | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 格式化考试时间 | ||||||
|  | const formatExamTime = (examDate: string, startTime: string, endTime: string) => { | ||||||
|  |   if (!examDate || !startTime || !endTime) return '' | ||||||
|  |   return `${examDate} ${startTime}-${endTime}` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 格式化考试地点 | ||||||
|  | const formatExamLocation = ( | ||||||
|  |   provinceName: string, | ||||||
|  |   cityName: string, | ||||||
|  |   address: string, | ||||||
|  |   locationName: string, | ||||||
|  | ) => { | ||||||
|  |   const parts = [provinceName, cityName, address, locationName].filter(Boolean) | ||||||
|  |   return parts.join('') | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 报名考试 | ||||||
|  | const handleRegisterExam = (exam: any) => { | ||||||
|  |   uni.navigateTo({ | ||||||
|  |     url: `/pages/exam/detail?id=${exam.id}`, | ||||||
|  |   }) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 卡片hover效果 | ||||||
|  | const handleCardHover = (examId: string) => { | ||||||
|  |   // 可以在这里添加额外的hover逻辑,比如改变按钮样式等 | ||||||
|  |   console.log('卡片hover:', examId) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const handleCardLeave = (examId: string) => { | ||||||
|  |   // 可以在这里添加离开时的逻辑 | ||||||
|  |   console.log('卡片离开:', examId) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 切换用户菜单 | ||||||
|  | const toggleUserMenu = () => { | ||||||
|  |   showUserMenu.value = !showUserMenu.value | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 关闭用户菜单 | ||||||
|  | const closeUserMenu = () => { | ||||||
|  |   showUserMenu.value = false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 修改密码 | ||||||
|  | const handleModifyPassword = () => { | ||||||
|  |   showUserMenu.value = false | ||||||
|  |   uni.navigateTo({ | ||||||
|  |     url: '/pages/user/modify-password', | ||||||
|  |   }) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 修改个人信息 | ||||||
|  | const handleModifyProfile = () => { | ||||||
|  |   showUserMenu.value = false | ||||||
|  |   uni.navigateTo({ | ||||||
|  |     url: '/pages/user/profile', | ||||||
|  |   }) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 退出登录 | ||||||
|  | const handleLogout = () => { | ||||||
|  |   showUserMenu.value = false | ||||||
|  |   uni.showModal({ | ||||||
|  |     title: '提示', | ||||||
|  |     content: '确定要退出登录吗?', | ||||||
|  |     success: (res) => { | ||||||
|  |       if (res.confirm) { | ||||||
|  |         // 清除本地存储 | ||||||
|  |         uni.removeStorageSync('token') | ||||||
|  |         uni.removeStorageSync('loginData') | ||||||
|  |         // 跳转到登录页 | ||||||
|  |         uni.reLaunch({ | ||||||
|  |           url: '/pages/login/index', | ||||||
|  |         }) | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |   }) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 状态标签文本 | ||||||
|  | const statusText = (status: string) => { | ||||||
|  |   switch (status) { | ||||||
|  |     case '2': | ||||||
|  |       return '待举办' | ||||||
|  |     case '4': | ||||||
|  |       return '待考试' | ||||||
|  |     case '5': | ||||||
|  |       return '进行中' | ||||||
|  |     case '100': | ||||||
|  |       return '已结束' | ||||||
|  |     case '101': | ||||||
|  |       return '已发证' | ||||||
|  |     case '-4': | ||||||
|  |       return '撤销考试' | ||||||
|  |     default: | ||||||
|  |       return '已报名' | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | // 状态标签颜色 | ||||||
|  | const statusClass = (status: string) => { | ||||||
|  |   switch (status) { | ||||||
|  |     case '2': | ||||||
|  |       return 'bg-blue-100 text-blue-600' | ||||||
|  |     case '4': | ||||||
|  |       return 'bg-yellow-100 text-yellow-700' | ||||||
|  |     case '5': | ||||||
|  |       return 'bg-green-100 text-green-600' | ||||||
|  |     case '100': | ||||||
|  |       return 'bg-gray-100 text-gray-500' | ||||||
|  |     case '101': | ||||||
|  |       return 'bg-purple-100 text-purple-600' | ||||||
|  |     case '-4': | ||||||
|  |       return 'bg-red-100 text-red-600' | ||||||
|  |     default: | ||||||
|  |       return 'bg-gray-200 text-gray-500' | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | onLoad(() => { | ||||||
|  |   // 获取本地存储的用户昵称 | ||||||
|  |   try { | ||||||
|  |     const loginData = uni.getStorageSync('loginData') | ||||||
|  |     userName.value = loginData.user.nickName | ||||||
|  |   } catch (e) { | ||||||
|  |     userName.value = '' | ||||||
|  |   } | ||||||
|  |   // getExamList() // 可选,onShow会自动刷新 | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | onShow(() => { | ||||||
|  |   getExamList() | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // 下拉刷新 | ||||||
|  | onPullDownRefresh(() => { | ||||||
|  |   getExamList().then(() => { | ||||||
|  |     uni.stopPullDownRefresh() | ||||||
|  |   }) | ||||||
|  | }) | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | /* 菜单淡入淡出动画 */ | ||||||
|  | .menu-fade-enter-active, | ||||||
|  | .menu-fade-leave-active { | ||||||
|  |   transition: all 0.2s ease-in-out; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .menu-fade-enter-from { | ||||||
|  |   opacity: 0; | ||||||
|  |   transform: scale(0.95) translateY(-10px); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .menu-fade-leave-to { | ||||||
|  |   opacity: 0; | ||||||
|  |   transform: scale(0.95) translateY(-10px); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .menu-fade-enter-to, | ||||||
|  | .menu-fade-leave-from { | ||||||
|  |   opacity: 1; | ||||||
|  |   transform: scale(1) translateY(0); | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -2,7 +2,7 @@ | |||||||
|   <view class="mb-8"> |   <view class="mb-8"> | ||||||
|     <view class="flex justify-between items-center mb-4"> |     <view class="flex justify-between items-center mb-4"> | ||||||
|       <view class="flex items-center"> |       <view class="flex items-center"> | ||||||
|         <text class="text-2xl font-bold text-primary">红娘推荐</text> |         <text class="text-2xl font-bold text-primary">红娘推荐111</text> | ||||||
|         <view class="ml-2 px-2 py-1 bg-primary/10 rounded-full"> |         <view class="ml-2 px-2 py-1 bg-primary/10 rounded-full"> | ||||||
|           <text class="text-xs text-primary font-medium">专业认证</text> |           <text class="text-xs text-primary font-medium">专业认证</text> | ||||||
|         </view> |         </view> | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
| { | { | ||||||
|   layout: 'default', |   layout: 'default', | ||||||
|   style: { |   style: { | ||||||
|     navigationBarTitleText: '红娘', |     navigationBarTitleText: '', | ||||||
|   }, |   }, | ||||||
| } | } | ||||||
| </route> | </route> | ||||||
|  | |||||||
| @ -15,6 +15,7 @@ export interface ExamItem { | |||||||
|   estimatedAttendees: string |   estimatedAttendees: string | ||||||
|   examinersName?: string |   examinersName?: string | ||||||
|   supervisorsName?: string |   supervisorsName?: string | ||||||
|  |   status?: number | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** 获取可报名考试列表 */ | /** 获取可报名考试列表 */ | ||||||
| @ -25,6 +26,13 @@ export const getCanBookExamListAPI = () => | |||||||
| export const getCanBookExamInfoAPI = (id: string) => | export const getCanBookExamInfoAPI = (id: string) => | ||||||
|   request.get<BaseResponse<ExamItem>>('/exam/getCanBookExamInfo', { params: { id } }) |   request.get<BaseResponse<ExamItem>>('/exam/getCanBookExamInfo', { params: { id } }) | ||||||
| 
 | 
 | ||||||
|  | export const getAlreadyBookExamList = (id: string) => | ||||||
|  |   request.get<BaseResponse<ExamItem>>('/exam/getAlreadyBookExamList', { params: { id } }) | ||||||
|  | 
 | ||||||
| /** 报名接口 */ | /** 报名接口 */ | ||||||
| export const joinExamInfoAPI = (id: string) => | export const joinExamInfoAPI = (id: string) => | ||||||
|   request.get<BaseResponse<any>>('/exam/joinExamInfo', { params: { id } }) |   request.get<BaseResponse<any>>('/exam/joinExamInfo', { params: { id } }) | ||||||
|  | 
 | ||||||
|  | /** 获取已报名考试列表 */ | ||||||
|  | export const getAlreadyBookExamListAPI = () => | ||||||
|  |   request.get<BaseResponse<ExamItem[]>>('/exam/getAlreadyBookExamList') | ||||||
|  | |||||||
							
								
								
									
										3
									
								
								src/types/uni-pages.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								src/types/uni-pages.d.ts
									
									
									
									
										vendored
									
									
								
							| @ -5,6 +5,7 @@ | |||||||
| 
 | 
 | ||||||
| interface NavigateToOptions { | interface NavigateToOptions { | ||||||
|   url: "/pages/index/index" | |   url: "/pages/index/index" | | ||||||
|  |        "/pages/exam/my" | | ||||||
|        "/pages/exam/detail" | |        "/pages/exam/detail" | | ||||||
|        "/pages/activity/detail" | |        "/pages/activity/detail" | | ||||||
|        "/pages/activity/index" | |        "/pages/activity/index" | | ||||||
| @ -32,7 +33,7 @@ interface NavigateToOptions { | |||||||
| interface RedirectToOptions extends NavigateToOptions {} | interface RedirectToOptions extends NavigateToOptions {} | ||||||
| 
 | 
 | ||||||
| interface SwitchTabOptions { | interface SwitchTabOptions { | ||||||
|   url: "/pages/index/index" | "/pages/fate/fate" |   url: "/pages/index/index" | "/pages/exam/my" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type ReLaunchOptions = NavigateToOptions | SwitchTabOptions; | type ReLaunchOptions = NavigateToOptions | SwitchTabOptions; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Quincy_J
						Quincy_J