1

parent 5fdcac5e
...@@ -39,7 +39,7 @@ const props = defineProps({ ...@@ -39,7 +39,7 @@ const props = defineProps({
default: () => [] default: () => []
} }
}); });
const emit = defineEmits(["update:modelValue"]); const emit = defineEmits(["update:modelValue", "update"]);
// 激活类名 // 激活类名
const isActive = e => { const isActive = e => {
if (props.multiple) { if (props.multiple) {
...@@ -61,6 +61,8 @@ const onClickItem = e => { ...@@ -61,6 +61,8 @@ const onClickItem = e => {
} else { } else {
emit("update:modelValue", value); emit("update:modelValue", value);
} }
emit("update");
}; };
</script> </script>
......
...@@ -15,9 +15,204 @@ ...@@ -15,9 +15,204 @@
</view> </view>
</wd-checkbox-group> </wd-checkbox-group>
</view> </view>
<view v-else>2</view> <view v-else>
<view class="from-2" v-for="(item, index) in jobForm" :key="index">
<view class="title">新增岗位信息{{ index + 1 }}</view>
<selectbox
@update="initSalaryColumns"
:options="EnumWorkMode"
label-key="text"
value-key="code"
v-model="item.workMode"
></selectbox>
<!-- 职位类型 -->
<form-row>
<form-item title="职位类型">
<wd-col-picker
v-model="positionTypeValue"
:columns="columns"
:column-change="columnChange"
@confirm="params => handleConfirm(params, item)"
label-key="name"
value-key="id"
use-default-slot
>
<view :class="`inner flex-between ${item.jobTypeName ? '' : 'placeholder'}`">
{{ item.jobTypeName || "请选择职位类型" }}
</view>
</wd-col-picker>
</form-item>
</form-row>
<!-- 职位标题 -->
<form-row>
<form-item title="职位标题" icon="arrow">
<input type="text" v-model="item.name" placeholder="输入职位标题如“财务总监”" />
</form-item>
</form-row>
<!-- 职位描述 -->
<form-row>
<form-item title="职位描述" :border="false" icon="">
<textarea v-model="item.positionDesc" placeholder="请输入你的职位描述"></textarea>
</form-item>
</form-row>
<view class="transverse">
<form-item title="职位薪资" icon="">
<view
v-if="item.settlementType == 4"
:class="`inner flex-between ${item.salaryText ? '' : 'placeholder'}`"
@click="onOpen(item, index)"
>
{{ item.salaryText || "请选择月薪范围" }}
<!-- <view class="arrow"></view> -->
<checkbox
class="checkbox"
:value="item.negotiableSalary"
@click="onChecked(item)"
:checked="item.negotiableSalary == 1"
>面议</checkbox
>
</view>
<view
v-else
:class="`inner flex-between ${item.salaryText ? '' : 'placeholder'}`"
@click="onOpen(item, index)"
>
{{ item.salaryText || "请选择时薪范围" }}
<!-- <view class="arrow"></view> -->
<checkbox
class="checkbox"
:value="item.negotiableSalary"
@click="onChecked(item)"
:checked="item.negotiableSalary == 1"
>面议</checkbox
>
</view>
</form-item>
<form-item title="工作地址" icon="">
<wd-col-picker
v-model="cityValue"
:columns="cityOpstion"
value-key="code"
label-key="name"
:column-change="columnChangeCity"
@confirm="params => handleConfirmCity(params, item)"
use-default-slot
>
<p :class="{ placeholder: !item.cityText }" class="text-single">
{{ item.cityText || "请选择公司所在地" }}
</p>
</wd-col-picker>
</form-item>
</view>
<form-item title="是否提供食宿" icon="">
<wd-radio-group v-model="item.accommodation" inline shape="dot">
<wd-radio v-for="(v, n) in radioOpstion" :value="v.code" :key="n">{{ v.text }}</wd-radio>
</wd-radio-group>
</form-item>
<form-item title="福利待遇" icon="">
<view class="welfare">
<view
v-for="(el, nl) in item.myBenefits"
:class="`t ${el.active ? 'active' : ''}`"
@tap="onChangeBenefits(el, item)"
:key="nl"
>{{ el.text }}</view
>
</view>
</form-item>
<form-item title="身份要求" icon="">
<wd-picker
:columns="identityPostion"
value-key="code"
label-key="text"
v-model="item.identityRequirement"
@confirm="params => handleConfirmIdentity(params, item)"
use-default-slot
>
<view :class="`inner flex-between ${item.identityText ? '' : 'placeholder'}`">
<view class="flex-align-center">
{{ item.identityText || "请选择身份要求" }}
</view>
</view>
</wd-picker>
</form-item>
<view class="transverse">
<form-item title="学历要求" icon="">
<wd-picker
:columns="educationPostion"
value-key="code"
label-key="text"
v-model="item.educationRequirement"
@confirm="params => handleConfirmEducation(params, item)"
use-default-slot
>
<view :class="`inner flex-between ${item.educationText ? '' : 'placeholder'}`">
<view class="flex-align-center">
{{ item.educationText || "请选择学历" }}
</view>
</view>
</wd-picker> </form-item
><form-item title="年龄要求" icon="">
<wd-col-picker
v-model="ageValue"
:columns="ageColumns"
:column-change="ageColumnChange"
@confirm="params => ageHandleConfirm(params, item)"
use-default-slot
>
<view :class="`inner flex-between ${item.ageText ? '' : 'placeholder'}`">
{{ item.ageText || "请选择年龄范围" }}
</view>
</wd-col-picker>
</form-item>
</view>
<form-row :fill="false">
<form-item title="职业资格/技能等级证书" icon="edit">
<input type="text" v-model="certificateInputValue" placeholder="请填写职业资格" />
</form-item>
<form-item title="">
<wd-picker
:columns="levelOptions"
value-key="text"
label-key="text"
v-model="certificateSelectValue"
use-default-slot
>
<view :class="`inner flex-between ${certificateSelectValue ? '' : 'placeholder'}`">
<view class="flex-align-center" bind:tap="onShowIdentitySelect">
{{ certificateSelectValue || "请选择职业资格等级" }}
</view>
</view>
</wd-picker>
</form-item>
</form-row>
</view>
</view>
</wd-tab> </wd-tab>
</block> </block>
<wd-popup
v-model="salaryShow"
position="bottom"
custom-style="height:40%;border-radius: 20rpx;z-index:999;"
@close="handleClose"
>
<view class="title-box"
><view></view>
<view class="title">薪资选择</view>
<wd-icon @click="handleClose" name="close" size="30rpx"></wd-icon>
</view>
<wd-picker-view
@change="params => salaryHandleConfirm(params, item)"
use-default-slot
:columns="salaryColumns"
v-if="salaryShow"
v-model="salaryValue"
></wd-picker-view>
<view style="display: flex; justify-content: center; width: 100%"
><wd-button style="width: 80%" @click="handleClose" block :round="false">确定</wd-button></view
>
</wd-popup>
</wd-tabs> </wd-tabs>
<wd-tabbar <wd-tabbar
v-if="tab == 0" v-if="tab == 0"
...@@ -46,20 +241,149 @@ ...@@ -46,20 +241,149 @@
<script setup> <script setup>
import { ref } from "vue"; import { ref } from "vue";
import { positionList } from "@/api/user"; import { positionList } from "@/api/user";
import Selectbox from "@/components/form/selectbox.vue";
import FormItem from "@/components/form/form-item.vue";
import FormRow from "@/components/form/form-row.vue";
import { dictJobTypeApi, getTreeListApi } from "@/api/common";
import town from "@/assets/town.json";
import { getEumData } from "@/utils/utils"; import { getEumData } from "@/utils/utils";
const tab = ref(0); const tab = ref(1);
const value = ref([]); const value = ref([]);
const gwList = ref([]); const gwList = ref([]);
const columns = ref([]);
/* 获取省市区 */
const cityOpstion = ref([]);
const cityValue = ref([]);
const cityText = ref("");
let citySelectedItems = [];
const salaryShow = ref(false);
const salaryValue = ref([]);
const identityPostion = ref([]);
const educationPostion = ref([]);
/* 福利待遇 */
/* 薪资选择 */
let salaryText = ref("");
const salaryColumns = ref([]);
/* 是否提供住宿 */
const radioOpstion = ref([]);
/* 职业类型 */
const positionTypeValue = ref([]);
/* 兼职全职枚举 */
const EnumWorkMode = ref([]); const EnumWorkMode = ref([]);
/* 等级选择项 */
const levelOptions = ref(["初级", "中级", "高级", "高级以上"]);
const ageValue = ref([]);
const ageColumns = ref([]);
const jobForm = ref([
{
workMode: 1,
name: "",
jobTypeId: null,
jobTypePid: "",
jobTypeName: "",
postitDesc: "",
negotiableSalary: 0,
settlementType: 4,
minSalary: null,
maxSalary: null,
benefits: "",
identityRequirement: 1,
educationRequirement: null,
minAgeRequirement: null,
maxAgeRequirement: null,
recruitmentNumber: 1,
accommodation: 0,
provinceCode: "",
cityCode: "",
districtCode: "",
street: "",
address: "",
contactPerson: "",
contactPhone: "",
articleId: "",
positionalTitle: "",
professionalCertificates: "",
specialCertificates: "",
salaryText: "", //显示
myBenefits: [
{
text: "年底双薪",
active: false
},
{
text: "节假日福利",
active: false
},
{
text: "旅游团建",
active: false
},
{
text: "生日福利",
active: false
},
{
text: "五险一金",
active: false
},
{
text: "三险一金",
active: false
}
]
}
]);
const tabList = ref([ const tabList = ref([
{ id: 213213, name: "选择已有岗位", type: 1 }, { id: 213213, name: "选择已有岗位", type: 1 },
{ id: 1651651, name: "新增岗位", type: 2 } { id: 1651651, name: "新增岗位", type: 2 }
]); ]);
const getEnumCertificatesLevel = async () => {
levelOptions.value = await getEumData("EnumCertificatesLevel");
console.log(levelOptions.value);
};
getEnumCertificatesLevel();
const initPostion = async () => {
identityPostion.value = await getEumData("EnumIdentityRequirement");
educationPostion.value = await getEumData("EnumEducationRequirement");
};
initPostion();
function handleClose() {
if (salaryValue.value[1] < salaryValue.value[0]) {
xma.showToast({
title: "最高薪资不能小于最低薪资",
icon: "none"
});
return;
}
salaryShow.value = false;
}
const initageColumns = () => {
const temp = [
{
value: "不限",
label: "不限",
next: false
}
];
for (let i = 16; i < 81; i++) {
temp.push({
value: i,
label: i + "岁",
next: true
});
}
ageColumns.value.push(temp);
};
initageColumns();
const getEnumWorkMode = async () => { const getEnumWorkMode = async () => {
EnumWorkMode.value = await getEumData("EnumWorkMode"); EnumWorkMode.value = await getEumData("EnumWorkMode");
console.log("EnumWorkMode.value", EnumWorkMode.value);
}; };
getTreeListApi({ provinceName: "贵州省" }).then(res => {
cityOpstion.value.push(res.data[0].children);
});
getEnumWorkMode(); getEnumWorkMode();
positionList({}).then(res => { positionList({}).then(res => {
res.data = res.data.map(item => { res.data = res.data.map(item => {
...@@ -68,11 +392,272 @@ positionList({}).then(res => { ...@@ -68,11 +392,272 @@ positionList({}).then(res => {
}); });
gwList.value = res.data; gwList.value = res.data;
}); });
const getJobType = () => {
dictJobTypeApi({}).then(res => {
columns.value.push(res.data);
});
};
getJobType();
const initRadioOpstion = async () => {
radioOpstion.value = await getEumData("EnumAccommodation");
};
initRadioOpstion();
// 职业类型
const columnChange = ({ selectedItem, resolve, finish }) => {
if (selectedItem.children?.length > 0) {
resolve(selectedItem.children);
} else {
finish();
}
};
const handleConfirm = (params, item) => {
const { selectedItems, value } = params;
item.jobTypeName = selectedItems[1].name;
item.jobTypePid = selectedItems[1].id;
item.jobTypeParentId = selectedItems[0].id;
};
// 职业类型
// 地址
const columnChangeCity = ({ selectedItem, resolve, finish }) => {
if (selectedItem.children) {
resolve(selectedItem.children);
} else {
// 选择街道
if (selectedItem.children === null && town[selectedItem.code]) {
resolve(town[selectedItem.code].map((v, i) => ({ ...v, code: i })));
} else {
finish();
}
}
};
const handleConfirmCity = (params, item) => {
const { selectedItems } = params;
item.cityText = selectedItems.map(v => v.name || "").join("-");
citySelectedItems = selectedItems;
const [city, district, street] = selectedItems;
item.address = selectedItems.map(v => v.name || "").join("");
item.provinceCode = 520000;
item.cityCode = city.code;
item.districtCode = district.code;
item.street = street ? street.name : "";
};
// 地址
// 薪资-fun
const activeIndex = ref(0);
const initSalaryColumns = () => {
salaryColumns.value = [];
let index = activeIndex.value;
let multiple = 1;
// 确定 settlementType
jobForm.value[index].settlementType = jobForm.value[index].workMode === 2 ? 1 : 4;
// 设置基准值
multiple = jobForm.value[index].settlementType === 1 ? 50 : 1000;
const temp = [];
const maxSalary = jobForm.value[index].settlementType == 1 ? 1000 : 50 * multiple;
if (jobForm.value[index].settlementType == 1) {
temp.push({
value: 10,
label: "10",
next: true
});
}
// 生成序列
for (let i = 1; i * multiple <= maxSalary; i++) {
const currentValue = i * multiple;
temp.push({
value: currentValue,
label: jobForm.value[index].settlementType == 1 ? currentValue : `${currentValue / 1000}k`,
next: true
});
}
// 确保 columns.value 是一个数组
if (!Array.isArray(salaryColumns.value)) {
salaryColumns.value = [];
}
// 清空原来的数组,以确保只包含新的数据
salaryColumns.value.length = 0;
// 将 temp 复制两次,推入 columns.value
salaryColumns.value.push([...temp], [...temp]);
};
initSalaryColumns();
function onChecked(item) {
item.negotiableSalary = item.negotiableSalary == 1 ? 0 : 1;
// 如果勾选了面议
if (item.negotiableSalary == 1) {
salaryText.value = "";
item.maxSalary = 0;
item.minSalary = 0;
item.negotiableSalary = 1;
} else {
item.negotiableSalary = 0;
}
}
function onOpen(item, index) {
salaryValue.value = [];
activeIndex.value = index;
initSalaryColumns();
if (item.negotiableSalary == 1) return;
salaryShow.value = true;
}
const salaryHandleConfirm = (params, item) => {
let multiple = 1;
multiple = jobForm.value[activeIndex.value].settlementType === 1 ? 50 : 1000;
const { selectedItems, value } = params;
if (value[1] < value[0]) {
xma.showToast({
title: "最高薪资不能小于最低薪资",
icon: "none"
});
return;
}
jobForm.value[activeIndex.value].negotiableSalary = 0;
if (jobForm.value[activeIndex.value].settlementType === 1) {
jobForm.value[activeIndex.value].salaryText = value.join("~");
} else {
jobForm.value[activeIndex.value].salaryText = value.map(num => `${num / multiple}k`).join("~");
}
const [min, max] = value;
if (max) {
jobForm.value[activeIndex.value].maxSalary = max;
jobForm.value[activeIndex.value].minSalary = min;
jobForm.value[activeIndex.value].negotiableSalary = 0;
} else {
jobForm.value[activeIndex.value].maxSalary = 0;
jobForm.value[activeIndex.value].minSalary = 0;
jobForm.value[activeIndex.value].negotiableSalary = 1;
}
};
const onChangeBenefits = (el, item) => {
el.active = !el.active;
item.benefits = item.myBenefits
.filter(benefit => benefit.active) // 只保留选中的
.map(benefit => benefit.text) // 获取文本
.join(", ");
};
// 选择身份
const handleConfirmIdentity = (params, item) => {
const { selectedItems, value } = params;
item.identityText = selectedItems.text;
};
const ageColumnChange = ({ selectedItem, resolve, finish }) => {
console.log(selectedItem);
if (selectedItem.next) {
const temp = [];
for (let i = 1; i < 50; i++) {
temp.push({
value: i + selectedItem.value,
label: i + selectedItem.value + "岁",
next: false
});
resolve(temp);
}
} else {
finish();
}
};
const ageHandleConfirm = (params, item) => {
const { selectedItems, value } = params;
item.ageText = value.join("~");
const [min, max] = value;
if (max) {
// 没有选择不限
item.maxAgeRequirement = max;
item.minAgeRequirement = min;
} else {
item.maxAgeRequirement = 0;
item.minAgeRequirement = 0;
}
};
// 选择学历
const handleConfirmEducation = (params, item) => {
const { selectedItems, value } = params;
item.educationText = selectedItems.text;
};
function addPost() {
jobForm.value.push({
workMode: 1,
name: "",
jobTypeId: null,
jobTypePid: "",
jobTypeName: "",
postitDesc: "",
negotiableSalary: 0,
settlementType: 4,
minSalary: null,
maxSalary: null,
benefits: "",
identityRequirement: 1,
educationRequirement: null,
minAgeRequirement: null,
maxAgeRequirement: null,
recruitmentNumber: 1,
accommodation: 0,
provinceCode: "",
cityCode: "",
districtCode: "",
street: "",
address: "",
contactPerson: "",
contactPhone: "",
articleId: "",
positionalTitle: "",
professionalCertificates: "",
specialCertificates: "",
salaryText: "", //显示
myBenefits: [
{
text: "年底双薪",
active: false
},
{
text: "节假日福利",
active: false
},
{
text: "旅游团建",
active: false
},
{
text: "生日福利",
active: false
},
{
text: "五险一金",
active: false
},
{
text: "三险一金",
active: false
}
]
});
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
page {
}
.page { .page {
width: 100%; width: 100%;
.title-box {
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-between;
padding: 32rpx;
}
.from-1 { .from-1 {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
...@@ -99,6 +684,70 @@ positionList({}).then(res => { ...@@ -99,6 +684,70 @@ positionList({}).then(res => {
} }
} }
} }
.from-2 {
width: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
padding: 32rpx;
margin-top: 32rpx;
.title {
font-size: 48rpx;
font-weight: 500;
color: #1b2026;
margin-bottom: 32rpx;
}
textarea {
box-sizing: border-box;
width: 100%;
padding: 32rpx;
background: #f2f5fb;
border-radius: 8rpx;
}
.placeholder {
width: 50%;
text-wrap: nowrap;
}
.checkbox {
white-space: nowrap;
flex-shrink: 0;
}
.transverse {
display: flex;
align-items: baseline;
justify-content: space-between;
:deep(.uni-checkbox-input) {
border-radius: 50% !important;
margin-left: 20rpx;
flex-shrink: 0;
}
}
.welfare {
display: flex;
flex-wrap: wrap;
gap: 24rpx;
view {
gap: 12rpx;
padding: 12rpx 20rpx;
font-size: 24rpx;
line-height: 36rpx;
color: #1f86ff;
background: rgb(31 134 255 / 10%);
border-radius: 8rpx;
&.active {
color: #ffffff;
background-color: #1f86ff;
}
}
}
.text-single {
width: 100%;
margin-left: 20rpx;
white-space: wrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.footer { .footer {
display: flex; display: flex;
align-items: center; align-items: center;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment