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>
|
||||||
|
|||||||
@ -162,7 +162,7 @@ const formatExamLocation = (
|
|||||||
locationName: string,
|
locationName: string,
|
||||||
) => {
|
) => {
|
||||||
const parts = [provinceName, cityName, address, locationName].filter(Boolean)
|
const parts = [provinceName, cityName, address, locationName].filter(Boolean)
|
||||||
return parts.join(' ')
|
return parts.join('')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 报名考试
|
// 报名考试
|
||||||
|
|||||||
@ -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