Files
ks-app-employment-service/components/screening-job-requirements/screening-job-requirements.vue
史典卓 0216f6053a flat:AI+
2025-03-28 15:19:42 +08:00

262 lines
6.7 KiB
Vue

<template>
<view v-if="show" class="modal-mask">
<view class="modal-container">
<!-- 头部 -->
<view class="modal-header">
<text class="back-btn" @click="handleClose">
<uni-icons type="left" size="24"></uni-icons>
</text>
<text class="modal-title">{{ title }}</text>
<view class="back-btn"></view>
</view>
<!-- 内容区域 -->
<view class="content-wrapper">
<!-- 左侧筛选类别 -->
<scroll-view class="filter-nav" scroll-y>
<view
v-for="(item, index) in filterOptions"
:key="index"
class="nav-item"
:class="{ active: activeTab === item.key }"
@click="scrollTo(item.key)"
>
{{ item.label }}
</view>
</scroll-view>
<!-- 右侧筛选内容 -->
<scroll-view class="filter-content" :scroll-into-view="activeTab" scroll-y>
<template v-for="(item, index) in filterOptions" :key="index">
<view class="content-item">
<view class="item-title" :id="item.key">{{ item.label }}</view>
<checkbox-group class="check-content" @change="(e) => handleSelect(item.key, e)">
<label
v-for="option in item.options"
:key="option.value"
class="checkbox-item"
:class="{ checkedstyle: selectedValues[item.key]?.includes(String(option.value)) }"
>
<checkbox
style="display: none"
:value="String(option.value)"
:checked="selectedValues[item.key]?.includes(String(option.value))"
/>
<text class="option-label">{{ option.label }}</text>
</label>
</checkbox-group>
</view>
</template>
</scroll-view>
</view>
<!-- 底部按钮 -->
<view class="modal-footer">
<button class="footer-btn" type="default" @click="handleClear">清除</button>
<button class="footer-btn" type="primary" @click="handleConfirm">确认</button>
</view>
</view>
</view>
</template>
<script setup>
import { ref, reactive, computed, onBeforeMount } from 'vue';
import useDictStore from '@/stores/useDictStore';
const { getTransformChildren } = useDictStore();
const props = defineProps({
show: Boolean,
title: {
type: String,
default: '筛选',
},
area: {
type: Boolean,
default: true,
},
});
const emit = defineEmits(['confirm', 'close', 'update:show']);
// 当前激活的筛选类别
const activeTab = ref('');
// 存储已选中的值 {key: [selectedValues]}
const selectedValues = reactive({});
const filterOptions = ref([]);
onBeforeMount(() => {
const arr = [
getTransformChildren('education', '学历要求'),
getTransformChildren('experience', '工作经验'),
getTransformChildren('scale', '公司规模'),
];
if (props.area) {
arr.push(getTransformChildren('area', '区域'));
}
filterOptions.value = arr;
activeTab.value = 'education';
});
// 处理选项选择
const handleSelect = (key, e) => {
selectedValues[key] = e.detail.value.map(String);
};
const scrollTo = (key) => {
activeTab.value = key;
};
// 清除所有选择
const handleClear = () => {
Object.keys(selectedValues).forEach((key) => {
selectedValues[key] = [];
});
};
// 确认筛选
function handleConfirm() {
emit('confirm', selectedValues);
handleClose();
}
// 关闭弹窗
const handleClose = () => {
emit('update:show', false);
emit('close');
};
</script>
<style lang="scss" scoped>
.modal-mask {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
.modal-container {
width: 100vw;
height: 100vh;
background-color: #fff;
overflow: hidden;
display: flex;
flex-direction: column;
}
.modal-header {
height: 88rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 32rpx;
border-bottom: 1rpx solid #eee;
position: relative;
.back-btn {
font-size: 36rpx;
width: 48rpx;
}
.modal-title {
font-size: 32rpx;
font-weight: 500;
}
}
.content-wrapper {
flex: 1;
display: flex;
overflow: hidden;
}
.filter-nav {
width: 200rpx;
background-color: #f5f5f5;
.nav-item {
height: 100rpx;
padding: 0 20rpx;
line-height: 100rpx;
font-size: 28rpx;
color: #666;
&.active {
background-color: #fff;
color: #007aff;
font-weight: bold;
}
}
}
.filter-content {
flex: 1;
padding: 20rpx;
.content-item {
margin-top: 40rpx;
.item-title {
width: 281rpx;
height: 52rpx;
font-family: Inter, Inter;
font-weight: 400;
font-size: 35rpx;
color: #000000;
line-height: 41rpx;
text-align: left;
font-style: normal;
text-transform: none;
}
}
.content-item:first-child {
margin-top: 0rpx;
}
.check-content {
display: grid;
grid-template-columns: 50% 50%;
place-items: center;
.checkbox-item {
display: flex;
align-items: center;
width: 228rpx;
height: 65rpx;
margin: 20rpx 20rpx 0 0;
text-align: center;
background-color: #d9d9d9;
.option-label {
font-size: 28rpx;
width: 100%;
}
}
.checkedstyle {
background-color: #007aff;
color: #ffffff;
}
}
}
.modal-footer {
height: 100rpx;
display: flex;
border-top: 1rpx solid #eee;
.footer-btn {
flex: 1;
margin: 0;
border-radius: 0;
line-height: 100rpx;
&:first-child {
border-right: 1rpx solid #eee;
}
}
}
</style>