639 lines
14 KiB
Vue
639 lines
14 KiB
Vue
<template>
|
||
<view class="job-dialog">
|
||
<view class="header-title">
|
||
<image :src="`${imgBaseUrl}/jobfair/xb.png`" mode=""></image>
|
||
<text>招聘会报名</text>
|
||
</view>
|
||
<view class="dialog-content">
|
||
<view class="detail-item" v-if="type == 2">
|
||
<view class="gw-label">选择展区展位:</view>
|
||
<!-- 展位状态说明 -->
|
||
<view class="status-description">
|
||
<view class="status-title">
|
||
<text>展位状态说明:</text>
|
||
</view>
|
||
<view class="status-item">
|
||
<view class="status-color available"></view>
|
||
<text class="status-text">未被占用</text>
|
||
</view>
|
||
<view class="status-item">
|
||
<view class="status-color occupied"></view>
|
||
<text class="status-text">已被占用</text>
|
||
</view>
|
||
<view class="status-item">
|
||
<view class="status-color pending"></view>
|
||
<text class="status-text">待审核占用</text>
|
||
</view>
|
||
<view class="status-item">
|
||
<view class="status-color selected"></view>
|
||
<text class="status-text">当前选中</text>
|
||
</view>
|
||
</view>
|
||
<view class="gw-value">
|
||
<view class="cd-detail" v-for="(item, index) in areaAndBoothList" :key="index">
|
||
<view class="cd-name">{{ item.jobFairAreaName }}</view>
|
||
<view class="cd-con">
|
||
<view class="cd-con-item" :class="getBoothStatusClass(booth)"
|
||
v-for="(booth, boothIndex) in item.boothList" :key="boothIndex"
|
||
@click="selectBooth(booth, item.jobFairAreaId)">
|
||
<text>{{ booth.jobFairBoothName }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="detail-item">
|
||
<view class="gw-label">请选择招聘岗位:</view>
|
||
<view class="gw-value">
|
||
<view class="checkbox-group">
|
||
<view class="checkbox-item job-item" v-for="(item, index) in jobList" :key="index"
|
||
:class="{ 'checked': checkList.includes(item) }" @click="toggleJobSelection(item)">
|
||
<view class="item-checkbox">
|
||
<view class="checkbox-icon" :class="{ 'checked': checkList.includes(item) }">
|
||
<text v-if="checkList.includes(item)">✓</text>
|
||
</view>
|
||
<view class="job-info">
|
||
<view class="job-name">{{ item.jobTitle }}</view>
|
||
<view class="salary">{{ item.minSalary }} - {{ item.maxSalary }}元/月</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="detail-item">
|
||
<view class="gw-label">请上传招聘海报:</view>
|
||
<view class="gw-value">
|
||
<view v-if="imageUrl">
|
||
<image v-if="imageUrl" :src="publicUrl + '/file/file/minio' + imageUrl" class="avatar"
|
||
mode="aspectFit" />
|
||
<button type="warn" class="del-icon" @click="imageUrl = ''" size="mini">删除</button>
|
||
</view>
|
||
<view v-else>
|
||
<button @click="chooseImage" class="avatar-uploader transparent-btn" type="default">
|
||
<view class="avatar-uploader-icon">+</view>
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="btn-box">
|
||
<button style="background: #409EFF;color: #fff;" @click="submitForm">提交</button>
|
||
<button type="default" @click="closeDialog">取消</button>
|
||
</view>
|
||
</view>
|
||
|
||
</template>
|
||
|
||
<script setup>
|
||
import config from "@/config.js"
|
||
import {
|
||
ref,
|
||
reactive,
|
||
onMounted,
|
||
nextTick,
|
||
watch,
|
||
inject
|
||
} from 'vue';
|
||
|
||
const emit = defineEmits(['closePopup']);
|
||
import {
|
||
createRequest
|
||
} from '@/utils/request.js';
|
||
const {
|
||
$api
|
||
} = inject('globalFunction');
|
||
|
||
// 定义props
|
||
const props = defineProps({
|
||
// 招聘会类型1线上 2线下
|
||
signType: {
|
||
type: Number,
|
||
default: 1
|
||
},
|
||
// 报名角色 ent企业 person个人
|
||
signRole: {
|
||
type: String,
|
||
default: 'ent'
|
||
},
|
||
// 招聘会id
|
||
jobFairId: {
|
||
type: String,
|
||
default: ''
|
||
}
|
||
});
|
||
|
||
// 监听props变化
|
||
watch(() => props.signType, (newVal) => {
|
||
type.value = newVal;
|
||
});
|
||
|
||
// 响应式数据
|
||
const checkList = ref([]);
|
||
const imageUrl = ref('');
|
||
const type = ref('');
|
||
const id = ref('');
|
||
const jobList = ref([]);
|
||
const userId = ref('');
|
||
const areaAndBoothList = ref([]);
|
||
const jobFairAreaId = ref(null);
|
||
const jobFairBoothId = ref(null);
|
||
const avatarUploader = ref(null);
|
||
|
||
// 配置
|
||
const publicUrl = config.LCBaseUrl;
|
||
const imgBaseUrl = config.imgBaseUrl
|
||
const uploadUrl = config.LCBaseUrl + "/file/file/upload";
|
||
|
||
// 方法
|
||
const selectBooth = (booth, jobFairAreaIdVal) => {
|
||
if (booth.status == 0) {
|
||
jobFairBoothId.value = booth.jobFairBoothId;
|
||
jobFairAreaId.value = jobFairAreaIdVal;
|
||
}
|
||
};
|
||
|
||
const submitForm = async () => {
|
||
if (type.value == "2") {
|
||
if (!jobFairBoothId.value || !jobFairAreaId.value) {
|
||
uni.showToast({
|
||
title: '请选择展区展位',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
}
|
||
if (checkList.value.length === 0) {
|
||
uni.showToast({
|
||
title: '请选择招聘岗位',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
if (!imageUrl.value) {
|
||
uni.showToast({
|
||
title: '请上传招聘海报',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
|
||
$api.myRequest("/system/user/login/user/info", {}, "GET", 10100, {
|
||
Authorization: `Bearer ${uni.getStorageSync("Padmin-Token")}`
|
||
}).then((userInfo) => {
|
||
let data = {}
|
||
if (type.value == "2") {
|
||
data = {
|
||
jobFairId: id.value,
|
||
enterpriseId: userInfo.info.userId,
|
||
jobInfoList: checkList.value,
|
||
poster: imageUrl.value,
|
||
jobFairAreaId: jobFairAreaId.value,
|
||
jobFairBoothId: jobFairBoothId.value,
|
||
code: userInfo.info.entCreditCode
|
||
};
|
||
} else {
|
||
data = {
|
||
jobFairId: id.value,
|
||
enterpriseId: userInfo.info.userId,
|
||
jobInfoList: checkList.value,
|
||
poster: imageUrl.value,
|
||
code: userInfo.info.entCreditCode
|
||
};
|
||
}
|
||
$api.myRequest("/jobfair/public/job-fair-sign-up-enterprise/sign-up", data, "post", 9100, {
|
||
Authorization: `Bearer ${uni.getStorageSync("Padmin-Token")}`
|
||
}).then((res) => {
|
||
if (res.code === 200) {
|
||
uni.showToast({
|
||
title: '报名成功',
|
||
icon: 'success'
|
||
});
|
||
closeDialog();
|
||
} else {
|
||
uni.showToast({
|
||
title: res.msg || '报名失败',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
});
|
||
})
|
||
};
|
||
|
||
const closeDialog = () => {
|
||
checkList.value = [];
|
||
imageUrl.value = '';
|
||
jobFairBoothId.value = null;
|
||
jobFairAreaId.value = null;
|
||
emit('closePopup')
|
||
};
|
||
|
||
const handleAvatarSuccess = (response) => {
|
||
imageUrl.value = response.data.url;
|
||
uni.showToast({
|
||
title: '海报上传成功',
|
||
icon: 'success'
|
||
});
|
||
};
|
||
|
||
const showDialog = (dialogType, dialogId) => {
|
||
type.value = dialogType;
|
||
id.value = dialogId;
|
||
nextTick(() => {
|
||
getJobList();
|
||
if (type.value === "2") {
|
||
getAreaAndBoothInfo();
|
||
}
|
||
});
|
||
};
|
||
|
||
// 展区展位列表
|
||
const getAreaAndBoothInfo = () => {
|
||
const data = {
|
||
jobFairId: props.jobFairId,
|
||
}
|
||
$api.myRequest("/jobfair/public/jobfair/area-and-booth-info-by-job-fair-id", data, "GET", 9100, {
|
||
Authorization: `Bearer ${uni.getStorageSync("Padmin-Token")}`
|
||
}).then((resData) => {
|
||
areaAndBoothList.value = resData.data || [];
|
||
});
|
||
};
|
||
|
||
// 岗位列表
|
||
const getJobList = () => {
|
||
$api.myRequest("/system/user/login/user/info", {}, "GET", 10100, {
|
||
Authorization: `Bearer ${uni.getStorageSync("Padmin-Token")}`
|
||
}).then((userInfo) => {
|
||
const data = {
|
||
jobFairId: id.value,
|
||
enterpriseId: userInfo.info.userId,
|
||
pageNum: 1,
|
||
pageSize: 1000,
|
||
code: userInfo.info.entCreditCode
|
||
}
|
||
$api.myRequest("/jobfair/public/job-info/list", data, "GET", 9100, {
|
||
Authorization: `Bearer ${uni.getStorageSync("Padmin-Token")}`
|
||
}).then((resData) => {
|
||
jobList.value = resData.data.list || [];
|
||
});
|
||
});
|
||
};
|
||
|
||
const getBoothStatusClass = (booth) => {
|
||
const s = booth.status || 0;
|
||
if (s == 1) return "cd-con-item-checked";
|
||
if (s == 2) return "cd-con-item-review";
|
||
if (jobFairBoothId.value && jobFairBoothId.value == booth.jobFairBoothId)
|
||
return "cd-con-item-mychecked";
|
||
return "";
|
||
};
|
||
|
||
// 选择图片
|
||
const chooseImage = () => {
|
||
uni.chooseImage({
|
||
count: 1,
|
||
sizeType: ['original', 'compressed'],
|
||
sourceType: ['album', 'camera'],
|
||
success: (res) => {
|
||
const tempFilePath = res.tempFilePaths[0];
|
||
uploadImage(tempFilePath);
|
||
}
|
||
});
|
||
};
|
||
|
||
// 上传图片
|
||
const uploadImage = (tempFilePath) => {
|
||
uni.uploadFile({
|
||
url: uploadUrl,
|
||
filePath: tempFilePath,
|
||
name: 'file',
|
||
success: (uploadFileRes) => {
|
||
try {
|
||
const response = JSON.parse(uploadFileRes.data);
|
||
handleAvatarSuccess(response);
|
||
} catch (e) {
|
||
uni.showToast({
|
||
title: '上传失败,请重试',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
console.error('上传失败:', err);
|
||
uni.showToast({
|
||
title: '上传失败,请重试',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
});
|
||
};
|
||
|
||
// 切换岗位选择
|
||
const toggleJobSelection = (item) => {
|
||
const index = checkList.value.indexOf(item);
|
||
if (index > -1) {
|
||
checkList.value.splice(index, 1);
|
||
} else {
|
||
checkList.value.push(item);
|
||
}
|
||
};
|
||
|
||
// 暴露方法给父组件
|
||
defineExpose({
|
||
showDialog
|
||
});
|
||
|
||
onMounted(() => {
|
||
setTimeout(() => {
|
||
type.value = props.signType;
|
||
if (props.jobFairId) {
|
||
id.value = props.jobFairId;
|
||
getJobList();
|
||
if (props.signType == 2) {
|
||
getAreaAndBoothInfo();
|
||
}
|
||
}
|
||
}, 100);
|
||
});
|
||
|
||
// 监听jobFairId变化
|
||
watch(() => props.jobFairId, (newVal) => {
|
||
if (newVal) {
|
||
id.value = newVal;
|
||
getJobList();
|
||
if (type.value === 2) {
|
||
getAreaAndBoothInfo();
|
||
}
|
||
}
|
||
});
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.del-icon {
|
||
margin-left: 30rpx;
|
||
}
|
||
|
||
.btn-box {
|
||
width: 100%;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
margin-top: 30rpx;
|
||
}
|
||
|
||
.btn-box button {
|
||
padding: 0 80rpx;
|
||
height: 80rpx;
|
||
line-height: 80rpx;
|
||
}
|
||
|
||
.avatar-uploader {
|
||
border: 2rpx solid #0983ff;
|
||
border-radius: 12rpx;
|
||
cursor: pointer;
|
||
position: relative;
|
||
overflow: hidden;
|
||
width: 400rpx;
|
||
height: 200rpx;
|
||
}
|
||
|
||
.avatar-uploader-icon {
|
||
font-size: 56rpx;
|
||
color: #007AFF;
|
||
line-height: 200rpx;
|
||
text-align: center;
|
||
}
|
||
|
||
.job-dialog {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.dialog-content {
|
||
padding: 0 20rpx;
|
||
height: calc(100% - 17vh);
|
||
overflow-y: auto;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.checkbox-group {
|
||
width: 100%;
|
||
}
|
||
|
||
.checkbox-item {
|
||
display: flex;
|
||
align-items: center;
|
||
border-bottom: 2rpx solid #b5d3ff;
|
||
padding: 30rpx 0;
|
||
}
|
||
|
||
.job-item {
|
||
width: 97%;
|
||
}
|
||
|
||
.checkbox-icon {
|
||
width: 40rpx;
|
||
height: 40rpx;
|
||
border: 2rpx solid #ddd;
|
||
border-radius: 8rpx;
|
||
margin-right: 20rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.checkbox-icon.checked {
|
||
background-color: #409eff;
|
||
border-color: #409eff;
|
||
color: white;
|
||
}
|
||
|
||
.job-info {
|
||
flex: 1;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
|
||
.detail-item {
|
||
margin-bottom: 40rpx;
|
||
}
|
||
|
||
.detail-item .gw-label {
|
||
font-size: 32rpx;
|
||
color: #333333;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
|
||
.detail-item .gw-value {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.detail-item .gw-value .cd-detail {
|
||
width: 100%;
|
||
background: #fff;
|
||
border-radius: 20rpx;
|
||
margin-bottom: 28rpx;
|
||
margin-top: 28rpx;
|
||
}
|
||
|
||
.detail-item .gw-value .cd-detail .cd-name {
|
||
background: #d3e8ff;
|
||
color: #0076d9;
|
||
font-size: 40rpx;
|
||
height: 80rpx;
|
||
line-height: 80rpx;
|
||
padding: 0 40rpx;
|
||
border-radius: 16rpx;
|
||
overflow: hidden;
|
||
position: relative;
|
||
}
|
||
|
||
.detail-item .gw-value .cd-detail .cd-name::after {
|
||
content: "";
|
||
position: absolute;
|
||
left: 0;
|
||
top: 0;
|
||
width: 10rpx;
|
||
height: 100%;
|
||
background: #349cfc;
|
||
}
|
||
|
||
.detail-item .gw-value .cd-detail .cd-con {
|
||
display: flex;
|
||
align-items: center;
|
||
flex-wrap: wrap;
|
||
padding: 30rpx 40rpx;
|
||
gap: 20rpx;
|
||
}
|
||
|
||
.detail-item .gw-value .cd-detail .cd-con .cd-con-item {
|
||
width: 80rpx;
|
||
height: 80rpx;
|
||
background: #67CFA7;
|
||
line-height: 80rpx;
|
||
text-align: center;
|
||
color: #fff;
|
||
border: 2rpx solid #ddd;
|
||
border-radius: 20rpx;
|
||
cursor: pointer;
|
||
font-weight: 600;
|
||
font-size: 32rpx;
|
||
}
|
||
|
||
.detail-item .gw-value .cd-detail .cd-con .cd-con-item-review {
|
||
background-color: #F8BB92;
|
||
}
|
||
|
||
.detail-item .gw-value .cd-detail .cd-con .cd-con-item-checked {
|
||
background: #F6A1A1;
|
||
}
|
||
|
||
.detail-item .gw-value .cd-detail .cd-con .cd-con-item-mychecked {
|
||
background: #79BEFE;
|
||
}
|
||
|
||
.item-checkbox {
|
||
width: 100%;
|
||
padding: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.job-name {
|
||
font-size: 32rpx;
|
||
color: #409eff;
|
||
}
|
||
|
||
.salary {
|
||
font-size: 32rpx;
|
||
color: #ff6e27;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.header-title {
|
||
font-size: 38rpx;
|
||
font-weight: 600;
|
||
color: #303133;
|
||
padding: 20rpx;
|
||
padding-bottom: 40rpx;
|
||
background: #fff;
|
||
display: flex;
|
||
align-items: center;
|
||
position: sticky;
|
||
top: 0;
|
||
}
|
||
|
||
.header-title image {
|
||
width: 14rpx;
|
||
height: 33rpx;
|
||
margin-right: 14rpx;
|
||
}
|
||
|
||
.avatar {
|
||
width: 400rpx;
|
||
height: 200rpx;
|
||
border-radius: 12rpx;
|
||
}
|
||
|
||
/* 展位状态说明样式 */
|
||
.status-description {
|
||
margin-top: 30rpx;
|
||
padding: 20rpx;
|
||
background-color: #f5f7fa;
|
||
border-radius: 8rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.status-title {
|
||
font-weight: bold;
|
||
margin-bottom: 16rpx;
|
||
width: 100%;
|
||
}
|
||
|
||
.status-item {
|
||
width: 43%;
|
||
display: flex;
|
||
align-items: center;
|
||
margin-right: 30rpx;
|
||
margin-bottom: 10rpx;
|
||
}
|
||
|
||
.status-color {
|
||
width: 40rpx;
|
||
height: 40rpx;
|
||
margin-right: 16rpx;
|
||
}
|
||
|
||
.status-color.available {
|
||
background-color: #67CFA7;
|
||
border: 2rpx solid #ddd;
|
||
}
|
||
|
||
.status-color.occupied {
|
||
background-color: #F6A1A1;
|
||
}
|
||
|
||
.status-color.pending {
|
||
background-color: #F8BB92;
|
||
}
|
||
|
||
.status-color.selected {
|
||
background-color: #79BEFE;
|
||
}
|
||
|
||
.status-text {
|
||
margin-right: 16rpx;
|
||
}
|
||
|
||
/* 透明按钮样式 */
|
||
.transparent-btn {
|
||
background: transparent !important;
|
||
border: 2rpx dashed #0983ff !important;
|
||
}
|
||
</style> |