1
@@ -16,5 +16,5 @@ VITE_APP_BASE_API_Url = 'https://aitstest.jlbank.com.cn:7001'
|
||||
# h5专用地址
|
||||
|
||||
# 王洋洋
|
||||
VITE_APP_BASE_H5_API_Url = 'http://25.64.16.140:9604'
|
||||
#VITE_APP_BASE_H5_API_Url = 'https://aitstest.jlbank.com.cn:7001'
|
||||
#VITE_APP_BASE_H5_API_Url = 'http://25.64.16.140:9604'
|
||||
VITE_APP_BASE_H5_API_Url = 'https://aitstest.jlbank.com.cn:7001'
|
||||
@@ -141,4 +141,7 @@ view {
|
||||
.no-overflow{
|
||||
overflow: hidden;
|
||||
}
|
||||
.bold{
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import request from '@/api/request'
|
||||
import { getToken } from '@/common/common.js'
|
||||
import { get_base_url } from '@/api/request'
|
||||
const base_url = '/traexam'
|
||||
|
||||
// 开始考试(试卷信息)
|
||||
export const startTraExamPapersInfo = (data) => {
|
||||
return request({
|
||||
url: base_url + '/traExamPapers/startTraExamPapersInfo',
|
||||
method: 'post',
|
||||
toastErrors: true,
|
||||
data
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
export const optionSuccessIcon = (color : string) : string => {
|
||||
const svgXml = `
|
||||
<svg t="1754618739937" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6322" width="64" height="64"><path d="M843.693959 293.609061 425.255869 712.056362 186.145026 472.947566 66.579883 592.504522 425.255869 951.165158 963.260126 413.174204Z" fill="${color}" p-id="6323"></path></svg>
|
||||
`.trim();
|
||||
|
||||
return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgXml)}`;
|
||||
};
|
||||
export const optionErrorIcon = () : string => {
|
||||
const svgXml = `
|
||||
<svg t="1754619171929" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6505" width="64" height="64"><path d="M910.336 186.368l-72.704-72.704L512 439.808 186.368 113.664 113.664 186.368 439.808 512l-326.144 325.632 72.704 72.704L512 584.192l325.632 326.144 72.704-72.704L584.192 512l326.144-325.632z" fill="#F5212D" p-id="6506"></path></svg>
|
||||
`.trim();
|
||||
return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgXml)}`;
|
||||
};
|
||||
|
||||
export const examinationSheetIcon = () : string => {
|
||||
const svgXml = `
|
||||
<svg t="1754630871725" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6324" width="64" height="64"><path d="M802.107077 51.2a145.289846 145.289846 0 0 1 145.092923 145.526154v630.547692a145.289846 145.289846 0 0 1-145.092923 145.526154H221.892923a145.329231 145.329231 0 0 1-145.092923-145.526154V196.726154A145.289846 145.289846 0 0 1 221.892923 51.2h580.214154z m-3.387077 76.8H225.28a71.837538 71.837538 0 0 0-71.561846 67.741538l-0.118154 4.253539v624.009846a71.837538 71.837538 0 0 0 67.465846 71.876923l4.214154 0.118154h573.44c38.203077 0 69.356308-29.932308 71.561846-67.741538l0.118154-4.253539V200.034462a71.876923 71.876923 0 0 0-67.465846-71.876924l-4.214154-0.157538zM729.6 512a38.4 38.4 0 1 1 0 76.8h-230.4a38.4 38.4 0 1 1 0-76.8h230.4z m-384 0a38.4 38.4 0 1 1 0 76.8h-51.2a38.4 38.4 0 1 1 0-76.8h51.2z m384-204.8a38.4 38.4 0 1 1 0 76.8h-230.4a38.4 38.4 0 1 1 0-76.8h230.4z m-384 0a38.4 38.4 0 1 1 0 76.8h-51.2a38.4 38.4 0 0 1 0-76.8h51.2z" p-id="6325"></path></svg>
|
||||
`.trim();
|
||||
return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgXml)}`;
|
||||
};
|
||||
@@ -0,0 +1,135 @@
|
||||
<template>
|
||||
<view class="item">
|
||||
<view class="top">
|
||||
<view class="type">
|
||||
{{subject_type_text}}
|
||||
</view>
|
||||
<view class="score">
|
||||
5分
|
||||
</view>
|
||||
<view class="fl1">
|
||||
|
||||
</view>
|
||||
<view class="right">
|
||||
<!-- <view class="right_text">展开</view>
|
||||
<uv-icon class="arrow-icon" name="arrow-right"></uv-icon> -->
|
||||
</view>
|
||||
</view>
|
||||
<view class="question_text">
|
||||
{{subject_data.qnsContent}}
|
||||
</view>
|
||||
<view class="option_div">
|
||||
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
reactive,
|
||||
onMounted,
|
||||
nextTick,
|
||||
computed,
|
||||
toRaw
|
||||
} from 'vue'
|
||||
import radioSubjectItem from './radio-subject-item.vue'
|
||||
import {
|
||||
SUBJECT_TYPE
|
||||
} from '@/enum.js'
|
||||
const customStyle = {
|
||||
borderRadius: '16rpx',
|
||||
width: '292rpx',
|
||||
backgroundColor: '#0066FF',
|
||||
border: '1rpx solid rgb(12, 123, 245)',
|
||||
}
|
||||
const emit = defineEmits(['click_option'])
|
||||
const props = defineProps({
|
||||
item: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
required: true,
|
||||
}
|
||||
});
|
||||
|
||||
const subject_data = reactive({
|
||||
qnsId: '',
|
||||
qnsContent: '',
|
||||
qnsTyp: '',
|
||||
})
|
||||
Object.assign(subject_data, {
|
||||
qnsId: props.item.qnsId,
|
||||
qnsContent: props.item.qnsContent,
|
||||
qnsTyp: props.item.qnsTyp,
|
||||
})
|
||||
// 题类型
|
||||
const subject_type_text = computed(() => SUBJECT_TYPE.find(res => subject_data.qnsTyp === res.value)?.label || '')
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
.item {
|
||||
// height: 170rpx;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: 40rpx;
|
||||
|
||||
.top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.type {
|
||||
width: 108rpx;
|
||||
height: 46rpx;
|
||||
background: #267EFF;
|
||||
border-radius: 8rpx;
|
||||
font-family: PingFangSC;
|
||||
font-weight: 500;
|
||||
font-size: 25rpx;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
line-height: 46rpx;
|
||||
}
|
||||
|
||||
.score {
|
||||
margin-left: 24rpx;
|
||||
font-family: ArialMT;
|
||||
font-size: 30rpx;
|
||||
color: #333333;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.right_text {
|
||||
font-family: PingFangSC;
|
||||
font-weight: 600;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
line-height: 40rpx;
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.question_text {
|
||||
font-family: PingFangSC;
|
||||
font-weight: 500;
|
||||
font-size: 30rpx;
|
||||
color: #333333;
|
||||
line-height: 48rpx;
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,134 @@
|
||||
<template>
|
||||
<view class="option_item" @click.stop="click_option()" :class="select_status">
|
||||
<view class="option_text">
|
||||
{{props.analysisVo.itemContent}}
|
||||
</view>
|
||||
<!-- <image v-show="select_status==='primary'" class="img" src="@/static/images/common/primary.png" mode="heightFix">
|
||||
</image>
|
||||
<image v-show="select_status==='success'" class="img" src="@/static/images/common/success.png" mode="heightFix">
|
||||
</image>
|
||||
<image v-show="select_status==='error'" class="img" src="@/static/images/common/error.png" mode="heightFix">
|
||||
</image> -->
|
||||
<image :src="select_status_icon" class="img"></image>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
reactive,
|
||||
onMounted,
|
||||
nextTick,
|
||||
computed,
|
||||
toRaw
|
||||
} from 'vue'
|
||||
import {
|
||||
optionErrorIcon,
|
||||
optionSuccessIcon
|
||||
} from '@/common/imgSvg'
|
||||
const emit = defineEmits(['click_option'])
|
||||
const props = defineProps({
|
||||
analysisVo: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
required: false,
|
||||
},
|
||||
my_answer: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
backend_answer: {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
const select_status = computed(() => {
|
||||
if (props.backend_answer.length === 0) {
|
||||
return props.my_answer.includes(props.analysisVo.itemId) ? 'primary' : 'info';
|
||||
} else {
|
||||
return props.my_answer.includes(props.analysisVo.itemId) ? 'success' :
|
||||
'error';
|
||||
}
|
||||
})
|
||||
const select_status_icon = computed(() => {
|
||||
if (select_status.value === 'primary') {
|
||||
return optionSuccessIcon('#0066FF')
|
||||
} else if (select_status.value === 'success') {
|
||||
return optionSuccessIcon('#15B859')
|
||||
} else if (select_status.value === 'error') {
|
||||
return optionErrorIcon()
|
||||
}
|
||||
|
||||
})
|
||||
const click_option = () => {
|
||||
console.log('props.analysisVo.itemId', props.analysisVo.itemId);
|
||||
emit('click_option', props.analysisVo)
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.success {
|
||||
color: #15B859;
|
||||
background: #E7F8ED;
|
||||
}
|
||||
|
||||
.primary {
|
||||
color: #333333;
|
||||
background: #ECF3FE;
|
||||
}
|
||||
|
||||
.info {
|
||||
color: #333333;
|
||||
background: #F9F9F9;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: #F5212D;
|
||||
background: #FCE8E9;
|
||||
}
|
||||
|
||||
.option_item {
|
||||
|
||||
width: 100%;
|
||||
height: 108rpx;
|
||||
border-radius: 15rpx;
|
||||
margin-top: 32rpx;
|
||||
font-family: PingFangSC;
|
||||
font-weight: 500;
|
||||
font-size: 30rpx;
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
padding-left: 52rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
|
||||
// display: -webkit-box;
|
||||
// -webkit-box-orient: vertical;
|
||||
// -webkit-line-clamp: 2;
|
||||
/* 显示的行数 */
|
||||
overflow: hidden;
|
||||
.option_text {
|
||||
flex: 1;
|
||||
white-space: nowrap;
|
||||
/* 强制不换行 */
|
||||
overflow: hidden;
|
||||
/* 超出部分隐藏 */
|
||||
text-overflow: ellipsis;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
.img {
|
||||
width: 30rpx;
|
||||
// height: 30rpx;
|
||||
padding-right: 30rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,174 @@
|
||||
<template>
|
||||
<view class="item">
|
||||
<view class="top">
|
||||
<view class="type">
|
||||
{{subject_type_text}}
|
||||
</view>
|
||||
<view class="score">
|
||||
5分
|
||||
</view>
|
||||
<view class="fl1">
|
||||
|
||||
</view>
|
||||
<view class="right">
|
||||
<!-- <view class="right_text">展开</view>
|
||||
<uv-icon class="arrow-icon" name="arrow-right"></uv-icon> -->
|
||||
</view>
|
||||
</view>
|
||||
<view class="question_text">
|
||||
{{subject_data.qnsContent}}
|
||||
</view>
|
||||
<view class="option_div">
|
||||
<radioSubjectItem v-for="(analysisVo,index) in subject_data.itemVos" @click_option="click_option"
|
||||
:key="index" :analysisVo="analysisVo" :my_answer="props.item.my_answer"
|
||||
:backend_answer="props.item.backend_answer"></radioSubjectItem>
|
||||
</view>
|
||||
<view class="option_div_button" v-if="subject_data.qnsTyp==='MU' && props.mode=='practice'" >
|
||||
<uv-button type="primary" class="send_evaluate" :custom-style="customStyle" :throttleTime="300"
|
||||
:hairline="false" >确定</uv-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
reactive,
|
||||
onMounted,
|
||||
nextTick,
|
||||
computed,
|
||||
toRaw
|
||||
} from 'vue'
|
||||
import radioSubjectItem from './radio-subject-item.vue'
|
||||
import {
|
||||
SUBJECT_TYPE
|
||||
} from '@/enum.js'
|
||||
const customStyle = {
|
||||
borderRadius: '16rpx',
|
||||
width: '292rpx',
|
||||
backgroundColor: '#0066FF',
|
||||
border: '1rpx solid rgb(12, 123, 245)',
|
||||
}
|
||||
const emit = defineEmits(['click_option'])
|
||||
const props = defineProps({
|
||||
item: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
required: true,
|
||||
}
|
||||
});
|
||||
|
||||
const subject_data = reactive({
|
||||
qnsId: '',
|
||||
qnsContent: '',
|
||||
qnsTyp: '',
|
||||
itemVos: props.item.itemVos.map(res => ({
|
||||
...res,
|
||||
// 选择状态, 'info表示未选' , primary 表示蓝色, sunccess 表示绿色, error 表示红色
|
||||
select_status: 'info'
|
||||
})),
|
||||
})
|
||||
Object.assign(subject_data, {
|
||||
qnsId: props.item.qnsId,
|
||||
qnsContent: props.item.qnsContent,
|
||||
qnsTyp: props.item.qnsTyp,
|
||||
})
|
||||
|
||||
// 题类型
|
||||
const subject_type_text = computed(() => SUBJECT_TYPE.find(res => subject_data.qnsTyp === res.value)?.label || '')
|
||||
// 点击答题
|
||||
const click_option = (analysisVo) => {
|
||||
// emit('click_option', props.item.qnsId, analysisVo)
|
||||
|
||||
// // 无论什么类型如果表里已经有了,再次点击就是弹出
|
||||
if (props.item.my_answer.includes(analysisVo.itemId)) {
|
||||
// console.log('无论什么类型如果表里已经有了,再次点击就是弹出', analysisVo.itemId);
|
||||
props.item.my_answer = props.item.my_answer.filter(id => id !== analysisVo.itemId);
|
||||
}
|
||||
else if (props.item.qnsTyp === 'SN') { // 单选
|
||||
// 单选插入,并且移除其他
|
||||
props.item.my_answer[0] = analysisVo.itemId
|
||||
}
|
||||
else if (props.item.qnsTyp === 'MU') { // 多选题
|
||||
// 多选直接插入
|
||||
props.item.my_answer.push(analysisVo.itemId)
|
||||
} else if (props.item.qnsTyp === 'JD') { // 判断题
|
||||
// 判断插入,并且移除其他
|
||||
props.item.my_answer = [analysisVo.itemId]
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.option_div_button{
|
||||
width: 100%;
|
||||
height: 84rpx;
|
||||
padding-top: 30rpx;
|
||||
// background-color: red;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.item {
|
||||
// height: 170rpx;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: 40rpx;
|
||||
|
||||
.top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.type {
|
||||
width: 108rpx;
|
||||
height: 46rpx;
|
||||
background: #267EFF;
|
||||
border-radius: 8rpx;
|
||||
font-family: PingFangSC;
|
||||
font-weight: 500;
|
||||
font-size: 25rpx;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
line-height: 46rpx;
|
||||
}
|
||||
|
||||
.score {
|
||||
margin-left: 24rpx;
|
||||
font-family: ArialMT;
|
||||
font-size: 30rpx;
|
||||
color: #333333;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.right_text {
|
||||
font-family: PingFangSC;
|
||||
font-weight: 600;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
line-height: 40rpx;
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.question_text {
|
||||
font-family: PingFangSC;
|
||||
font-weight: 500;
|
||||
font-size: 30rpx;
|
||||
color: #333333;
|
||||
line-height: 48rpx;
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -3,7 +3,8 @@ export const Max_Upload_Document_Size = 102400 // 最大文档上传限制
|
||||
export const TextareaInputLimitCharacter = 160 // 全局多行文本输入框限制字数
|
||||
// 公共tab页的图片
|
||||
export const LineBg =
|
||||
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAABL0lEQVQ4T6XSv0uCURTG8e9jgpRNDS1BU1sELUFLQVM1tgQFtcR7A8m1LQqaLGhOkQKH/o5aKiiHlgiE0K1oCYLAMk9ov/RF8e313u2ew4dzzzmi2+NsA9gH3hCr6srzbAJxDkS/nbvwYNJilMkDow1FXYUHneWAlV/MqN3ZcKCzHWDb164MGa3/H/Qshdj0YbdUmORIL8HBNRsgShZjoQkznvioY/e19wCgCccSsAcM+bBnjHmyuvx5bw8mrJ93FoEkYrzFej0g5kjrpjH2BTrro8oIYhgYQ0xhTCPibfb0ggjLHKrojwvPEogDIBZgycsYKQrscqpKq3zh7BXo7YBVgRMibLWqqvnLzh6BwTZgESNHD8edoL+hOJupT9CII0oYJcQ14oy0CgHa0JTyCeBLVNeWygE5AAAAAElFTkSuQmCC";
|
||||
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAABL0lEQVQ4T6XSv0uCURTG8e9jgpRNDS1BU1sELUFLQVM1tgQFtcR7A8m1LQqaLGhOkQKH/o5aKiiHlgiE0K1oCYLAMk9ov/RF8e313u2ew4dzzzmi2+NsA9gH3hCr6srzbAJxDkS/nbvwYNJilMkDow1FXYUHneWAlV/MqN3ZcKCzHWDb164MGa3/H/Qshdj0YbdUmORIL8HBNRsgShZjoQkznvioY/e19wCgCccSsAcM+bBnjHmyuvx5bw8mrJ93FoEkYrzFej0g5kjrpjH2BTrro8oIYhgYQ0xhTCPibfb0ggjLHKrojwvPEogDIBZgycsYKQrscqpKq3zh7BXo7YBVgRMibLWqqvnLzh6BwTZgESNHD8edoL+hOJupT9CII0oYJcQ14oy0CgHa0JTyCeBLVNeWygE5AAAAAElFTkSuQmCC";
|
||||
// 性别
|
||||
export const GENDER = [{
|
||||
value: "m",
|
||||
label: "男性",
|
||||
@@ -12,4 +13,22 @@ export const GENDER = [{
|
||||
value: "f",
|
||||
label: "女性",
|
||||
}
|
||||
] // 性别
|
||||
]
|
||||
// 试题题型
|
||||
export const SUBJECT_TYPE = [{
|
||||
value: "SN",
|
||||
label: "单选题",
|
||||
},
|
||||
{
|
||||
value: "MU",
|
||||
label: "多选题",
|
||||
},
|
||||
{
|
||||
value: "JD",
|
||||
label: "判断题",
|
||||
},
|
||||
{
|
||||
value: "ES",
|
||||
label: "问答题",
|
||||
},
|
||||
]
|
||||
@@ -190,6 +190,24 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/examination/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "考试",
|
||||
"app-plus": {
|
||||
"titleNView": false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/practice/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "练习",
|
||||
"app-plus": {
|
||||
"titleNView": false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/course/index",
|
||||
"style": {
|
||||
|
||||
@@ -73,14 +73,13 @@
|
||||
<uv-button type="primary"
|
||||
@click="common.navigateTo('/pages/course/study?crsNum='+crsNum+'&crsId='+form.crsId + '&imgId=' + form.imgId)">去学习</uv-button>
|
||||
<uv-button type="primary">去练习</uv-button>
|
||||
<uv-button type="primary">去考试</uv-button>
|
||||
<uv-button type="primary" @click="goto_examination()">去考试</uv-button>
|
||||
</template>
|
||||
<template v-if="tabAct == 2">
|
||||
<uv-button type="primary" class="send_evaluate"
|
||||
@click="common.navigateTo('/pages/courseDetail/submit?crsNum='+crsNum+'&imgId='+form.imgId)">发布评价</uv-button>
|
||||
</template>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -161,7 +160,15 @@
|
||||
const swiper_change = (res) => {
|
||||
tabAct.value = res.detail.current
|
||||
}
|
||||
|
||||
// 去考试
|
||||
const goto_examination = () => {
|
||||
// papersId.value = e.papersId
|
||||
// paperData.value = setPageCache('examination_'+papersId.value)
|
||||
// if (!papersId.value || !paperData.value) {
|
||||
// common.navigateBack()
|
||||
// return
|
||||
// }
|
||||
}
|
||||
// const getElementPosition = () => {
|
||||
// return new Promise((resolve) => {
|
||||
// uni.createSelectorQuery()
|
||||
@@ -181,6 +188,7 @@
|
||||
tabAct.value = 2
|
||||
})
|
||||
})
|
||||
|
||||
onLoad((params) => {
|
||||
crsNum.value = params.crsNum;
|
||||
});
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
<template>
|
||||
<view class="main_div max_page">
|
||||
<nav-bar :is_seat="true"></nav-bar>
|
||||
<view class="nav-div">
|
||||
<view class="title ellipsis-text">
|
||||
这里是练习名称
|
||||
</view>
|
||||
<view class="back_div"></view>
|
||||
</view>
|
||||
<view class="countdown-and-question-number-div">
|
||||
<view class="top">
|
||||
<view class="countdown">
|
||||
<text class="grey">答题进度</text> <text class="bold">2</text><text class="grey">/10</text>
|
||||
</view>
|
||||
<view class="question">
|
||||
<view class="grey">剩余时间</view>
|
||||
<uv-count-down :time="30 * 60 * 60 * 1000" format="HH:mm:ss"></uv-count-down>
|
||||
</view>
|
||||
</view>
|
||||
<view class="progress">
|
||||
<uv-line-progress :percentage="30" :showText="false" activeColor="#FFFFFF" inactiveColor="#89B8FF"
|
||||
:height="8"></uv-line-progress>
|
||||
</view>
|
||||
</view>
|
||||
<view class="scroll_div">
|
||||
<swiper class="swiper" :current="tabAct" :indicator-dots="false" :disable-touch="true">
|
||||
<swiper-item>
|
||||
<view class="content">
|
||||
<view class="expose_shadow"></view>
|
||||
<scroll-view :scroll-y="true" class="scroll-Y" :show-scrollbar="false" :refresher-threshold="0">
|
||||
<RadioSubject></RadioSubject>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import RadioSubject from '@/components/examination/radio-subject.vue'
|
||||
import {
|
||||
ref,
|
||||
computed,
|
||||
onMounted,
|
||||
nextTick,
|
||||
getCurrentInstance
|
||||
} from 'vue';
|
||||
const {
|
||||
proxy
|
||||
} = getCurrentInstance() // 获取当前组件实例
|
||||
// 用于存储尺寸信息的响应式变量
|
||||
const dimensions = ref({
|
||||
containerHeight: 0,
|
||||
contentHeight: 0
|
||||
});
|
||||
// 检查尺寸并更新
|
||||
const checkDimensions = async () => {
|
||||
await nextTick(); // 确保DOM已更新
|
||||
// 创建查询
|
||||
const query = uni.createSelectorQuery().in(proxy);
|
||||
// 添加内容高度查询
|
||||
query.select('.content').boundingClientRect(data => {
|
||||
dimensions.value.contentHeight = data?.height || 0;
|
||||
});
|
||||
// 添加容器高度查询(注意这里没有调用.exec())
|
||||
query.select('.scroll_div').boundingClientRect(data => {
|
||||
dimensions.value.containerHeight = data?.height || 0;
|
||||
});
|
||||
// 执行所有查询(只调用一次exec())
|
||||
query.exec();
|
||||
};
|
||||
|
||||
// 计算属性:判断是否需要开启滚动
|
||||
const isScrollable = computed(() => {
|
||||
return dimensions.value.contentHeight > dimensions.value.containerHeight - 20;
|
||||
});
|
||||
// 初始化时检查
|
||||
onMounted(() => {
|
||||
checkDimensions();
|
||||
// 监听窗口尺寸变化(可选)
|
||||
uni.onWindowResize(() => {
|
||||
checkDimensions();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
$bg-margin-left: 30rpx;
|
||||
|
||||
.scroll-Y {
|
||||
max-height: calc(100vh - var(--status-bar-height) - 70rpx - 70rpx - 40rpx - 64rpx - 68rpx - 60rpx);
|
||||
min-height: calc(100vh - var(--status-bar-height) - 70rpx - 70rpx - 40rpx - 64rpx - 68rpx - 60rpx - 380rpx);
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
margin: 32rpx $bg-margin-left;
|
||||
border-radius: 16rpx;
|
||||
padding: 34rpx 30rpx 34rpx 36rpx;
|
||||
background-color: #fff;
|
||||
|
||||
.expose_shadow {
|
||||
margin-left: 36rpx;
|
||||
position: absolute;
|
||||
bottom: -26rpx;
|
||||
left: 0%;
|
||||
width: calc(100% - 66rpx);
|
||||
height: 28rpx;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 0 0 14rpx 14rpx;
|
||||
opacity: 0.4;
|
||||
z-index: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.countdown-and-question-number-div {
|
||||
margin: 20rpx $bg-margin-left;
|
||||
height: 70rpx;
|
||||
// background-color: red;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
z-index: 10;
|
||||
|
||||
.top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-family: PingFangSC;
|
||||
font-size: 26rpx;
|
||||
color: #FFFFFF;
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.question {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
// background-color: red;
|
||||
width: 242rpx;
|
||||
color: red;
|
||||
|
||||
.grey {
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
:deep(.uv-count-down__text) {
|
||||
color: #FFFFFF !important;
|
||||
font-weight: 600;
|
||||
font-size: 26rpx !important;
|
||||
}
|
||||
}
|
||||
|
||||
.grey {
|
||||
color: #B6E2FF;
|
||||
}
|
||||
|
||||
.bold {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-div {
|
||||
position: relative;
|
||||
|
||||
.title {
|
||||
// padding-top:var(--status-bar-height);
|
||||
// padding: 0 30rpx;
|
||||
margin: 0 calc($bg-margin-left + 70rpx);
|
||||
height: 70rpx;
|
||||
font-family: PingFangSC;
|
||||
font-weight: 500;
|
||||
font-size: 34rpx;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
font-style: normal;
|
||||
line-height: 70rpx;
|
||||
|
||||
}
|
||||
|
||||
.back_div {
|
||||
position: absolute;
|
||||
right: $bg-margin-left;
|
||||
top: 0;
|
||||
width: 70rpx;
|
||||
height: 70rpx;
|
||||
// background-color: red;
|
||||
}
|
||||
}
|
||||
|
||||
.main_div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: linear-gradient(to top, #3480FF, #0066FF);
|
||||
/* 确保背景占满整个视口高度 */
|
||||
min-height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,304 @@
|
||||
<template>
|
||||
<view class="main_div max_page">
|
||||
<nav-bar :is_seat="true"></nav-bar>
|
||||
<view class="nav-div">
|
||||
<view class="title ellipsis-text" @click="hand_in_paper()">
|
||||
{{paperData.papersName}}
|
||||
</view>
|
||||
<view class="back_div"></view>
|
||||
</view>
|
||||
<view class="countdown-and-question-number-div">
|
||||
<view class="top">
|
||||
<view class="countdown">
|
||||
<text class="grey">答题进度</text> <text class="bold">{{questionNumber + 1}}</text><text
|
||||
class="grey">/{{topicList.length}}</text>
|
||||
</view>
|
||||
<view class="question">
|
||||
<view class="grey">剩余时间</view>
|
||||
<uv-count-down :time="paperData.limitTm * 1000" format="HH:mm:ss"></uv-count-down>
|
||||
</view>
|
||||
</view>
|
||||
<view class="progress">
|
||||
<uv-line-progress :percentage="progress" :showText="false" activeColor="#FFFFFF" inactiveColor="#89B8FF"
|
||||
:height="8"></uv-line-progress>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="scroll_div">
|
||||
<swiper class="swiper" :indicator-dots="false" @change="swiperChange" :current="questionNumber" easing-function="linear">
|
||||
<swiper-item v-for="(item,index) in topicList">
|
||||
<view class="content">
|
||||
<view class="expose_shadow"></view>
|
||||
<scroll-view :scroll-y="true" class="scroll-Y" :show-scrollbar="false" :refresher-threshold="0">
|
||||
<RadioSubject :item="item" v-if="item.qnsTyp !== 'ES'" :mode="mode">
|
||||
</RadioSubject>
|
||||
<CharactersSubject :item="item" v-if="item.qnsTyp === 'ES'" :mode="mode">
|
||||
</CharactersSubject>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
|
||||
<view class="fixed-btn-box font_pf">
|
||||
<view class="sheet">
|
||||
<image :src="examinationSheetIcon()" class="img"></image>
|
||||
<view class="sheet_text">答题卡</view>
|
||||
</view>
|
||||
<view class="button_div">
|
||||
<uv-button class="button" type="primary" :throttleTime="100" text="上一题" color="#E2EDFF"
|
||||
custom-style="color:#0066FF;borderRadius:16rpx;height:92rpx;" @click="button_tab(-1)"></uv-button>
|
||||
<view style="width:46rpx"></view>
|
||||
<uv-button class="button" type="primary" :throttleTime="100" text="下一题" color="#0066FF"
|
||||
custom-style="color:#FFFFFF;borderRadius:16rpx;height:92rpx;" @click="button_tab(1)"></uv-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import RadioSubject from '@/components/examination/radio-subject.vue'
|
||||
import CharactersSubject from '@/components/examination/characters-subject.vue'
|
||||
import {
|
||||
ref,
|
||||
reactive,
|
||||
computed,
|
||||
onMounted,
|
||||
nextTick,
|
||||
getCurrentInstance
|
||||
} from 'vue';
|
||||
import {
|
||||
examinationSheetIcon
|
||||
} from '@/common/imgSvg'
|
||||
import {
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app'
|
||||
import common from '@/common/common';
|
||||
import {
|
||||
getPageCache
|
||||
} from '@/common/common';
|
||||
|
||||
const examId = ref('')
|
||||
const mode = ref('examination') // 考试 examination 练习practice
|
||||
const paperData = reactive({
|
||||
papersId: '',
|
||||
limitTm: 0,
|
||||
papersName: '',
|
||||
}) // 试卷信息
|
||||
const progress = computed(() => { // 计算进度百分比(保留两位小数)
|
||||
const total = topicList.length;
|
||||
if (total === 0) return 0;
|
||||
const completed = questionNumber.value + 1;
|
||||
return Math.min(Math.round((completed / total) * 10000) / 100, 100);
|
||||
})
|
||||
const topicList = reactive([]) // 问题列表
|
||||
const questionNumber = ref(0) // 题号
|
||||
const swiperChange = (item) => {
|
||||
questionNumber.value = item.detail.current
|
||||
}
|
||||
// 按上一题下一题
|
||||
const button_tab = (num) => {
|
||||
let newNumber = questionNumber.value + num;
|
||||
if (newNumber < 0) {
|
||||
newNumber = 0;
|
||||
} else if (newNumber >= topicList.length) {
|
||||
newNumber = topicList.length - 1;
|
||||
}
|
||||
questionNumber.value = newNumber;
|
||||
}
|
||||
|
||||
// 初始化时检查
|
||||
onLoad(() => {
|
||||
const examination = getPageCache('examination')
|
||||
if (!examination) {
|
||||
common.navigateBack()
|
||||
return
|
||||
}
|
||||
paperData.papersId = examination.papersId
|
||||
paperData.limitTm = examination.limitTm
|
||||
paperData.papersName = examination.papersName
|
||||
topicList.push(...examination.qnsInfoVos.map(res => ({
|
||||
...res,
|
||||
my_answer: [],
|
||||
backend_answer: [],
|
||||
})))
|
||||
});
|
||||
const hand_in_paper = () => {
|
||||
console.log('点击交卷', topicList);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
$bg-margin-left: 30rpx;
|
||||
|
||||
.fixed-btn-box {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
height: 154rpx;
|
||||
background: #FFFFFF;
|
||||
border-radius: 16rpx 16rpx 0px 0px;
|
||||
border: 2rpx solid #E5E5E5;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 20rpx 20rpx 20rpx;
|
||||
|
||||
.sheet {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin: 0 70rpx;
|
||||
|
||||
.img {
|
||||
width: 38rpx;
|
||||
height: 40rpx;
|
||||
|
||||
}
|
||||
|
||||
.sheet_text {
|
||||
margin-top: 8rpx;
|
||||
font-family: PingFangSC;
|
||||
font-weight: 500;
|
||||
font-size: 24rpx;
|
||||
color: #000000;
|
||||
}
|
||||
}
|
||||
|
||||
.button_div {
|
||||
flex: 1;
|
||||
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.button {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.scroll-Y {
|
||||
max-height: calc(100vh - var(--status-bar-height) - 70rpx - 70rpx - 40rpx - 64rpx - 68rpx - 60rpx);
|
||||
min-height: calc(100vh - var(--status-bar-height) - 70rpx - 70rpx - 40rpx - 64rpx - 68rpx - 60rpx - 380rpx);
|
||||
// background-color: yellow;
|
||||
}
|
||||
|
||||
.swiper {
|
||||
// 状态栏 var(--status-bar-height)
|
||||
// 标题栏 70rpx
|
||||
// 进度时间栏 70rpx
|
||||
// 进度时间栏上下间距 40rpx = 20rpx + 20rpx
|
||||
// 正文上下间距 64rpx
|
||||
height: calc(100vh - var(--status-bar-height) - 70rpx - 70rpx - 40rpx - 64rpx);
|
||||
// background-color: red;
|
||||
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
margin: 32rpx $bg-margin-left;
|
||||
border-radius: 16rpx;
|
||||
padding: 34rpx 30rpx 34rpx 36rpx;
|
||||
background-color: #fff;
|
||||
|
||||
.expose_shadow {
|
||||
margin-left: 36rpx;
|
||||
position: absolute;
|
||||
bottom: -26rpx;
|
||||
left: 0%;
|
||||
width: calc(100% - 66rpx);
|
||||
height: 28rpx;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 0 0 14rpx 14rpx;
|
||||
opacity: 0.4;
|
||||
z-index: 0;
|
||||
// background-color: red;
|
||||
}
|
||||
}
|
||||
|
||||
.countdown-and-question-number-div {
|
||||
margin: 20rpx $bg-margin-left;
|
||||
height: 70rpx;
|
||||
// background-color: red;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
z-index: 10;
|
||||
|
||||
.top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-family: PingFangSC;
|
||||
font-size: 26rpx;
|
||||
color: #FFFFFF;
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.question {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
// background-color: red;
|
||||
width: 242rpx;
|
||||
color: red;
|
||||
|
||||
.grey {
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
:deep(.uv-count-down__text) {
|
||||
color: #FFFFFF !important;
|
||||
font-weight: 600;
|
||||
font-size: 26rpx !important;
|
||||
}
|
||||
}
|
||||
|
||||
.grey {
|
||||
color: #B6E2FF;
|
||||
}
|
||||
|
||||
.bold {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-div {
|
||||
position: relative;
|
||||
|
||||
.title {
|
||||
// padding-top:var(--status-bar-height);
|
||||
// padding: 0 30rpx;
|
||||
margin: 0 calc($bg-margin-left + 70rpx);
|
||||
height: 70rpx;
|
||||
font-family: PingFangSC;
|
||||
font-weight: 500;
|
||||
font-size: 34rpx;
|
||||
color: #FFFFFF;
|
||||
text-align: center;
|
||||
font-style: normal;
|
||||
line-height: 70rpx;
|
||||
|
||||
}
|
||||
|
||||
.back_div {
|
||||
position: absolute;
|
||||
right: $bg-margin-left;
|
||||
top: 0;
|
||||
width: 70rpx;
|
||||
height: 70rpx;
|
||||
// background-color: red;
|
||||
}
|
||||
}
|
||||
|
||||
.main_div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: linear-gradient(to top, #3480FF, #0066FF);
|
||||
/* 确保背景占满整个视口高度 */
|
||||
min-height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
@@ -88,7 +88,8 @@
|
||||
<image class="icon" src="@/static/images/index/navigation_question_answering.png"></image>
|
||||
<view class="title">AI问答</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
|
||||
<view class="item" @click="common.navigateTo('/pages/examination/index')">
|
||||
<image class="icon" src="@/static/images/index/navigation_ai.png"></image>
|
||||
<view class="title">AI陪练</view>
|
||||
</view>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</view>
|
||||
<view>消息</view>
|
||||
<view class="delete_div" @click="common.navigateBack()">
|
||||
<image class="img" src="@/static/images/message_notification/delete_icon.png" mode="aspectFit">
|
||||
<image class="img" src="@/static/images/messageNotification/delete_icon.png" mode="aspectFit">
|
||||
</image>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<template>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
@@ -76,6 +76,7 @@
|
||||
|
||||
}
|
||||
const getData = (from = '') => {
|
||||
console.log('getDatagetDatagetDatagetDatagetDatagetDatagetData');
|
||||
if (from == 'first') {
|
||||
if (total.value !== -1) return;
|
||||
status.value = 'loading'
|
||||
@@ -100,8 +101,11 @@
|
||||
params.examStat = 'N'
|
||||
}
|
||||
queryTraExamPapersPage(params).then(res => {
|
||||
console.log('resresresresres', res);
|
||||
total.value = res.total
|
||||
data_list.push(...res.body)
|
||||
}).catch(res => {
|
||||
console.log('谢谢谢谢谢谢', res);
|
||||
}).finally(() => {
|
||||
if (data_list.length >= total.value) {
|
||||
status.value = 'nomore'
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
<view>考试详情</view>
|
||||
</view>
|
||||
<view class="detail_div completed incomplete">
|
||||
<view class="subscript">已完成</view>
|
||||
<view class="title_div">
|
||||
<view class="title ellipsis-text">{{detailData.papersName}}萨达萨达萨达萨达萨达阿斯顿萨达萨达萨达</view>
|
||||
<view class="title ellipsis-text">{{detailData.papersName}}</view>
|
||||
<!-- <view class="subscript" >未完成</view> -->
|
||||
<view class="subscript" >已完成</view>
|
||||
</view>
|
||||
<view class="time">
|
||||
<text class="color_3">起止时间:</text><text
|
||||
@@ -24,30 +24,58 @@
|
||||
<view class="paper_div">
|
||||
<view class="paper">
|
||||
<!-- 试卷信息 -->
|
||||
<view class="title">
|
||||
试卷信息
|
||||
<view class="paper_title_div">
|
||||
<image src="@/static/images/testingHall/testing.png" mode="heightFix" class="img"></image>
|
||||
<view class="title">
|
||||
试卷信息
|
||||
</view>
|
||||
</view>
|
||||
<view class="title-note">
|
||||
试卷总分:{{detailData.totalGrade}}分
|
||||
考试时长:<text class="bold">{{detailData.totalGrade}}</text>分钟
|
||||
</view>
|
||||
<view class="title-note">
|
||||
通过分数:{{detailData.passGrade}}分
|
||||
</view>
|
||||
<view class="title-note">
|
||||
考试次数:不限制
|
||||
</view>
|
||||
<view class="title-note">
|
||||
试卷类型:随机试卷
|
||||
</view>
|
||||
<!-- 试卷结构 -->
|
||||
<view class="title">
|
||||
试卷结构
|
||||
</view>
|
||||
<view class="table">
|
||||
<view class="table_tr">
|
||||
<view class="table_td">
|
||||
类型
|
||||
|
||||
<view class="title-table">
|
||||
<view class="title-table-item">
|
||||
<view class="top">
|
||||
<text class="text_2">{{detailData.passGrade}}</text><text class="text_1">分</text>
|
||||
</view>
|
||||
<view class="bottom text_1">
|
||||
试卷总分
|
||||
</view>
|
||||
</view>
|
||||
<view class="title-table-item">
|
||||
<view class="top">
|
||||
<text class="text_2">{{detailData.passGrade}}</text><text class="text_1">分</text>
|
||||
</view>
|
||||
|
||||
<view class="bottom text_1">
|
||||
通过分数
|
||||
</view>
|
||||
</view>
|
||||
<view class="title-table-item">
|
||||
<view class="top text_2">
|
||||
不限制
|
||||
</view>
|
||||
<view class="bottom text_1">
|
||||
通过次数
|
||||
</view>
|
||||
</view>
|
||||
<view class="title-table-item">
|
||||
<view class="top text_2">
|
||||
随机
|
||||
</view>
|
||||
<view class="bottom text_1">
|
||||
试卷类型
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="table">
|
||||
<view class="table_th">
|
||||
<view class="table_td">
|
||||
题型
|
||||
</view>
|
||||
<view class="fl1"></view>
|
||||
<view class="table_td">
|
||||
数量
|
||||
</view>
|
||||
@@ -59,6 +87,7 @@
|
||||
<view class="table_td">
|
||||
判断题
|
||||
</view>
|
||||
<view class="fl1"></view>
|
||||
<view class="table_td">
|
||||
{{detailData.judgeNumber}}
|
||||
</view>
|
||||
@@ -66,10 +95,11 @@
|
||||
{{detailData.judgeGrade}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="table_tr">
|
||||
<view class="table_tr table_tr_dark">
|
||||
<view class="table_td">
|
||||
单选题
|
||||
</view>
|
||||
<view class="fl1"></view>
|
||||
<view class="table_td">
|
||||
{{detailData.singleNumber}}
|
||||
</view>
|
||||
@@ -81,6 +111,7 @@
|
||||
<view class="table_td">
|
||||
多选题
|
||||
</view>
|
||||
<view class="fl1"></view>
|
||||
<view class="table_td">
|
||||
{{detailData.multiNumber}}
|
||||
</view>
|
||||
@@ -88,10 +119,11 @@
|
||||
{{detailData.multiGrade}}
|
||||
</view>
|
||||
</view>
|
||||
<view class="table_tr">
|
||||
<view class="table_tr table_tr_dark">
|
||||
<view class="table_td">
|
||||
问答题
|
||||
</view>
|
||||
<view class="fl1"></view>
|
||||
<view class="table_td">
|
||||
{{detailData.essayNumber}}
|
||||
</view>
|
||||
@@ -103,6 +135,7 @@
|
||||
<view class="table_td">
|
||||
总计
|
||||
</view>
|
||||
<view class="fl1"></view>
|
||||
<view class="table_td">
|
||||
20
|
||||
</view>
|
||||
@@ -116,8 +149,7 @@
|
||||
</view>
|
||||
<view class="fixed_button_div">
|
||||
<uv-button type="primary" class="send_evaluate" :custom-style="customStyle" :throttleTime="300"
|
||||
:hairline="false"
|
||||
@click="common.navigateTo('/pages/courseDetail/submit?crsNum='+crsNum+'&imgId='+form.imgId)">发布评价</uv-button>
|
||||
:hairline="false" @click="goto_examination()">开始考试</uv-button>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
@@ -131,6 +163,12 @@
|
||||
import {
|
||||
reactive
|
||||
} from 'vue'
|
||||
import {
|
||||
startTraExamPapersInfo
|
||||
} from '@/api/examination.js'
|
||||
|
||||
import common from '@/common/common';
|
||||
import {setPageCache, getPageCache} from '@/common/common';
|
||||
const detailData = reactive({
|
||||
papersId: '',
|
||||
papersName: '',
|
||||
@@ -140,14 +178,30 @@
|
||||
planPersionNumber: '',
|
||||
})
|
||||
const customStyle = {
|
||||
borderRadius: '40rpx', //圆角
|
||||
backgroundColor: 'rgb(12, 123, 245)',
|
||||
backgroundColor: '#0066FF',
|
||||
border: '1px solid rgb(12, 123, 245)',
|
||||
}
|
||||
const goto_examination = async () => {
|
||||
common.loading()
|
||||
startTraExamPapersInfo({
|
||||
examId : "1"
|
||||
}).then(res => {
|
||||
setPageCache('examination', res.body)
|
||||
common.navigateTo('/pages/examination/index')
|
||||
}).finally(() => {
|
||||
common.hideLoading()
|
||||
})
|
||||
// papersId.value = e.papersId
|
||||
// paperData.value = setPageCache('examination_'+papersId.value)
|
||||
// if (!papersId.value || !paperData.value) {
|
||||
// common.navigateBack()
|
||||
// return
|
||||
// }
|
||||
}
|
||||
onLoad((e) => {
|
||||
console.log(e);
|
||||
const testing_hall_details = getPageCache('testing_hall_details')
|
||||
Object.assign(detailData, {
|
||||
...e
|
||||
...testing_hall_details
|
||||
})
|
||||
})
|
||||
</script>
|
||||
@@ -156,30 +210,89 @@
|
||||
.fixed_button_div {
|
||||
position: fixed;
|
||||
bottom: 30rpx;
|
||||
width: 80vw;
|
||||
width: calc(100vw - 60rpx);
|
||||
}
|
||||
|
||||
.title-table {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
|
||||
background-color: #F4F6F9;
|
||||
border-radius: 16rpx;
|
||||
padding: 28rpx 28rpx 26rpx 28rpx;
|
||||
margin: 32rpx 0 48rpx 0;
|
||||
|
||||
.title-table-item {
|
||||
// background-color: red;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 96rpx;
|
||||
}
|
||||
|
||||
.text_1 {
|
||||
font-family: PingFangTC;
|
||||
font-weight: 400;
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.text_2 {
|
||||
font-family: Arial, Arial;
|
||||
font-weight: normal;
|
||||
font-size: 34rpx;
|
||||
color: #333333;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.text_3 {}
|
||||
}
|
||||
|
||||
.paper_div {
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
background-color: rgb(130, 142, 244);
|
||||
flex: 1;
|
||||
|
||||
.paper {
|
||||
// width: 100%;
|
||||
background-color: red;
|
||||
height: 100%;
|
||||
margin: 24rpx 24rpx 0 24rpx;
|
||||
background-color: #fff;
|
||||
margin: 24rpx 30rpx 0 30rpx;
|
||||
border-radius: 20rpx;
|
||||
padding: 16rpx;
|
||||
background-color: #FFFFFF;
|
||||
// /* 顶部100px区域设置渐变 */
|
||||
background-image: linear-gradient(to bottom, #EBF2FE, #FFFFFF);
|
||||
// /* 只显示顶部100px的渐变 */
|
||||
background-size: 100% 100px;
|
||||
background-repeat: no-repeat;
|
||||
box-shadow: 0 23rpx 38rpx 0px rgba(0, 0, 0, 0.06);
|
||||
border: 2rpx solid #fff;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 30rpx;
|
||||
color: rgb(0, 0, 0);
|
||||
font-weight: 600;
|
||||
height: 70rpx;
|
||||
line-height: 70rpx;
|
||||
.paper_title_div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.img {
|
||||
height: 32rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: 600;
|
||||
height: 70rpx;
|
||||
line-height: 70rpx;
|
||||
font-family: PingFangTC;
|
||||
font-weight: 600;
|
||||
font-size: 30rpx;
|
||||
color: #333333;
|
||||
font-style: normal;
|
||||
margin-left: 12rpx;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.title-note {
|
||||
@@ -197,18 +310,42 @@
|
||||
justify-content: space-between;
|
||||
padding: 20rpx 0 80rpx 0;
|
||||
|
||||
.table_th {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
background-color: #F4F6F9;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.table_tr_dark {
|
||||
background-color: #FAFAFA;
|
||||
}
|
||||
|
||||
.table_th>.table_td {
|
||||
color: #333333;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.table_tr {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.table_td {
|
||||
padding: 14rpx 0;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-family: PingFangSC;
|
||||
font-size: 30rpx;
|
||||
line-height: 30rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.table_tr>.table_td {
|
||||
color: #666666;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,17 +355,55 @@
|
||||
align-items: center;
|
||||
padding-top: var(--status-bar-height);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.body-title {
|
||||
background-color: #337FFF;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
height: 140rpx;
|
||||
line-height: 140rpx;
|
||||
font-family: PingFangSC;
|
||||
font-weight: 500;
|
||||
font-size: 38rpx;
|
||||
color: #FFFFFF;
|
||||
font-style: normal;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.detail_div {
|
||||
margin-top: -20rpx;
|
||||
z-index: 2;
|
||||
width: 100%;
|
||||
padding: 48rpx 40rpx 20rpx 40rpx;
|
||||
|
||||
.title_div{
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 16rpx 16rpx 0 0;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
.subscript {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 102rpx;
|
||||
height: 42rpx;
|
||||
font-family: PingFangSC;
|
||||
font-weight: 400;
|
||||
font-size: 24rpx;
|
||||
line-height: 42rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 0 0 0 28rpx;
|
||||
}
|
||||
|
||||
.title_div {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex: 1;
|
||||
|
||||
.title {
|
||||
font-family: PingFangSC;
|
||||
font-weight: 600;
|
||||
@@ -238,21 +413,11 @@
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
}
|
||||
.subscript {
|
||||
width: 102rpx;
|
||||
height: 42rpx;
|
||||
border-radius: 10rpx;
|
||||
font-family: PingFangSC;
|
||||
font-weight: 400;
|
||||
font-size: 24rpx;
|
||||
line-height: 42rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
.time {
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
@@ -283,29 +448,65 @@
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
|
||||
.incomplete {
|
||||
|
||||
|
||||
// 进行中
|
||||
.subscript {
|
||||
color: #FFFFFF;
|
||||
background-color: #EF5705;
|
||||
}
|
||||
|
||||
|
||||
.color_class {
|
||||
color: #D70C18;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.completed {
|
||||
|
||||
|
||||
// 已完成
|
||||
.subscript {
|
||||
color: #FFFFFF;
|
||||
background-color: #33C583;
|
||||
}
|
||||
|
||||
|
||||
.color_class {
|
||||
color: #0066FF;
|
||||
}
|
||||
}
|
||||
|
||||
.back_div {
|
||||
position: absolute;
|
||||
left: 26rpx;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.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 #fff;
|
||||
border-left: 4rpx solid #fff;
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -47,6 +47,7 @@
|
||||
import {
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app'
|
||||
import {setPageCache} from '@/common/common';
|
||||
import common from '@/common/common';
|
||||
const customStyle = {
|
||||
backgroundColor: "#F1F5FA",
|
||||
@@ -96,21 +97,16 @@
|
||||
console.log('搜索', searchText.value);
|
||||
}
|
||||
const gotoDetails = (item) => {
|
||||
|
||||
const detailData = {
|
||||
...item
|
||||
};
|
||||
const params = new URLSearchParams();
|
||||
for (const key in detailData) {
|
||||
params.append(key, detailData[key]);
|
||||
}
|
||||
const urlParams = params.toString();
|
||||
common.navigateTo(`/pages/testingHall/details?${urlParams}`);
|
||||
|
||||
setPageCache('testing_hall_details', item)
|
||||
common.navigateTo('/pages/testingHall/details');
|
||||
}
|
||||
onMounted(() => {
|
||||
|
||||
triggered.value = true
|
||||
watch(tabAct, (newValue, oldValue) => {
|
||||
console.log('resresresresresxxxxxxxxxx', contentRefs.value);
|
||||
console.log('resresresresresxxxxxxxxxx', newValue);
|
||||
console.log('resresresresresxxxxxxxxxx', contentRefs.value[newValue]);
|
||||
typeof contentRefs.value[newValue]?.getData === 'function' && contentRefs.value[newValue]
|
||||
?.getData('first')
|
||||
}, {
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
computed,
|
||||
nextTick,
|
||||
onMounted,
|
||||
watch
|
||||
watch
|
||||
} from 'vue';
|
||||
import {
|
||||
LineBg
|
||||
@@ -51,7 +51,7 @@
|
||||
} from '@/api/courseDetail.js';
|
||||
import common from '@/common/common';
|
||||
const statusBarHeight = uni.getSystemInfoSync().statusBarHeight;
|
||||
|
||||
|
||||
const courseRef = ref(null);
|
||||
const correctRef = ref(null);
|
||||
const tabAct = ref(0);
|
||||
@@ -60,7 +60,7 @@
|
||||
}, {
|
||||
name: '已订正'
|
||||
}]);
|
||||
|
||||
|
||||
const tabChange = (item) => {
|
||||
tabAct.value = item.index;
|
||||
};
|
||||
@@ -68,13 +68,15 @@
|
||||
tabAct.value = item.detail.current;
|
||||
};
|
||||
onMounted(() => {
|
||||
watch(tabAct, (newValue, oldValue) => {
|
||||
if(newValue === 0) {
|
||||
courseRef.value?.getData('first')
|
||||
} else if(newValue === 1) {
|
||||
correctRef.value?.getData('first')
|
||||
}
|
||||
}, { immediate: true }) // 这里的immediate会在onMounted之后执行
|
||||
watch(tabAct, (newValue, oldValue) => {
|
||||
if (newValue === 0) {
|
||||
courseRef.value?.getData('first')
|
||||
} else if (newValue === 1) {
|
||||
correctRef.value?.getData('first')
|
||||
}
|
||||
}, {
|
||||
immediate: true
|
||||
}) // 这里的immediate会在onMounted之后执行
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -82,6 +84,7 @@
|
||||
$bg-margin-left: 50rpx;
|
||||
|
||||
.my_tabs {
|
||||
|
||||
// 解决这个圆角的图片,开穿透
|
||||
:deep(.uv-tabs__wrapper__nav__line) {
|
||||
height: 26rpx !important;
|
||||
@@ -90,7 +93,7 @@
|
||||
background-repeat: no-repeat !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.swiper {
|
||||
height: calc(100vh - var(--status-bar-height) - 54rpx - 88rpx - 20rpx - 10rpx);
|
||||
}
|
||||
@@ -134,6 +137,7 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #fff;
|
||||
|
||||
.back_div {
|
||||
position: absolute;
|
||||
left: 20rpx;
|
||||
|
||||
@@ -125,6 +125,25 @@
|
||||
"titleNView": false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/examination/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "考试",
|
||||
"app-plus": {
|
||||
"titleNView": false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/practice/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "练习",
|
||||
"app-plus": {
|
||||
"titleNView": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 738 B |
|
After Width: | Height: | Size: 845 B |
|
Before Width: | Height: | Size: 867 B After Width: | Height: | Size: 867 B |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 472 B |
@@ -0,0 +1,9 @@
|
||||
## 1.0.3(2023-10-13)
|
||||
1. unmounted兼容vue3
|
||||
## 1.0.2(2023-06-20)
|
||||
1. 增加外部样式customStyle参数
|
||||
## 1.0.1(2023-05-16)
|
||||
1. 优化组件依赖,修改后无需全局引入,组件导入即可使用
|
||||
2. 优化部分功能
|
||||
## 1.0.0(2023-05-10)
|
||||
uv-count-down 倒计时
|
||||
@@ -0,0 +1,25 @@
|
||||
export default {
|
||||
props: {
|
||||
// 倒计时时长,单位ms
|
||||
time: {
|
||||
type: [String, Number],
|
||||
default: 0
|
||||
},
|
||||
// 时间格式,DD-日,HH-时,mm-分,ss-秒,SSS-毫秒
|
||||
format: {
|
||||
type: String,
|
||||
default: 'HH:mm:ss'
|
||||
},
|
||||
// 是否自动开始倒计时
|
||||
autoStart: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 是否展示毫秒倒计时
|
||||
millisecond: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
...uni.$uv?.props?.countDown
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
// 补0,如1 -> 01
|
||||
function padZero(num, targetLength = 2) {
|
||||
let str = `${num}`
|
||||
while (str.length < targetLength) {
|
||||
str = `0${str}`
|
||||
}
|
||||
return str
|
||||
}
|
||||
const SECOND = 1000
|
||||
const MINUTE = 60 * SECOND
|
||||
const HOUR = 60 * MINUTE
|
||||
const DAY = 24 * HOUR
|
||||
export function parseTimeData(time) {
|
||||
const days = Math.floor(time / DAY)
|
||||
const hours = Math.floor((time % DAY) / HOUR)
|
||||
const minutes = Math.floor((time % HOUR) / MINUTE)
|
||||
const seconds = Math.floor((time % MINUTE) / SECOND)
|
||||
const milliseconds = Math.floor(time % SECOND)
|
||||
return {
|
||||
days,
|
||||
hours,
|
||||
minutes,
|
||||
seconds,
|
||||
milliseconds
|
||||
}
|
||||
}
|
||||
export function parseFormat(format, timeData) {
|
||||
let {
|
||||
days,
|
||||
hours,
|
||||
minutes,
|
||||
seconds,
|
||||
milliseconds
|
||||
} = timeData
|
||||
// 如果格式化字符串中不存在DD(天),则将天的时间转为小时中去
|
||||
if (format.indexOf('DD') === -1) {
|
||||
hours += days * 24
|
||||
} else {
|
||||
// 对天补0
|
||||
format = format.replace('DD', padZero(days))
|
||||
}
|
||||
// 其他同理于DD的格式化处理方式
|
||||
if (format.indexOf('HH') === -1) {
|
||||
minutes += hours * 60
|
||||
} else {
|
||||
format = format.replace('HH', padZero(hours))
|
||||
}
|
||||
if (format.indexOf('mm') === -1) {
|
||||
seconds += minutes * 60
|
||||
} else {
|
||||
format = format.replace('mm', padZero(minutes))
|
||||
}
|
||||
if (format.indexOf('ss') === -1) {
|
||||
milliseconds += seconds * 1000
|
||||
} else {
|
||||
format = format.replace('ss', padZero(seconds))
|
||||
}
|
||||
return format.replace('SSS', padZero(milliseconds, 3))
|
||||
}
|
||||
export function isSameSecond(time1, time2) {
|
||||
return Math.floor(time1 / 1000) === Math.floor(time2 / 1000)
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
<template>
|
||||
<view
|
||||
class="uv-count-down"
|
||||
:style="[$uv.addStyle(customStyle)]">
|
||||
<slot>
|
||||
<text class="uv-count-down__text">{{ formattedTime }}</text>
|
||||
</slot>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
|
||||
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
|
||||
import props from './props.js';
|
||||
import {
|
||||
isSameSecond,
|
||||
parseFormat,
|
||||
parseTimeData
|
||||
} from './utils';
|
||||
/**
|
||||
* uv-count-down 倒计时
|
||||
* @description 该组件一般使用于某个活动的截止时间上,通过数字的变化,给用户明确的时间感受,提示用户进行某一个行为操作。
|
||||
* @tutorial https://www.uvui.cn/components/countDown.html
|
||||
* @property {String | Number} time 倒计时时长,单位ms (默认 0 )
|
||||
* @property {String} format 时间格式,DD-日,HH-时,mm-分,ss-秒,SSS-毫秒 (默认 'HH:mm:ss' )
|
||||
* @property {Boolean} autoStart 是否自动开始倒计时 (默认 true )
|
||||
* @property {Boolean} millisecond 是否展示毫秒倒计时 (默认 false )
|
||||
* @event {Function} finish 倒计时结束时触发
|
||||
* @event {Function} change 倒计时变化时触发
|
||||
* @event {Function} start 开始倒计时
|
||||
* @event {Function} pause 暂停倒计时
|
||||
* @event {Function} reset 重设倒计时,若 auto-start 为 true,重设后会自动开始倒计时
|
||||
* @example <uv-count-down :time="time"></uv-count-down>
|
||||
*/
|
||||
export default {
|
||||
name: 'uv-count-down',
|
||||
mixins: [mpMixin, mixin, props],
|
||||
data() {
|
||||
return {
|
||||
timer: null,
|
||||
// 各单位(天,时,分等)剩余时间
|
||||
timeData: parseTimeData(0),
|
||||
// 格式化后的时间,如"03:23:21"
|
||||
formattedTime: '0',
|
||||
// 倒计时是否正在进行中
|
||||
runing: false,
|
||||
endTime: 0, // 结束的毫秒时间戳
|
||||
remainTime: 0, // 剩余的毫秒时间
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
time(n) {
|
||||
this.reset()
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.reset()
|
||||
},
|
||||
// 开始倒计时
|
||||
start() {
|
||||
if (this.runing) return
|
||||
// 标识为进行中
|
||||
this.runing = true
|
||||
// 结束时间戳 = 此刻时间戳 + 剩余的时间
|
||||
this.endTime = Date.now() + this.remainTime
|
||||
this.toTick()
|
||||
},
|
||||
// 根据是否展示毫秒,执行不同操作函数
|
||||
toTick() {
|
||||
if (this.millisecond) {
|
||||
this.microTick()
|
||||
} else {
|
||||
this.macroTick()
|
||||
}
|
||||
},
|
||||
macroTick() {
|
||||
this.clearTimeout()
|
||||
// 每隔一定时间,更新一遍定时器的值
|
||||
// 同时此定时器的作用也能带来毫秒级的更新
|
||||
this.timer = setTimeout(() => {
|
||||
// 获取剩余时间
|
||||
const remain = this.getRemainTime()
|
||||
// 重设剩余时间
|
||||
if (!isSameSecond(remain, this.remainTime) || remain === 0) {
|
||||
this.setRemainTime(remain)
|
||||
}
|
||||
// 如果剩余时间不为0,则继续检查更新倒计时
|
||||
if (this.remainTime !== 0) {
|
||||
this.macroTick()
|
||||
}
|
||||
}, 30)
|
||||
},
|
||||
microTick() {
|
||||
this.clearTimeout()
|
||||
this.timer = setTimeout(() => {
|
||||
this.setRemainTime(this.getRemainTime())
|
||||
if (this.remainTime !== 0) {
|
||||
this.microTick()
|
||||
}
|
||||
}, 50)
|
||||
},
|
||||
// 获取剩余的时间
|
||||
getRemainTime() {
|
||||
// 取最大值,防止出现小于0的剩余时间值
|
||||
return Math.max(this.endTime - Date.now(), 0)
|
||||
},
|
||||
// 设置剩余的时间
|
||||
setRemainTime(remain) {
|
||||
this.remainTime = remain
|
||||
// 根据剩余的毫秒时间,得出该有天,小时,分钟等的值,返回一个对象
|
||||
const timeData = parseTimeData(remain)
|
||||
this.$emit('change', timeData)
|
||||
// 得出格式化后的时间
|
||||
this.formattedTime = parseFormat(this.format, timeData)
|
||||
// 如果时间已到,停止倒计时
|
||||
if (remain <= 0) {
|
||||
this.pause()
|
||||
this.$emit('finish')
|
||||
}
|
||||
},
|
||||
// 重置倒计时
|
||||
reset() {
|
||||
this.pause()
|
||||
this.remainTime = this.time
|
||||
this.setRemainTime(this.remainTime)
|
||||
if (this.autoStart) {
|
||||
this.start()
|
||||
}
|
||||
},
|
||||
// 暂停倒计时
|
||||
pause() {
|
||||
this.runing = false;
|
||||
this.clearTimeout()
|
||||
},
|
||||
// 清空定时器
|
||||
clearTimeout() {
|
||||
clearTimeout(this.timer)
|
||||
this.timer = null
|
||||
}
|
||||
},
|
||||
// #ifdef VUE2
|
||||
beforeDestroy() {
|
||||
this.clearTimeout()
|
||||
},
|
||||
// #endif
|
||||
// #ifdef VUE3
|
||||
unmounted() {
|
||||
this.clearTimeout()
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
|
||||
@import '@/uni_modules/uv-ui-tools/libs/css/color.scss';
|
||||
$uv-count-down-text-color: $uv-content-color !default;
|
||||
$uv-count-down-text-font-size: 15px !default;
|
||||
$uv-count-down-text-line-height: 22px !default;
|
||||
.uv-count-down {
|
||||
&__text {
|
||||
color: $uv-count-down-text-color;
|
||||
font-size: $uv-count-down-text-font-size;
|
||||
line-height: $uv-count-down-text-line-height;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"id": "uv-count-down",
|
||||
"displayName": "uv-count-down 倒计时 全面兼容小程序、nvue、vue2、vue3等多端",
|
||||
"version": "1.0.3",
|
||||
"description": "该倒计时组件一般使用于某个活动的截止时间上,通过数字的变化,给用户明确的时间感受,提示用户进行某一个行为操作。",
|
||||
"keywords": [
|
||||
"uv-count-down",
|
||||
"uvui",
|
||||
"uv-ui",
|
||||
"countDown",
|
||||
"倒计时"
|
||||
],
|
||||
"repository": "",
|
||||
"engines": {
|
||||
"HBuilderX": "^3.1.0"
|
||||
},
|
||||
"dcloudext": {
|
||||
"type": "component-vue",
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "插件不采集任何数据",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": ""
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [
|
||||
"uv-ui-tools"
|
||||
],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "y"
|
||||
},
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "y"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "y",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "y",
|
||||
"百度": "y",
|
||||
"字节跳动": "y",
|
||||
"QQ": "y",
|
||||
"钉钉": "u",
|
||||
"快手": "u",
|
||||
"飞书": "u",
|
||||
"京东": "u"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
## CountDown 倒计时
|
||||
|
||||
> **组件名:uv-count-down**
|
||||
|
||||
该组件一般使用于某个活动的截止时间上,通过数字的变化,给用户明确的时间感受,提示用户进行某一个行为操作。
|
||||
|
||||
### <a href="https://www.uvui.cn/components/countDown.html" target="_blank">查看文档</a>
|
||||
|
||||
### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui)
|
||||
|
||||
#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a>
|
||||
@@ -0,0 +1,7 @@
|
||||
## 1.0.2(2023-06-20)
|
||||
1. 适配height参数携带单位
|
||||
## 1.0.1(2023-05-16)
|
||||
1. 优化组件依赖,修改后无需全局引入,组件导入即可使用
|
||||
2. 优化部分功能
|
||||
## 1.0.0(2023-05-10)
|
||||
uv-line-progress 线形进度条
|
||||
@@ -0,0 +1,29 @@
|
||||
export default {
|
||||
props: {
|
||||
// 激活部分的颜色
|
||||
activeColor: {
|
||||
type: String,
|
||||
default: '#19be6b'
|
||||
},
|
||||
inactiveColor: {
|
||||
type: String,
|
||||
default: '#ececec'
|
||||
},
|
||||
// 进度百分比,数值
|
||||
percentage: {
|
||||
type: [String, Number],
|
||||
default: 0
|
||||
},
|
||||
// 是否在进度条内部显示百分比的值
|
||||
showText: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 进度条的高度,单位px
|
||||
height: {
|
||||
type: [String, Number],
|
||||
default: 12
|
||||
},
|
||||
...uni.$uv?.props?.lineProgress
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<view
|
||||
class="uv-line-progress"
|
||||
:style="[$uv.addStyle(customStyle)]"
|
||||
>
|
||||
<view
|
||||
class="uv-line-progress__background"
|
||||
ref="uv-line-progress__background"
|
||||
:style="[{
|
||||
backgroundColor: inactiveColor,
|
||||
height: $uv.addUnit($uv.getPx(height))
|
||||
}]"
|
||||
>
|
||||
</view>
|
||||
<view
|
||||
class="uv-line-progress__line"
|
||||
:style="[progressStyle]"
|
||||
>
|
||||
<slot>
|
||||
<text v-if="showText && percentage >= 10" class="uv-line-progress__text">{{innserPercentage + '%'}}</text>
|
||||
</slot>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
|
||||
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
|
||||
import props from './props.js';
|
||||
// #ifdef APP-NVUE
|
||||
const dom = uni.requireNativePlugin('dom')
|
||||
// #endif
|
||||
/**
|
||||
* lineProgress 线型进度条
|
||||
* @description 展示操作或任务的当前进度,比如上传文件,是一个线形的进度条。
|
||||
* @tutorial https://www.uvui.cn/components/lineProgress.html
|
||||
* @property {String} activeColor 激活部分的颜色 ( 默认 '#19be6b' )
|
||||
* @property {String} inactiveColor 背景色 ( 默认 '#ececec' )
|
||||
* @property {String | Number} percentage 进度百分比,数值 ( 默认 0 )
|
||||
* @property {Boolean} showText 是否在进度条内部显示百分比的值 ( 默认 true )
|
||||
* @property {String | Number} height 进度条的高度,单位px ( 默认 12 )
|
||||
*
|
||||
* @example <uv-line-progress :percent="70" :show-percent="true"></uv-line-progress>
|
||||
*/
|
||||
export default {
|
||||
name: "uv-line-progress",
|
||||
mixins: [mpMixin, mixin, props],
|
||||
data() {
|
||||
return {
|
||||
lineWidth: 0,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
percentage(n) {
|
||||
this.resizeProgressWidth()
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
progressStyle() {
|
||||
let style = {}
|
||||
style.width = this.lineWidth
|
||||
style.backgroundColor = this.activeColor
|
||||
style.height = this.$uv.addUnit(this.$uv.getPx(this.height))
|
||||
return style
|
||||
},
|
||||
innserPercentage() {
|
||||
// 控制范围在0-100之间
|
||||
return this.$uv.range(0, 100, this.percentage)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.$uv.sleep(20).then(() => {
|
||||
this.resizeProgressWidth()
|
||||
})
|
||||
},
|
||||
getProgressWidth() {
|
||||
// #ifndef APP-NVUE
|
||||
return this.$uvGetRect('.uv-line-progress__background')
|
||||
// #endif
|
||||
|
||||
// #ifdef APP-NVUE
|
||||
// 返回一个promise
|
||||
return new Promise(resolve => {
|
||||
dom.getComponentRect(this.$refs['uv-line-progress__background'], (res) => {
|
||||
resolve(res.size)
|
||||
})
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
resizeProgressWidth() {
|
||||
this.getProgressWidth().then(size => {
|
||||
const {
|
||||
width
|
||||
} = size
|
||||
// 通过设置的percentage值,计算其所占总长度的百分比
|
||||
this.lineWidth = width * this.innserPercentage / 100 + 'px'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
|
||||
|
||||
.uv-line-progress {
|
||||
align-items: stretch;
|
||||
position: relative;
|
||||
@include flex(row);
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
border-radius: 100px;
|
||||
|
||||
&__background {
|
||||
background-color: #ececec;
|
||||
border-radius: 100px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&__line {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
align-items: center;
|
||||
@include flex(row);
|
||||
color: #ffffff;
|
||||
border-radius: 100px;
|
||||
transition: width 0.5s ease;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
&__text {
|
||||
font-size: 10px;
|
||||
align-items: center;
|
||||
text-align: right;
|
||||
color: #FFFFFF;
|
||||
margin-right: 5px;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"id": "uv-line-progress",
|
||||
"displayName": "uv-line-progress 线形进度条 全面兼容小程序、nvue、vue2、vue3等多端",
|
||||
"version": "1.0.2",
|
||||
"description": "uv-line-progress 该组件展示操作或任务的当前进度,比如上传文件,是一个线形的进度条。",
|
||||
"keywords": [
|
||||
"uv-line-progress",
|
||||
"uvui",
|
||||
"uv-ui",
|
||||
"progress",
|
||||
"进度条"
|
||||
],
|
||||
"repository": "",
|
||||
"engines": {
|
||||
"HBuilderX": "^3.1.0"
|
||||
},
|
||||
"dcloudext": {
|
||||
"type": "component-vue",
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "插件不采集任何数据",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": ""
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [
|
||||
"uv-ui-tools"
|
||||
],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "y"
|
||||
},
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "y"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "y",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "y",
|
||||
"百度": "y",
|
||||
"字节跳动": "y",
|
||||
"QQ": "y",
|
||||
"钉钉": "u",
|
||||
"快手": "u",
|
||||
"飞书": "u",
|
||||
"京东": "u"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
## LineProgress 线形进度条
|
||||
|
||||
> **组件名:uv-line-progress**
|
||||
|
||||
展示操作或任务的当前进度,比如上传文件,是一个线形的进度条。
|
||||
|
||||
### <a href="https://www.uvui.cn/components/lineProgress.html" target="_blank">查看文档</a>
|
||||
|
||||
### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui)
|
||||
|
||||
#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a>
|
||||