Files
ks-app-employment-service/packageB/train/wrongAnswer/mistakeNotebook.vue
2025-11-11 19:20:22 +08:00

585 lines
15 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-box">
<div class="con-box">
<template #headContent>
<view class="collection-search">
<view class="search-content">
<view class="header-input button-click">
<uni-icons class="iconsearch" color="#6A6A6A" type="search" size="22"></uni-icons>
<input
class="input"
v-model="searchKeyword"
@confirm="searchVideo"
placeholder="输入题目关键词"
placeholder-class="inputplace"
/>
<uni-icons
v-if="searchKeyword"
class="clear-icon"
type="clear"
size="24"
color="#999"
@click="clearSearch"
/>
</view>
</view>
<view>
<checkbox-group>
<label>
<checkbox :value="checkeds" :checked="checkeds" @click="selects()" />全选
</label>
</checkbox-group>
</view>
</view>
<div class="serchBtns">
<div class="btn" @click="startPractice" style="background-color: #4B9FF5;">开始练习</div>
<div class="btn" @click="batchMark" style="background-color: #FF9F51;">批量标记</div>
<div class="btn" @click="clearNotebook" style="background-color: #F1705F;">清空错题本</div>
</div>
</template>
<scroll-view scroll-y class="main-scroll" @scrolltolower="handleScrollToLower">
<div class="cards" v-for="(item,index) in dataList">
<div class="choices">
<checkbox-group>
<label>
<checkbox value="cb" :checked="item.checked" @click="choice(index)" color="#FFCC33" style="transform:scale(0.7)" />
</label>
</checkbox-group>
</div>
<div class="cardHead">
<div class="cardHeadLeft">
<div class="cardTitle">{{item.content}}</div>
</div>
<div class="titleType primary2" v-if="item.status==0">未复习</div>
<div class="titleType primary" v-if="item.status==1">已复习</div>
<div class="titleType success" v-if="item.status==2">已掌握</div>
</div>
<div class="heng"></div>
<div class="cardCon">
<div class="conten" style="width: 40%;">类型
<div class="titleType primary" v-if="item.type=='single'">单选</div>
<div class="titleType success" v-if="item.type=='multiple'">多选</div>
<div class="titleType tertiary" v-if="item.type=='judge'">判断</div>
</div>
<div class="conten" style="width: 60%;">错误时间{{item.errorTime}}</div>
<div class="conten" style="width: 40%;">等级
<div class="titleType success" v-if="item.diffculty=='easy'">初级</div>
<div class="titleType tertiary" v-if="item.diffculty=='medium'">中级</div>
<div class="titleType primary2" v-if="item.diffculty=='hard'">高级</div>
</div>
<div class="conten" style="width: 60%;">最后复习{{item.reviewTime || '未复习'}}</div>
</div>
<div class="flooter">
<div @click="handleDetail(item)">查看详情</div>
<div @click="removeFromNotebook(item.questionId,3)">移出错题</div>
</div>
</div>
</scroll-view>
</div>
<div class="cards2" v-if="dialogVisible">
<div class="cardCon" style="height: 50%;">
<div class="cardHead" style="margin-bottom: 30rpx;">
<div>批量标记</div>
<div style="font-size: 40rpx;" @click="clones()">×</div>
</div>
<div class="detailTitle">已选择{{selectedItems.length}}道错题</div>
<div class="status-tags">
<radio-group @change="radioChange">
<label class="uni-list-cell uni-list-cell-pd">
<view style="margin: 20rpx 20%;">
<radio :value="1" :checked="1 === current" />标记为已复习
</view>
<view style="margin: 20rpx 20%;">
<radio :value="2" :checked="2 === current" />标记为已掌握
</view>
<view style="margin: 20rpx 20%;">
<radio :value="3" :checked="3 === current" />移出错题本
</view>
<!-- <view>{{item.name}}</view> -->
</label>
</radio-group>
</div>
<div style="display: flex;justify-content: center;margin-top: 30rpx;">
<div class="rightBtn" @click="mark()">标记</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { inject, ref, reactive,watch } from 'vue';
import { onLoad, onShow } from '@dcloudio/uni-app';
const { $api, navTo, navBack,urls } = inject('globalFunction');
import config from "@/config.js"
const userInfo = ref({});
const Authorization = ref('');
const searchKeyword = ref('');
const dataList=ref([])
const pageSize=ref(10)
const pageNum=ref(1)
const totalNum=ref(0)
const dates=ref('')
// const classification=ref([])
// const levalLabels=ref([])
const examInfo = ref({})
const baseUrl = config.imgBaseUrl
const dialogVisible = ref(false);
const checkeds = ref(false);
const selectedItems = ref([]);
const current = ref("");
const handleScrollToLower = () => {
getDataList('add');
};
function selects(){
checkeds.value=!checkeds.value;
dataList.value.forEach(item=>{
item.checked=checkeds.value
})
};
function choice(i){
dataList.value[i].checked=!dataList.value[i].checked;
}
onLoad(() => {
// getDictionary()
// const date = new Date();
// let year = date.getFullYear();
// let month = date.getMonth() + 1; // 月份从0开始需要加1
// let day = date.getDate();
// month=month>9?month:'0'+month
// day=day>9?day:'0'+day
// dates.value=year+'-'+month+'-'+day
// Authorization.value=uni.getStorageSync('Padmin-Token')||''
// getHeart();
});
onShow(()=>{
Authorization.value=uni.getStorageSync('Padmin-Token')||''
getHeart();
})
function getHeart() {
const raw =Authorization.value;
const token = typeof raw === "string" ? raw.trim() : "";
const headers = token ? { 'Authorization': raw.startsWith("Bearer ") ? raw : `Bearer ${token}` }: {}
$api.myRequest("/dashboard/auth/heart", {}, "POST", 10100, headers).then((resData) => {
if (resData.code == 200) {
getUserInfo();
} else {
navTo('/packageB/login')
}
});
};
function getUserInfo(){
let header={
'Authorization':Authorization.value
}
$api.myRequest('/system/user/login/user/info', {},'get',10100,header).then((resData) => {
userInfo.value = resData.info || {};
getDataList('refresh');
});
};
// function getDictionary(){
// $api.myRequest('/system/public/dict/data/type/question_classification', {},'get',9100).then((resData) => {
// classification.value=resData.data
// });
// $api.myRequest('/system/public/dict/data/type/question_level', {},'get',9100).then((resData) => {
// levalLabels.value=resData.data
// });
// }
// 搜索
function searchVideo() {
getDataList('refresh');
}
// 清除搜索内容
function clearSearch() {
searchKeyword.value = '';
getDataList('refresh');
}
// 获取错题列表
function getDataList(type = 'add') {
let maxPage=Math.ceil(totalNum.value/pageSize.value)
let params={}
if (type === 'refresh') {
pageNum.value = 1;
params={
content:searchKeyword.value,
pageSize:pageSize.value,
pageNum:pageNum.value,
userId:userInfo.value.userId
}
$api.myRequest('/train/public/mistackUser/mistackTable', params).then((resData) => {
if(resData.code==200){
dataList.value=resData.rows
totalNum.value=resData.total
dataList.value.forEach(item=>{
item.checked=false
})
}
});
}
if (type === 'add' && pageNum.value < maxPage) {
pageNum.value += 1;
params={
content:searchKeyword.value,
pageSize:pageSize.value,
pageNum:pageNum.value,
userId:userInfo.value.userId
}
$api.myRequest('/train/public/mistackUser/mistackTable', params).then((resData) => {
if(resData.code==200){
dataList.value=dataList.value.concat(resData.rows)
totalNum.value=resData.total
dataList.value.forEach(item=>{
item.checked=false
})
}
});
}
}
function handleDetail(row){
navTo(`/packageB/train/wrongAnswer/wrongDetail?questionId=${row.questionId}`);
}
function startPractice(row){
navTo('/packageB/train/wrongAnswer/questionPractice');
}
function clones(){
dialogVisible.value=false
}
function radioChange(evt) {
current.value=evt.detail.value;
}
function clearNotebook() {
$api.myRequest('/train/public/mistackUser/clear', {
userId:userInfo.value.userId,
}).then((resData) => {
if(resData&&resData.code==200){
getDataList('refresh');
}
});
};
function batchMark() {
// 批量标记逻辑
dataList.value.forEach(item=>{
if(item.checked){
selectedItems.value.push(item)
}
})
if(selectedItems.value.length>0){
dialogVisible.value=true
}else{
$api.msg('请先选择要标记的错题!')
}
};
function mark(){
let ids=[]
selectedItems.value.forEach(item=>{
ids.push(item.questionId)
})
$api.myRequest('/train/public/mistackUser/batchUpdate', {
userId:userInfo.value.userId,
questionIds:ids.join(","),
status:current.value
}).then((resData) => {
if(resData&&resData.code==200){
if(current.value==3){
$api.msg('移出成功!')
}else{
$api.msg('标记成功!')
}
dialogVisible.value=false
getDataList('refresh');
}
});
};
function removeFromNotebook(id,i) {
$api.myRequest('/train/public/mistackUser/batchUpdate', {
userId:userInfo.value.userId,
questionId:id,
status:i
}).then((resData) => {
if(resData&&resData.code==200){
if(i==3){
$api.msg('移出成功!')
}else{
$api.msg('标记成功!')
}
getDataList('refresh');
}
});
}
</script>
<style lang="stylus" scoped>
.app-box{
width: 100%;
height: 100vh;
position: relative;
.con-box{
position: absolute;
width: 100%;
height: 100%;
left: 0;
top:0;
z-index: 10;
padding: 20rpx 28rpx;
box-sizing: border-box;
overflow: hidden;
.serchBtns{
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20rpx;
.btn{
width: 30%;
height: 50rpx;
line-height: 50rpx;
text-align: center
color: #fff;
border-radius: 10rpx
}
}
.collection-search{
padding: 10rpx 20rpx;
display: flex;
align-items: center;
justify-content: space-between;
.search-content{
width: 80%;
position: relative
display: flex
align-items: center
padding: 14rpx 0
.header-input{
padding: 0
width: calc(100%);
position: relative
.iconsearch{
position: absolute
left: 30rpx;
top: 50%
transform: translate(0, -50%)
z-index: 1
}
.input{
padding: 0 80rpx 0 80rpx
height: 80rpx;
background: #FFFFFF;
border-radius: 75rpx 75rpx 75rpx 75rpx;
border: 2rpx solid #ECECEC
font-size: 28rpx;
}
.clear-icon{
position: absolute
right: 30rpx;
top: 50%
transform: translate(0, -50%)
z-index: 1
cursor: pointer
}
.inputplace{
font-weight: 400;
font-size: 28rpx;
color: #B5B5B5;
}
}
}
}
.main-scroll {
width: 100%;
height: 85%;
.cards{
width: 100%;
height: 280rpx;
background: linear-gradient(0deg, #E3EFFF 0%, #FBFDFF 100%);
// box-shadow: 0px 0px 6px 0px rgba(0,71,200,0.32);
border-radius: 12rpx;
border: 2px solid #EDF5FF;
margin-bottom: 30rpx;
padding: 30rpx 40rpx 0;
box-sizing: border-box;
position: relative;
.choices{
position: absolute;
top: 0;
left: -10rpx;
}
.cardHead{
display: flex;
align-items: center;
justify-content: space-between;
.cardHeadLeft{
display: flex;
align-items: center
width: 75%;
.cardTitle{
font-weight: bold;
font-size: 28rpx;
color: #0069CB;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.titleType{
border-radius: 4px;
font-size: 22rpx;
color: #157EFF;
width: 100rpx;
height: 38rpx;
text-align: center;
line-height: 38rpx;
margin-left: 10rpx;
}
}
}
.heng{
width: 120rpx;
height: 4rpx;
background: linear-gradient(88deg, #015EEA 0%, #00C0FA 100%);
margin: 10rpx 0 20rpx;
}
.cardCon{
display: flex;
flex-wrap: wrap;
.conten{
width: 50%;
font-size: 22rpx;
color: #666666;
display: flex;
align-items: center
margin-bottom: 20rpx;
}
.status-tags{
display: flex;
align-items: center;
}
}
.flooter{
border-top: 1px solid #ccc;
display: flex;
justify-content: flex-end;
align-items: center;
view{
font-size: 28rpx;
margin-left: 30rpx;
color: #2175F3;
padding-top: 10rpx;
}
}
}
}
}
.cards2{
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100vh;
background-color: rgba(0,0,0,0.5);
z-index: 10000;
padding: 100rpx 50rpx;
box-sizing: border-box;
.cardCon{
height: 70%;
background-color: #fff;
padding: 20rpx;
box-sizing: border-box;
.cardHead{
display: flex;
align-items: center;
justify-content: space-between;
font-size: 30rpx;
font-weight: 600;
}
}
}
}
.titleType{
display: inline-block
border-radius: 4px;
font-size: 22rpx;
color: #157EFF;
width: 100rpx;
height: 38rpx;
text-align: center;
line-height: 38rpx;
margin-left: 10rpx;
}
.primary{
border: 1px solid #157EFF!important;
color: #157EFF!important
}
.success{
border: 1px solid #05A636!important;
color: #05A636!important
}
.info{
border: 1px solid #898989!important;
color: #898989!important
}
.tertiary{
border: 1px solid #E6A340!important;
color: #E6A340!important
}
.primary2{
border: 1px solid #F56C6C!important;
color: #F56C6C!important
}
.rightBtn{
width: 140rpx;
height: 44rpx;
line-height: 44rpx;
background: linear-gradient(90deg, #00C0FA 0%, #1271FF 100%);
border-radius: 4px;
color: #fff;
font-size: 24rpx;
text-align: center;
}
.detailTitle{
font-size: 28rpx;
font-weight: 600;
margin: 30rpx 0;
}
.detailCon{
font-size: 28rpx;
line-height: 40rpx;
}
.exam-info {
display: flex;
justify-content: space-between;
margin-bottom: 35rpx;
margin-top: 20rpx;
}
.info-item {
flex: 1;
text-align: center;
}
.info-value {
font-family: 'D-DIN-Medium';
font-size: 26rpx;
font-weight: 600;
color: #409EFF;
margin-bottom: 8rpx;
}
.info-label {
font-size: 26rpx;
color: #333;
}
.info-divider {
width: 2px;
background-color: #C3E1FF;
}
</style>