验证玩pk上传

This commit is contained in:
田岩
2025-11-12 13:54:19 +08:00
parent 728a52b9eb
commit 375b5a1f1e
24 changed files with 371 additions and 356 deletions
-8
View File
@@ -3,11 +3,3 @@ ENV = 'development'
# 'development'
VITE_APP_BASE_API_Url = ''
VITE_APP_BASE_H5_API_Url = 'http://25.18.122.65:7001'
# VITE_APP_BASE_H5_API_Url = 'http://25.18.122.91:9786'
# VITE_APP_BASE_H5_API_Url = 'http://25.18.122.78:9786'
# VITE_APP_BASE_H5_API_Url_TRAAPP = 'http://192.168.247.200'
# VITE_APP_BASE_H5_API_Url_TRASTUDY = 'http://25.64.32.154:9602'
VITE_APP_BASE_H5_API_Url_TRAEXAM = ''http://25.64.32.154:9604'
# VITE_APP_BASE_H5_API_Url_TRAASK = 'http://25.64.32.154:9605'
+1 -1
View File
@@ -15,7 +15,7 @@
"build:app-plus:sit": "uni build -p app-plus --mode sit",
"build:app-plus:uat": "uni build -p app-plus --mode uat",
"build:app-plus:prod": "uni build -p app-plus",
"build:h5:dev": "uni build -p app-plus --mode development_h5",
"build:h5:dev": "uni build -p h5 --mode development_h5",
"build:h5": "uni build"
},
"dependencies": {
+1 -1
View File
@@ -110,7 +110,7 @@
<view class="reference_answer_title">参考答案:</view>
{{ subject_data.itemVos[0]?.itemAnswer ?? '' }}
</view>
<view class="analysis_note">试题解析:{{ subject_data?.analyContent }}</view>
<view class="analysis_note" v-if="props.mode !== 'pk_in'">试题解析:{{ subject_data?.analyContent }}</view>
</view>
</view>
</view>
+29 -20
View File
@@ -1,6 +1,6 @@
<template>
<view class="">
<uni-popup ref="popup">
<view class="" style="background-color: aqua;">
<uni-popup ref="popup" background-color="rgba(10,10,10, 0.8)" >
<view class="popup-content" @touchmove.stop>
<view class="fl1"></view>
<view class="max-div">
@@ -20,14 +20,11 @@
</view>
<swiper class="swiper">
<swiper-item class="swiper-item-div">
<image src="@/static/images/test/xz2.jpg" class="img" ></image>
<image src="@/static/images/test/xz.png" class="img"></image>
</swiper-item>
<swiper-item class="swiper-item-div">
<image src="@/static/images/test/xz2.jpg" class="img"></image>
<!-- // <image-preview :src="item.imgAddr" class="img" mode="widthFix"></image-preview> -->
<image src="@/static/images/test/xz.png" class="img"></image>
<!-- // <image-preview :src="item.imgAddr" class="img" mode="widthFix"></image-preview> -->
</swiper-item>
</swiper>
<view class="doct_icon" @click="doct_click(1)">
@@ -64,7 +61,7 @@
import { optionErrorIcon, optionSuccessIcon } from '@/common/imgSvg';
import { addPointsByCheckIn, queryCheckIn } from '@/api/pointsAndRank.js';
import common from '@/common/common';
import {arrowRightIcon} from '@/common/imgSvg'
import { arrowRightIcon } from '@/common/imgSvg';
const popup = ref(null);
const nowImgSrc = ref('');
const badgesList = ref([]);
@@ -97,22 +94,31 @@
<style scoped lang="scss">
.points-div {
width: 100%;
// width: 100%;
display: flex;
position: relative;
align-items: center;
justify-content: center;
.swiper {
flex: 1;
height: 400rpx;
width: 520rpx;
.swiper-item-div {
// background-color: firebrick;
/* 父容器只需居中对齐,无需设置背景图 */
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
background-image: url('@/static/images/pointsAndRank/fs.png');
background-size: 110% 110%; /* 背景图比img大10% */
background-position: center; /* 背景图居中 */
background-repeat: no-repeat; /* 禁止背景图重复 */
.img {
width: 384rpx;
height: 340rpx;
/* 1. 缩放img(根据需要调整宽高,这里缩到原来的80%左右示例) */
width: 300rpx;
height: 270rpx;
transform: scale(0.8);
}
}
}
@@ -125,7 +131,7 @@
align-items: center;
justify-content: center;
}
.left{
.left {
transform: rotate(180deg);
}
width: 8vw;
@@ -183,7 +189,7 @@
.title {
font-family: AlimamaShuHeiTi, AlimamaShuHeiTi;
font-weight: bold;
font-size: 46rpx;
font-size: 36rpx;
color: #d88f50;
margin: 0rpx 30rpx;
text-align: center;
@@ -203,19 +209,22 @@
}
.popup-content {
width: 100%;
width: 100vw;
height: 100vh;
z-index: 99999;
display: flex;
flex-direction: column;
align-items: center;
padding: 40rpx 0;
// padding: 40rpx 0;
}
.max-div {
width: 80vw;
// max-width: 400rpx;
// width: 80vw;
background-color: #fefbfa;
border-radius: 38rpx;
position: relative;
padding: 26rpx;
// padding: 26rpx;
overflow: hidden;
margin-top: var(--status-bar-height);
margin-bottom: 120rpx;
+330 -320
View File
@@ -1,337 +1,347 @@
<template>
<view class="main_div max_page">
<template v-if="!isMatchingSuccess">
<!-- 顶部一些按钮 -->
<view class="top-button-div">
<view class="back_div" @click="common.navigateBack()">
<view class="back-icon"></view>
</view>
<view class="fl1"></view>
<view class="top-icon-div" @click="click_top_icon(1)">
<image class="img1" :src="data_info.isAnony === 'N' ? pkAnonymousClose() : pkAnonymousOpen()"></image>
<view class="text">{{ data_info.isAnony === 'N' ? '不匿名' : '匿名' }}</view>
</view>
<view class="top-icon-div" @click="click_top_icon(2)">
<image class="img2" :src="pkRules()"></image>
<view class="text">规则说明</view>
</view>
<view class="top-icon-div" @click="click_top_icon(3)">
<image class="img3" :src="pkRankingList()"></image>
<view class="text">排行榜</view>
</view>
</view>
<view class="title-div" :class="{ hidden: challengeLoading }">
{{ data_info.comName }}
</view>
<view class="match-msg-div" :class="{ hidden: !challengeLoading }">匹配中...</view>
<view class="avatar-div">
<view class="avatar-surround-div">
<view class="avatar-img-div" :class="{ hidden: challengeLoading }">
<cached-avatar v-show="data_info.isAnony === 'N'" class="img"></cached-avatar>
<image v-show="data_info.isAnony === 'Y'" class="img" :src="defaultAnonymousAvatar"></image>
</view>
</view>
<view class="avatar-name-div">{{ data_info.isAnony === 'N' ? data_info.userName : '匿名' }}</view>
</view>
<view class="select-div" :class="{ hidden: challengeLoading }" @click="selectionInstitutionsRef.open(true)">
<view class="select-institution-div">
{{ data_info.orgName }}
<image class="img" :src="switchIcon()"></image>
</view>
<view class="select-institution-msg-div">*选择机构后会根据机构进行人员随机匹配挑战</view>
</view>
<view class="fl1"></view>
<!-- 匹配时间 -->
<view class="match-time-div" :class="{ hidden: !challengeLoading }">
{{ formatTime(practiceTime) }}
</view>
<view class="button-div" v-show="challengeButtonStatus">
<view
:class="{ start_button: !challengeLoading, cancel_button: challengeLoading, 'button-transition': true }"
@click="start_challenge"
>
{{ challengeLoading ? '取消匹配' : '开始挑战' }}
</view>
</view>
<view class="fl1"></view>
<view class="fl1"></view>
<view class="fl1"></view>
</template>
<template v-else>
<view class="matching-success-msg">匹配成功</view>
<view class="matching-success-animation">
<view class="left animate-left">
<image class="img" src="@/static/images/competition/matching-success-left.png" mode="widthFix"></image>
<view class="information-div-left">
<view class="avatar-img-div">
<cached-avatar v-show="data_info.isAnony === 'N'" class="img"></cached-avatar>
<image v-show="data_info.isAnony === 'Y'" class="img" :src="defaultAnonymousAvatar"></image>
</view>
<view class="name">
{{ data_info.isAnony === 'N' ? data_info.userName : '匿名' }}
</view>
<view class="org">
{{ data_info.isAnony === 'N' ? data_info.orgIdName : '机构不显示' }}
</view>
</view>
</view>
<view class="right animate-right">
<image class="img" src="@/static/images/competition/matching-success-right.png" mode="widthFix"></image>
<view class="information-div-right">
<view class="avatar-img-div">
<image-preview
v-if="data_info.pkIsAnony === 'N'"
class="img"
:src="data_info.pkimgAddr"
></image-preview>
<image v-else class="img" :src="defaultAnonymousAvatar" mode="aspectFill"></image>
</view>
<view class="name">
{{ data_info.pkIsAnony === 'N' ? data_info.pkUserName : '匿名' }}
</view>
<view class="org">
{{ data_info.pkIsAnony === 'N' ? data_info.pkOrgIdName : '机构不显示' }}
</view>
</view>
</view>
</view>
<view class="matching-success-text">准备</view>
</template>
<uni-popup ref="popupRef" class="popup">
<view class="sheet_popup_div">
<view class="title_div">双人对战规则说明</view>
<view class="note_div">
{{ data_info.ruleDesc }}
</view>
</view>
</uni-popup>
<selectionInstitutions ref="selectionInstitutionsRef" @submit="selectionInstitutionsSubmit"></selectionInstitutions>
<uv-picker ref="anonyPickerRef" :columns="[anonyOptions]" keyName="label" @confirm="anonyConfirm"></uv-picker>
</view>
<view class="main_div max_page">
<template v-if="!isMatchingSuccess">
<!-- 顶部一些按钮 -->
<view class="top-button-div">
<view class="back_div" @click="common.navigateBack()">
<view class="back-icon"></view>
</view>
<view class="fl1"></view>
<view class="top-icon-div" @click="click_top_icon(1)">
<image class="img1" :src="data_info.isAnony === 'N' ? pkAnonymousClose() : pkAnonymousOpen()"></image>
<view class="text">{{ data_info.isAnony === 'N' ? '不匿名' : '匿名' }}</view>
</view>
<view class="top-icon-div" @click="click_top_icon(2)">
<image class="img2" :src="pkRules()"></image>
<view class="text">规则说明</view>
</view>
<view class="top-icon-div" @click="click_top_icon(3)">
<image class="img3" :src="pkRankingList()"></image>
<view class="text">排行榜</view>
</view>
</view>
<view class="title-div" :class="{ hidden: challengeLoading }">
{{ data_info.comName }}
</view>
<view class="match-msg-div" :class="{ hidden: !challengeLoading }">匹配中...</view>
<view class="avatar-div">
<view class="avatar-surround-div">
<view class="avatar-img-div" :class="{ hidden: challengeLoading }">
<cached-avatar v-show="data_info.isAnony === 'N'" class="img"></cached-avatar>
<image v-show="data_info.isAnony === 'Y'" class="img" :src="defaultAnonymousAvatar"></image>
</view>
</view>
<view class="avatar-name-div">{{ data_info.isAnony === 'N' ? data_info.userName : '匿名' }}</view>
</view>
<view class="select-div" :class="{ hidden: challengeLoading }" @click="selectionInstitutionsRef.open(true)">
<view class="select-institution-div">
{{ data_info.orgName }}
<image class="img" :src="switchIcon()"></image>
</view>
<view class="select-institution-msg-div">*选择机构后会根据机构进行人员随机匹配挑战</view>
</view>
<view class="fl1"></view>
<!-- 匹配时间 -->
<view class="match-time-div" :class="{ hidden: !challengeLoading }">
{{ formatTime(practiceTime) }}
</view>
<view class="button-div" v-show="challengeButtonStatus">
<view
:class="{ start_button: !challengeLoading, cancel_button: challengeLoading, 'button-transition': true }"
@click="start_challenge"
>
{{ challengeLoading ? '取消匹配' : '开始挑战' }}
</view>
</view>
<view class="fl1"></view>
<view class="fl1"></view>
<view class="fl1"></view>
</template>
<template v-else>
<view class="matching-success-msg">匹配成功</view>
<view class="matching-success-animation">
<view class="left animate-left">
<image class="img" src="@/static/images/competition/matching-success-left.png" mode="widthFix"></image>
<view class="information-div-left">
<view class="avatar-img-div">
<cached-avatar v-show="data_info.isAnony === 'N'" class="img"></cached-avatar>
<image v-show="data_info.isAnony === 'Y'" class="img" :src="defaultAnonymousAvatar"></image>
</view>
<view class="name">
{{ data_info.isAnony === 'N' ? data_info.userName : '匿名' }}
</view>
<view class="org">
{{ data_info.isAnony === 'N' ? data_info.orgIdName : '机构不显示' }}
</view>
</view>
</view>
<view class="right animate-right">
<image class="img" src="@/static/images/competition/matching-success-right.png" mode="widthFix"></image>
<view class="information-div-right">
<view class="avatar-img-div">
<image-preview
v-if="data_info.pkIsAnony === 'N'"
class="img"
:src="data_info.pkImgAddr"
></image-preview>
<image v-else class="img" :src="defaultAnonymousAvatar" mode="aspectFill"></image>
</view>
<view class="name">
{{ data_info.pkIsAnony === 'N' ? data_info.pkUserName : '匿名' }}
</view>
<view class="org">
{{ data_info.pkIsAnony === 'N' ? data_info.pkOrgIdName : '机构不显示' }}
</view>
</view>
</view>
</view>
<view class="matching-success-text">准备</view>
</template>
<uni-popup ref="popupRef" class="popup">
<view class="sheet_popup_div">
<view class="title_div">双人对战规则说明</view>
<view class="note_div">
{{ data_info.ruleDesc }}
</view>
</view>
</uni-popup>
<selectionInstitutions ref="selectionInstitutionsRef" @submit="selectionInstitutionsSubmit"></selectionInstitutions>
<uv-picker ref="anonyPickerRef" :columns="[anonyOptions]" keyName="label" @confirm="anonyConfirm"></uv-picker>
</view>
</template>
<script setup lang="ts">
import {ref, onMounted, reactive} from 'vue';
import common, {getUserInfo} from '@/common/common';
import {MatchTimeGenerator, formatTime} from './js/matching';
import {queryTraCompetitionInfoByPkUser} from '@/api/competition';
import {onLoad} from '@dcloudio/uni-app';
import {defaultAnonymousAvatar} from '@/enum';
import {pkAnonymousClose, pkAnonymousOpen, pkRankingList, pkRules, switchIcon} from '@/common/imgSvg';
import {queryTraUserAnonyByUserId, updateTraUserAnony} from '@/api/user';
import selectionInstitutions from '@/components/selection-institutions/index.vue';
import { ref, onMounted, reactive } from 'vue';
import common, { getUserInfo } from '@/common/common';
import { MatchTimeGenerator, formatTime } from './js/matching';
import { queryTraCompetitionInfoByPkUser } from '@/api/competition';
import { onLoad } from '@dcloudio/uni-app';
import { defaultAnonymousAvatar } from '@/enum';
import { pkAnonymousClose, pkAnonymousOpen, pkRankingList, pkRules, switchIcon } from '@/common/imgSvg';
import { queryTraUserAnonyByUserId, updateTraUserAnony } from '@/api/user';
import selectionInstitutions from '@/components/selection-institutions/index.vue';
import { nextTick } from 'process';
const data_info = reactive({
userId: '',
userName: '',
orgName: '全部', // 机构名称
orgId: 'A', // 机构的ID,全行是A
papersId: '', // 试卷id
isAnony: '', // 是否匿名 Y是N否
ruleDesc: '', // 规则说明
comName: '', // 标题
comId: '',
orgIdName: '',
pkIsAnony: '',
pkimgAddr: '',
pkUserName: '',
pkOrgIdName: ''
});
const data_info = reactive({
userId: '',
userName: '',
orgName: '全部', // 机构名称
orgId: 'A', // 机构的ID,全行是A
papersId: '', // 试卷id
isAnony: '', // 是否匿名 Y是N否
ruleDesc: '', // 规则说明
comName: '', // 标题
comId: '',
orgIdName: '', // 自己的机构名称
pkIsAnony: '',
pkImgAddr: '',
pkUserName: '',
pkOrgIdName: ''
});
const popupRef = ref(null);
const anonyPickerRef = ref(null);
const selectionInstitutionsRef = ref(null);
const challengeLoading = ref(false);
const isMatchingSuccess = ref(false); // 匹配成功状态
const challengeButtonStatus = ref(true); // 匹配按钮显示
const practiceTime = ref(0); // 匹配时间
let practiceTimeTimer: number | null = null; // 匹配时间计时器
let matchTimer: number | null = null; // 匹配成功定时器
const anonyOptions = [
{
value: 'Y',
label: '匿名'
},
{
value: 'N',
label: '不匿名'
}
];
// 开始挑战
const start_challenge = () => {
if (!challengeLoading.value) {
challengeLoading.value = true;
// 清除旧计时器
if (practiceTimeTimer) {
clearInterval(practiceTimeTimer);
}
// 开始计时
const practiceStartTime = new Date().getTime();
practiceTimeTimer = setInterval(() => {
const currentTime = Date.now();
practiceTime.value = Math.floor((currentTime - practiceStartTime) / 1000);
}, 1000);
const popupRef = ref(null);
const anonyPickerRef = ref(null);
const selectionInstitutionsRef = ref(null);
const challengeLoading = ref(false);
const isMatchingSuccess = ref(false); // 匹配成功状态
const challengeButtonStatus = ref(true); // 匹配按钮显示
const practiceTime = ref(0); // 匹配时间
let practiceTimeTimer: number | null = null; // 匹配时间计时器
let matchTimer: number | null = null; // 匹配成功定时器
const anonyOptions = [
{
value: 'Y',
label: '匿名'
},
{
value: 'N',
label: '不匿名'
}
];
// 开始挑战
const start_challenge = () => {
if (!challengeLoading.value) {
challengeLoading.value = true;
// 清除旧计时器
if (practiceTimeTimer) {
clearInterval(practiceTimeTimer);
}
// 开始计时
const practiceStartTime = new Date().getTime();
practiceTimeTimer = setInterval(() => {
const currentTime = Date.now();
practiceTime.value = Math.floor((currentTime - practiceStartTime) / 1000);
}, 1000);
// 生成匹配延迟时间
// const delayTime = 0;
const delayTime = MatchTimeGenerator.generateInSeconds();
// 生成匹配延迟时间
// const delayTime = 0;
const delayTime = MatchTimeGenerator.generateInSeconds();
// 匹配定时器
matchTimer = setTimeout(async () => {
try {
challengeButtonStatus.value = false;
const orgId = data_info.orgId
const papersId = data_info.papersId
const comId = data_info.comId
const pkDataBody = await queryTraCompetitionInfoByPkUser({
// orgId:510121,
// papersId:'COMPETITION_PAPERS0250640321542025101615442400000003107',
// comId:'TRA_COMPETITION_INFO0250640321542025101615442400000003099'
orgId, papersId, comId
});
const pkData = pkDataBody.body;
// 下面两行是给后端擦屁股,后端传回的数值为空
pkData.orgId = orgId
pkData.papersId = papersId
common.setPageCache('competition_pk', pkData);
// 1. 显示匹配成功状态
isMatchingSuccess.value = true;
uni.vibrateLong({
success: function () {
}
});
// 2. 执行匹配成功动画(等待1.5秒)
await new Promise((resolve) => setTimeout(resolve, 600));
// 3. 清除计时器
if (practiceTimeTimer) {
clearInterval(practiceTimeTimer);
practiceTimeTimer = null;
}
// 5. 跳转页面
common.navigateTo('/pages/competition/pk');
challengeLoading.value = true;
} catch (error) {
common.msg('队列繁忙,请稍后再试!');
// 出错处理
} finally {
resetChallengeState();
}
}, delayTime * 1000);
} else {
// 取消挑战
resetChallengeState();
}
};
// 匹配定时器
matchTimer = setTimeout(async () => {
try {
challengeButtonStatus.value = false;
const orgId = data_info.orgId;
const papersId = data_info.papersId;
const comId = data_info.comId;
const pkDataBody = await queryTraCompetitionInfoByPkUser({
// orgId:510121,
// papersId:'COMPETITION_PAPERS0250640321542025101615442400000003107',
// comId:'TRA_COMPETITION_INFO0250640321542025101615442400000003099'
orgId,
papersId,
comId
});
const pkData = pkDataBody.body;
// 下面两行是给后端擦屁股,后端传回的数值为空
pkData.orgId = orgId;
pkData.papersId = papersId;
pkData.userId = data_info.userId;
pkData.userName = data_info.userName;
data_info.orgIdName = pkData.orgIdName;
data_info.pkUserName = pkData.pkUserName;
data_info.pkOrgIdName = pkData.pkOrgIdName;
data_info.pkImgAddr = pkData.pkImgAddr;
data_info.pkIsAnony = pkData.pkIsAnony;
console.log('上一页数据', pkData);
common.setPageCache('competition_pk', pkData);
// 1. 显示匹配成功状态
isMatchingSuccess.value = true;
// 震动
uni.vibrateLong({
success: function () {}
});
// 2. 执行匹配成功动画(等待1.5秒)
await new Promise((resolve) => setTimeout(resolve, 600));
// 3. 清除计时器
if (practiceTimeTimer) {
clearInterval(practiceTimeTimer);
practiceTimeTimer = null;
}
// 5. 跳转页面
common.navigateTo('/pages/competition/pk');
challengeLoading.value = true;
} catch (error) {
common.msg('队列繁忙,请稍后再试!');
// 出错处理
} finally {
resetChallengeState();
}
}, delayTime * 100);
} else {
// 取消挑战
// resetChallengeState();
}
};
interface InstitutionItem {
orgName: string; // 机构名称,类型为字符串
orgId: string; // 机构ID,类型为字符串
parentId: string; // 父级ID,类型为字符串
children?: InstitutionItem[];
}
interface InstitutionItem {
orgName: string; // 机构名称,类型为字符串
orgId: string; // 机构ID,类型为字符串
parentId: string; // 父级ID,类型为字符串
children?: InstitutionItem[];
}
const selectionInstitutionsSubmit = (options: [InstitutionItem, ...InstitutionItem[]]) => {
// 缓存起来
common.setValue('cache_selection_institutions' + data_info.userId, options);
const lastItem = options.at(-1);
data_info.orgName = lastItem.orgName;
data_info.orgId = lastItem.orgId;
const selectionInstitutionsSubmit = (options: [InstitutionItem, ...InstitutionItem[]]) => {
// 缓存起来
common.setValue('cache_selection_institutions' + data_info.userId, options);
const lastItem = options.at(-1);
data_info.orgName = lastItem.orgName;
data_info.orgId = lastItem.orgId;
selectionInstitutionsRef.value.close();
};
const anonyConfirm = (e) => {
const originalIsAnony = data_info.isAnony;
const isAnony = e.value[0].value;
if (isAnony === data_info.isAnony) return;
data_info.isAnony = isAnony;
common.loading('修改中');
updateTraUserAnony({isAnony})
.then(() => {
setTimeout(() => common.msg('切换成功'), 400);
})
.catch(() => {
// 4. 请求失败:用初始值回滚
data_info.isAnony = originalIsAnony;
common.msg('切换失败,请重试'); // 可选:提示失败
})
.finally(() => {
common.hideLoading();
});
};
const click_top_icon = (type: number) => {
// 匿名切换
if (type === 1) {
anonyPickerRef.value.setIndexs([data_info.isAnony === 'Y' ? 0 : 1], true);
anonyPickerRef.value.open();
} else if (type === 2) {
// 打开规则说明
popupRef.value.open('bottom');
} else if (type === 3) {
// 去排行榜
common.navigateTo(`/pages/competition/ranking?papersId=${data_info.papersId}&orgId=${data_info.orgId}`)
}
};
// 统一重置状态的函数
const resetChallengeState = () => {
if (matchTimer) {
clearTimeout(matchTimer);
matchTimer = null;
}
if (practiceTimeTimer) {
clearInterval(practiceTimeTimer);
practiceTimeTimer = null;
}
challengeButtonStatus.value = true;
challengeLoading.value = false;
isMatchingSuccess.value = false;
practiceTime.value = 0;
};
selectionInstitutionsRef.value.close();
};
const anonyConfirm = (e) => {
const originalIsAnony = data_info.isAnony;
const isAnony = e.value[0].value;
if (isAnony === data_info.isAnony) return;
data_info.isAnony = isAnony;
common.loading('修改中');
updateTraUserAnony({ isAnony })
.then(() => {
setTimeout(() => common.msg('切换成功'), 400);
})
.catch(() => {
// 4. 请求失败:用初始值回滚
data_info.isAnony = originalIsAnony;
common.msg('切换失败,请重试'); // 可选:提示失败
})
.finally(() => {
common.hideLoading();
});
};
const click_top_icon = (type: number) => {
// 匿名切换
if (type === 1) {
anonyPickerRef.value.setIndexs([data_info.isAnony === 'Y' ? 0 : 1], true);
anonyPickerRef.value.open();
} else if (type === 2) {
// 打开规则说明
popupRef.value.open('bottom');
} else if (type === 3) {
// 去排行榜
common.navigateTo(`/pages/competition/ranking?papersId=${data_info.papersId}&orgId=${data_info.orgId}`);
}
};
// 统一重置状态的函数
const resetChallengeState = () => {
if (matchTimer) {
clearTimeout(matchTimer);
matchTimer = null;
}
if (practiceTimeTimer) {
clearInterval(practiceTimeTimer);
practiceTimeTimer = null;
}
challengeButtonStatus.value = true;
challengeLoading.value = false;
isMatchingSuccess.value = false;
practiceTime.value = 0;
};
onLoad((e) => {
const lastData = common.getPageCache('competition_list');
console.log('lastData', lastData);
const userInfo = getUserInfo();
Object.assign(data_info, {
...lastData,
userId: userInfo.userId,
userName: userInfo.userName,
gender: userInfo.gender,
papersId: e.papersId,
comId: e.comId
});
const selectOptions = common.getValue('cache_selection_institutions' + data_info.userId);
if (Array.isArray(selectOptions) && selectOptions.length > 0) {
const lastItem = selectOptions.at(-1);
data_info.orgName = lastItem.orgName;
data_info.orgId = lastItem.orgId;
// const orgTreeInit = common.getValue('orgTree');
// if (Array.isArray(orgTreeInit) && orgTreeInit.length > 0) {
// console.log('selectOptions', selectOptions);
// }
}
});
onLoad((e) => {
const lastData = common.getPageCache('competition_list');
console.log('lastData', lastData);
const userInfo = getUserInfo();
console.log('userInfo', userInfo);
Object.assign(data_info, {
...lastData,
userId: userInfo.userId,
userName: userInfo.userName,
gender: userInfo.gender,
papersId: e.papersId,
comId: e.comId
});
const selectOptions = common.getValue('cache_selection_institutions' + data_info.userId);
if (Array.isArray(selectOptions) && selectOptions.length > 0) {
const lastItem = selectOptions.at(-1);
data_info.orgName = lastItem.orgName;
data_info.orgId = lastItem.orgId;
// const orgTreeInit = common.getValue('orgTree');
// if (Array.isArray(orgTreeInit) && orgTreeInit.length > 0) {
// console.log('selectOptions', selectOptions);
// }
}
});
</script>
<style scoped lang="scss">
// 匹配成功样式动画
@import './style/matching-success.scss';
@import './style/matching-loading.scss';
@import './style/matching-prelude.scss';
// 匹配成功样式动画
@import './style/matching-success.scss';
@import './style/matching-loading.scss';
@import './style/matching-prelude.scss';
/* 容器样式 */
.max_page {
width: 100%;
min-height: 100vh;
background-image: url('@/static/images/competition/bg.png');
background-color: #000; /* 图片高度不足时的背景色 */
background-size: 100% auto; /* 宽度填满,高度自适应 */
background-position: center top; /* 图片顶部居中显示 */
background-repeat: no-repeat; /* 不重复平铺 */
overflow: hidden;
display: flex;
flex-direction: column;
align-items: center;
}
/* 容器样式 */
.max_page {
width: 100%;
min-height: 100vh;
background-image: url('@/static/images/competition/bg.png');
background-color: #000; /* 图片高度不足时的背景色 */
background-size: 100% auto; /* 宽度填满,高度自适应 */
background-position: center top; /* 图片顶部居中显示 */
background-repeat: no-repeat; /* 不重复平铺 */
overflow: hidden;
display: flex;
flex-direction: column;
align-items: center;
}
</style>
+2 -1
View File
@@ -138,7 +138,6 @@
// 计算对方分数
const opponentScore = computed(() => {
// 筛选出所有 asrTm <= 当前时长的项
const validItems = pkData.traCompetitionPkTimeRecordVos.filter((item) => item.asrTm <= practiceTime.value);
if (validItems.length > 0) {
@@ -413,6 +412,8 @@
// console.log('倒计时时间', practiceRemainingTime.value);
// Pk时间到
if (practiceRemainingTime.value <= 0) {
}
}, 1000);
};
+5 -4
View File
@@ -57,7 +57,7 @@
</view>
<view class="pk-msg-right-div">
<view class="avatar-div">
<image-preview v-if="pkData.isAnonyPk === 'N'" class="img" :src="pkData.imgPk"></image-preview>
<image-preview v-if="pkData.pkIsAnony === 'N'" class="img" :src="pkData.imgPk"></image-preview>
<image v-else class="img" :src="defaultAnonymousAvatar" mode="aspectFill"></image>
</view>
<view class="name-div">{{ pkData.userNamePk }}</view>
@@ -123,7 +123,7 @@
userIdPk: '', // 用户Id String
userNamePk: '', // 用户姓名 String
imgPk: '', // 对方头像 String
isAnonyPk: 'Y', // 匿名 String
pkIsAnony: 'Y', // 匿名 String
correctNubPk: 0, // 正确数 int
qnsNubPk: 0, // 总数 int
timeTakenPk: 0, // 用时 int
@@ -147,7 +147,8 @@
const pkDataInit = common.getPageCache('competition_pk_to_resulf');
Object.assign(pkData, {
userName: pkDataInit.userName,
isAnony: pkDataInit.isAnony
isAnony: pkDataInit.isAnony,
pkIsAnony: pkDataInit.pkIsAnony,
});
});
onMounted(() => {
@@ -168,7 +169,7 @@
userIdPk: userResult.userIdPk, // 用户Id String
userNamePk: userResult.userNamePk, // 用户姓名 String
imgPk: userResult.imgPk, // 用户姓名 String
pkIsAnony: userResult.pkIsAnony, // 匿名 String
pkIsAnony: userResult.isAnonyPk, // 匿名 String
correctNubPk: userResult.correctNubPk, // 正确数 int
qnsNubPk: userResult.qnsNubPk || 0, // 总数 int
timeTakenPk: userResult.timeTakenPk || 0, // 用时 int
+2
View File
@@ -165,6 +165,7 @@
display: flex;
align-items: center;
justify-content: center;
flex-wrap: nowrap;
margin: 30rpx 0;
.title {
margin: 0 16rpx;
@@ -173,6 +174,7 @@
color: #ae723b;
text-align: center;
font-style: normal;
white-space: nowrap;
}
.img {
width: 242rpx;
Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Before

Width:  |  Height:  |  Size: 2.7 MiB

After

Width:  |  Height:  |  Size: 2.7 MiB

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 1.5 MiB

Before

Width:  |  Height:  |  Size: 2.8 MiB

After

Width:  |  Height:  |  Size: 2.8 MiB

Before

Width:  |  Height:  |  Size: 2.6 MiB

After

Width:  |  Height:  |  Size: 2.6 MiB