瀏覽代碼

推荐信息管理

lizeyu 1 年之前
父節點
當前提交
490d5551d0

+ 11 - 0
h5app/src/App.vue

@@ -204,6 +204,17 @@ ion-content {
 .list-page {
   --background: #fafafa !important;
 
+  .custom {
+    --placeholder-color: gray;
+    --placeholder-opacity: 0.5;
+  }
+
+  .container {
+    display: flex;
+    justify-content: center; /* 水平居中 */
+    align-items: center; /* 垂直居中 */
+  }
+
   .list-content {
     margin: 10px 8px;
     background-color: #f0f2f5;

+ 52 - 61
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">
     <ion-header class="header-theme2">
       <ion-toolbar>
         <ion-buttons slot="start">
@@ -11,33 +11,41 @@
     <ion-content>
       <ion-item class="search-item">
         <ion-input placeholder="姓名" class="custom"
-                   v-model="searchParams.jobUserName" style="border: 1px solid #f2f2f5;border-radius: 14px;--padding-start: 10px;height: 35px;"></ion-input>
-        <ion-button slot="end" style="height: 33px;width: 70px;margin-left: 10px;--box-shadow: none;--border-radius: 14px;" @click="reload" >搜索
+                   v-model="searchParams.jobUserName"
+                   style="border: 1px solid #f2f2f5;border-radius: 14px;--padding-start: 10px;height: 35px;"></ion-input>
+        <ion-button slot="end"
+                    style="height: 33px;width: 70px;margin-left: 10px;--box-shadow: none;--border-radius: 14px;"
+                    @click="reload">搜索
         </ion-button>
       </ion-item>
-      <ion-list class="list-content">
-        <ion-item v-for="(record,key) in dataList" :key="key">
-          <ion-label>
-            <ion-label style="display: flex;justify-content: space-between;">
-            <h2>{{ record.jobUserName}}</h2>
-            <h2>{{ record.professionName }}</h2>
-            </ion-label>
-            <p>人才类型:{{record.jobUserTypeStr}}</p>
-            <ion-label style="display: flex;justify-content: space-between;">
-              <p>
-                工作年限:{{ record.workYear }}
-              </p>
-              <p>
-                求职类型:{{ record.jobHuntTypeStr }}
-              </p>
-            </ion-label>
-            <p>月薪要求:{{ record.minSalary }}至{{ record.maxSalary }}元</p>
-          </ion-label>
-          <ion-avatar @click="onRecommendJob(record);$event.preventDefault();$event.stopPropagation();" aria-hidden="true" class="container" slot="end">
-            <p style="font-size: 14px !important;">推荐</p>
-          </ion-avatar>
-        </ion-item>
-      </ion-list>
+      <div class="bw-vue-list">
+        <div class="list-content">
+          <ion-list>
+            <ion-item v-for="(record,key) in dataList" :key="key">
+              <ion-label>
+                <div class="multi-title">
+                  <h2>{{ record.jobUserName }}</h2>
+                  <h2>{{ record.professionName }}</h2>
+                </div>
+                <p>人才类型:{{ record.jobUserTypeStr }}</p>
+                <div class="multi-title">
+                  <p>
+                    工作年限:{{ record.workYear }}
+                  </p>
+                  <p>
+                    求职类型:{{ record.jobHuntTypeStr }}
+                  </p>
+                </div>
+                <p>月薪要求:{{ record.minSalary }}至{{ record.maxSalary }}元</p>
+              </ion-label>
+              <ion-avatar @click="onRecommendJob(record);$event.preventDefault();$event.stopPropagation();"
+                          aria-hidden="true" class="container" slot="end">
+                <ion-button size="small" fill="outline">推荐</ion-button>
+              </ion-avatar>
+            </ion-item>
+          </ion-list>
+        </div>
+      </div>
       <b-empty v-if="dataList.length<=0" :loading="loading"/>
       <ion-infinite-scroll threshold="100px" @ionInfinite="onScroll($event)">
         <ion-infinite-scroll-content
@@ -104,8 +112,22 @@ export default defineComponent({
       }, 500);
     }
 
-    const onRecommendJob = (item: any) =>{
-      router.push({path: './recommend', query: {reload: 1,professionID:item.professionID,professionName:item.professionName,jobHuntID:item.jobHuntID,jobUserName:item.jobUserName,type:0}});
+    const onRecommendJob = (item: any) => {
+      router.push({
+        path: './recommend', query: {
+          reload: 1,
+          professionID: item.professionID,
+          professionName: item.professionName,
+          jobHuntID: item.jobHuntID,
+          jobUserName: item.jobUserName,
+          type: 0,
+          parentProfessionID: item.parentProfessionID,
+          cultureRank: item.cultureRank,
+          workYear: item.workYear,
+          minSalary: item.minSalary,
+          maxSalary: item.maxSalary
+        }
+      });
     }
 
     const onBack = () => {
@@ -113,7 +135,7 @@ export default defineComponent({
     }
 
     onIonViewDidEnter(() => {
-      if(route.query.reload)reload();
+      if (route.query.reload) reload();
     });
 
     return {
@@ -131,39 +153,8 @@ export default defineComponent({
       reload,
       dayjs,
     }
-  },created() {
+  }, created() {
     this.loadData();
   }
 });
 </script>
-
-<style lang="less">
-.custom{
-  --placeholder-color: gray;
-  --placeholder-opacity: 0.5;
-}
-
-.company-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;
-      }
-    }
-  }
-}
-
-.container {
-  display: flex;
-  justify-content: center; /* 水平居中 */
-  align-items: center; /* 垂直居中 */
-}
-</style>

