2025-08-02 13:57:00 +08:00

222 lines
5.0 KiB
Vue

<template>
<view class="picker-wrap">
<uni-popup ref="popupRef" :is-mask-click="false" animation type="bottom">
<view class="popup_box">
<view v-if="title" class="header_title">
{{ title }}
</view>
<view class="picker-view">
<scroll-view :scroll-y="true" style="height: 650rpx;">
<view class="picker-list">
<view class="picker-list-item" v-for="(item, index) in pickList" :key="index" @click="selectedItem(item)">
<view class="picker-list-item-text">{{item.name}}</view>
<view class="state">
<wd-img v-if="checkedList.includes(item.value)" width="30rpx" height="30rpx" :src="radio"></wd-img>
<view v-else class="empty-selected"></view>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
<view class="footer">
<button class="cancel_btn flex-center" @click="tapCancelBtn">取消</button>
<button class="confirm_btn flex-center" @click="tapConfirmBtn">确定</button>
</view>
</uni-popup>
</view>
</template>
<script setup>
import { nextTick, ref, watch } from 'vue';
import radio from "@/static/svg/radio.svg";
import {getKnowledgeFlag} from "@/api/modules/inspector";
const props = defineProps({
title: {
type: String,
default: '',
},
modelValue: {
type: Boolean,
default: false,
},
pickList: {
type: Array,
default: () => [],
},
pickVal: {
type: Array,
default: () => [],
},
});
const emits = defineEmits(['update:modelValue', 'confirm']);
const popupRef = ref(null);
const checkedList = ref([])
// 取消
function tapCancelBtn() {
emits('update:modelValue', false);
}
// 确定
function tapConfirmBtn() {
if (!checkedList.value.length) {
uni.showToast({
title: '请选择知识点',
icon: 'none',
duration: 3000,
});
return;
}
const checked = props.pickList.filter(item => checkedList.value.includes(item.value))
emits('confirm', checked);
emits('update:modelValue', false);
}
watch(
() => props.modelValue,
() => {
if (props.modelValue) {
nextTick(() => {
popupRef.value.open();
checkedList.value = props.pickVal;
});
} else {
if (popupRef.value) {
popupRef.value.close();
}
}
},
{
immediate: true,
deep: true,
},
);
const knowledgeFlag = ref({})
const selectedItem = async (item) => {
try {
if ((knowledgeFlag.value[item.value] ?? "") === "") {
await uni.showLoading()
const data = await getKnowledgeFlag(item.value)
knowledgeFlag.value[item.value] = data
uni.hideLoading()
}
if (knowledgeFlag.value[item.value] === false) {
// 没有练习题
await uni.showToast({
title: "该知识点没有练习题",
icon: "none",
duration: 3000
})
} else {
if (!checkedList.value.includes(item.value)) {
checkedList.value.push(item.value);
} else {
checkedList.value = checkedList.value.filter(val => val !== item.value);
}
}
} catch (e) {
}finally {
uni.hideLoading()
}
}
</script>
<style lang="scss" scoped>
.picker-wrap {
.popup_box {
position: relative;
height: 700rpx;
background-color: #fff;
border-radius: 20rpx 20rpx 0 0;
overflow: hidden;
.header_title {
padding: 30rpx 0 30rpx 30rpx;
color: #333;
font-size: 32rpx;
}
.picker-view {
width: 750rpx;
height: 650rpx;
.picker-list {
padding: 0 30rpx 200rpx 30rpx;
display: flex;
flex-direction: column;
justify-content: center;
.picker-list-item {
padding: 30rpx 0;
height: 90rpx;
box-sizing: border-box;
border-bottom: 1px solid #eeeeee;
display: flex;
justify-content: space-between;
align-items: center;
.empty-selected {
width: 30rpx;
height: 30rpx;
border-radius: 6rpx;
border: 1px solid #eeeeee;
background-color: #f9f9fb;
}
}
}
}
.picker_item {
line-height: 100rpx;
text-align: center;
}
.selected_item {
color: #615dff;
}
}
}
.flex-center {
display: flex;
align-items: center;
justify-content: center;
}
.footer {
display: flex;
justify-content: space-between;
align-items: center;
position: fixed;
width: 100%;
padding: 30rpx;
box-sizing: border-box;
border-top: 1px solid #eeeeee;
bottom: 0;
z-index: 9;
background-color: #fff;
button::after {
border: none;
}
.cancel_btn {
width: 230rpx;
height: 90rpx;
color: #615dff;
font-size: 30rpx;
background-color: #ececff;
border-radius: 20rpx;
}
.confirm_btn {
margin-left: 20rpx;
height: 90rpx;
width: 440rpx;
color: #fff;
font-size: 30rpx;
border-radius: 20rpx;
background: #615dff;
}
}
</style>