Files
qingdao-employment-service/packageA/pages/addPosition/addPosition.vue
2025-11-30 16:47:06 +08:00

311 lines
8.7 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>
<AppLayout title="添加岗位">
<template #headerleft>
<view class="btn">
<image src="@/static/icon/back.png" @click="navBack"></image>
</view>
</template>
<view class="main">
<view class="content-title">
<view class="title-lf">
<view class="lf-h1">想找什么工作</view>
<view class="lf-text">选择想找的工作我的将在首页为你推荐</view>
</view>
<view class="title-ri">
<!-- <text style="color: #256bfa">2</text>
<text>/2</text> -->
</view>
</view>
<view class="content-list">
<view class="list-search">
<uni-icons type="search" color="#333333" size="24"></uni-icons>
<input
class="search-input"
v-model="inputVal"
placeholder="请输入岗位名称"
@input="handelChangeInpute"
@blur="handleBlur"
@focus="handleFocus"
/>
<view class="search-container" v-show="filterList.length">
<view
class="list-item"
v-for="(item, index) in filterList"
@click="handelClickItem(item)"
:key="item.id"
>
<view class="item-txt line_1">{{ item.lable }}</view>
</view>
</view>
</view>
<view class="list-row" v-for="(item, index) in userInfo.jobTitle" :key="index">
<text>{{ item }}</text>
<image
class="row-image button-click"
@click="deleteItem(item, index)"
src="@/static/icon/delete1.png"
mode=""
></image>
</view>
<view class="list-row-add button-click" @click="changeJobs">添加求职岗位</view>
</view>
</view>
<SelectJobs ref="selectJobsModel"></SelectJobs>
</AppLayout>
<uni-popup ref="popup" type="dialog">
<uni-popup-dialog
mode="base"
title="确定添加该期望岗位吗"
type="info"
:duration="2000"
:before-close="true"
@confirm="confirm"
@close="close"
></uni-popup-dialog>
</uni-popup>
</template>
<script setup>
import { inject, ref, reactive } from 'vue';
import SelectJobs from '@/components/selectJobs/selectJobs.vue';
import { onLoad, onUnload } from '@dcloudio/uni-app';
const { $api, navBack } = inject('globalFunction');
import { storeToRefs } from 'pinia';
import useUserStore from '@/stores/useUserStore';
const { getUserResume } = useUserStore();
const { userInfo } = storeToRefs(useUserStore());
const popup = ref(null);
const selectJobsModel = ref(null);
const treeDataList = ref([]);
const dataSource = ref([]);
const filterList = ref([]);
const dataItem = ref(null);
const inputVal = ref('');
onLoad(() => {
getTree();
});
function close() {
popup.value.close();
}
function handleBlur() {
setTimeout(() => {
filterList.value = [];
}, 100);
}
function handleFocus() {
const val = inputVal.value.toLowerCase();
if (val && dataSource.value) {
filterList.value = dataSource.value.filter((item) => item.lable.toLowerCase().search(val) !== -1);
} else {
filterList.value = [];
}
}
function confirm() {
const { id } = dataItem.value;
let ids = userInfo.value.jobTitleId + `,${id}`;
const result = dedupeAndCheck(ids);
if (result.hasDuplicate) {
popup.value.close();
$api.msg('期望岗位已重复');
return;
}
complete({ jobTitleId: result.deduplicated });
inputVal.value = '';
popup.value.close();
}
function dedupeAndCheck(str) {
const items = str.split(',').map((s) => s.trim());
const uniqueItems = [...new Set(items)];
const hasDuplicate = uniqueItems.length !== items.length;
return {
deduplicated: uniqueItems.join(','),
hasDuplicate,
};
}
function deleteItem(item, index) {
const ids = userInfo.value.jobTitleId
.split(',')
.filter((_, vIndex) => vIndex !== index)
.join(',');
complete({ jobTitleId: ids });
}
function changeJobs() {
selectJobsModel.value?.open({
title: '添加岗位',
maskClick: true,
data: treeDataList.value,
success: (ids, labels) => {
complete({ jobTitleId: ids });
},
});
}
function handelChangeInpute(e) {
const val = e.detail.value.toLowerCase();
if (val && dataSource.value) {
filterList.value = dataSource.value.filter((item) => item.lable.toLowerCase().search(val) !== -1);
} else {
filterList.value = [];
}
}
function handelClickItem(item) {
dataItem.value = item;
popup.value.open();
}
function complete(values) {
if (!values.jobTitleId.length) {
return $api.msg('至少添加一份期望岗位');
}
$api.createRequest('/app/user/resume', values, 'post').then((resData) => {
$api.msg('完成');
getUserResume();
});
}
function getTree() {
const LoadCache = (resData) => {
if (resData.code === 200) {
dataSource.value = flattenTree(resData.data);
treeDataList.value = resData.data;
}
};
$api.createRequestWithCache('/app/common/jobTitle/treeselect', {}, 'GET', false, LoadCache).then(LoadCache);
}
function flattenTree(treeData, parentPath = '') {
let result = [];
treeData.forEach((node) => {
const currentName = node.lable || node.label;
const fullPath = parentPath ? `${parentPath}-${currentName}` : currentName;
const children = node.children || node.chidren;
if (children && children.length > 0) {
result = result.concat(flattenTree(children, fullPath));
} else {
result.push({
id: node.id,
lable: fullPath,
currentName,
});
}
});
return result;
}
</script>
<style lang="stylus" scoped>
.list-search{
height: 76rpx;
background: #FFFFFF;
border-radius: 8rpx;
border: 1px solid #ECECEC;
margin-bottom: 24rpx;
display: flex;
align-items: center;
padding: 0 24rpx;
position: relative;
.search-input{
flex: 1;
padding: 0 20rpx;
font-size: 28rpx;
color: #6C7282;
border: none;
outline: none;
background: transparent;
}
.search-container{
position: absolute;
top: 100%;
left: 0;
right: 0;
background: #FFFFFF;
border: 2rpx solid #ECECEC;
border-top: 0;
z-index: 1;
max-height: 30vh;
overflow: hidden;
.list-item{
height: 80rpx
padding: 0rpx 24rpx;
display: flex;
align-items: center;
justify-items: flex-start;
border-top: 2rpx dashed #e3e3e3;
}
.list-item:hover{
background: #e5e5e5
}
}
}
.btn {
display: flex;
justify-content: space-between;
align-items: center;
width: 60rpx;
height: 60rpx;
image {
height: 100%;
width: 100%;
}
}
.main{
padding: 54rpx 28rpx 28rpx 28rpx
.content-list{
.list-row{
background: #FFFFFF;
border-radius: 12rpx 12rpx 12rpx 12rpx;
border: 2rpx solid #DCDCDC;
padding: 30rpx 28rpx
display: flex;
align-items: center
justify-content: space-between
margin-bottom: 28rpx;
.row-image{
width: 36rpx;
height: 36rpx;
}
}
.list-row-add{
background: #FFFFFF;
color: #256BFA
font-size: 28rpx
font-weight: 500
border-radius: 12rpx 12rpx 12rpx 12rpx;
border: 2rpx dashed #256BFA;
padding: 30rpx 28rpx
text-align: center
}
}
}
.content-title
display: flex
justify-content: space-between;
align-items: center
margin-bottom: 50rpx
.title-lf
font-size: 44rpx;
color: #000000;
font-weight: 600;
.lf-text
font-weight: 400;
font-size: 28rpx;
color: #6C7282;
.title-ri
font-size: 36rpx;
color: #000000;
font-weight: 600;
</style>