liao-sea hace 11 meses
padre
commit
0d66e013db

+ 2 - 2
h5app/src/api/company/index.ts

@@ -83,11 +83,11 @@ export function getCompanyPostList(params:any){
     })
 }
 
-export function getCompanyById(id: string) {
+export function getCompanyById(id: string,loginUserID:string) {
     return request({
         url: 'companyService/company/getCompanyByID',
         method: 'get',
-        params: {id}
+        params: {id,loginUserID}
     }, {
         isNew: true
     })

+ 2 - 2
h5app/src/api/jobUserInfo/index.ts

@@ -24,12 +24,12 @@ export function getJobUserDataList(){
     );
 }
 
-export function getJobUserById(id: any) {
+export function getJobUserById(id: any,loginUserID:string) {
     return request(
         {
             url: 'jobUserService/jobUser/getDataByID',
             method: 'get',
-            params: {id},
+            params: {id,loginUserID},
         },
         { isNew: true },
     );

+ 22 - 3
h5app/src/router/index.ts

@@ -33,6 +33,10 @@ const routes: Array<RouteRecordRaw> = [
                 path: 'tabMain/jobhunt/list',
                 component: () => import('@/views/pages/jobhunt/list.vue')
             },
+            {
+                path: 'tabMain/jobhunt/detail',
+                component: () => import('@/views/pages/jobhunt/detail.vue')
+            },
             {
                 path: 'tabMain/jobhunt/edit',
                 component: () => import('@/views/pages/jobhunt/edit.vue')
@@ -225,10 +229,25 @@ const routes: Array<RouteRecordRaw> = [
             }
             ,
             {
-                path: 'companyedit',
-                name: 'companyedit',
+                path: 'companyEdit',
+                name: 'companyEdit',
                 component: () => import('@/views/pages/jobUserInfo/companyEdit.vue'),
-            }
+            },
+            {
+                path: 'postList',
+                name: 'postList',
+                component: () => import('@/views/pages/jobUserInfo/postList.vue'),
+            },
+            {
+                path: 'postEdit',
+                name: 'postEdit',
+                component: () => import('@/views/pages/jobUserInfo/postEdit.vue'),
+            },
+            {
+                path: 'finish',
+                name: 'finish',
+                component: () => import('@/views/pages/jobUserInfo/finish.vue'),
+            },
         ]
     },
     {

+ 2 - 2
h5app/src/views/pages/company/detail.vue

@@ -58,7 +58,7 @@ interface FormData{
   dataModel:any
 }
 export default defineComponent({
-  name: 'CompanyMenu',
+  name: 'CompanyDetail',
   setup() {
     const router = useRouter();
     const route = useRoute();
@@ -79,7 +79,7 @@ export default defineComponent({
 
     const loadData = async (companyID:any)=>{
       loading.value = true;
-      const reqData = await getCompanyById(companyID);
+      const reqData = await getCompanyById(companyID,"60ea0d5b-a75c-11ed-a6c5-7085c2a9999e");
       formData.dataModel = reqData;
       console.log("dataModel",formData.dataModel);
       loading.value = false;

+ 2 - 2
h5app/src/views/pages/company/edit.vue

@@ -204,7 +204,7 @@
 <script lang="ts">
 import {defineComponent, ref, reactive, computed, toRefs} from "vue";
 import {chevronDownOutline, chevronUpOutline, arrowBackOutline} from 'ionicons/icons';
-import {getRegionList, getSiteList, getStreeList} from '@/api/company/index'
+import {getRegionList, getSiteList, getStreeList} from '@/api/company/index';
 import {useRoute,useRouter} from "vue-router";
 import {alertController, IonIcon, onIonViewDidEnter} from "@ionic/vue";
 import {useVuelidate} from "@vuelidate/core";
@@ -444,7 +444,7 @@ export default defineComponent({
     const loadData = async (companyID: any,status:any) => {
       curStepData.value.statusVal = status;
       isAdd.value = companyID == null;
-      const reqData = await getCompanyById(companyID);
+      const reqData = await getCompanyById(companyID,"60ea0d5b-a75c-11ed-a6c5-7085c2a9999e");
       formState.dataModel = reqData;
       isLongDate.value = formState.dataModel.validDate == "2099-12-31T00:00:00.000+08:00";
       console.log('dataModel',formState.dataModel);

+ 15 - 0
h5app/src/views/pages/company/list.vue

@@ -265,6 +265,21 @@ export default defineComponent({
   --placeholder-opacity: 0.5;
 }
 
+.search-item{
+  margin: 10px 0;
+  font-size: 14px;
+  ion-input{
+    border: 1px solid #f2f2f5;
+    border-radius: 4px;
+    --padding-start: 10px;
+    width: 100px;
+  }
+
+  input{
+    padding: 6px !important;
+  }
+}
+
 .company-list-page {
   .list-content {
     margin: 0px 15px !important;

+ 1 - 1
h5app/src/views/pages/company/menu.vue

@@ -94,7 +94,7 @@ export default defineComponent({
       loading.value = true;
       curStepData.value.statusVal = status;
       console.log(companyID);
-      const reqData = await getCompanyById(companyID);
+      const reqData = await getCompanyById(companyID,"60ea0d5b-a75c-11ed-a6c5-7085c2a9999e");
       formData.dataModel = reqData;
       console.log("dataModel",formData.dataModel);
       loading.value = false;

+ 547 - 6
h5app/src/views/pages/jobUserInfo/companyEdit.vue

@@ -9,29 +9,570 @@
       </ion-toolbar>
     </ion-header>
     <ion-content>
-      companyInfoEidt
+      <div class="stepFlex">
+        <div v-for="(record,key) in stepList" :key="key" class="stepFlex-item">
+          <div
+              :class="[(record.val < curStepData?.statusVal || curStepData?.statusVal == stepList.val) ? 'greenCircle' :record.val == curStepData?.statusVal ? 'now' : 'grayCircle']"></div>
+          <div v-if="key !== stepList.length - 1"
+               :class="[record.val < curStepData?.statusVal ? 'greenLine' : 'grayLine']"></div>
+          <div class="stepFlex-item-label">
+            <p class="stepFlex-item-label-title">{{ record.title }}</p>
+            <p class="stepFlex-item-label-desc">{{ record.desc }}</p>
+          </div>
+        </div>
+      </div>
+      <form autocomplete="off">
+        <div class="bw-vue-form">
+          <div class="form-title">基本信息</div>
+          <div class="form-input">
+            <ion-label>企业名称<span class="danger">*</span></ion-label>
+            <ion-input placeholder="请输入企业名称" label-placement="stacked" :clear-input="true"
+                       v-model="dataModel.companyName" class="custom">
+            </ion-input>
+            <!--          <ion-note slot="error">企业名称不能为空</ion-note>-->
+          </div>
+          <div class="form-input">
+            <ion-label>统一信用代码<span class="danger">*</span></ion-label>
+            <ion-input placeholder="请输入统一信用代码" label-placement="stacked" :clear-input="true"
+                       v-model="dataModel.companyCode" class="custom">
+            </ion-input>
+            <!--            <ion-note slot="error">统一信用代码不能为空</ion-note>-->
+          </div>
+          <div class="form-select">
+            <ion-label>所属街道<span class="danger">*</span></ion-label>
+            <ion-select interface="action-sheet" placeholder="请选择区/县" cancel-text="取消"
+                        id="regionCode" v-model="dataModel.regionCode" style="width: 100%;text-align: left;">
+              <ion-select-option v-for="(record,key) in regionList" :key="key"
+                                 v-model:value="record.code">
+                {{ record.name }}
+              </ion-select-option>
+            </ion-select>
+            <!--           <ion-multi-picker item-content v-model="dataModel.regionCode"-->
+            <!--                             :placeholder="defaultAddText" :multiPickerColumns="cityColumns"-->
+            <!--                             cancelText="取消" doneText="选择">-->
+            <!--           </ion-multi-picker>-->
+            <ion-select interface="action-sheet" placeholder="请选择所属街道" cancel-text="取消"
+                        id="streetCode" v-model="dataModel.streetCode" style="width: 100%;text-align: left;">
+              <ion-select-option v-for="(record,key) in streetList" :key="key"
+                                 v-model:value="record.code">
+                {{ record.name }}
+              </ion-select-option>
+            </ion-select>
+
+          </div>
+          <div class="form-select">
+            <ion-label>所属驿站<span class="danger">*</span></ion-label>
+            <ion-select id="siteID" name="siteID"  cancel-text="取消"  v-model="dataModel.siteID"
+                        interface="action-sheet" placeholder="请选择服务驿站"  style="width: 100%;text-align: left;">
+              <ion-select-option v-for="(record,key) in siteList" :key="key"  v-model:value="record.siteID">
+                {{ record.siteName }}
+              </ion-select-option>
+            </ion-select>
+            <!--            <ion-note slot="error">服务驿站不能为空</ion-note>-->
+          </div>
+          <div class="form-input">
+            <ion-label>办公地址<span class="danger">*</span></ion-label>
+            <ion-textarea placeholder="请输入办公地址" label-placement="stacked" :rows="3" :clear-input="true"
+                          v-model="dataModel.companyAddress" class="custom" style="border-bottom: 1px solid #fff2e8;">
+            </ion-textarea>
+            <!--            <ion-note slot="error">办公地址不能为空</ion-note>-->
+          </div>
+          <div class="form-input">
+            <ion-label>企业联系人<span class="danger">*</span></ion-label>
+            <ion-input placeholder="请输入企业联系人" label-placement="stacked" :clear-input="true"
+                       v-model="dataModel.userName" class="custom">
+            </ion-input>
+            <!--            <ion-note slot="error">企业联系人不能为空</ion-note>-->
+          </div>
+          <div class="form-input">
+            <ion-label>联系电话<span class="danger">*</span></ion-label>
+            <ion-input placeholder="请输入联系电话" label-placement="stacked" :clear-input="true"
+                       v-model="dataModel.userMobile" class="custom">
+            </ion-input>
+            <!--            <ion-note slot="error">企业联系电话不能为空</ion-note>-->
+          </div>
+          <div class="form-select">
+            <ion-label>企业状态<span class="danger">*</span></ion-label>
+            <ion-select id="recordStatus" name="recordStatus" cancel-text="取消"  v-model="dataModel.recordStatus"
+                        interface="action-sheet" placeholder="请选择企业状态" style="width: 100%;text-align: left;">
+              <ion-select-option v-for="(record,key) in companyStatusList" :key="key"
+                                 v-model:value="record.value">
+                {{ record.name }}
+              </ion-select-option>
+            </ion-select>
+            <!--            <ion-note slot="error">企业状态不能为空</ion-note>-->
+          </div>
+          <div class="form-select">
+            <ion-label>是否缺工<span class="danger">*</span></ion-label>
+            <ion-select id="isShortAge" name="isShortAge" cancel-text="取消"  v-model="dataModel.isShortage"
+                        interface="action-sheet" placeholder="请选择是否缺工" style="width: 100%;text-align: left;">
+              <ion-select-option v-for="(record,key) in shortAgeTypeList" :key="key"
+                                 v-model:value="record.value">
+                {{ record.name }}
+              </ion-select-option>
+            </ion-select>
+            <!--            <ion-note slot="error">是否缺工不能为空</ion-note>-->
+          </div>
+          <div class="form-title">
+            其他信息
+            <div style="float:right;">
+              <ion-icon :icon="chevronDownOutline" @click="isShow=!isShow" v-show="!isShow"
+                        style="font-size: 24px;"></ion-icon>
+              <ion-icon :icon="chevronUpOutline" @click="isShow=!isShow" v-show="isShow"
+                        style="font-size: 24px;"></ion-icon>
+            </div>
+          </div>
+
+          <div v-show="isShow" >
+            <div class="form-input">
+              <ion-label>法定代表人(负责人)</ion-label>
+              <ion-input placeholder="请输入法定代表人" label-placement="stacked" :clear-input="true"
+                         v-model="dataModel.frName" class="custom">
+              </ion-input>
+            </div>
+            <div class="form-input">
+              <ion-label>营业执照有效期</ion-label>
+              <div>
+                <ion-radio v-model:checked="isLongDate" justify="start" labelPlacement="end"
+                           @click="changeLongDate" style="height:30px;">至长期</ion-radio>
+                <ion-datetime-button datetime="validDate" style="position:relative;right:110px;"></ion-datetime-button>
+                <ion-modal :keep-contents-mounted="true" >
+                  <ion-datetime id="validDate" name="validDate" placeholder="营业执照有效期"
+                                v-model="dataModel.validDate"  :prefer-wheel="true"  @ionChange="changeValidDate"
+                                dataformatas="YYYY-MM-DD" presentation="date" cancel-text="取消" done-text="确定"
+                                :show-default-buttons="true" >
+                  </ion-datetime>
+                </ion-modal>
+              </div>
+            </div>
+            <div class="form-input" >
+              <ion-label>企业邮箱</ion-label>
+              <ion-input placeholder="请输入企业邮箱" label-placement="stacked" :clear-input="true"
+                         v-model="dataModel.companyEmail" class="custom">
+              </ion-input>
+            </div>
+            <div class="form-select">
+              <ion-label>企业分类</ion-label>
+              <ion-select interface="action-sheet" placeholder="请选择企业分类" cancel-text="取消"
+                          id="companyType" v-model="dataModel.companyType"  style="width: 100%;text-align: left;">
+                <ion-select-option v-for="(record,key) in companyTypeList" :key="key"
+                                   v-model:value="record.code">
+                  {{ 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="companyModel" v-model="dataModel.companyModel"  style="width: 100%;text-align: left;">
+                <ion-select-option v-for="(record,key) in companyModelList" :key="key"
+                                   v-model:value="record.value" style="width:100%;text-align: left;">
+                  {{ record.name }}
+                </ion-select-option>
+              </ion-select>
+            </div>
+            <div class="form-input">
+              <ion-label>用工情况(人)</ion-label>
+              <ion-input type="number" placeholder="请输入用工人数" label-placement="stacked" :clear-input="true"
+                         v-model="dataModel.workSituation" class="custom">
+              </ion-input>
+            </div>
+            <div class="form-input">
+              <ion-label>参保人数(人)</ion-label>
+              <ion-input type="number" placeholder="请输入参保人数" label-placement="stacked" :clear-input="true"
+                         v-model="dataModel.insuredCount" class="custom">
+              </ion-input>
+            </div>
+            <div class="form-input">
+              <ion-label>经营范围</ion-label>
+              <ion-textarea placeholder="请输入经营范围" :rows="3" label-placement="stacked" :clear-input="true"
+                            v-model="dataModel.businScope" 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" :clear-input="true"
+                            v-model="dataModel.companyDesc" class="custom" style="border-bottom: 1px solid #fff2e8;">
+              </ion-textarea>
+            </div>
+          </div>
+        </div>
+      </form>
     </ion-content>
+    <ion-footer>
+      <ion-toolbar>
+        <ion-button style="width:100%;" @click="onNext">保存并下一步</ion-button>
+      </ion-toolbar>
+    </ion-footer>
   </ion-page>
 </template>
-<script>
-import {defineComponent} from "vue";
-import {arrowBackOutline} from 'ionicons/icons';
+<script lang="ts">
+import {computed, defineComponent, reactive, ref, toRefs} from "vue";
+import {arrowBackOutline, chevronDownOutline, chevronUpOutline} from 'ionicons/icons';
 import {useRouter} from "vue-router";
+import dayjs from "dayjs";
+import {useRoute} from "vue-router/dist/vue-router";
+import {getSysDictionaryList} from "@/api/system/dictionary";
+import {required} from "@vuelidate/validators";
+import {useVuelidate} from "@vuelidate/core";
+import {getCompanyById, getRegionList, getSiteList, getStreeList, saveCompanyInfo} from "@/api/company";
+import {alertController, onIonViewDidEnter} from "@ionic/vue";
 
+interface StepParams{
+  loginUserID: string,
+  statusVal: number
+}
 export default defineComponent({
-  name: "companyInfoEidt",
+  name: "companyInfoEdit",
   setup() {
+    const route = useRoute();
     const router = useRouter();
+    const isAllowCommit = ref(true);
+    const curStepData = ref<StepParams>({
+      loginUserID:"",
+      statusVal: 1
+    });
+    const isShow = ref<any>(false);
+    const isLongDate = ref<any>(false);
+    const formState = reactive({
+      dataModel: {
+        companyID:null,
+        companyCode: '',
+        companyName: null,
+        siteID: null,
+        companyAddress: null,
+        userName: null,
+        userMobile: '',
+        recordStatus: null,
+        isShortage: null,
+        frName: null,
+        validDate: dayjs().format("YYYY-MM-DD"),
+        companyEmail: '',
+        companyType: null,
+        companyModel: null,
+        regionCode: null,
+        streetCode: null,
+        workSituation: null,
+        insuredCount: null,
+        businScope: null,
+        companyDesc: null
+      }});
+    const stepList = ref([
+      {title: '基础信息', desc: '企业基础信息', val: 1},
+      {title: '岗位信息', desc: '企业岗位信息', val: 2}
+    ]);
+
+    const companyTypeList = ref<any>([]);
+    const companyModelList = ref<any>([]);
+    const regionList = ref<any>([]);
+    const streetList = ref<any>([]);
+    const siteList = ref<any>([]);
+    const companyStatusList = [
+      {value: 1, name: '在营'},
+      {value: 0, name: '关闭'},
+    ];
+    const shortAgeTypeList = [
+      {value: 1, name: '是'},
+      {value: 0, name: '否'},
+    ];
+
+    const getCompanyModelList = async function(){
+      const companyModelResult :any = await getSysDictionaryList("CompanyModel");
+      companyModelList.value = companyModelResult;
+    }
+
+    const getCompanyTypeList = async function(){
+      const companyTypeResult :any = await getSysDictionaryList("CompanyType");
+      companyTypeList.value = companyTypeResult;
+    }
+
+    const rules = computed(() => {
+      return {
+        dataModel: {
+          companyCode: {required},
+          companyName: {required},
+          siteID: {required},
+          companyAddress: {required},
+          userName: {required},
+          userMobile: {required},
+          recordStatus: {required},
+          isShortage: {required},
+        }
+      }
+    });
+    const v$ = useVuelidate(rules, formState);
+
+    const changeLongDate = ()=>{
+      isLongDate.value = true;
+      formState.dataModel.validDate = "2099-12-31T00:00:00.000+08:00";
+    };
+
+    const changeValidDate = () => {
+      isLongDate.value = false;
+    };
+
+    const companyCodeValidate = ()=>{
+      isAllowCommit.value = true;
+      const codeReg = /^[0-9A-Z]+$/;
+      console.log(formState.dataModel.companyCode);
+      if(formState.dataModel.companyCode.length != 18 || !codeReg.test(formState.dataModel.companyCode)){
+        presentAlert("输入的信用代码有误!");
+        isAllowCommit.value = false;
+      }else{
+        let aCode;
+        let aCodeValue;
+        let total = 0;
+        const weightedFactors = [1,3,9,27,19,26,16,17,20,29,25,13,8,24,10,30,28];
+        const str = '0123456789ABCDEFGHJKLMNPQRTUWXY';
+        for(let i =0;i < formState.dataModel.companyCode.length-1;i++){
+          aCode = formState.dataModel.companyCode.substring(i,i+1);
+          aCodeValue = str.indexOf(aCode);
+          total += aCodeValue * weightedFactors[i];
+        }
+        let logicCheckCode = 31 - total % 31;
+        if(logicCheckCode == 31){
+          logicCheckCode = 0;
+        }
+        const Str = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,T,U,W,X,Y";
+        const Array_Str = Str.split(',');
+        const correctCodeStr  = Array_Str[logicCheckCode];
+        console.log("正确的校验码是",correctCodeStr);
+        const currentCodeStr = formState.dataModel.companyCode.substring(17, 18);
+        if (correctCodeStr != currentCodeStr) {
+          presentAlert('输入的统一信用代码无效!');
+          isAllowCommit.value = false;
+        }
+      }
+    }
+
+    const inputDataValidate = () =>{
+      const mobileReg = /^1[3|4|5|6|7|8|9]\d{9}$/;
+      if(!mobileReg.test(formState.dataModel.userMobile)){
+        presentAlert("输入的联系电话有误!");
+        isAllowCommit.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.companyEmail!=null&&formState.dataModel.companyEmail!=""){
+        if(!emailReg.test(formState.dataModel.companyEmail)){
+          presentAlert("输入的企业邮箱有误!");
+          isAllowCommit.value = false;
+        }
+      }
+    };
+
+
+    const getRegionListData = () => {
+      getRegionList({}).then(data => {
+        regionList.value = data;
+        console.log(regionList.value);
+      });
+    }
+    const getStreetListData = (code: any) => {
+      getStreeList({code: code}).then(data => {
+        streetList.value = data;
+      });
+    }
+    const getSiteListData = () => {
+      getSiteList({}).then(data => {
+        siteList.value = data;
+      });
+    }
+    const changeCity = () => {
+      console.log(formState.dataModel.regionCode);
+      if (formState.dataModel.regionCode)
+        getStreetListData(formState.dataModel.regionCode);
+    }
+
+    const loadData = async (companyID: any,status:any,userID:string) => {
+      curStepData.value.statusVal = status;
+      curStepData.value.loginUserID = userID;
+      await getCompanyModelList();
+      await getCompanyTypeList();
+      await getRegionListData();
+      await getSiteListData();
+      const reqData = await getCompanyById(companyID,userID);
+      formState.dataModel = reqData;
+      isLongDate.value = formState.dataModel.validDate == "2099-12-31T00:00:00.000+08:00";
+      console.log('dataModel',formState.dataModel);
+      if(formState.dataModel.regionCode!=null) getStreetListData(formState.dataModel.regionCode);
+    };
+
+
+    const reload = (companyID:any,status:any,userID:any) => {
+      isShow.value = false;
+      loadData(companyID,status,userID);
+    }
+
+    onIonViewDidEnter(() => {
+      if (route.query.reload) {
+        reload(route.query.id,1,route.query.siteUserId);
+      }
+    });
+
+    const presentAlert = async (message: string) => {
+      const alert = await alertController.create({
+        header: '错误!',
+        message: message,
+        buttons: [
+          '确定'
+        ],
+      });
+
+      await alert.present();
+    }
+
+
     const onBack = () => {
       router.push('/jobUserInfo/index');
     }
+
+    const onNext = async () => {
+      const isFormCorrect = await v$.value.$validate();
+      if (!isFormCorrect) {
+        await presentAlert('请输入完整信息!');
+        return null;
+      }
+      companyCodeValidate();
+      inputDataValidate();
+      if(isAllowCommit.value){
+        saveCompanyInfo(formState.dataModel).then(result => {
+          if (result) {
+            router.push({path: './postList', query: {reload:1,id:formState.dataModel.companyID,status:2,userID:curStepData.value.loginUserID }});
+          }
+        });
+      }
+    };
+
     return {
+      ...toRefs(formState),
       arrowBackOutline,
-      onBack
+      chevronDownOutline,
+      chevronUpOutline,
+      route,
+      router,
+      isShow,
+      v$,
+      isLongDate,
+      curStepData,
+      stepList,
+      companyTypeList,
+      siteList,
+      regionList,
+      streetList,
+      shortAgeTypeList,
+      companyStatusList,
+      companyModelList,
+      onNext,
+      onBack,
+      changeCity,
+      changeLongDate,
+      changeValidDate,
+      loadData,
     }
   }
 });
 </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, ion-input, ion-select, ion-datetime-button {
+    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>

+ 38 - 0
h5app/src/views/pages/jobUserInfo/finish.vue

@@ -0,0 +1,38 @@
+<template>
+  <ion-page class="list-page">
+    <ion-header class="header-theme2 header-theme3">
+      <ion-toolbar>
+        <ion-title>惠州就业驿站</ion-title>
+      </ion-toolbar>
+    </ion-header>
+    <ion-content>
+      <div class="bw-vue-form" style="text-align: center;margin-top: 100px;">
+         <h1>录入信息成功!</h1>
+      </div>
+    </ion-content>
+  </ion-page>
+</template>
+<script>
+</script>
+<style lang="less">
+.bw-vue-form {
+  padding: 20px 10px;
+}
+
+.page_button {
+  display: flex;
+  justify-content: space-around;
+  padding: 20px;
+
+  ion-button {
+    width: 150px;
+  }
+}
+
+.header-theme3 {
+  ion-title {
+    margin-left: 0px !important;
+  }
+}
+
+</style>

+ 407 - 0
h5app/src/views/pages/jobUserInfo/postEdit.vue

@@ -0,0 +1,407 @@
+<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>
+            <ion-input placeholder="请选择岗位" label-placement="stacked" disabled
+                       v-model="dataModel.professionName" style="width: 88%;float:left;color:black;" >
+            </ion-input>
+            <picker :ProfessionID="dataModel.professionID" aria-disabled="false"  @SetProfessionID="onSetProfessionID" style="width: 10%;float:left;"></picker>
+<!--            <ion-note slot="error">请选择岗位</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-icon :icon="chevronDownOutline"  @click="isShow=!isShow" v-if="!isShow"
+                        style="font-size: 24px;"></ion-icon>
+              <ion-icon :icon="chevronUpOutline"  @click="isShow=!isShow" v-if="isShow"
+                        style="font-size: 24px;"></ion-icon>
+            </div>
+          </div>
+          <div v-show="isShow" >
+            <div class="form-input">
+              <ion-label>岗位月薪(元)</ion-label>
+              <div>
+                <ion-input 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;">
+                <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 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.welfare" 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.postDesc" class="custom" style="border-bottom: 1px solid #fff2e8;">
+              </ion-textarea>
+            </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 {minLength, required} from "@vuelidate/validators";
+import {getSysDictionaryList} from "@/api/system/dictionary";
+import dayjs from "dayjs";
+import Picker from "@/components/picker.vue";
+
+export default defineComponent({
+  name: 'PostEdit',
+  components:{Picker},
+  setup() {
+    const router = useRouter();
+    const route = useRoute();
+    const isShow = ref<any>(false);
+    const isEdit = ref<any>(false);
+    const formState = reactive({
+      dataModel: {
+        companyID:null,
+        postID: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:null,
+        trailMinSalary:null,
+        trailMaxSalary:null,
+        workYear:null,
+        cultureRank:null,
+        welfare:null,
+        postDesc:null
+      }});
+    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 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 onSave = async function (){
+      const isFormCorrect = await v$.value.$validate();
+      console.log("当前岗位信息",formState.dataModel);
+      if (!isFormCorrect) {
+        await presentAlert('请输入完整信息!');
+        return null;
+      }
+      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 loadData = async (postID: any,companyID:any) => {
+      await getWorkYearList();
+      await getCultureRankList();
+      const reqData = await getPostByID(postID);
+      formState.dataModel = reqData;
+      formState.dataModel.companyID = companyID;
+      console.log("初始化岗位信息",formState.dataModel);
+    };
+
+    const reload = (postID: any,companyID:any) => {
+      formState.dataModel.recruitCount = null;
+      loadData(postID,companyID);
+    }
+
+    onIonViewDidEnter(() => {
+      if (route.query.reload)
+        reload(route.query.id,route.query.companyID);
+    });
+
+    return {
+      ...toRefs(formState),
+      chevronDownOutline,
+      chevronUpOutline,
+      arrowBackOutline,
+      route,
+      router,
+      isShow,
+      isEdit,
+      isTrailList,
+      workYearList,
+      cultureRankList,
+      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>

+ 426 - 0
h5app/src/views/pages/jobUserInfo/postList.vue

@@ -0,0 +1,426 @@
+<template>
+  <ion-page class="list-page post-list-page">
+    <ion-header class="header-theme2">
+      <ion-toolbar>
+        <ion-buttons slot="start">
+          <ion-icon :icon="arrowBackOutline" @click="onBack"></ion-icon>
+        </ion-buttons>
+        <ion-title>
+          企业岗位信息
+        </ion-title>
+      </ion-toolbar>
+    </ion-header>
+
+    <ion-content>
+      <div class="stepFlex">
+        <div v-for="(record,key) in stepList" :key="key" class="stepFlex-item">
+          <div
+              :class="[(record.val < curStepData?.statusVal || curStepData?.statusVal==stepList.val) ? 'greenCircle' :record.val == curStepData?.statusVal ? 'now' : 'grayCircle']"></div>
+          <div v-if="key !== stepList.length - 1"
+               :class="[record.val < curStepData?.statusVal ? 'greenLine' : 'grayLine']"></div>
+          <div class="stepFlex-item-label">
+            <p class="stepFlex-item-label-title">{{ record.title }}</p>
+            <p class="stepFlex-item-label-desc">{{ record.desc }}</p>
+          </div>
+        </div>
+      </div>
+
+      <form autocomplete="off">
+        <div class="bw-vue-form">
+          <div class="form-title">
+            岗位信息
+            <ion-icon :icon="addCircleOutline" class="iconBtn" style="float:right;"
+                       @click="onAdd()" ></ion-icon>
+          </div>
+          <div class="bw-vue-list">
+            <div class="list-content" v-if="!loading">
+            <ion-list>
+              <div v-for="(record,key) in postList" :key="key" >
+                <ion-item-sliding>
+                <ion-item detail @click="onEdit(record.postID)">
+                  <ion-label>
+                    <h2>
+                      {{ record.professionName }}
+                    </h2>
+                    <p v-if="record.startTime!=null&&record.endTime!=null">
+                      {{ dayjs(record.startTime).format("YYYY-MM-DD") }}至{{ dayjs(record.endTime).format("YYYY-MM-DD") }}
+                    </p>
+                    <p v-if="record.startTime==null||record.endTime==null">
+                      暂未设置有效期限
+                    </p>
+                    <p>
+                      招聘数量:{{ record.recruitCount }}
+                    </p>
+                  </ion-label>
+                </ion-item>
+                <ion-item-options>
+                  <ion-item-option color="danger" @click="setDelAlertOpen(true, record.postID)">
+                    <ion-icon :icon="trashOutline"></ion-icon>
+                  </ion-item-option>
+             </ion-item-options>
+                </ion-item-sliding>
+              </div>
+            </ion-list>
+            </div>
+          </div>
+          <ion-infinite-scroll  threshold="100px" @ionInfinite="onScroll($event)">
+            <ion-infinite-scroll-content
+                :loadingText="pageParams.total>pageParams.pageIndex*pageParams.pageSize?'正在加载...':'暂无更多'"
+                loadingSpinner="bubbles">
+            </ion-infinite-scroll-content>
+          </ion-infinite-scroll>
+        </div>
+      </form>
+    </ion-content>
+    <ion-footer>
+      <ion-toolbar>
+        <ion-button style="width: 48%;float:left;margin-left: 1%;" @click="onBack" >上一步</ion-button>
+        <ion-button style="width: 48%;float:left;margin-right: 1%;" @click="onFinish" >完  成</ion-button>
+      </ion-toolbar>
+    </ion-footer>
+
+    <ion-alert
+        :is-open="delAlertOpen"
+        header="删除确认"
+        message="确定要删除该岗位吗?"
+        :buttons="delAlertButtons"
+        @didDismiss="setDelAlertOpen(false, null)"
+    ></ion-alert>
+
+    <ion-alert
+        :is-open="infoAlertOpen"
+        :header="infoAlterData.title"
+        :message="infoAlterData.message"
+        :buttons="infoAlertButtons"
+        @didDismiss="setInfoAlertOpen(false)"
+    ></ion-alert>
+    <ion-loading
+        :is-open="delLoading"
+        message="删除中..."
+        @didDismiss="setDelLoadingOpen(false)" >
+    </ion-loading>
+  </ion-page>
+</template>
+<script lang="ts">
+import {defineComponent, reactive, ref} from "vue";
+import {useRoute, useRouter} from "vue-router";
+import {alertController, onIonViewDidEnter} from "@ionic/vue";
+import {arrowBackOutline, addCircleOutline,trashOutline} from 'ionicons/icons';
+import {getCompanyPostList} from '@/api/company/index'
+import dayjs from "dayjs";
+import {post} from "@/api/common";
+
+interface StepParams{
+  loginUserID: string,
+  statusVal: number
+}
+
+export default defineComponent({
+  name: 'PostList',
+  setup() {
+    const router = useRouter();
+    const route = useRoute();
+    const loading = ref(false);
+    const postList = ref<any>([]);
+    const pageParams = reactive({
+      pageIndex: 1,
+      pageSize: 10,
+      total:0,
+      companyID:''
+    });
+    const curStepData = ref<StepParams>({
+      loginUserID:"",
+      statusVal: 1
+    });
+    const stepList = ref([
+      {
+        title: '基础信息',
+        desc: '企业基础信息',
+        val: 1
+      },{
+        title: '',
+        desc: '',
+        val: 2
+      },
+      {
+        title: '岗位信息',
+        desc: '企业岗位信息',
+        val: 3
+      }]);
+    const presentAlert = async (message: string) => {
+      const alert = await alertController.create({
+        header: '错误!',
+        message: message,
+        buttons: [
+          '确定'
+        ],
+      });
+
+      await alert.present();
+    };
+
+
+
+    // 信息弹窗内容
+    const infoAlterData = reactive({
+      title:"",
+      message:""
+    });
+    // 删除警告弹窗开关
+    const delAlertOpen = ref(false);
+    // 删除警告弹窗按钮定义
+    const infoAlertButtons = [
+      {
+        text: '确定',
+        role: 'confirm',
+        handler: () => {
+          reload(pageParams.companyID,curStepData.value.statusVal,curStepData.value.loginUserID);
+        },
+      },
+    ];
+
+    // 删除数据
+    const delPostID = ref("");
+    // 删除加载
+    const delLoading = ref(false);
+    // 信息弹窗开关
+    const infoAlertOpen = ref(false);
+    // 删除警告弹窗按钮定义
+    const delAlertButtons = [
+      {
+        text: '取消',
+        role: 'cancel',
+        handler: () => {
+          reload(pageParams.companyID,curStepData.value.statusVal,curStepData.value.loginUserID);
+        },
+      },
+      {
+        text: '确定',
+        role: 'confirm',
+        handler: () => {
+          delLoading.value = true;
+          post("companyService/post/delete",[delPostID.value],"岗位信息删除").then((res) => {
+           /* infoAlterData.title = "提示";
+            infoAlterData.message = "删除成功";
+            setInfoAlertOpen(true);*/
+          }).finally(()=>{
+            delLoading.value = false;
+            reload(pageParams.companyID,curStepData.value.statusVal,curStepData.value.loginUserID);
+          });
+        },
+      },
+    ];
+    // 设置要删除的求职人员
+    function setDelAlertOpen(value: boolean, postID: any) {
+      delAlertOpen.value = value;
+      if(postID != null) {
+        delPostID.value = postID;
+      }
+    }
+    // 设置信息提示弹窗开关
+    function setInfoAlertOpen(value: boolean) {
+      infoAlertOpen.value = value;
+    }
+    // 设置删除弹窗开启关闭
+    function setDelLoadingOpen(value: boolean) {
+      delLoading.value = value;
+    }
+
+    const onAdd = () => {
+      router.push({path: './postEdit', query: {reload:1,id: null,companyID:pageParams.companyID}});
+    };
+    const onEdit = (postID:any) => {
+      router.push({path: './postEdit', query: {reload:1,id:postID,companyID:pageParams.companyID}});
+    };
+    const onBack = () => {
+        router.push({path: './companyEdit', query: {reload:1,id:pageParams.companyID,siteUserId:curStepData.value.loginUserID}});
+    };
+
+    const onFinish = () => {
+      router.push('/jobUserInfo/finish');
+    }
+
+    const onScroll = (e: any) => {
+      setTimeout(() => {
+        e.target.complete();
+        if (pageParams.total > pageParams.pageIndex * pageParams.pageSize) {
+          pageParams.pageSize += 10;
+          loadData(pageParams.companyID,curStepData.value.statusVal,curStepData.value.loginUserID);
+        }
+      }, 500);
+    }
+    const loadData = async function (companyID:any,status:any,userID:string) {
+      loading.value = true;
+      pageParams.companyID = companyID;
+      curStepData.value.statusVal = status;
+      curStepData.value.loginUserID = userID;
+      //console.log("S",pageParams);
+      const result:any = await getCompanyPostList(pageParams);
+      postList.value = postList.value.concat(result.list);
+      pageParams.total = result.total;
+      //console.log(postList.value);
+      loading.value = false;
+    };
+
+    const reload = (companyID:any,status:any,userID:any) => {
+      pageParams.pageIndex = 1;
+      postList.value = [];
+      loadData(companyID,status,userID);
+      /*const jsonPostList = localStorage.getItem("postData");
+      postList.value = JSON.parse(jsonPostList ?? "");*/
+    };
+
+    onIonViewDidEnter(() => {
+      if (route.query.reload)
+        reload(route.query.id,route.query.status,route.query.userID);
+    });
+
+    return {
+      arrowBackOutline,
+      addCircleOutline,
+      trashOutline,
+      route,
+      router,
+      loading,
+      pageParams,
+      curStepData,
+      postList,
+      stepList,
+      delPostID,
+      delAlertButtons,
+      infoAlertButtons,
+      delAlertOpen,
+      infoAlertOpen,
+      delLoading,
+      infoAlterData,
+      onBack,
+      onAdd,
+      onEdit,
+      onFinish,
+      onScroll,
+      loadData,
+      presentAlert,
+      /*calculateEndDate,*/
+      dayjs,
+      setDelAlertOpen,
+      setInfoAlertOpen,
+      setDelLoadingOpen,
+    }
+  }
+});
+</script>
+
+<style lang="less">
+.next-btn {
+  width: 100%;
+  --border-radius: 0px;
+  --background: #f2f2f5;
+  margin: 20px 0 0 0;
+  color: #363432;
+  font-size: 14px;
+}
+
+.iconBtn{
+  width:24px;
+  height:24px;
+}
+.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;
+  }
+
+
+  .post-list-page {
+    .list-content {
+      margin: 0px 15px !important;
+      background-color: white !important;
+      border-radius: 0 !important;
+
+      ion-item {
+        margin-top: 10px;
+        font-size: 14px;
+        border: 1px solid rgb(242, 242, 245);
+
+        p {
+          font-size: 12px;
+        }
+      }
+    }
+  }
+
+}
+
+</style>

+ 204 - 0
h5app/src/views/pages/jobhunt/detail.vue

@@ -0,0 +1,204 @@
+<template>
+  <ion-page>
+    <ion-header class="header-theme2">
+      <ion-toolbar>
+        <ion-buttons slot="start">
+          <ion-icon :icon="arrowBackOutline" @click="onBack"></ion-icon>
+        </ion-buttons>
+        <ion-title>
+          求职人员详情
+        </ion-title>
+      </ion-toolbar>
+    </ion-header>
+    <ion-content>
+      <div class="bw-vue-form">
+        <div class="form-detail">
+          <ion-label>姓名</ion-label>
+          <ion-text>{{ dataModel.name }}</ion-text>
+        </div>
+        <div class="form-detail">
+          <ion-label>性别</ion-label>
+          <ion-text>{{ dataModel.genderName }}</ion-text>
+        </div>
+        <div class="form-detail">
+          <ion-label>所属驿站</ion-label>
+          <ion-text>{{ dataModel.siteName }}</ion-text>
+        </div>
+        <div class="form-detail">
+          <ion-label>状态</ion-label>
+          <ion-text>{{ dataModel.jobStatusName }}</ion-text>
+        </div>
+        <div class="form-detail">
+          <ion-label>联系电话</ion-label>
+          <ion-text>{{ dataModel.userMobile }}</ion-text>
+        </div>
+        <div class="form-detail">
+          <ion-label>居住地址</ion-label>
+          <ion-text>{{ dataModel.address }}</ion-text>
+        </div>
+      </div>
+    </ion-content>
+    <ion-footer>
+    </ion-footer>
+  </ion-page>
+</template>
+<script lang="ts">
+import {defineComponent, ref, reactive, watch, toRefs} from "vue";
+import {getJobUserById} from "@/api/jobUserInfo";
+import {useRoute, useRouter} from "vue-router";
+import {onIonViewDidEnter} from "@ionic/vue";
+import {arrowBackOutline} from 'ionicons/icons';
+
+
+interface FormData{
+  dataModel:any
+}
+export default defineComponent({
+  name: 'UserDetail',
+  setup() {
+    const router = useRouter();
+    const route = useRoute();
+    const loading = ref<boolean>(false);
+    const formData = reactive<FormData>({
+      dataModel: {
+      }
+    });
+    const onBack=()=>{
+      router.push({path:'./list',query:{reload:1}});
+    };
+
+
+    const loadData = async (jobUserID:any)=>{
+      loading.value = true;
+      const reqData = await getJobUserById(jobUserID,"60ea0d5b-a75c-11ed-a6c5-7085c2a9999e");
+      formData.dataModel = reqData;
+      console.log("dataModel",formData.dataModel);
+      loading.value = false;
+    };
+
+    const reload = (jobUserID:any) => {
+      loadData(jobUserID);
+    };
+
+    watch(() => route.query, () => {
+      if (route.query.reload) {
+        reload(route.query.id);
+      }
+    });
+
+    onIonViewDidEnter(() => {
+      if (route.query.reload) {
+        reload(route.query.id)
+      }
+    });
+
+
+    return {
+      ...toRefs(formData),
+      arrowBackOutline,
+      route,
+      loading,
+      onBack,
+      loadData,
+      router,
+    }
+  },
+  mounted() {
+    const companyID = this.route.query.id;
+    this.loadData(companyID);
+  }
+});
+</script>
+
+<style lang="less">
+ion-item {
+  --border-width: 0;
+  --border-style: none;
+
+  ion-label, ion-input, ion-select, ion-datetime-button {
+    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>

+ 4 - 2
h5app/src/views/pages/jobhunt/edit.vue

@@ -65,7 +65,7 @@
             </div>
             <div class="form-select">
               <ion-label>市/县<span class="danger">*</span></ion-label>
-              <ion-select name="regionCode"  id="regionCode" okText="确定" cancelText="取消" v-model="baseData.regionCode"
+              <ion-select class="disable" disabled name="regionCode"  id="regionCode" okText="确定" cancelText="取消" v-model="baseData.regionCode"
                           interface="action-sheet" placeholder="请选择市/县" style="width:100%;text-align:left;" @ionChange="regionChange()" >
                 <ion-select-option v-for=" (it,key) in regionList" :key="key" :value="it.code">
                   {{ it.name }}
@@ -710,7 +710,7 @@ export default defineComponent({
       curStepData.value.statusVal = status;
       console.log("当前jobUserID",jobUserID);
       if(curStepData.value.statusVal==1){
-        const reqData = await getJobUserById(jobUserID);
+        const reqData = await getJobUserById(jobUserID,"60ea0d5b-a75c-11ed-a6c5-7085c2a9999e");
         baseInfoData.baseData = reqData;
         console.log('baseData',baseInfoData.baseData);
         await getStreetList();
@@ -821,6 +821,8 @@ export default defineComponent({
 });
 </script>
 <style lang="less">
+ion-select#siteID.md.select-disabled.legacy-select::after{display: none;}
+ion-select#regionCode.md.select-disabled.legacy-select::after{display: none;}
 .custom{
   --placeholder-color: gray;
   --placeholder-opacity: 0.5;

+ 2 - 2
h5app/src/views/pages/jobhunt/recommend/list.vue

@@ -1,5 +1,5 @@
 <template>
-  <ion-page class="list-page company-list-page">
+  <ion-page class="list-page recommend-list-page">
     <ion-header class="header-theme2">
       <ion-toolbar>
         <ion-buttons slot="start">
@@ -143,7 +143,7 @@ export default defineComponent({
   --placeholder-opacity: 0.5;
 }
 
-.company-list-page {
+.recommend-list-page {
   .list-content {
     margin: 0px 15px !important;
     background-color: white !important;

+ 1 - 1
h5app/src/views/pages/post/detail.vue

@@ -240,7 +240,7 @@ export default defineComponent({
       formStatus.loading = true;
       recommendPostList.value = [];
       /*查询求职人员信息*/
-      const userInfo :any = await getJobUserById(jobUserID);
+      const userInfo :any = await getJobUserById(jobUserID,"60ea0d5b-a75c-11ed-a6c5-7085c2a9999e");
       dataModel.value = userInfo;
       /*查询求职意向信息*/
       await getCurHuntList(jobUserID);

+ 15 - 3
src/main/java/com/hz/employmentsite/controller/companyService/CompanyController.java

@@ -36,6 +36,9 @@ public class CompanyController {
     @Autowired
     private PcSiteUserMapper pcSiteUserMapper;
 
+    @Autowired
+    private PcSiteMapper pcSiteMapper;
+
     @Autowired
     private DateUtils dateUtils;
 
@@ -59,7 +62,7 @@ public class CompanyController {
     }
 
     @GetMapping("/getCompanyByID")
-    public BaseResponse<CompanyVo> getCompanyById(String id) {
+    public BaseResponse<CompanyVo> getCompanyById(String id,String loginUserID) {
         var data = companyService.getDataById(id);
         if (data == null) {
             data = new CompanyVo();
@@ -69,10 +72,19 @@ public class CompanyController {
             data.isShortage = 1;
             PcSiteUserExample siteUserExp = new PcSiteUserExample();
             PcSiteUserExample.Criteria siteUserCro = siteUserExp.createCriteria();
-            siteUserCro.andUserIDEqualTo(accountService.getLoginUserID());
+            siteUserCro.andUserIDEqualTo(loginUserID);
+            //siteUserCro.andUserIDEqualTo(accountService.getLoginUserID());
             var curSiteUserInfo = pcSiteUserMapper.selectByExample(siteUserExp).stream().findFirst().orElse(null);
             if(curSiteUserInfo != null){
-                data.siteID = curSiteUserInfo.getSiteID();
+                data.setSiteID(curSiteUserInfo.getSiteID());
+                PcSiteExample siteExp = new PcSiteExample();
+                PcSiteExample.Criteria siteCro = siteExp.createCriteria();
+                siteCro.andSiteIDEqualTo(curSiteUserInfo.getSiteID());
+                var curSiteInfo = pcSiteMapper.selectByExample(siteExp).stream().findFirst().orElse(null);
+                if(curSiteInfo != null){
+                    data.setRegionCode(curSiteInfo.getRegionCode());
+                    data.setStreetCode(curSiteInfo.getStreetCode());
+                }
             }
         }
         return RespGenerstor.success(data);

+ 14 - 3
src/main/java/com/hz/employmentsite/controller/jobUserManager/JobUserController.java

@@ -5,8 +5,10 @@ import com.hz.employmentsite.filter.exception.BaseErrorEnum;
 import com.hz.employmentsite.filter.exception.BaseException;
 import com.hz.employmentsite.filter.exception.BaseResponse;
 import com.hz.employmentsite.filter.exception.RespGenerstor;
+import com.hz.employmentsite.mapper.PcSiteMapper;
 import com.hz.employmentsite.mapper.PcSiteUserMapper;
 import com.hz.employmentsite.model.PcJobuser;
+import com.hz.employmentsite.model.PcSiteExample;
 import com.hz.employmentsite.model.PcSiteUserExample;
 import com.hz.employmentsite.model.SelectProps;
 import com.hz.employmentsite.services.service.AccountService;
@@ -35,6 +37,9 @@ public class JobUserController {
     @Autowired
     private PcSiteUserMapper pcSiteUserMapper;
 
+    @Autowired
+    private PcSiteMapper pcSiteMapper;
+
     @Autowired
     private DateUtils dateUtils;
 
@@ -52,17 +57,23 @@ public class JobUserController {
 
     @ResponseBody
     @GetMapping("/getDataByID")
-    public BaseResponse<PcJobuser> getDataById(@RequestParam(required = false) String id) {
+    public BaseResponse<PcJobuser> getDataById(String id,String loginUserID) {
         var data = jobuserService.getDataById(id);
         if (data == null) {
             data = new JobUserVo();
             data.setJobUserID(UUID.randomUUID().toString());
             PcSiteUserExample siteUserExp = new PcSiteUserExample();
-            PcSiteUserExample.Criteria siteUserCro = siteUserExp.createCriteria();
-            siteUserCro.andUserIDEqualTo(accountService.getLoginUserID());
+            siteUserExp.or().andUserIDEqualTo(loginUserID);
+            //siteUserExp.or().andUserIDEqualTo(accountService.getLoginUserID());
             var curSiteUserInfo = pcSiteUserMapper.selectByExample(siteUserExp).stream().findFirst().orElse(null);
             if(curSiteUserInfo != null){
                 data.setSiteID(curSiteUserInfo.getSiteID());
+                PcSiteExample siteExp = new PcSiteExample();
+                siteExp.or().andSiteIDEqualTo(curSiteUserInfo.getSiteID());
+                var curSiteInfo = pcSiteMapper.selectByExample(siteExp).stream().findFirst().orElse(null);
+                if(curSiteInfo != null){
+                    data.setRegionCode(curSiteInfo.getRegionCode());
+                }
             }
         }
         return RespGenerstor.success(data);

+ 29 - 0
src/main/java/com/hz/employmentsite/services/impl/jobUserManager/JobUserServiceImpl.java

@@ -12,6 +12,7 @@ import com.hz.employmentsite.mapper.cquery.JobUserCQuery;
 import com.hz.employmentsite.model.*;
 import com.hz.employmentsite.services.service.jobUserManager.JobUserService;
 import com.hz.employmentsite.util.StringUtils;
+import com.hz.employmentsite.vo.companyService.CompanyVo;
 import com.hz.employmentsite.vo.jobUserManager.JobUserVo;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -301,9 +302,37 @@ public class JobUserServiceImpl implements JobUserService {
         return result;
     }
 
+    private int ifHadRepeatData(JobUserVo data){
+
+        var result = 0;
+        PcJobuserExample jobUserExp1 = new PcJobuserExample();
+        jobUserExp1.or().andIdentityNumberEqualTo(data.getIdentityNumber()).andJobuserIDNotEqualTo(data.getJobUserID());
+        var ifRepeatIdentity = pcJobuserMapper.selectByExample(jobUserExp1).size()>0;
+
+        PcJobuserExample jobUserExp2= new PcJobuserExample();
+        jobUserExp2.or().andUserMobileEqualTo(data.getUserMobile()).andJobuserIDNotEqualTo(data.getJobUserID());
+        var ifRepeatMobile = pcJobuserMapper.selectByExample(jobUserExp2).size()>0;
+
+        result += ifRepeatIdentity? 1:0;
+        result += ifRepeatMobile? 2:0;
+        return result;
+    }
+
     @Override
     public int baseInfoSave(JobUserVo data, String userId) {
         int result = 0;
+        var repeatResult = ifHadRepeatData(data);
+        switch (repeatResult){
+            default:
+            case 0:
+                break;
+            case 1:
+                throw new  BaseException("1004","身份证号码已存在!");
+            case 2:
+                throw new  BaseException("1004","联系电话已存在!");
+            case 3:
+                throw new  BaseException("1004","身份证号码、联系电话重复!");
+        }
         PcJobuser dbData = pcJobuserMapper.selectByPrimaryKey(data.getJobUserID());
         if (dbData == null) {
             dbData = new PcJobuser();