123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557 |
- <template>
- <ion-page class="list-page">
- <ion-header class="header-theme2">
- <ion-toolbar>
- <ion-buttons slot="start">
- <ion-icon :icon="arrowBackOutline" @click="back"></ion-icon>
- </ion-buttons>
- <ion-title>
- 岗位信息收集
- </ion-title>
- </ion-toolbar>
- </ion-header>
- <ion-content>
- <form autocomplete="off">
- <div class="bw-vue-form">
- <ion-list>
- <div class="form-title">基本信息</div>
- <div class="form-input">
- <ion-label>岗位名称<span class="danger">*</span></ion-label>
- <div>
- <ion-input placeholder="请选择岗位" label-placement="stacked" style="float: left;width:78%;"
- v-model="dataModel.professionName" class="custom">
- </ion-input>
- <ion-item style="width:22%;float: right;padding:0px;margin: 0px;">
- <post-selection :ProfessionID="dataModel.professionID" @SetProfessionID="onSetProfessionID"></post-selection>
- </ion-item>
- </div>
- <!-- <ion-note v-show="isCommit&&v$.dataModel.professionID.$error" class="danger" >请选择岗位</ion-note>-->
- </div>
- <div style="width: 100%;overflow: hidden;"></div>
- <div class="form-input">
- <ion-label>招聘数量(人)<span class="danger">*</span></ion-label>
- <ion-input type="number" placeholder="请输入招聘数量" label-placement="stacked" :clear-input="true"
- v-model="dataModel.recruitCount" class="custom">
- </ion-input>
- <!-- <ion-note slot="error">请输入招聘数量</ion-note>-->
- </div>
- <div class="form-input">
- <ion-label>招聘日期<span class="danger">*</span></ion-label>
- <div>
- <ion-datetime-button datetime="startTime" style="float:left;"></ion-datetime-button>
- <span style="float:left;padding-top: 5px;">至</span>
- <ion-datetime-button datetime="endTime" style="float:left;"></ion-datetime-button>
- <ion-modal :keep-contents-mounted="true">
- <ion-datetime placeholder="招聘日期" id="startTime"
- v-model="dataModel.startTime" :prefer-wheel="true"
- dataformatas="YYYY-MM-DD" presentation="date" cancel-text="取消" done-text="确定"
- :show-default-buttons="true" style="text-align: left;width: 100%;">
- </ion-datetime>
- </ion-modal>
- <ion-modal :keep-contents-mounted="true">
- <ion-datetime placeholder="招聘日期" id="endTime"
- v-model="dataModel.endTime" :prefer-wheel="true"
- dataformatas="YYYY-MM-DD" presentation="date" cancel-text="取消" done-text="确定"
- :show-default-buttons="true" style="text-align: left;width: 100%;">
- </ion-datetime>
- </ion-modal>
- <!-- <ion-note slot="error">招聘开始日期与结束日期不能为空</ion-note>-->
- </div>
- </div>
- <div style="overflow: hidden;width:100%;"></div>
- <div class="form-input">
- <ion-label>招聘地点<span class="danger">*</span></ion-label>
- <ion-textarea placeholder="请输入招聘地点" :rows="3" label-placement="stacked" :clear-input="true"
- v-model="dataModel.jobPlace" class="custom" style="border-bottom: 1px solid #fff2e8;">
- </ion-textarea>
- <!-- <ion-note slot="error">请输入招聘地点</ion-note>-->
- </div>
- <div class="form-title">
- 其他信息
- <div style="float: right;">
- <ion-label style="color: red;font-size: 14px;" @click="isShow=!isShow">{{isShow?"收起":"展开"}}</ion-label>
- </div>
- </div>
- <div v-show="isShow" >
- <div class="form-select">
- <ion-label>工作性质</ion-label>
- <ion-select interface="action-sheet" placeholder="请选择工作性质" cancel-text="取消" name="workNatureID"
- id="workNatureID" v-model="dataModel.workNatureID" style="width: 100%;text-align: left;" @ionChange="onIsTrailChange">
- <ion-select-option v-for="(record,key) in workNatureList" :key="key"
- v-model:value="record.value">
- {{ record.name }}
- </ion-select-option>
- </ion-select>
- </div>
- <div class="form-input">
- <ion-label>岗位月薪(元)</ion-label>
- <div>
- <ion-input type="number" placeholder="请输入金额" label-placement="stacked" style="float:left;width:40%;"
- v-model="dataModel.minSalary" class="custom">
- </ion-input>
- <ion-label style="float:left;width:5%;padding-top: 8px;">至</ion-label>
- <ion-input placeholder="请输入金额" label-placement="stacked" style="float:left;width:40%;"
- v-model="dataModel.maxSalary" class="custom">
- </ion-input>
- </div>
- </div>
- <div style="overflow: hidden;width:100%;"></div>
- <div class="form-select">
- <ion-label>是否有试用期</ion-label>
- <ion-select interface="action-sheet" placeholder="请选择是否有试用期" cancel-text="取消"
- id="isTrail" v-model="dataModel.isTrail" style="width: 100%;text-align: left;" @ionChange="onIsTrailChange">
- <ion-select-option v-for="(record,key) in isTrailList" :key="key"
- v-model:value="record.value">
- {{ record.name }}
- </ion-select-option>
- </ion-select>
- </div>
- <div class="form-input">
- <ion-label>试用期(月)</ion-label>
- <ion-input :disabled="!dataModel.isTrail" type="number" placeholder="请输入试用期月数" label-placement="stacked"
- v-model="dataModel.trailMonths" class="custom">
- </ion-input>
- </div>
- <div class="form-input">
- <ion-label>试用期月薪(元)</ion-label>
- <div>
- <ion-input placeholder="请输入金额" label-placement="stacked" style="float:left;width:40%;"
- v-model="dataModel.trailMinSalary" class="custom">
- </ion-input>
- <ion-label style="float:left;width:5%;padding-top: 8px;">至</ion-label>
- <ion-input placeholder="请输入金额" label-placement="stacked" style="float:left;width:40%;"
- v-model="dataModel.trailMaxSalary" class="custom">
- </ion-input>
- </div>
- </div>
- <div style="overflow: hidden;width:100%;"></div>
- <div class="form-select">
- <ion-label>工作年限要求</ion-label>
- <ion-select interface="action-sheet" placeholder="请选择工作年限" cancel-text="取消"
- id="workYear" v-model="dataModel.workYear" style="width: 100%;text-align: left;">
- <ion-select-option v-for="(record,key) in workYearList" :key="key"
- v-model:value="record.value">
- {{ record.name }}
- </ion-select-option>
- </ion-select>
- </div>
- <div class="form-select">
- <ion-label>学历要求</ion-label>
- <ion-select interface="action-sheet" placeholder="请选择学历" cancel-text="取消"
- id="cultureRank" v-model="dataModel.cultureRank" style="width: 100%;text-align: left;">
- <ion-select-option v-for="(record,key) in cultureRankList" :key="key"
- v-model:value="record.value">
- {{ record.name }}
- </ion-select-option>
- </ion-select>
- </div>
- <div class="form-input">
- <ion-label>其他要求</ion-label>
- <ion-textarea placeholder="请输入其他要求" :rows="3" label-placement="stacked"
- v-model="dataModel.postDesc" class="custom" style="border-bottom: 1px solid #fff2e8;">
- </ion-textarea>
- </div>
- <div class="form-input">
- <ion-label>福利待遇</ion-label>
- <ion-textarea placeholder="请输入福利待遇" :rows="3" label-placement="stacked"
- v-model="dataModel.welfare" class="custom" style="border-bottom: 1px solid #fff2e8;">
- </ion-textarea>
- </div>
- <div class="form-input">
- <ion-label>岗位联系人</ion-label>
- <ion-input placeholder="请输入岗位联系人" label-placement="stacked"
- v-model="dataModel.contactName" class="custom">
- </ion-input>
- </div>
- <div class="form-input">
- <ion-label>岗位联系电话</ion-label>
- <ion-input placeholder="请输入岗位联系电话" label-placement="stacked"
- v-model="dataModel.contactMobile" class="custom">
- </ion-input>
- </div>
- <div class="form-input">
- <ion-label>岗位联系人邮箱</ion-label>
- <ion-input placeholder="请输入岗位联系人邮箱" label-placement="stacked"
- v-model="dataModel.contactEmail" class="custom">
- </ion-input>
- </div>
- <div class="form-select">
- <ion-label>岗位标签</ion-label>
- <ion-select interface="action-sheet" placeholder="请选择岗位标签" cancel-text="取消"
- id="tagID" v-model="dataModel.tagID" style="width: 100%;text-align: left;">
- <ion-select-option v-for="(record,key) in postTagList" :key="key"
- v-model:value="record.value">
- {{ record.name }}
- </ion-select-option>
- </ion-select>
- </div>
- </div>
- </ion-list>
- </div>
- </form>
- </ion-content>
- <ion-footer>
- <ion-toolbar>
- <ion-button style="width: 100%;" @click="onSave">提交</ion-button>
- </ion-toolbar>
- </ion-footer>
- </ion-page>
- </template>
- <script lang="ts">
- import {computed, defineComponent, reactive, ref, toRefs, watch} from "vue";
- import {chevronDownOutline, chevronUpOutline, arrowBackOutline} from 'ionicons/icons';
- import {useRoute, useRouter} from "vue-router";
- import {alertController, onIonViewDidEnter} from "@ionic/vue";
- import {useVuelidate} from "@vuelidate/core";
- import {getPostByID,savePost} from "@/api/post";
- import {required} from "@vuelidate/validators";
- import {getSysDictionaryList} from "@/api/system/dictionary";
- import dayjs from "dayjs";
- import postSelection from "@/components/postSelection.vue";
- interface StepParams{
- loginUserID: string,
- }
- export default defineComponent({
- name: 'PostEdit',
- components:{postSelection},
- setup() {
- const router = useRouter();
- const route = useRoute();
- const isShow = ref<any>(false);
- const isEdit = ref<any>(false);
- const isCommit = ref<any>(false);
- const formState = reactive({
- dataModel: {
- companyID:null,
- professionName:null,
- professionID:null,
- postName:null,
- recruitCount:null,
- startTime:dayjs().format("YYYY-MM-DD"),
- endTime:dayjs().format("YYYY-MM-DD"),
- jobPlace:null,
- minSalary:null,
- maxSalary:null,
- isTrail:null,
- trailMonths:0,
- trailMinSalary:null,
- trailMaxSalary:null,
- workYear:null,
- cultureRank:null,
- welfare:null,
- postDesc:null,
- workNatureID:null,
- contactName:null,
- contactMobile:null,
- contactEmail:null,
- tagID:null,
- bonus:null,
- loginUserID:''
- }});
- const rules = computed(() => {
- return {
- dataModel: {
- professionName: {required},
- recruitCount: {required},
- startTime: {required},
- endTime: {required},
- jobPlace:{required}
- }
- }
- });
- const v$ = useVuelidate(rules, formState);
- const isTrailList = ref([
- {value: true, name: '是'},
- {value: false, name: '否'},
- ]);
- const workYearList = ref([]);
- const cultureRankList = ref([]);
- const workNatureList = ref([]);
- const postTagList = ref([]);
- const curStepData = ref<StepParams>({
- loginUserID:""
- });
- const presentAlert = async (message: string) => {
- const alert = await alertController.create({
- header: '错误!',
- message: message,
- buttons: [
- '确定'
- ],
- });
- await alert.present();
- }
- const onSetProfessionID = (data: any)=>{
- formState.dataModel.professionID = data.value;
- formState.dataModel.professionName = data.text;
- }
- const ifInputAllValid = ()=>{
- let errorMessage = "";
- let hasMinSalary = false;
- let hasTrailMinSalary = false;
- let curMinSalary = 0;
- let curTrailMinSalary = 0;
- if(dayjs(formState.dataModel.startTime).isAfter(dayjs(formState.dataModel.endTime))){
- errorMessage +="招聘结束日期不能早于开始日期!";
- isCommit.value = false;
- }
- if (formState.dataModel.minSalary!=null) {
- hasMinSalary = true;
- curMinSalary = formState.dataModel.minSalary;
- if(formState.dataModel.minSalary<0){
- errorMessage +="岗位最低月薪不能小于0!";
- isCommit.value = false;
- }
- }
- if (formState.dataModel.trailMinSalary!=null) {
- hasTrailMinSalary = true;
- curTrailMinSalary = formState.dataModel.trailMinSalary;
- if(formState.dataModel.trailMinSalary<0){
- errorMessage +="试用期最低月薪不能小于0!";
- isCommit.value = false;
- }
- }
- if (formState.dataModel.maxSalary!=null) {
- if(formState.dataModel.maxSalary<0){
- errorMessage +="岗位最高月薪不能小于0!";
- isCommit.value = false;
- }
- if(hasMinSalary){
- if(formState.dataModel.maxSalary < curMinSalary){
- errorMessage +="岗位最高月薪不能小于岗位最低月薪!";
- isCommit.value = false;
- }
- }
- }
- if (formState.dataModel.trailMaxSalary!=null) {
- if(formState.dataModel.trailMaxSalary<0){
- errorMessage +="试用期最高月薪不能小于0!";
- isCommit.value = false;
- }
- if(hasTrailMinSalary){
- if(formState.dataModel.trailMaxSalary < curTrailMinSalary){
- errorMessage +="试用期最高月薪不能小于岗位最低月薪!";
- isCommit.value = false;
- }
- }
- }
- if (formState.dataModel.trailMonths!=null) {
- if(formState.dataModel.isTrail&&formState.dataModel.trailMonths<0){
- errorMessage +="试用月数不能小于0!";
- isCommit.value = false;
- }
- }
- const mobileReg = /^1[3|4|5|6|7|8|9]\d{9}$/;
- const landlineReg = /[0-9-()()]{7,18}/;
- if(formState.dataModel.contactMobile != null){
- if(!mobileReg.test(formState.dataModel.contactMobile)&&!landlineReg.test(formState.dataModel.contactMobile)){
- errorMessage += "输入的联系电话有误!";
- isCommit.value = false;
- }
- }
- const emailReg = /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/;
- if(formState.dataModel.contactEmail!=""&&formState.dataModel.contactEmail!=null){
- if(!emailReg.test(formState.dataModel.contactEmail)){
- errorMessage += "输入的邮箱有误!";
- isCommit.value = false;
- }
- }
- if(!isCommit.value){presentAlert(errorMessage);}
- }
- const onSave = async function (){
- isCommit.value = true;
- ifInputAllValid();
- const isFormCorrect = await v$.value.$validate();
- console.log("当前岗位信息",formState.dataModel);
- if (!isFormCorrect) {
- await presentAlert('请输入完整信息!');
- return null;
- }
- formState.dataModel.loginUserID = curStepData.value.loginUserID;
- savePost(formState.dataModel).then(result=>{
- if(result){
- router.push({path: "./postList", query: {reload:1,id:formState.dataModel.companyID,status: 3}});
- }
- })
- }
- const back = () => {
- router.push({path: "./postList", query: {reload:1,id:formState.dataModel.companyID,status: 2}});
- }
- const getWorkYearList = async function(){
- const data :any = await getSysDictionaryList("WorkYearType");
- workYearList.value = data;
- console.log(workYearList.value);
- }
- const getCultureRankList = async function(){
- const data:any = await getSysDictionaryList("CultureLevel");
- cultureRankList.value = data;
- console.log(cultureRankList.value);
- }
- const getWorkNationList = async function(){
- const data:any = await getSysDictionaryList("WorkNature");
- workNatureList.value = data;
- }
- const getPostTagList = async function(){
- const data:any = await getSysDictionaryList("PostTag");
- postTagList.value = data;
- }
- const loadData = async (postID: any,companyID:any,loginUserID:any) => {
- isCommit.value =false;
- curStepData.value.loginUserID = loginUserID;
- await getWorkYearList();
- await getCultureRankList();
- await getWorkNationList();
- await getPostTagList();
- const reqData = await getPostByID(postID);
- formState.dataModel = reqData;
- formState.dataModel.companyID = companyID;
- formState.dataModel.welfare = formState.dataModel.bonus;
- console.log("初始化岗位信息",formState.dataModel);
- };
- const reload = (postID: any,companyID:any,loginUserID:any) => {
- formState.dataModel.recruitCount = null;
- loadData(postID,companyID,loginUserID);
- }
- onIonViewDidEnter(() => {
- if (route.query.reload)
- reload(route.query.id,route.query.companyID,route.query.loginUserID);
- });
- return {
- ...toRefs(formState),
- chevronDownOutline,
- chevronUpOutline,
- arrowBackOutline,
- route,
- router,
- isShow,
- isEdit,
- isTrailList,
- workYearList,
- cultureRankList,
- workNatureList,
- postTagList,
- v$,
- onSetProfessionID,
- onSave,
- back,
- }
- }
- });
- </script>
- <style lang="less">
- .custom{
- --placeholder-color: gray;
- --placeholder-opacity: 0.5;
- }
- .title-item{
- margin-left: 15px;
- color:#1c3d70 !important;
- font-size: 14px !important;
- font-weight: bold;
- }
- ion-item {
- --border-width: 0;
- --border-style: none;
- ion-label, input, ion-select, ion-datetime {
- font-size: 14px !important;
- }
- }
- .stepFlex {
- margin: 0;
- display: flex;
- width: 100%;
- .stepFlex-item {
- position: relative;
- flex: 1;
- text-align: center;
- margin-top: -10px;
- .stepFlex-item-label {
- padding-top: 60px;
- font-size: 14px;
- .stepFlex-item-label-title {
- margin-top: 30px;
- }
- .stepFlex-item-label-desc {
- margin-top: 5px;
- color: #b9b9bd;
- }
- }
- }
- .greenCircle {
- top: calc(50% - 15px);
- left: calc(50% - 4px);
- position: absolute;
- z-index: 2;
- width: 10px;
- height: 10px;
- border-radius: 50%;
- background-color: #31A2FE;
- }
- .now {
- top: calc(50% - 18px);
- left: calc(50% - 8px);
- position: absolute;
- z-index: 3;
- width: 16px;
- height: 16px;
- border-radius: 50%;
- background-color: #31A2FE;
- border: 4px solid #c5e8f9;
- }
- .grayCircle {
- top: calc(50% - 15px);
- left: calc(50% - 4px);
- position: absolute;
- z-index: 2;
- width: 10px;
- height: 10px;
- border-radius: 50%;
- background-color: #ccc;
- }
- .greenLine {
- width: 100%;
- top: calc(50% - 11px);
- left: calc(50% - 2px);
- height: 2px;
- background-color: #31A2FE;
- position: absolute;
- }
- .grayLine {
- height: 0;
- border: 1px dashed #ccc;
- width: 100%;
- top: calc(50% - 11px);
- left: calc(50% - 2px);
- position: absolute;
- }
- }
- </style>
|