+ 119 - 53
h5app/src/views/pages/jobhunt/recommend/recommend.vue

@@ -1,5 +1,5 @@
 <template>
-  <ion-page class="list-page company-list-page">
+  <ion-page class="list-page">
     <ion-header class="header-theme2">
       <ion-toolbar>
         <ion-buttons slot="start">
@@ -15,19 +15,49 @@
           <br/>
           <h2>{{ searchParams.professionName }}</h2>
         </ion-label>
+        <ion-button id="popover-checkbox" @click="popoverCheckboxIsOpen = true" slot="end"
+                    style="height: 33px;width: 70px;margin-left: 10px;--box-shadow: none;--border-radius: 14px;">招聘岗位筛选
+        </ion-button>
+        <ion-popover size="auto" trigger="popover-checkbox" :is-open="popoverCheckboxIsOpen" :backdrop-dismiss="false"
+                     :dismiss-on-select="false">
+          <ion-content>
+            <ion-list>
+              <ion-item v-for="(record,key) in recommendPostWhereList" :key="key">
+                <ion-checkbox :detail="false" v-model="record.check" label-placement="end">{{ record.name }}
+                </ion-checkbox>
+              </ion-item>
+              <ion-item>
+                <ion-button @click="onRestRecommendPostWhere" slot="end" fill="clear" size="small">重置</ion-button>
+                <ion-button @click="onPopoverConfirm" slot="end" size="small">确定</ion-button>
+              </ion-item>
+            </ion-list>
+          </ion-content>
+        </ion-popover>
       </ion-item>
-      <ion-list class="list-content">
-        <ion-item v-for="(record,key) in dataList" detail :key="key">
-          <ion-label>
-            <h2>{{ record.professionName }}</h2>
-            <p>单位:{{ record.companyName }}</p>
-            <p>薪资待遇:{{ record.minSalary }}至{{ record.maxSalary }}元</p>
-          </ion-label>
-          <ion-avatar aria-hidden="true" class="container" slot="end">
-            <ion-text style="text-align:right;" @click="onRecommend(record)">推荐</ion-text>
-          </ion-avatar>
-        </ion-item>
-      </ion-list>
+      <div class="bw-vue-list">
+        <div class="list-content">
+          <ion-list>
+            <ion-item v-for="(record,key) in dataList" :key="key">
+              <ion-label>
+                <h2>{{ record.professionName }}</h2>
+                <p>单位:{{ record.companyName }}</p>
+                <div class="multi-title">
+                  <p>
+                    学历:{{ record.cultureRankName }}
+                  </p>
+                  <p>
+                    工作年限:{{ record.workYearName }}
+                  </p>
+                </div>
+                <p>薪资待遇:{{ record.minSalary }}至{{ record.maxSalary }}元</p>
+              </ion-label>
+              <ion-avatar aria-hidden="true" class="container" slot="end">
+                <ion-button size="small" @click="onRecommend(record)" fill="outline">推荐</ion-button>
+              </ion-avatar>
+            </ion-item>
+          </ion-list>
+        </div>
+      </div>
       <b-empty v-if="dataList.length<=0" :loading="loading"/>
       <ion-infinite-scroll threshold="100px" @ionInfinite="onScroll($event)">
         <ion-infinite-scroll-content
@@ -48,6 +78,7 @@ import {computed, defineComponent, reactive, ref, watch} from 'vue';
 import {arrowBackOutline, addCircleOutline} from 'ionicons/icons';
 import {alertController, IonIcon, onIonViewDidEnter} from '@ionic/vue';
 import {getRecommendCompanyPostList, addRecommend} from "@/api/recommendmgt";
