Files
ks-app-employment-service/components/selectJobs/selectJobs.vue
2025-07-21 14:49:45 +08:00

290 lines
7.6 KiB
Vue

<template>
<uni-popup
ref="popup"
type="bottom"
borderRadius="10px 10px 0 0"
background-color="#FFFFFF"
:mask-click="maskClick"
>
<view class="popup-content">
<view class="popup-header">
<view class="btn-cancel" @click="cancel">取消</view>
<view class="title">
<text>{{ title }}</text>
<text style="color: #256bfa">·{{ count }}</text>
</view>
<view class="btn-confirm" @click="confirm">&nbsp;&nbsp;</view>
</view>
<view class="popup-list">
<expected-station
:search="false"
@onChange="changeJobTitleId"
:station="state.stations"
:max="5"
></expected-station>
</view>
<view class="popup-bottom">
<view class="btn-cancel" @click="cleanup">清除</view>
<view class="btn-confirm" @click="confirm">确认</view>
</view>
</view>
</uni-popup>
</template>
<script setup>
import { ref, reactive, computed, inject, nextTick, defineExpose, onMounted } from 'vue';
const { $api, navTo, setCheckedNodes, cloneDeep } = inject('globalFunction');
import useUserStore from '@/stores/useUserStore';
import { storeToRefs } from 'pinia';
const { userInfo } = storeToRefs(useUserStore());
const maskClick = ref(false);
const title = ref('标题');
const confirmCallback = ref(null);
const cancelCallback = ref(null);
const changeCallback = ref(null);
const listData = ref([]);
const selectedIndex = ref([0, 0, 0]);
const rowLabel = ref('label');
const rowKey = ref('value');
const selectedItems = ref([]);
const popup = ref(null);
const count = ref(0);
const JobsIdsValue = ref('');
const JobsLabelValue = ref('');
const state = reactive({
jobTitleId: '',
stations: [],
visible: false,
});
// onMounted(() => {
// serchforIt();
// });
// 统一处理二维数组格式
const processedListData = computed(() => {
return listData.value.map((column) => {
if (!Array.isArray(column)) return [];
return column.map((item) => {
return typeof item === 'object' ? item : { [rowLabel.value]: item, [rowKey.value]: item };
});
});
});
const open = (newConfig = {}) => {
const {
title: configTitle,
success,
cancel,
change,
data,
rowLabel: configRowLabel = 'label',
rowKey: configRowKey = 'value',
maskClick: configMaskClick = false,
defaultId = '',
} = newConfig;
reset();
serchforIt(defaultId);
if (configTitle) title.value = configTitle;
if (typeof success === 'function') confirmCallback.value = success;
if (typeof cancel === 'function') cancelCallback.value = cancel;
if (typeof change === 'function') changeCallback.value = change;
if (Array.isArray(data)) listData.value = data;
rowLabel.value = configRowLabel;
rowKey.value = configRowKey;
maskClick.value = configMaskClick;
nextTick(() => {
popup.value?.open();
});
};
const close = () => {
popup.value?.close();
};
const cancel = () => {
handleClick(cancelCallback.value);
};
const confirm = () => {
if (JobsIdsValue.value) {
handleClick(confirmCallback.value);
} else {
$api.msg('请选择期望岗位');
}
};
const cleanup = () => {
setCheckedNodes(state.stations, []);
count.value = 0;
reset();
};
const changeJobTitleId = (e) => {
const ids = e.ids.split(',').map((id) => Number(id));
count.value = ids.length;
JobsIdsValue.value = e.ids;
JobsLabelValue.value = e.labels;
};
const handleClick = async (callback) => {
if (typeof callback !== 'function') {
close();
return;
}
try {
const result = await callback(JobsIdsValue.value, JobsLabelValue.value);
if (result !== false) close();
} catch (error) {
console.error('confirmCallback 执行出错:', error);
}
};
function serchforIt(defaultId) {
if (state.stations.length) {
const ids = defaultId
? defaultId.split(',').map((id) => Number(id))
: userInfo.value.jobTitleId.split(',').map((id) => Number(id));
count.value = ids.length;
state.jobTitleId = defaultId ? defaultId : userInfo.value.jobTitleId;
setCheckedNodes(state.stations, ids);
state.visible = true;
return;
}
$api.createRequest('/app/common/jobTitle/treeselect', {}, 'GET').then((resData) => {
if (userInfo.value.jobTitleId) {
const ids = userInfo.value.jobTitleId.split(',').map((id) => Number(id));
count.value = ids.length;
setCheckedNodes(resData.data, ids);
}
state.jobTitleId = userInfo.value.jobTitleId;
state.stations = resData.data;
state.visible = true;
});
}
const reset = () => {
maskClick.value = false;
changeCallback.value = null;
listData.value = [];
selectedIndex.value = [0, 0, 0];
rowLabel.value = 'label';
rowKey.value = 'value';
selectedItems.value = [];
JobsIdsValue.value = '';
JobsLabelValue.value = '';
};
// 暴露方法给父组件
defineExpose({
open,
close,
});
</script>
<style lang="scss" scoped>
.popup-content {
color: #000000;
height: 80vh;
}
.popup-bottom {
padding: 40rpx 28rpx 20rpx 28rpx;
display: flex;
justify-content: space-between;
.btn-cancel {
font-weight: 400;
font-size: 32rpx;
color: #666d7f;
line-height: 90rpx;
width: 33%;
min-width: 222rpx;
height: 90rpx;
background: #f5f5f5;
border-radius: 12rpx 12rpx 12rpx 12rpx;
text-align: center;
}
.btn-confirm {
font-weight: 400;
font-size: 32rpx;
color: #ffffff;
text-align: center;
width: 67%;
height: 90rpx;
margin-left: 28rpx;
line-height: 90rpx;
background: #256bfa;
min-width: 444rpx;
border-radius: 12rpx 12rpx 12rpx 12rpx;
}
}
.popup-list {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
justify-content: space-evenly;
height: calc(80vh - 100rpx - 150rpx);
overflow: hidden;
.picker-view {
width: 100%;
height: 500rpx;
margin-top: 20rpx;
.uni-picker-view-mask {
background: rgba(0, 0, 0, 0);
}
.item {
line-height: 84rpx;
height: 84rpx;
text-align: center;
font-weight: 400;
font-size: 32rpx;
color: #cccccc;
}
.item-active {
color: #333333;
}
.uni-picker-view-indicator:after {
border-color: #e3e3e3;
}
.uni-picker-view-indicator:before {
border-color: #e3e3e3;
}
}
// .list {
// .row {
// font-weight: 400;
// font-size: 32rpx;
// color: #333333;
// line-height: 84rpx;
// text-align: center;
// }
// }
}
.popup-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 40rpx 40rpx 10rpx 40rpx;
.title {
font-weight: 500;
font-size: 36rpx;
color: #333333;
text-align: center;
}
.btn-cancel {
font-weight: 400;
font-size: 32rpx;
color: #666d7f;
line-height: 38rpx;
}
.btn-confirm {
font-weight: 400;
font-size: 32rpx;
color: #256bfa;
}
}
</style>