290 lines
7.6 KiB
Vue
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"> </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>
|