| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- <template>
- <view v-if="loading" class="loading-container">
- <text class="loading-text">正在加载...</text>
- </view>
- <view v-else-if="errorMessage" class="loading-container">
- <text class="error-text">{{ errorMessage }}</text>
- </view>
-
- <!-- 模式 1: 显示维度列表 -->
- <view v-else-if="showExamList" class="exam-list-container">
- <view class="title">请选择要参加的测评维度</view>
- <view v-for="(item, index) in examList" :key="index" class="exam-item" @click="selectExam(item.url)">
- <view class="exam-left">
- <text class="exam-name">{{ item.name || '专业能力测评' }}</text>
- <text v-if="item.isFinished" class="exam-status done">已完成</text>
- </view>
- <text :class="['start-btn', item.isFinished ? 'retry' : '']">{{ item.isFinished ? '重考' : '开始' }}</text>
- </view>
-
- <!-- 查看考试报告按钮:始终显示,未考完为灰色不可点击 -->
- <view class="result-footer">
- <button :class="['report-btn', allFinished ? '' : 'disabled']" :disabled="!allFinished" @tap="goToResult">
- 查看考试报告
- </button>
- <text v-if="!allFinished" class="report-hint">完成所有维度测评后可查看报告</text>
- </view>
- </view>
-
- <!-- 模式 2: 兜底 Web-view -->
- <web-view v-else-if="url" :src="url"></web-view>
- </template>
- <script setup>
- import { ref } from 'vue'
- import { onLoad, onShow } from '@dcloudio/uni-app'
- import { kaoshixingSilentLogin, getEvaluationResult } from '../../api/assessment.js'
- const url = ref('')
- const loading = ref(true)
- const errorMessage = ref('')
- const examList = ref([])
- const showExamList = ref(false)
- const allFinished = ref(false)
- const assessmentId = ref('')
- const selectExam = (examUrl) => {
- if (!examUrl) {
- uni.showToast({ title: '考试链接无效', icon: 'none' })
- return
- }
- uni.setStorageSync('temp_exam_url', examUrl)
- uni.navigateTo({
- url: `/pages/assessment/quiz?from=kaoshixing&assessmentId=${encodeURIComponent(assessmentId.value || '')}`
- })
- }
- const goToResult = () => {
- if (!assessmentId.value || assessmentId.value === 'undefined') {
- uni.showToast({ title: '参数错误', icon: 'none' })
- return
- }
- uni.navigateTo({
- url: `/pages/assessment/result?id=${assessmentId.value}`
- })
- }
- onShow(() => {
- if (showExamList.value) {
- checkEvaluationStatus()
- }
- })
- const checkEvaluationStatus = async () => {
- try {
- const userInfo = uni.getStorageSync('userInfo') || {}
- const studentId = userInfo.studentId || userInfo.id
- if (!studentId || !assessmentId.value || assessmentId.value === 'undefined') return
- const res = await getEvaluationResult(assessmentId.value, studentId)
- if (res.code === 200 && res.data) {
- allFinished.value = res.data.allFinished || false
-
- // 更新每个维度的完成状态
- const abilityResults = res.data.abilityResults || []
- if (abilityResults.length > 0) {
- examList.value = examList.value.map(exam => {
- const matched = abilityResults.find(a =>
- a.name === exam.name || a.abilityName === exam.name
- )
- return {
- ...exam,
- isFinished: matched ? matched.isPass !== undefined : false
- }
- })
- }
- }
- } catch (error) {
- console.error('检查测评状态失败:', error)
- }
- }
- onLoad(async (options) => {
- assessmentId.value = options.assessmentId || ''
- const mode = options.mode || ''
- const fallbackUrl = options.fallbackUrl ? decodeURIComponent(options.fallbackUrl) : ''
- // 处理直接传入的 URL (用于单次考试或报告查看)
- if (options.url && mode !== 'kaoshixing') {
- // 重新拼接可能被拆散的 URL
- let combinedUrl = decodeURIComponent(options.url)
- const queryParams = []
- for (let key in options) {
- if (key !== 'assessmentId' && key !== 'mode' && key !== 'url') {
- queryParams.push(`${key}=${options[key]}`)
- }
- }
- if (queryParams.length > 0) {
- combinedUrl += (combinedUrl.indexOf('?') !== -1 ? '&' : '?') + queryParams.join('&')
- }
- url.value = combinedUrl
- loading.value = false
- return
- }
- if (mode !== 'kaoshixing') {
- url.value = fallbackUrl
- if (!url.value) errorMessage.value = '缺少测评链接'
- loading.value = false
- return
- }
- // 考试星列表模式
- try {
- const userInfo = uni.getStorageSync('userInfo') || {}
- const studentId = userInfo.studentId || userInfo.id
- const studentName = userInfo.name || userInfo.nickName || '学员'
- const loginRes = await kaoshixingSilentLogin({
- user_id: String(studentId),
- user_name: studentName,
- department: '学员',
- evaluationId: assessmentId.value
- })
- if (loginRes.code === 200 && loginRes.data) {
- if (loginRes.data.exams && loginRes.data.exams.length > 0) {
- examList.value = loginRes.data.exams
- showExamList.value = true
- checkEvaluationStatus()
- } else if (loginRes.data.url) {
- uni.setStorageSync('temp_exam_url', loginRes.data.url)
- uni.redirectTo({
- url: `/pages/assessment/quiz?from=kaoshixing&assessmentId=${encodeURIComponent(assessmentId.value || '')}`
- })
- return
- }
- } else {
- throw new Error(loginRes.msg || '考试星登录失败')
- }
- } catch (error) {
- errorMessage.value = error.message || '加载失败'
- } finally {
- loading.value = false
- }
- })
- </script>
- <style scoped>
- .loading-container {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- height: 100vh;
- background-color: #f8f9fb;
- }
- .loading-text { font-size: 28rpx; color: #999; }
- .error-text { font-size: 28rpx; color: #ff4d4f; padding: 0 40rpx; text-align: center; }
- .exam-list-container { padding: 40rpx 30rpx; padding-bottom: 200rpx; min-height: 100vh; background-color: #fff; }
- .exam-list-container .title { font-size: 32rpx; font-weight: bold; margin-bottom: 40rpx; text-align: center; }
- .exam-item { display: flex; justify-content: space-between; align-items: center; padding: 30rpx; background-color: #f8f9fb; border-radius: 12rpx; margin-bottom: 24rpx; }
- .exam-left { display: flex; flex-direction: column; gap: 8rpx; flex: 1; }
- .exam-name { font-size: 28rpx; color: #333; }
- .exam-status { font-size: 22rpx; }
- .exam-status.done { color: #52c41a; }
- .start-btn { font-size: 24rpx; color: #fff; background-color: #2b5cff; padding: 10rpx 30rpx; border-radius: 30rpx; flex-shrink: 0; }
- .start-btn.retry { background-color: #FF9500; }
- .result-footer { position: fixed; bottom: 40rpx; left: 30rpx; right: 30rpx; display: flex; flex-direction: column; align-items: center; gap: 16rpx; }
- .report-btn { background-color: #2b5cff; color: #fff; border-radius: 44rpx; font-size: 30rpx; width: 100%; text-align: center; }
- .report-btn.disabled { background-color: #ccc; color: #fff; }
- .report-hint { font-size: 22rpx; color: #999; text-align: center; }
- </style>
|