修复pk的bug和兑换

This commit is contained in:
田岩
2025-11-19 17:20:04 +08:00
parent 9eb03164c1
commit 65c125ca9f
17 changed files with 787 additions and 413 deletions
+4 -3
View File
@@ -5,13 +5,13 @@ ENV = 'development'
# VITE_APP_BASE_API_Url = 'https://aits.jlbank.com.cn:7001'
VITE_APP_BASE_API_Url = 'https://aitstest.jlbank.com.cn:7002'
# VITE_APP_BASE_API_Url = 'https://aitstest.jlbank.com.cn:7001'
# VITE_APP_BASE_API_Url = 'http://192.168.247.200'
# VITE_APP_BASE_API_Url = 'http://aitscdn.jlbank.com.cn:7001'
# VITE_APP_BASE_API_Url = 'http://192.168.108.129'
# dev
# VITE_APP_BASE_API_Url = 'http://25.18.122.65:7001'
VITE_APP_BASE_API_Url = 'http://25.18.122.65:7001'
# sit
@@ -34,7 +34,8 @@ VITE_APP_BASE_API_Url = 'https://aitstest.jlbank.com.cn:7002'
#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_TRAAPP = 'http://25.64.32.158:9601'
VITE_APP_BASE_H5_API_Url_TEST = 'http://127.0.0.1:5000'
#VITE_APP_BASE_H5_API_Url_TRAEXAM = 'http://192.168.247.200'
# VITE_APP_BASE_H5_API_Url_TRAASK = 'http://25.64.32.154:9605'
+7 -1
View File
@@ -44,8 +44,14 @@ export const addPointsByCheckIn = (data) => {
changePoints 本次获得积分 int
*/
export const addPointsByTask = (data) => {
// base_url
// return request({
// url: base_url + '/traPointsInfo/addPointsByTask',
// method: 'post',
// data
// });
return request({
url: base_url + '/traPointsInfo/addPointsByTask',
url: '/test/traPointsInfo/addPointsByTask',
method: 'post',
data
});
+20
View File
@@ -0,0 +1,20 @@
import request from '@/api/request'
const base_url = '/traapp'
// String actId,活动id
export const queryPointsActivityDetail = (data) => {
return request({
url: base_url + '/traPointsActivity/queryPointsActivityDetail',
method: 'post',
data
});
};
export const addPointsExchange = (data) => {
return request({
url: base_url + '/traPointsActivity/addPointsExchange',
method: 'post',
data
});
};
+17
View File
@@ -63,6 +63,23 @@ const loading = (title = '加载中', mask = true) => uni.showLoading({
})
const hideLoading = () => uni.hideLoading()
// 根据姓名的长度生成对应的带星号格式
export const formatName = (name) => {
// 处理空值或非字符串情况
if (!name || typeof name !== 'string') {
return '';
}
const familyName = name.charAt(0); // 取姓氏(第一个字符)
const givenNameLength = name.length - 1; // 名字部分的长度
// 根据名字长度计算星号数量,最多4个
const starCount = Math.min(givenNameLength, 3);
const stars = '*'.repeat(starCount);
return familyName + stars;
}
// 防抖工具函数
function debounce(fn, wait = 300) {
@@ -1,9 +1,9 @@
/**
完成课程学习 首次完成1分 每天最多获取5分 完成课程学习 crsId 02 完成调用 杨航
完成课程练习 首次完成1分 每天最多获取5分 完成课程练习 crsId 04 完成练习调用 田岩
通过课程考试 首次完成1分 每天最多获取5分 通过课程考试 crsId 03 通过调用 田岩
完成考试中心考试 首次完成1分 每天最多获取5分 完成考试中心考试 papersId 05 完成调用 田岩
完成竞赛PK 每次1分 每天最多获取5分 完成竞赛PK 11 完成调用 田岩
完成课程练习 首次完成1分 每天最多获取5分 完成课程练习 crsId 04 完成练习调用 田岩 已完成
通过课程考试 首次完成1分 每天最多获取5分 通过课程考试 crsId 03 通过调用 田岩 已完成
完成考试中心考试 首次完成1分 每天最多获取5分 完成考试中心考试 papersId 05 完成调用 田岩 已完成
完成竞赛PK 每次1分 每天最多获取5分 完成竞赛PK 11 完成调用 田岩 已完成
通过AI陪练练习 每次1分 每天最多获取5分 通过AI陪练练习 07 通过调用 杨航
通过AI陪练考试 每次1分 每天最多获取5分 通过AI陪练考试 08 通过调用 杨航
签到 每日1积分,
@@ -15,7 +15,7 @@ import {
addPointsByTask
} from '@/api/pointsAndRank.js'
import {
ref
ref, nextTick
} from 'vue'
import {
pop_up_time
@@ -90,6 +90,13 @@ export default function usePointsAndBadge() {
// 调用积分接口
console.log('调用积分接口');
const res = await addPointsByTask(requestParams);
if(type=== '04') { // 完成课程练习,自己处理逻辑
return {
points: res.body.points,
message: res.body.message,
taskBadges: res.body.taskBadges ?? [],
}
}
console.log('调用积分接口', res);
console.log('pointsRefpointsRef', pointsRef.value);
@@ -98,7 +105,9 @@ export default function usePointsAndBadge() {
if (badgesList.length > 0) {
nextTick(() => {
setTimeout(() => {
badgeRef.value.open(pointsList, badgesList);
badgeRef.value.open(pointsList, badgesList, () => {
badgeRef.value.close()
});
}, pop_up_time);
});
}
+9
View File
@@ -393,6 +393,15 @@
}
}
},
{
"path": "pages/pointsRedemption/index",
"style": {
"navigationBarTitleText": "积分兑换",
"app-plus": {
"titleNView": false
}
}
},
{
"path": "pages/course/index",
"style": {
+5 -5
View File
@@ -31,7 +31,7 @@
<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 class="avatar-name-div">{{ data_info.isAnony === 'N' ? data_info.userName : formatName(data_info.userName) }}</view>
</view>
<view class="select-div" :class="{ hidden: challengeLoading }" @click="selectionInstitutionsRef.open(true)">
<view class="select-institution-div">
@@ -68,7 +68,7 @@
<image v-show="data_info.isAnony === 'Y'" class="img" :src="defaultAnonymousAvatar"></image>
</view>
<view class="name">
{{ data_info.isAnony === 'N' ? data_info.userName : '匿名' }}
{{ data_info.isAnony === 'N' ? data_info.userName : formatName(data_info.userName)}}
</view>
<view class="org">
{{ data_info.isAnony === 'N' ? data_info.orgIdName : '机构不显示' }}
@@ -87,7 +87,7 @@
<image v-else class="img" :src="defaultAnonymousAvatar" mode="aspectFill"></image>
</view>
<view class="name">
{{ data_info.pkIsAnony === 'N' ? data_info.pkUserName : '匿名' }}
{{ data_info.pkIsAnony === 'N' ? data_info.pkUserName : formatName(data_info.pkUserName)}}
</view>
<view class="org">
{{ data_info.pkIsAnony === 'N' ? data_info.pkOrgIdName : '机构不显示' }}
@@ -101,7 +101,7 @@
<view class="sheet_popup_div">
<view class="title_div">双人对战规则说明</view>
<view class="note_div">
{{ data_info.ruleDesc }}
{{ ' xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'|| data_info.ruleDesc }}
</view>
</view>
</uni-popup>
@@ -112,7 +112,7 @@
<script setup lang="ts">
import { ref, onMounted, reactive } from 'vue';
import common, { getUserInfo } from '@/common/common';
import common, { getUserInfo, formatName } from '@/common/common';
import { MatchTimeGenerator, formatTime } from './js/matching';
import { queryTraCompetitionInfoByPkUser } from '@/api/competition';
import { onLoad } from '@dcloudio/uni-app';
+3 -3
View File
@@ -14,7 +14,7 @@
<cached-avatar v-if="pkData.isAnony === 'N'" class="img"></cached-avatar>
<image v-else class="img" :src="defaultAnonymousAvatar" mode="aspectFill"></image>
</view>
<view class="name-div ellipsis-text">{{ pkData.isAnony === 'N' ? pkData.userName : '匿名' }}</view>
<view class="name-div ellipsis-text">{{ pkData.isAnony === 'N' ? pkData.userName : formatName(pkData.userName) }}</view>
</view>
<view class="fraction-div left">
<view class="fraction-title">分数</view>
@@ -29,7 +29,7 @@
<image-preview v-if="pkData.pkIsAnony === 'N'" class="img" :src="pkData.pkImgAddr"></image-preview>
<image v-else class="img" :src="defaultAnonymousAvatar" mode="aspectFill"></image>
</view>
<view class="name-div">{{ pkData.pkIsAnony === 'N' ? pkData.pkUserName : '匿名' }}</view>
<view class="name-div">{{ pkData.pkIsAnony === 'N' ? pkData.pkUserName : formatName(pkData.pkUserName) }}</view>
</view>
</view>
<view class="body-area-div">
@@ -117,7 +117,7 @@
import CharactersSubject from '@/components/examination/characters-subject.vue';
import TouchBtn from '@/components/examination/touchBtn.vue';
import common from '@/common/common';
import { setPageCache, formatSeconds, getPageCache, setupKeyboardHeightListener } from '@/common/common';
import { setPageCache, formatSeconds, getPageCache, setupKeyboardHeightListener, formatName } from '@/common/common';
import { commonUploadVoiceFile } from '@/api/common.js';
import { optionErrorIcon, examinationSheetIcon, practiceExitIcon } from '@/common/imgSvg';
import { practiceCommit, queryCrsPracticeAnswerResult } from '@/api/practice.js';
+356 -354
View File
@@ -1,399 +1,401 @@
<template>
<view class="exam-ranking">
<image src="@/static/images/competition/ranking/ranking_bg.png" mode="widthFix" class="bg-box"></image>
<view class="ranking-box">
<view class="nav-div">
<view class="back_div" @click="common.navigateBack()">
<view class="back-icon"></view>
</view>
</view>
<view class="title-view">
<!-- <view class="title-info">考试排行榜</view> -->
<image
class="title-image"
src="@/static/images/competition/ranking/ranking_title.png"
mode="aspectFit"
></image>
<view class="title-desc">欲穷千里目更上一层楼</view>
<image class="cup-image" src="@/static/images/examRanking/cup.png" mode="aspectFit"></image>
</view>
<view class="ranking-body">
<view class="list-header list-item">
<view class="rank-column">排名</view>
<view class="user-column">用户名/所属机构</view>
<view class="score-column">最高分</view>
<view class="time-column">用时</view>
</view>
<scroll-view :scroll-y="true" class="scroll-items-view">
<view v-for="(item, index) in userList" :class="['list-item', 'item-' + (index + 1)]">
<view class="rank-column">
{{ item.ranking }}
</view>
<view class="user-column">
<view class="avatar-box">
<image-preview
v-if="item.ossAddr"
class="avatar-image"
:src="item.ossAddr"
mode="aspectFit"
></image-preview>
<image v-else class="avatar-image" :src="defaultAvatarSrc"></image>
</view>
<view class="user-name">{{ item.userName }}</view>
<view class="user-org">{{ item.orgName }}</view>
</view>
<view class="score-column">{{ item.examGrade }}</view>
<view class="time-column">{{ item.time ?? 0 }}s</view>
</view>
<list-no-data v-if="userList.length == 0">暂无数据</list-no-data>
</scroll-view>
</view>
<view class="ranking-self">
<view class="list-header list-item">
<view class="rank-column">我的排名</view>
</view>
<view class="list-item item-me">
<view class="rank-column">
{{ userRankObj.ranking }}
</view>
<view class="user-column">
<view class="avatar-box">
<image-preview
v-if="userRankObj.ossAddr"
class="avatar-image"
:src="userRankObj.ossAddr"
mode="aspectFit"
></image-preview>
<image class="avatar-image" v-else :src="defaultAvatarSrc"></image>
</view>
<view class="user-name">{{ userRankObj.userName }}</view>
<view class="user-org">{{ userRankObj.orgName }}</view>
</view>
<view class="score-column">{{ userRankObj.examGrade }}</view>
<view class="time-column">{{ userRankObj.time }}s</view>
</view>
</view>
</view>
</view>
<view class="exam-ranking">
<image src="@/static/images/competition/ranking/ranking_bg.png" mode="widthFix" class="bg-box"></image>
<view class="ranking-box">
<view class="nav-div">
<view class="back_div" @click="common.navigateBack()">
<view class="back-icon"></view>
</view>
</view>
<view class="title-view">
<!-- <view class="title-info">考试排行榜</view> -->
<image
class="title-image"
src="@/static/images/competition/ranking/ranking_title.png"
mode="aspectFit"
></image>
<view class="title-desc">欲穷千里目更上一层楼</view>
<image class="cup-image" src="@/static/images/examRanking/cup.png" mode="aspectFit"></image>
</view>
<view class="ranking-body">
<view class="list-header list-item">
<view class="rank-column">排名</view>
<view class="user-column">用户名/所属机构</view>
<view class="score-column">最高分</view>
<view class="time-column">用时</view>
</view>
<scroll-view :scroll-y="true" class="scroll-items-view">
<view v-for="(item, index) in userList" :class="['list-item', 'item-' + (index + 1)]">
<view class="rank-column">
{{ item.ranking }}
</view>
<view class="user-column">
<view class="avatar-box">
<image-preview
v-if="item.ossAddr"
class="avatar-image"
:src="item.ossAddr"
mode="aspectFit"
></image-preview>
<image v-else class="avatar-image" :src="defaultAvatarSrc"></image>
</view>
<view class="user-name">
{{ item.isAnony === 'N' ? item.userName : formatName(item.userName) }}
</view>
<view class="user-org">{{ item.orgName }}</view>
</view>
<view class="score-column">{{ item.examGrade }}</view>
<view class="time-column">{{ item.time ?? 0 }}s</view>
</view>
<list-no-data v-if="userList.length == 0">暂无数据</list-no-data>
</scroll-view>
</view>
<view class="ranking-self">
<view class="list-header list-item">
<view class="rank-column">我的排名</view>
</view>
<view class="list-item item-me">
<view class="rank-column">
{{ userRankObj.ranking }}
</view>
<view class="user-column">
<view class="avatar-box">
<image-preview
v-if="userRankObj.ossAddr"
class="avatar-image"
:src="userRankObj.ossAddr"
mode="aspectFit"
></image-preview>
<image class="avatar-image" v-else :src="defaultAvatarSrc"></image>
</view>
<view class="user-name">{{ userRankObj.isAnony === 'N' ? userRankObj.userName : formatName(userRankObj.userName) }}</view>
<view class="user-org">{{ userRankObj.orgName }}</view>
</view>
<view class="score-column">{{ userRankObj.examGrade }}</view>
<view class="time-column">{{ userRankObj.time }}s</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import {queryTraCompetitionRankingList} from '@/api/competition.js';
import {defaultAvatar} from '@/enum.js';
import common from '@/common/common';
import {onLoad} from '@dcloudio/uni-app';
import {formatSecondsToMS} from './js/tool';
import {ref} from 'vue';
const papersId = ref('');
const orgId = ref('');
const userList = ref([]);
const userRankObj = ref({});
onLoad((e) => {
papersId.value = e.papersId;
orgId.value = e.orgId;
getList();
});
const getList = () => {
queryTraCompetitionRankingList({
papersId: papersId.value,
orgId: orgId.value
}).then((res) => {
userList.value = res.body.rankingListVos || [];
userRankObj.value = res.body;
});
};
import { queryTraCompetitionRankingList } from '@/api/competition.js';
import { defaultAvatar } from '@/enum.js';
import common from '@/common/common';
import { onLoad } from '@dcloudio/uni-app';
import { formatSecondsToMS } from './js/tool';
import { ref } from 'vue';
import { formatName } from '@/common/common';
const papersId = ref('');
const orgId = ref('');
const userList = ref([]);
const userRankObj = ref({});
onLoad((e) => {
papersId.value = e.papersId;
orgId.value = e.orgId;
getList();
});
const getList = () => {
queryTraCompetitionRankingList({
papersId: papersId.value,
orgId: orgId.value
}).then((res) => {
userList.value = res.body.rankingListVos || [];
userRankObj.value = res.body;
});
};
</script>
<style scoped lang="scss">
$top-height: var(--status-bar-height);
$top-height: var(--status-bar-height);
.exam-ranking {
position: relative;
height: 100vh;
width: 100vw;
overflow: hidden;
box-sizing: border-box;
padding-top: $top-height;
.exam-ranking {
position: relative;
height: 100vh;
width: 100vw;
overflow: hidden;
box-sizing: border-box;
padding-top: $top-height;
// background:url(@/static/images/examRanking/bg.png) no-repeat top center;
.bg-box {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 412rpx;
z-index: 1;
}
// background:url(@/static/images/examRanking/bg.png) no-repeat top center;
.bg-box {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 412rpx;
z-index: 1;
}
.ranking-box {
height: calc(100% - $top-height);
overflow: hidden;
position: absolute;
top: $top-height;
width: 100%;
z-index: 2;
}
.ranking-box {
height: calc(100% - $top-height);
overflow: hidden;
position: absolute;
top: $top-height;
width: 100%;
z-index: 2;
}
.nav-div {
position: relative;
overflow: hidden;
height: 70rpx;
.nav-div {
position: relative;
overflow: hidden;
height: 70rpx;
.back_div {
margin-right: 10rpx;
position: absolute;
left: 25rpx;
top: 0;
padding: 15rpx;
.back_div {
margin-right: 10rpx;
position: absolute;
left: 25rpx;
top: 0;
padding: 15rpx;
.back-icon {
position: relative;
width: 40rpx;
height: 40rpx;
cursor: pointer;
}
.back-icon {
position: relative;
width: 40rpx;
height: 40rpx;
cursor: pointer;
}
.back-icon::before,
.back-icon::after {
content: '';
position: absolute;
transition: all 0.3s ease;
}
.back-icon::before,
.back-icon::after {
content: '';
position: absolute;
transition: all 0.3s ease;
}
.back-icon::after {
top: 25%;
left: 25%;
width: 40%;
height: 40%;
border-top: 4rpx solid #000;
border-left: 4rpx solid #000;
transform: rotate(-45deg);
}
}
}
.back-icon::after {
top: 25%;
left: 25%;
width: 40%;
height: 40%;
border-top: 4rpx solid #000;
border-left: 4rpx solid #000;
transform: rotate(-45deg);
}
}
}
.title-view {
height: 180rpx;
position: relative;
padding-left: 79rpx;
padding-top: 20rpx;
.title-view {
height: 180rpx;
position: relative;
padding-left: 79rpx;
padding-top: 20rpx;
.cup-image {
position: absolute;
right: 90rpx;
bottom: -5rpx;
width: 178rpx;
height: 159rpx;
}
.cup-image {
position: absolute;
right: 90rpx;
bottom: -5rpx;
width: 178rpx;
height: 159rpx;
}
.title-desc {
line-height: 34rpx;
font-size: 25rpx;
color: #ffffff;
margin-top: -6rpx;
}
.title-desc {
line-height: 34rpx;
font-size: 25rpx;
color: #ffffff;
margin-top: -6rpx;
}
.title-image {
width: 354rpx;
height: 88rpx;
margin-left: -20rpx;
}
}
.title-image {
width: 354rpx;
height: 88rpx;
margin-left: -20rpx;
}
}
.ranking-body {
height: calc(100% - 170rpx - 180rpx - 70rpx);
overflow: hidden;
background-color: #fff;
border-radius: 31rpx 31rpx 0 0;
padding-top: 20rpx;
box-sizing: border-box;
z-index: 100;
.ranking-body {
height: calc(100% - 170rpx - 180rpx - 70rpx);
overflow: hidden;
background-color: #fff;
border-radius: 31rpx 31rpx 0 0;
padding-top: 20rpx;
box-sizing: border-box;
z-index: 100;
.scroll-items-view {
height: calc(100% - 54rpx);
}
}
.scroll-items-view {
height: calc(100% - 54rpx);
}
}
.list-item {
height: 108rpx;
border-bottom: 2rpx solid #efefef;
overflow: hidden;
.list-item {
height: 108rpx;
border-bottom: 2rpx solid #efefef;
overflow: hidden;
&.list-header {
height: 54rpx;
line-height: 54rpx;
color: #999;
font-size: 25rpx;
border-bottom: 0;
&.list-header {
height: 54rpx;
line-height: 54rpx;
color: #999;
font-size: 25rpx;
border-bottom: 0;
.rank-column {
height: 54rpx;
line-height: 54rpx;
color: #999;
font-weight: normal;
font-size: 25rpx;
font-style: initial;
text-indent: 0;
}
.rank-column {
height: 54rpx;
line-height: 54rpx;
color: #999;
font-weight: normal;
font-size: 25rpx;
font-style: initial;
text-indent: 0;
}
.user-column {
padding: 0;
}
.user-column {
padding: 0;
}
.score-column {
line-height: 54rpx;
color: #999;
font-weight: normal;
font-size: 25rpx;
}
.score-column {
line-height: 54rpx;
color: #999;
font-weight: normal;
font-size: 25rpx;
}
.time-column {
line-height: 54rpx;
color: #999;
font-weight: normal;
font-size: 25rpx;
}
}
.time-column {
line-height: 54rpx;
color: #999;
font-weight: normal;
font-size: 25rpx;
}
}
&.item-1 {
border-bottom: 0;
margin-bottom: 8rpx;
background: linear-gradient(90deg, #fbf9f5 0%, #fffffd 100%);
&.item-1 {
border-bottom: 0;
margin-bottom: 8rpx;
background: linear-gradient(90deg, #fbf9f5 0%, #fffffd 100%);
.rank-column {
color: #ffffff00;
background: url(@/static/images/examRanking/no-1.png) no-repeat;
background-position: 40rpx center;
background-size: 44rpx 66rpx;
text-indent: 8rpx;
}
}
.rank-column {
color: #ffffff00;
background: url(@/static/images/examRanking/no-1.png) no-repeat;
background-position: 40rpx center;
background-size: 44rpx 66rpx;
text-indent: 8rpx;
}
}
&.item-2 {
border-bottom: 0;
margin-bottom: 8rpx;
background: linear-gradient(90deg, #f4f8f9 0%, #f7fbfe 100%);
&.item-2 {
border-bottom: 0;
margin-bottom: 8rpx;
background: linear-gradient(90deg, #f4f8f9 0%, #f7fbfe 100%);
.rank-column {
color: #ffffff00;
background: url(@/static/images/examRanking/no-2.png) no-repeat;
background-position: 40rpx center;
background-size: 44rpx 66rpx;
text-indent: 8rpx;
}
}
.rank-column {
color: #ffffff00;
background: url(@/static/images/examRanking/no-2.png) no-repeat;
background-position: 40rpx center;
background-size: 44rpx 66rpx;
text-indent: 8rpx;
}
}
&.item-3 {
border-bottom: 0;
margin-bottom: 8rpx;
background: linear-gradient(90deg, #faf6f5 0%, #fcfbfc 100%);
&.item-3 {
border-bottom: 0;
margin-bottom: 8rpx;
background: linear-gradient(90deg, #faf6f5 0%, #fcfbfc 100%);
.rank-column {
color: #ffffff00;
background: url(@/static/images/examRanking/no-3.png) no-repeat;
background-position: 40rpx center;
background-size: 44rpx 66rpx;
text-indent: 8rpx;
}
}
.rank-column {
color: #ffffff00;
background: url(@/static/images/examRanking/no-3.png) no-repeat;
background-position: 40rpx center;
background-size: 44rpx 66rpx;
text-indent: 8rpx;
}
}
&.item-me {
border-bottom: 0;
&.item-me {
border-bottom: 0;
.rank-column {
color: #06f;
}
}
.rank-column {
color: #06f;
}
}
.rank-column {
width: 170rpx;
padding-left: 40rpx;
float: left;
font-weight: 600;
line-height: 92rpx;
height: 108rpx;
color: #333;
font-size: 38rpx;
font-style: italic;
text-indent: 8rpx;
}
.rank-column {
width: 170rpx;
padding-left: 40rpx;
float: left;
font-weight: 600;
line-height: 92rpx;
height: 108rpx;
color: #333;
font-size: 38rpx;
font-style: italic;
text-indent: 8rpx;
}
.user-column {
width: 300rpx;
float: left;
padding: 15rpx 0;
.user-column {
width: 300rpx;
float: left;
padding: 15rpx 0;
.avatar-box {
width: 77rpx;
height: 77rpx;
overflow: hidden;
float: left;
background-color: #eee;
border-radius: 50%;
.avatar-box {
width: 77rpx;
height: 77rpx;
overflow: hidden;
float: left;
background-color: #eee;
border-radius: 50%;
.avatar-image {
width: 77rpx;
height: 77rpx;
}
}
.avatar-image {
width: 77rpx;
height: 77rpx;
}
}
.user-name {
float: left;
width: calc(100% - 77rpx);
padding-left: 18rpx;
padding-right: 18rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
height: 40rpx;
line-height: 40rpx;
font-size: 29rpx;
color: #000;
font-weight: 500;
}
.user-name {
float: left;
width: calc(100% - 77rpx);
padding-left: 18rpx;
padding-right: 18rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
height: 40rpx;
line-height: 40rpx;
font-size: 29rpx;
color: #000;
font-weight: 500;
}
.user-org {
float: left;
width: calc(100% - 77rpx);
padding-left: 18rpx;
padding-right: 18rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
height: 34rpx;
line-height: 34rpx;
font-size: 25rpx;
color: #999;
}
}
.user-org {
float: left;
width: calc(100% - 77rpx);
padding-left: 18rpx;
padding-right: 18rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
height: 34rpx;
line-height: 34rpx;
font-size: 25rpx;
color: #999;
}
}
.score-column {
width: 126rpx;
text-align: right;
float: left;
font-weight: 600;
line-height: 108rpx;
color: #333;
font-size: 31rpx;
}
.score-column {
width: 126rpx;
text-align: right;
float: left;
font-weight: 600;
line-height: 108rpx;
color: #333;
font-size: 31rpx;
}
.time-column {
width: 100rpx;
text-align: right;
float: left;
font-weight: 600;
line-height: 108rpx;
color: #333;
font-size: 31rpx;
}
}
.time-column {
width: 100rpx;
text-align: right;
float: left;
font-weight: 600;
line-height: 108rpx;
color: #333;
font-size: 31rpx;
}
}
.ranking-self {
height: 170rpx;
overflow: hidden;
background-color: #f5f9ff;
padding-top: 4rpx;
}
}
.ranking-self {
height: 170rpx;
overflow: hidden;
background-color: #f5f9ff;
padding-top: 4rpx;
}
}
</style>
+12 -7
View File
@@ -37,7 +37,7 @@
<image v-else class="img" :src="defaultAnonymousAvatar" mode="aspectFill"></image>
</view>
<view class="name-div">{{ pkData.userName }}</view>
<view class="name-div">{{ pkData.isAnony === 'N' ?pkData.userName:formatName(pkData.userName) }}</view>
<view class="title">正确/总题数</view>
<view class="topic-div number">
<text class="loadingNoText font-size-54">{{ pkData.correctNub }}</text>
@@ -60,7 +60,7 @@
<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.pkIsAnony === 'N' ? pkData.userNamePk : '匿名' }}</view>
<view class="name-div">{{ pkData.pkIsAnony === 'N' ? pkData.userNamePk : formatName(pkData.userNamePk) }}</view>
<view class="title">正确/总题数</view>
<view class="topic-div number">
<text class="loadingNoText font-size-54">{{ pkData.correctNubPk }}</text>
@@ -80,7 +80,9 @@
</view>
</view>
<!-- 查看排行榜按钮 -->
<view class="ranking-list-div" @click="buttonClick('toRanking')">查看排行榜</view>
<view class="ranking-list-div" @click="buttonClick('toRanking')">
<text v-if="mode==='pk_in'">查看排行榜</text>
</view>
<!-- 下方的两个按钮 -->
<view class="fl1"></view>
<view class="bottom-button-div" v-if="mode === 'pk_in'">
@@ -98,7 +100,7 @@
</template>
<script setup lang="ts">
import { ref, onMounted, reactive, computed, nextTick } from 'vue';
import common, { getUserInfo } from '@/common/common';
import common, { getUserInfo, formatName } from '@/common/common';
import { MatchTimeGenerator, formatTime } from './js/matching';
import { queryCompetitionAnswerResult } from '@/api/competition';
import { onLoad } from '@dcloudio/uni-app';
@@ -144,7 +146,8 @@
common.navigateBack(2);
} else if (type === 'continue') {
common.navigateBack();
} else if (type === 'toRanking') {
} else if (type === 'toRanking' && mode.value ==='pk_in') {
common.navigateTo(`/pages/competition/ranking?papersId=${pkData.papersId}&orgId=${pkData.orgId}`);
}
};
@@ -190,8 +193,10 @@
nextTick(() => {
action.value = 'result';
});
console.log('调用它');
pointAndBadgesRun('11')
if(mode.value === 'pk_in') {
console.log('调用它');
pointAndBadgesRun('11')
}
});
}, 2000);
});
@@ -329,6 +329,9 @@
}
.note_div {
padding: 20rpx 0 80rpx 0;
word-wrap: break-word; /* 旧版浏览器兼容,允许长单词换行到下一行 */
word-break: break-all; /* 强制断词,哪怕是连续字母也会换行(适合小程序) */
white-space: normal; /* 恢复默认换行(避免被其他样式覆盖) */
}
}
}
+19 -1
View File
@@ -120,6 +120,8 @@
</view>
</view>
</scroll-view>
<badge ref="badgeRef"></badge>
<points ref="pointsRef"></points>
</view>
</template>
@@ -134,6 +136,11 @@
import Subject from '@/components/examination/subject.vue';
import common from '@/common/common';
import badge from '@/components/points-and-badge/badge';
import points from '@/components/points-and-badge/points';
import usePointsAndBadge from '@/components/points-and-badge/usePointsAndBadge';
const { pointAndBadgesRun, badgeRef, pointsRef } = usePointsAndBadge();
const pass_status = ref(0);
const sheet_swiper_index = ref(0);
const result = reactive({
@@ -282,7 +289,18 @@
topicList.push(...body.qnsInfoVo);
requestCount.value = 0;
// 触发获取结果完成事件
console.log('触发获取结果完成事件');
console.log('触发获取结果完成事件', result.mode);
if(result.mode === 'examination') {
console.log('调用它');
if (result.crsId !== '') {
pointAndBadgesRun('03', result.crsId)
} else {
pointAndBadgesRun('05', result.papersId)
}
}
uni.$emit('get_result_completed');
}
})
+4 -5
View File
@@ -65,7 +65,7 @@
></uv-count-to>
</view>
</view>
<view class="item-interval" @click="test()"></view>
<view class="item-interval" @click="goTest()"></view>
<view class="item" @click="common.navigateTo('/pages/pointsAndRank/badge')">
<view class="top">徽章墙</view>
<view class="bottom">
@@ -239,11 +239,10 @@
checkInDays: 0 // 连续签到天数
});
const goTest = () => {
common.navigateTo('/pages/test/index');
};
const test = () => {
badgeRef.value.open();
console.log('xxxxxxxxx');
common.navigateTo('/pages/pointsRedemption/index');
};
// 签到打开
const checkInClick = () => {
checkInRef.value.open(user_info.checkInToday, user_info.checkInDays);
+180
View File
@@ -0,0 +1,180 @@
<template>
<z-paging
ref="pagingRef"
v-model="data_list"
@query="queryList"
class="scroll_div"
empty-view-text="暂无积分记录"
paging-class="z-paging-class"
>
<template #top>
<view class="top-main-div">
<view class="content">
<view class="body-title">
<view class="back_div" @click="common.navigateBack()">
<view class="back-icon"></view>
</view>
<view>积分明细</view>
</view>
<view class="fl1"></view>
</view>
</view>
</template>
<view class="scroll-Y"></view>
<template #bottom>
<uv-button
@click="buttonClick"
type="primary"
class="send_evaluate"
color="#0066FF"
:throttleTime="100"
text="20积分兑换"
loadingText="正在加载错题"
:custom-style="customStyle"
></uv-button>
</template>
</z-paging>
</template>
<script setup>
//
import { ref, reactive, watch, onMounted } from 'vue';
import { onLoad, onUnload } from '@dcloudio/uni-app';
import useZpaging from '@/composables/useZpaging.js';
import common from '@/common/common';
import { queryPointsActivityDetail, addPointsExchange } from '@/api/pointsRedemption.js';
const customStyle = {
borderRadius: '12rpx'
};
const startVal = ref(0);
const endVal = ref(0);
const countToRef = ref(null);
const fetchFunction = (params) => {
queryPointsActivityDetail({
actId:"TRAPOINTSACTIVITY02501812207220251113142216000003456"
}).then(({ body }) => {
console.log('body', body);
});
};
const { pagingRef, queryList, data_list } = useZpaging({
fetchFunction
});
const buttonClick = () => {};
onLoad(() => {
const points_data = common.getValue('points_data');
if (points_data) {
startVal.value = points_data.currentPoints; //
endVal.value = points_data.currentPoints; //
}
});
onUnload(() => {});
</script>
<style lang="scss" scoped>
.send_evaluate {
padding: 28rpx 42rpx 38rpx 42rpx;
}
.z-paging-class {
background-color: #e0e3ef;
::v-deep .zp-view-super {
background-color: #ffffff;
margin: 0 24rpx;
height: 100%;
border-radius: 30rpx;
}
}
.top-main-div {
/* 宽度占满父容器 */
width: 100%;
/* 隐藏超出容器的背景图部分 */
overflow: hidden;
/* 使用 padding-top 实现 78:35 的宽高比(计算公式:35/78*100% ≈ 44.87% */
padding-top: 44.87%;
/* 背景图设置,确保图片覆盖且不重复 */
background-image: url('@/static/images/pointsAndRank/bg.png');
background-size: cover;
background-repeat: no-repeat;
background-position: center;
/* 若盒子内有内容,需用相对定位让内容脱离文档流 */
position: relative;
margin-bottom: calc(-44.87% + 150rpx);
.content {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.my-points {
padding-bottom: 84rpx;
padding-left: 46rpx;
display: flex;
align-items: flex-end;
}
}
.scroll-Y {
overflow: hidden;
}
.body-title {
width: 100%;
height: 70rpx;
font-size: 33rpx;
font-weight: 500;
color: #ffffff;
position: relative;
text-align: center;
margin-top: var(--status-bar-height);
.delete_div {
position: absolute;
right: 20rpx;
top: 17rpx;
width: 50rpx;
height: 50rpx;
.img {
width: 34rpx;
height: 34rpx;
}
}
.back_div {
position: absolute;
left: 26rpx;
top: 17rpx;
.back-icon {
position: relative;
width: 50rpx;
height: 50rpx;
cursor: pointer;
display: flex;
align-items: center;
}
.back-icon::before,
.back-icon::after {
content: '';
position: absolute;
transition: all 0.3s ease;
}
.back-icon::after {
top: 25%;
left: 25%;
width: 40%;
height: 40%;
border-top: 4rpx solid #ffffff;
border-left: 4rpx solid #ffffff;
transform: rotate(-45deg);
}
}
}
</style>
+10 -8
View File
@@ -7,10 +7,7 @@
</view>
<view class="back_div" @click="exit_practice">
<image :src="practiceExitIcon()" class="img"></image>
<view class="text">
退出
</view>
<view class="text">退出</view>
</view>
</view>
<view class="countdown-and-question-number-div">
@@ -40,6 +37,8 @@
</view>
<view class="scroll_div">
<swiper
:disable-touch="showSwiper"
ref="swiperRef"
class="swiper"
:indicator-dots="false"
@change="swiperChange"
@@ -100,6 +99,7 @@
import { startExamByCrs } from '@/api/examination.js';
import { startPracticeByCrs } from '@/api/practice.js';
const swiperRef = ref(null);
const feedbackRef = ref(null);
const dialogRef = ref(null);
const touchBtnRef = ref(null);
@@ -118,7 +118,6 @@
const storageTopicList = ref([]); //
const popup_input_bottom = ref('0px');
const questionNumber = ref(0); //
const topic = computed({
get: () => topicList[questionNumber.value],
@@ -157,6 +156,7 @@
const isLastTopic = computed(
() => topicList.length === finishCurrent.value + 1 && finishCurrent.value === questionNumber.value
);
const showSwiper = ref(false);
const transition = (event) => {
if (isTriggered.value) return;
const dx = event.detail.dx;
@@ -405,7 +405,9 @@
const hand_in_paper_button_click = () => {
console.log('交卷按钮');
const stat = 'P';
//
showSwiper.value = true;
// 2. 50ms swiper
nextTick(() => {
common.redirectTo(
`/pages/practice/result?name=${paperData.name}&exrId=${paperData.exrId}&crsId=${paperData.crsId}&examLenTm=${practiceTime.value}&stat=${stat}&examStat=${examStat.value}`
@@ -747,7 +749,7 @@
width: 32rpx;
height: 32rpx;
}
.text{
.text {
color: #eaeaea;
font-size: 24rpx;
white-space: nowrap;
@@ -755,7 +757,7 @@
}
}
}
.main_div {
display: flex;
flex-direction: column;
+114 -20
View File
@@ -1,7 +1,26 @@
<template>
<view class="max_page">
<image src="@/static/images/common/wc.png" class="show_img"></image>
<view class="show_msg">练习完成</view>
<view class="max_page" :class="{points_bg:showData.num !== 0}">
<view class="" v-if="showData.num === 0">
<image src="@/static/images/common/wc.png" class="show_img"></image>
<view class="show_msg">练习完成</view>
</view>
<view class="" v-if="showData.num !== 0">
<view class="title_div">
<image class="img" src="@/static/images/pointsAndRank/badge-wheat-left.png"></image>
<view class="">
<view class="title">恭喜你完成练习</view>
<view class="title">并获得积分</view>
</view>
<image class="img" src="@/static/images/pointsAndRank/badge-wheat-right.png"></image>
</view>
<view class="points-div">
<view class="points-img-div">
<image class="img_100" src="@/static/images/pointsAndRank/like.png" mode=""></image>
</view>
<view class="points-num-div">+{{showData.num}}</view>
<view class="points-msg-div" v-show="showData.message"> {{showData.message}}</view>
</view>
</view>
<view class="fl1"></view>
<view class="show_button">
<uv-button
@@ -36,6 +55,7 @@
:custom-style="customStyle3"
></uv-button>
</view>
<badge ref="badgeRef"></badge>
</view>
</template>
@@ -47,6 +67,10 @@
import { startExamByCrs } from '@/api/examination.js';
import { startPracticeByCrs } from '@/api/practice.js';
import { practiceCommit } from '@/api/practice.js';
import badge from '@/components/points-and-badge/badge';
import { pop_up_time } from '@/enum';
import usePointsAndBadge from '@/components/points-and-badge/usePointsAndBadge';
const { pointAndBadgesRun, badgeRef } = usePointsAndBadge();
const customStyle1 = {
borderRadius: '12rpx',
color: '#FFFFFF',
@@ -74,7 +98,7 @@
const crsId = ref('');
const name = ref('');
const loading = ref('');
//
let isUnmounted = false;
//
@@ -124,37 +148,107 @@
loading.value = '';
}
};
const exrId = ref('')
const examLenTm = ref('')
const stat = ref('')
const examStat = ref('')
const commit = ref(false)
const exrId = ref('');
const examLenTm = ref('');
const stat = ref('');
const examStat = ref('');
const commit = ref(false);
// const changePoints = ref(0);
const showData = ref({
num: 0,
message:''
});
onLoad((e) => {
console.log('xx23333');
crsId.value = e.crsId
name.value = e.name
exrId.value = e.exrId
examLenTm.value = e.examLenTm
stat.value = e.stat
examStat.value = e.examStat??''
crsId.value = e.crsId;
name.value = e.name;
exrId.value = e.exrId;
examLenTm.value = e.examLenTm;
stat.value = e.stat;
examStat.value = e.examStat ?? '';
console.log('xxxx111');
practiceCommitFun()
practiceCommitFun();
});
const practiceCommitFun = () => {
practiceCommit({ exrId: exrId.value, examLenTm: examLenTm.value, stat: stat.value }).then(() => {
console.log('提交练习状态成功');
commit.value = true
})
}
commit.value = true;
pointAndBadgesRun('04', crsId.value).then(({ points, message, taskBadges }) => {
if (Array.isArray(points) && points.length > 0) {
showData.value.num = points[0]['changePoints'];
showData.value.message = message;
}
if (taskBadges.length > 0) {
nextTick(() => {
setTimeout(() => {
badgeRef.value.open([], taskBadges);
}, pop_up_time);
});
}
});
});
};
onUnmounted(() => {});
</script>
<style scoped lang="scss">
.points-div {
display: flex;
flex-direction: column;
align-items: center;
padding: 60rpx 0 0 0;
.points-img-div {
width: 320rpx;
height: 278rpx;
}
.points-num-div {
font-family: Arial, Arial;
font-weight: normal;
font-size: 108rpx;
color: #333333;
line-height: 108rpx;
text-align: center;
font-weight: 600;
}
.points-msg-div {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 30rpx;
color: #ae723b;
line-height: 40px;
text-align: center;
}
}
.title_div {
display: flex;
align-items: center;
justify-content: center;
margin-top: 84rpx;
height: 68rpx;
.img {
width: 36rpx;
height: 74rpx;
}
.title {
font-family: AlimamaShuHeiTi, AlimamaShuHeiTi;
font-weight: 500;
font-size: 46rpx;
color: #d88f50;
margin: 0rpx 30rpx;
text-align: center;
}
}
.max_page {
display: flex;
align-items: center;
flex-direction: column;
}
.points_bg {
background: linear-gradient( 180deg, #FFF9EB 0%, #F7F7F7 100%);
}
.show_img {
margin-top: 300rpx;
+9
View File
@@ -328,6 +328,15 @@
"titleNView": false
}
}
},
{
"path": "pages/pointsRedemption/index",
"style": {
"navigationBarTitleText": "积分兑换",
"app-plus": {
"titleNView": false
}
}
}
]
}