+import {getSysDictionaryList} from '@/api/system/dictionary'
 
 export default defineComponent({
   name: 'RecommendCompanyPost',
@@ -69,19 +100,35 @@ export default defineComponent({
       jobHuntID: '',
       professionID: '',
       professionName: null,
-      type: 0
+      type: 0,
+      parentProfessionID: '',
+      cultureRank: null,
+      workYear: null,
+      minSalary: null,
+      maxSalary: null
     })
+    const searchParamsCache = reactive({
+      professionID: '',
+      parentProfessionID: '',
+      cultureRank: null,
+      workYear: null,
+      minSalary: null,
+      maxSalary: null
+    });
     const dataList = ref<any>([]);
     const addRecommendList = ref<any>([]);
-    const colors = ref(["secondary", "tertiary", "success", "warning"]);
+    const recommendPostWhereList = ref<any>([]);
+    const popoverCheckboxIsOpen = ref<boolean>(false);
+
+    const getRecommendTypeList = () => {
+      getSysDictionaryList('RecommendPostWhere').then((data) => {
+        recommendPostWhereList.value = data;
+        recommendPostWhereList.value[0].check = true;
+      });
+    };
 
     const loadData = async function () {
       loading.value = true;
-      searchParams.jobHuntID = route.query.jobHuntID as any;
-      searchParams.jobUserName = route.query.jobUserName as any;
-      searchParams.professionID = route.query.professionID as any;
-      searchParams.professionName = route.query.professionName as any;
-      searchParams.type = route.query.type as any;
       getRecommendCompanyPostList(searchParams).then((data: any) => {
         dataList.value = dataList.value.concat(data.list);
         total.value = data.total;
@@ -99,6 +146,30 @@ export default defineComponent({
       }, 500);
     }
 
+    const onPopoverConfirm = () => {
+      const list = recommendPostWhereList.value.filter((x: any) => x.check == true).map((x: any) => x.value);
+
+      searchParams.professionID = list.findIndex((x: any) => x == 1) >= 0 ? searchParamsCache.professionID : "";
+      searchParams.cultureRank = list.findIndex((x: any) => x == 2) >= 0 ? searchParamsCache.cultureRank : null;
+      searchParams.workYear = list.findIndex((x: any) => x == 3) >= 0 ? searchParamsCache.workYear : null;
+      if (list.findIndex((x: any) => x == 4) >= 0) {
+        searchParams.minSalary = searchParamsCache.minSalary;
+        searchParams.maxSalary = searchParamsCache.maxSalary;
+      } else {
+        searchParams.minSalary = null;
+        searchParams.maxSalary = null;
+      }
+      searchParams.parentProfessionID = list.findIndex((x: any) => x == 5) >= 0 ? searchParamsCache.parentProfessionID : "";
+
+      popoverCheckboxIsOpen.value = false;
+      reload();
+    }
+
+    const onRestRecommendPostWhere = () => {
+      recommendPostWhereList.value.map((x: any) => x.check = false);
+      recommendPostWhereList.value[0].check = true;
+    }
+
     const onRecommend = (item: any) => {
       addRecommendList.value.push({
         recommendMgtID: item.recommendMgtID,
@@ -155,8 +226,25 @@ export default defineComponent({
       searchParams.pageIndex = 1;
       loadData();
     }
+
+    const reloadSearchParams = () => {
+      searchParams.jobHuntID = route.query.jobHuntID as any;
+      searchParams.jobUserName = route.query.jobUserName as any;
+      searchParams.professionID = route.query.professionID as any;
+      searchParams.professionName = route.query.professionName as any;
+      searchParams.type = route.query.type as any;
+      searchParamsCache.professionID = route.query.professionID as any;
+      searchParamsCache.parentProfessionID = route.query.parentProfessionID as any;
+      searchParamsCache.cultureRank = route.query.cultureRank as any;
+      searchParamsCache.workYear = route.query.workYear as any;
+      searchParamsCache.workYear = route.query.workYear as any;
+      searchParamsCache.minSalary = route.query.minSalary as any;
+      searchParamsCache.maxSalary = route.query.maxSalary as any;
+    }
+
     onIonViewDidEnter(() => {
       reload();
+      reloadSearchParams();
     });
 
     return {
@@ -164,56 +252,34 @@ export default defineComponent({
       addCircleOutline,
       router,
       route,
-      colors,
       loading,
       pagination,
       searchParams,
+      searchParamsCache,
       dataList,
+      recommendPostWhereList,
+      popoverCheckboxIsOpen,
       onScroll,
       loadData,
       reload,
       onBack,
       onRecommend,
       onBatchRecommend,
+      getRecommendTypeList,
+      onPopoverConfirm,
+      onRestRecommendPostWhere,
     }
+  }, created() {
+    this.getRecommendTypeList()
   }
 });
 </script>
 
 <style lang="less">
-.custom {
-  --placeholder-color: gray;
-  //--placeholder-font-style: italic;
-  --placeholder-opacity: 1;
-}
-
-.company-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;
-      }
-    }
-  }
-}
-
-.container {
-  display: flex;
-  justify-content: center; /* 水平居中 */
-  align-items: center; /* 垂直居中 */
-}
 
-.footer-ios ion-toolbar:first-of-type{
-  --border-width:0 !important;
-  --background:#ffffff !important;
+.footer-ios ion-toolbar:first-of-type {
+  --border-width: 0 !important;
+  --background: #ffffff !important;
 }
 
 </style>

+ 71 - 77
h5app/src/views/pages/post/list.vue

@@ -1,5 +1,5 @@
 <template>
-  <ion-page class="list-page company-list-page">
+  <ion-page class="list-page">
     <ion-header class="header-theme2">
       <ion-toolbar>
         <ion-buttons slot="start">
@@ -14,42 +14,53 @@
     <ion-content>
       <ion-item class="search-item">
         <ion-input placeholder="岗位名称" class="custom"
-                   v-model="searchParams.professionName" style="border: 1px solid #f2f2f5;border-radius: 14px;--padding-start: 10px;height: 35px;"></ion-input>
-        <ion-button slot="end" style="height: 33px;width: 70px;margin-left: 10px;--box-shadow: none;--border-radius: 14px;" @click="reload" >搜索
+                   v-model="searchParams.professionName"
+                   style="border: 1px solid #f2f2f5;border-radius: 14px;--padding-start: 10px;height: 35px;"></ion-input>
+        <ion-button slot="end"
+                    style="height: 33px;width: 70px;margin-left: 10px;--box-shadow: none;--border-radius: 14px;"
+                    @click="reload">搜索
         </ion-button>
       </ion-item>
-      <ion-list class="list-content">
-        <div v-for="(record,key) in dataList" :key="key">
-          <ion-item-sliding>
-        <ion-item>
-          <ion-label>
-            <h3>{{ record.professionName}}</h3>
-            <p>{{ record.companyName }}</p>
-            <p>{{ dayjs(record.startTime).format("YYYY-MM-DD")}}至{{ dayjs(record.endTime).format("YYYY-MM-DD")}}</p>
-            <ion-label style="display: flex;justify-content: space-between;">
-              <p>
-                招聘人数:{{ record.recruitCount == null ? "0" : record.recruitCount }}人
-              </p>
-              <p>
-                已推荐人数:{{ record.recommendNum }}
-              </p>
-            </ion-label>
-          </ion-label>
-          <ion-avatar @click="onRecommendJob(record);$event.preventDefault();$event.stopPropagation();" aria-hidden="true" class="container" slot="end">
-            <p style="font-size: 14px !important;">推荐</p>
-          </ion-avatar>
-        </ion-item>
-        <ion-item-options>
-          <ion-item-option @click="onEdit(record.postID)">
-            <ion-icon :icon="buildOutline"></ion-icon>
-          </ion-item-option>
-          <ion-item-option color="danger" @click="onDel(record.postID)">
-            <ion-icon :icon="trashOutline"></ion-icon>
-          </ion-item-option>
-        </ion-item-options>
-        </ion-item-sliding>
+      <div class="bw-vue-list">
+        <div class="list-content">
+          <ion-list>
+            <div v-for="(record,key) in dataList" :key="key" detail>
+              <ion-item-sliding>
+                <ion-item>
+                  <ion-label>
+                    <h3>{{ record.professionName }}</h3>
+                    <p>{{ record.companyName }}</p>
+                    <p>
+                      {{ dayjs(record.startTime).format("YYYY-MM-DD") }}至{{
+                        dayjs(record.endTime).format("YYYY-MM-DD")
+                      }}</p>
+                    <div class="multi-title">
+                      <p>
+                        招聘人数:{{ record.recruitCount == null ? "0" : record.recruitCount }}人
+                      </p>
+                      <p>
+                        已推荐人数:{{ record.recommendNum }}
+                      </p>
+                    </div>
+                  </ion-label>
+                  <ion-avatar @click="onRecommendJob(record);$event.preventDefault();$event.stopPropagation();"
+                              aria-hidden="true" class="container" slot="end">
+                    <ion-button size="small" fill="outline">推荐</ion-button>
+                  </ion-avatar>
+                </ion-item>
+                <ion-item-options>
+                  <ion-item-option @click="onEdit(record.postID)">
+                    <ion-icon :icon="buildOutline"></ion-icon>
+                  </ion-item-option>
+                  <ion-item-option color="danger" @click="onDel(record.postID)">
+                    <ion-icon :icon="trashOutline"></ion-icon>
+                  </ion-item-option>
+                </ion-item-options>
+              </ion-item-sliding>
+            </div>
+          </ion-list>
         </div>
-      </ion-list>
+      </div>
       <b-empty v-if="dataList.length<=0" :loading="loading"/>
       <ion-infinite-scroll threshold="100px" @ionInfinite="onScroll($event)">
         <ion-infinite-scroll-content
@@ -66,10 +77,10 @@
 import {computed, defineComponent, reactive, ref} from 'vue';
 import dayjs from "dayjs";
 import {useRoute, useRouter} from "vue-router";
-import {arrowBackOutline, addCircleOutline,buildOutline,trashOutline} from 'ionicons/icons';
+import {arrowBackOutline, addCircleOutline, buildOutline, trashOutline} from 'ionicons/icons';
 import {alertController, IonIcon, onIonViewDidEnter} from '@ionic/vue';
 import BEmpty from "@/components/empty.vue";
-import {getPostList,deletePostAndRecommendMgt} from '@/api/post/index'
+import {getPostList, deletePostAndRecommendMgt} from '@/api/post/index'
 
 export default defineComponent({
   name: 'PostList',
@@ -90,7 +101,6 @@ export default defineComponent({
       professionName: '',
     });
     const dataList = ref<any>([]);
-    const colors = ref(["secondary", "tertiary", "success", "warning"]);
 
     const loadData = async function () {
       loading.value = true;
@@ -119,15 +129,15 @@ export default defineComponent({
     }
 
     const onDetail = () => {
-      router.push({path: './detail', query: {reload: 1,id: null,status: 1}});
+      router.push({path: './detail', query: {reload: 1, id: null, status: 1}});
     }
 
     const onAdd = () => {
-      router.push({path: './edit', query: {reload: 1,id: null,status: 1}});
+      router.push({path: './edit', query: {reload: 1, id: null, status: 1}});
     }
 
-    const onEdit = (postID:string) => {
-      router.push({path: './edit', query: {reload: 1,id: postID,status: 2}});
+    const onEdit = (postID: string) => {
+      router.push({path: './edit', query: {reload: 1, id: postID, status: 2}});
     }
 
     const onDel = async (postID: any) => {
@@ -154,8 +164,23 @@ export default defineComponent({
       await alert.present();
     }
 
-    const onRecommendJob = (item: any) =>{
-      router.push({path: './recommendJob', query: {reload: 1,professionID:item.professionID,professionName:item.professionName,postID:item.postID,companyName:item.companyName,type:0}});
+    const onRecommendJob = (item: any) => {
+      router.push({
+        path: './recommendJob',
+        query: {
+          reload: 1,
+          professionID: item.professionID,
+          professionName: item.professionName,
+          postID: item.postID,
+          companyName: item.companyName,
+          type: 0,
+          parentProfessionID: item.parentProfessionID,
+          cultureRank: item.cultureRank,
+          workYear: item.workYear,
+          minSalary: item.minSalary,
+          maxSalary: item.maxSalary
+        }
+      });
     }
 
     const onBack = () => {
@@ -163,7 +188,7 @@ export default defineComponent({
     }
 
     onIonViewDidEnter(() => {
-      if(route.query.reload)reload();
+      if (route.query.reload) reload();
     });
 
     return {
@@ -187,39 +212,8 @@ export default defineComponent({
       reload,
       dayjs,
     }
-  },created() {
+  }, created() {
     this.loadData();
   }
 });
-</script>
-
-<style lang="less">
-.custom{
-  --placeholder-color: gray;
-  --placeholder-opacity: 0.5;
-}
-
-.company-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;
-      }
-    }
-  }
-}
-
-.container {
-  display: flex;
-  justify-content: center; /* 水平居中 */
-  align-items: center; /* 垂直居中 */
-}
-</style>
+</script>

+ 110 - 49
h5app/src/views/pages/post/recommendJob.vue

@@ -1,5 +1,5 @@
 <template>
-  <ion-page class="list-page company-list-page">
+  <ion-page class="list-page">
     <ion-header class="header-theme2">
       <ion-toolbar>
         <ion-buttons slot="start">
@@ -15,19 +15,41 @@
           <br/>
           <h2>{{ searchParams.companyName }}</h2>
         </ion-label>
+        <ion-button id="popover-checkbox" @click="popoverCheckboxIsOpen = true" slot="end"
+                    style="height: 33px;width: 90px;margin-left: 10px;--box-shadow: none;--border-radius: 14px;">求职人员筛选
+        </ion-button>
+        <ion-popover size="auto" trigger="popover-checkbox" :is-open="popoverCheckboxIsOpen" :backdrop-dismiss="false"
+                     :dismiss-on-select="false">
+          <ion-content>
+            <ion-list>
+              <ion-item v-for="(record,key) in recommendJobHuntWhereList" :key="key">
+                <ion-checkbox :detail="false" v-model="record.check" label-placement="end">{{ record.name }}
+                </ion-checkbox>
+              </ion-item>
+              <ion-item>
+                <ion-button @click="onRestRecommendWhere" slot="end" fill="clear" size="small">重置</ion-button>
+                <ion-button @click="onPopoverConfirm" slot="end" size="small">确定</ion-button>
+              </ion-item>
+            </ion-list>
+          </ion-content>
+        </ion-popover>
       </ion-item>
-      <ion-list class="list-content">
-        <ion-item v-for="(record,key) in dataList" detail :key="key">
-          <ion-label>
-            <h2>{{ record.userName }}</h2>
-            <p>应聘岗位:{{ record.professionName }}</p>
-            <p>电话:{{ record.userMobile }}</p>
-          </ion-label>
-          <ion-avatar aria-hidden="true" class="container" slot="end">
-            <ion-text style="text-align:right;" @click="onRecommend(record)">推荐</ion-text>
-          </ion-avatar>
-        </ion-item>
-      </ion-list>
+      <div class="bw-vue-list">
+        <div class="list-content">
+          <ion-list>
+            <ion-item v-for="(record,key) in dataList" :key="key">
+              <ion-label>
+                <h2>{{ record.userName }}</h2>
+                <p>应聘岗位:{{ record.professionName }}</p>
+                <p>电话:{{ record.userMobile }}</p>
+              </ion-label>
+              <ion-avatar aria-hidden="true" class="container" slot="end">
+                <ion-button size="small" @click="onRecommend(record)" fill="outline">推荐</ion-button>
+              </ion-avatar>
+            </ion-item>
+          </ion-list>
+        </div>
+      </div>
       <b-empty v-if="dataList.length<=0" :loading="loading"/>
       <ion-infinite-scroll threshold="100px" @ionInfinite="onScroll($event)">
         <ion-infinite-scroll-content
@@ -48,6 +70,7 @@ import {computed, defineComponent, reactive, ref, watch} from 'vue';
 import {arrowBackOutline, addCircleOutline} from 'ionicons/icons';
 import {alertController, IonIcon, onIonViewDidEnter} from '@ionic/vue';
 import {getRecommendJobList, addRecommend} from "@/api/recommendmgt";
+import {getSysDictionaryList} from "@/api/system/dictionary";
 
 export default defineComponent({
   name: 'RecommendJobList',
@@ -69,11 +92,32 @@ export default defineComponent({
       professionID: '',
       companyName: '',
       professionName: '',
-      type: 0
+      type: 0,
+      parentProfessionID: '',
+      cultureRank: null,
+      workYear: null,
+      minSalary: null,
+      maxSalary: null
     })
+    const searchParamsCache = reactive({
+      professionID: '',
+      parentProfessionID: '',
+      cultureRank: null,
+      workYear: null,
+      minSalary: null,
+      maxSalary: null
+    });
     const dataList = ref<any>([]);
     const addRecommendList = ref<any>([]);
-    const colors = ref(["secondary", "tertiary", "success", "warning"]);
+    const recommendJobHuntWhereList = ref<any>([]);
+    const popoverCheckboxIsOpen = ref<boolean>(false);
+
+    const getRecommendTypeList = () => {
+      getSysDictionaryList('RecommendJobHuntWhere').then((data) => {
+        recommendJobHuntWhereList.value = data;
+        recommendJobHuntWhereList.value[0].check = true;
+      });
+    };
 
     const loadData = async function () {
       loading.value = true;
@@ -89,6 +133,30 @@ export default defineComponent({
       loading.value = false;
     }
 
+    const onPopoverConfirm = () => {
+      const list = recommendJobHuntWhereList.value.filter((x: any) => x.check == true).map((x: any) => x.value);
+
+      searchParams.professionID = list.findIndex((x: any) => x == 1) >= 0 ? searchParamsCache.professionID : "";
+      searchParams.cultureRank = list.findIndex((x: any) => x == 2) >= 0 ? searchParamsCache.cultureRank : null;
+      searchParams.workYear = list.findIndex((x: any) => x == 3) >= 0 ? searchParamsCache.workYear : null;
+      if (list.findIndex((x: any) => x == 4) >= 0) {
+        searchParams.minSalary = searchParamsCache.minSalary;
+        searchParams.maxSalary = searchParamsCache.maxSalary;
+      } else {
+        searchParams.minSalary = null;
+        searchParams.maxSalary = null;
+      }
+      searchParams.parentProfessionID = list.findIndex((x: any) => x == 5) >= 0 ? searchParamsCache.parentProfessionID : "";
+
+      popoverCheckboxIsOpen.value = false;
+      reload();
+    }
+
+    const onRestRecommendWhere = () => {
+      recommendJobHuntWhereList.value.map((x: any) => x.check = false);
+      recommendJobHuntWhereList.value[0].check = true;
+    }
+
     const onScroll = (e: any) => {
       setTimeout(() => {
         e.target.complete();
@@ -155,8 +223,25 @@ export default defineComponent({
       searchParams.pageIndex = 1;
       loadData();
     }
+
+    const reloadSearchParams = () => {
+      searchParams.postID = route.query.postID as any;
+      searchParams.companyName = route.query.companyName as any;
+      searchParams.professionID = route.query.professionID as any;
+      searchParams.professionName = route.query.professionName as any;
+      searchParams.type = route.query.type as any;
+      searchParamsCache.professionID = route.query.professionID as any;
+      searchParamsCache.parentProfessionID = route.query.parentProfessionID as any;
+      searchParamsCache.cultureRank = route.query.cultureRank as any;
+      searchParamsCache.workYear = route.query.workYear as any;
+      searchParamsCache.workYear = route.query.workYear as any;
+      searchParamsCache.minSalary = route.query.minSalary as any;
+      searchParamsCache.maxSalary = route.query.maxSalary as any;
+    }
+
     onIonViewDidEnter(() => {
       reload();
+      reloadSearchParams();
     });
 
     return {
@@ -164,56 +249,32 @@ export default defineComponent({
       addCircleOutline,
       router,
       route,
-      colors,
       loading,
       pagination,
       searchParams,
       dataList,
+      recommendJobHuntWhereList,
+      popoverCheckboxIsOpen,
       onScroll,
       loadData,
       reload,
       onBack,
       onRecommend,
       onBatchRecommend,
+      getRecommendTypeList,
+      onPopoverConfirm,
+      onRestRecommendWhere,
     }
+  }, mounted() {
+    this.getRecommendTypeList()
   }
 });
 </script>
 
 <style lang="less">
-.custom {
-  --placeholder-color: gray;
-  //--placeholder-font-style: italic;
-  --placeholder-opacity: 1;
-}
-
-.company-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;
-      }
-    }
-  }
-}
-
-.container {
-  display: flex;
-  justify-content: center; /* 水平居中 */
-  align-items: center; /* 垂直居中 */
-}
-
-.footer-ios ion-toolbar:first-of-type{
-  --border-width:0 !important;
-  --background:#ffffff !important;
+.footer-ios ion-toolbar:first-of-type {
+  --border-width: 0 !important;
+  --background: #ffffff !important;
 }
 
 </style>

+ 25 - 53
h5app/src/views/pages/recommendMgt/list.vue

@@ -1,5 +1,5 @@
 <template>
-  <ion-page class="list-page company-list-page">
+  <ion-page class="list-page">
     <ion-header class="header-theme2">
       <ion-toolbar>
         <ion-buttons slot="start">
@@ -18,25 +18,29 @@
                     @click="reload">搜索
         </ion-button>
       </ion-item>
-      <ion-list class="list-content">
-        <ion-item v-for="(record,key) in dataList" :key="key" detail @click="onDetail(record.recommendMgtID)">
-          <ion-label>
-            <h2>{{ record.name }}</h2>
-            <ion-label style="display: flex;justify-content: space-between;">
-              <p>求职岗位:{{ record.qzProfessionName }}</p>
-              <p>{{ record.entryStateName }}</p>
-            </ion-label>
-            <p>招聘企业:{{ record.companyName }}</p>
-            <ion-label style="display: flex;justify-content: space-between;">
-              <p>联系电话:{{ record.userMobile }}</p>
-              <p>企业电话:{{ record.companyMobile }}</p>
-            </ion-label>
-            <p>
-              推送时间:{{ dayjs(record.createTime).format('YYYY-MM-DD') }}
-            </p>
-          </ion-label>
-        </ion-item>
-      </ion-list>
+      <div class="bw-vue-list">
+        <div class="list-content">
+          <ion-list>
+            <ion-item v-for="(record,key) in dataList" :key="key" detail @click="onDetail(record.recommendMgtID)">
+              <ion-label>
+                <h2>{{ record.name }}</h2>
+                <div class="multi-title">
+                  <p>求职岗位:{{ record.qzProfessionName }}</p>
+                  <p>{{ record.entryStateName }}</p>
+                </div>
+                <p>招聘企业:{{ record.companyName }}</p>
+                <div class="multi-title">
+                  <p>联系电话:{{ record.userMobile }}</p>
+                  <p>企业电话:{{ record.companyMobile }}</p>
+                </div>
+                <p>
+                  推送时间:{{ dayjs(record.createTime).format('YYYY-MM-DD') }}
+                </p>
+              </ion-label>
+            </ion-item>
+          </ion-list>
+        </div>
+      </div>
       <b-empty v-if="dataList.length<=0" :loading="loading"/>
       <ion-infinite-scroll threshold="100px" @ionInfinite="onScroll($event)">
         <ion-infinite-scroll-content
@@ -104,7 +108,7 @@ export default defineComponent({
     }
 
     const onDetail = (recommendMgtID: any) => {
-      router.push({path: './detail', query: {reload: 1, id: recommendMgtID,status: 1}});
+      router.push({path: './detail', query: {reload: 1, id: recommendMgtID, status: 1}});
     }
 
     const onBack = () => {
@@ -135,35 +139,3 @@ export default defineComponent({
   }
 });
 </script>
-
-<style lang="less">
-.custom {
-  --placeholder-color: gray;
-  //--placeholder-font-style: italic;
-  --placeholder-opacity: 1;
-}
-
-.company-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;
-      }
-    }
-  }
-}
-
-.container {
-  display: flex;
-  justify-content: center; /* 水平居中 */
-  align-items: center; /* 垂直居中 */
-}
-</style>

+ 2 - 0
src/main/java/com/hz/employmentsite/vo/jobUserManager/RecommendCompanyPostVo.java

@@ -13,4 +13,6 @@ public class RecommendCompanyPostVo {
     public String professionID;
     public String maxSalary;
     public String minSalary;
+    public String cultureRankName;
+    public String workYearName;
 }

+ 28 - 19
src/main/resources/mapping/cquery/RecommendMgtCQuery.xml

@@ -60,11 +60,14 @@
             resultType="com.hz.employmentsite.vo.jobUserManager.RecommendCompanyPostVo">
         select a.postid,b.companyname,c.professionname,a.recruitcount,a.starttime,a.endtime,b.companyAddress,
         case when d.recommendmgtid is null then '未推荐' else '已推荐' end as isRecommend,
-        d.recommendMgtID,a.professionid,c.professionname,a.maxsalary,a.minsalary
+        d.recommendMgtID,a.professionid,a.maxsalary,a.minsalary,
+        dic1.`name` as culturerankname, dic2.`name` as workyearname
         from pc_post a
         left join pc_company b on a.CompanyID = b.CompanyID
         left join pc_profession c on a.ProfessionID = c.ProfessionID
         left join pc_recommend_mgt d on a.PostID = d.PostID and d.JobHuntID = #{jobHuntID}
+        left join (select `Value`,`Name` from sys_dictionary_item where DictionaryCode='CultureLevel') dic1 on a.CultureRank = dic1.`Value`
+        left join (select `Value`,`Name` from sys_dictionary_item where DictionaryCode='WorkYearType') dic2 on a.WorkYear = dic2.`Value`
         <where>
             <if test="type!=null and type==0">
                 and d.RecommendMgtID is null
@@ -101,12 +104,18 @@
                     <otherwise>and 1=1</otherwise>
                 </choose>
             </if>
-            <if test="minSalary!=null and minSalary!=''">
-                and a.MinSalary <![CDATA[<=]]> #{minSalary}
-            </if>
-            <if test="maxSalary!=null and maxSalary!=''">
-                and a.MaxSalary <![CDATA[>=]]> #{maxSalary}
-            </if>
+            <choose>
+                <when test="minSalary!=null and maxSalary!=null">
+                    and a.MinSalary <![CDATA[<=]]> #{maxSalary} and a.MaxSalary <![CDATA[>=]]> #{minSalary}
+                </when>
+                <when test="minSalary!=null and minSalary!=''">
+                    and a.MinSalary <![CDATA[>=]]> #{minSalary}
+                </when>
+                <when test="maxSalary!=null and maxSalary!=''">
+                    and a.MaxSalary <![CDATA[<=]]> #{maxSalary}
+                </when>
+                <otherwise>and 1=1</otherwise>
+            </choose>
         </where>
         order by a.CreateTime desc
     </select>
@@ -153,18 +162,18 @@
             <if test="workYear!=null and workYear!=''">
                 and a.WorkYear <![CDATA[<=]]> #{workYear}
             </if>
-        <choose>
-            <when test="minSalary!=null and maxSalary!=null">
-                and a.MinSalary <![CDATA[<=]]> #{maxSalary} and a.MaxSalary <![CDATA[>=]]> #{minSalary}
-            </when>
-            <when test="minSalary!=null and minSalary!=''">
-                and a.MinSalary <![CDATA[>=]]> #{minSalary}
-            </when>
-            <when test="maxSalary!=null and maxSalary!=''">
-                and a.MaxSalary <![CDATA[<=]]> #{maxSalary}
-            </when>
-            <otherwise>and 1=1</otherwise>
-        </choose>
+            <choose>
+                <when test="minSalary!=null and maxSalary!=null">
+                    and a.MinSalary <![CDATA[<=]]> #{maxSalary} and a.MaxSalary <![CDATA[>=]]> #{minSalary}
+                </when>
+                <when test="minSalary!=null and minSalary!=''">
+                    and a.MinSalary <![CDATA[>=]]> #{minSalary}
+                </when>
+                <when test="maxSalary!=null and maxSalary!=''">
+                    and a.MaxSalary <![CDATA[<=]]> #{maxSalary}
+                </when>
+                <otherwise>and 1=1</otherwise>
+            </choose>
         </where>
         order by a.CreateTime desc
     </select>

+ 35 - 7
vue/src/views/jobUserManager/jobhunt/recommend.vue

@@ -1,6 +1,6 @@
 <template>
   <a-modal
-    :width="1100"
+    :width="1400"
     v-model:visible="visible"
     :title="title"
     :confirm-loading="confirmLoading"
@@ -165,16 +165,25 @@ export default defineComponent({
         customRender: (item) =>
           `${searchParams.pageSize * (searchParams.pageIndex - 1) + item.index + 1}`,
       },
-      {title: '企业名称', dataIndex: 'companyName', key: 'companyName', width: 100, align: "center",},
-      {title: '招聘岗位', dataIndex: 'professionName', key: 'professionName', width: 150, align: "center",},
-      {title: '招聘人数', dataIndex: 'recruitCount', key: 'recruitCount', width: 150, align: "center",},
-      {title: '工作地点', dataIndex: 'companyAddress', key: 'companyAddress', width: 150, align: "center",},
+      {title: '企业名称', dataIndex: 'companyName', key: 'companyName', align: "center",},
+      {title: '招聘岗位', dataIndex: 'professionName', key: 'professionName', align: "center",},
+      {title: '要求学历', dataIndex: 'cultureRankName', key: 'cultureRankName', align: "center",},
+      {title: '工作年限', dataIndex: 'workYearName', key: 'workYearName', align: "center",},
+      {title: '招聘人数', dataIndex: 'recruitCount', key: 'recruitCount', align: "center",},
       {
-        title: '工作开始时间', dataIndex: 'startTime', key: 'startTime', width: 100, align: "center",
+        title: '薪资要求', dataIndex: 'salary', key: 'salary', align: "center",
+        customRender: (item) => {
+          const salary = showSalary(item.record.minSalary, item.record.maxSalary);
+          return salary;
+        }
+      },
+      {title: '工作地点', dataIndex: 'companyAddress', key: 'companyAddress', align: "center",},
+      {
+        title: '工作开始时间', dataIndex: 'startTime', key: 'startTime', align: "center",
         customRender: ({record}) => record.startTime == null ? "" : dayjs(record.startTime).format('YYYY-MM-DD'),
       },
       {
-        title: '工作结束时间', dataIndex: 'endTime', key: 'endTime', width: 100, align: "center",
+        title: '工作结束时间', dataIndex: 'endTime', key: 'endTime',align: "center",
         customRender: ({record}) => record.endTime == null ? "" : dayjs(record.endTime).format('YYYY-MM-DD'),
       },
       {title: '操作', key: 'operation', width: 60, align: 'center'},
@@ -228,6 +237,7 @@ export default defineComponent({
         indeterminate: false,
       });
     };
+
     watch(
       () => state.checkRecommendPostWhereList,
       val => {
@@ -236,6 +246,22 @@ export default defineComponent({
       },
     );
 
+    const showSalary = (minSalary: any, maxSalary: any) => {
+      if (minSalary != null) {
+        if (maxSalary != null) {
+          return minSalary.toString() + "-" + maxSalary.toString();
+        } else {
+          return "≥" + minSalary.toString();
+        }
+      } else {
+        if (maxSalary != null) {
+          return "≤" + maxSalary.toString();
+        } else {
+          return "";
+        }
+      }
+    }
+
     const show = (professionID: any, professionName: any, jobHuntID: any, jobUserName: any, type: any,
                   parentProfessionID: any, cultureRank: any, workYear: any, minSalary: any, maxSalary: any,
                   titleName: string) => {
@@ -245,6 +271,7 @@ export default defineComponent({
       searchParams.professionID = professionID;
       searchParams.professionName = professionName;
       searchParams.type = type;
+      state.checkRecommendPostWhereList = [1];
       state.professionID = professionID;
       state.parentProfessionID = parentProfessionID;
       state.cultureRank = cultureRank;
@@ -320,6 +347,7 @@ export default defineComponent({
       recommendPostWhereList,
       show,
       onSearch,
+      showSalary,
       onCheckAllChange,
       onRecommend,
       onBatchRecommend,