dxj преди 6 години
родител
ревизия
6760541aeb
променени са 3 файла, в които са добавени 366 реда и са изтрити 96 реда
  1. 150 1
      assets/css/job/index.scss
  2. 26 23
      components/job/dealSeoIndex.js
  3. 190 72
      pages/job/index.vue

+ 150 - 1
assets/css/job/index.scss

@@ -1,7 +1,6 @@
 @import "../scssCommon";
 
 .jobList {
-
   .topArea {
     position: relative;
     width: 100%;
@@ -305,9 +304,159 @@
 
 }
 
+.jobListMobile {
+  width: 100vw;
+  height: 100vh;
+  overflow: hidden;
+
+  a {
+    display: block;
+  }
+  .topSelect {
+    height: pxtovw(45);
+    margin-bottom: pxtovw(5);
+  }
+  .listArea {
+    height: calc(100vh - 50px);
+    width: 100%;
+    overflow-x: hidden;
+    overflow-y: scroll;
+    background-color: #f6f5f8;
+
+    .sTitle {
+      height: 25px;
+      font-size: 18px;
+      font-weight: 500;
+      color: rgba(34, 34, 34, 1);
+      line-height: 25px;
+      margin-bottom: 14px;
+    }
+    .list {
+      .cell {
+        background: #FFF;
+        display: flex;
+        justify-content: center;
+        min-height: pxtovw(170);
+        width: 100%;
+        margin-top: pxtovw(5);
+        cursor: pointer;
+        flex-direction: column;
+        padding: pxtovw(17) pxtovw(10) pxtovw(7) pxtovw(10);
+
+        .topArea {
+          width: 100%;
+          height: pxtovw(22);
+          display: flex;
+          justify-content: space-between;
+          align-items: center;
+
+          .left {
+            max-width:pxtovw(231);
+            height:pxtovw(22);
+            font-size:pxtovw(16);
+            font-weight:600;
+            color:rgba(34,34,34,1);
+            line-height:pxtovw(22);
+            overflow: hidden;
+            text-overflow: ellipsis;
+            word-break: keep-all;
+            white-space: nowrap;
+          }
+          .right {
+            height:pxtovw(20);
+            font-size:pxtovw(17);
+            font-weight:600;
+            color:rgba(48,142,255,1);
+            line-height:pxtovw(20);
+          }
+        }
+        .workDesc {
+          margin-top: pxtovw(7);
+          flex-shrink: 0;
+          height:pxtovw(36);
+          font-size:pxtovw(13);
+          font-weight:400;
+          color:rgba(102,102,102,1);
+          line-height:pxtovw(18);
+          display: -webkit-box;
+          overflow: hidden;
+          text-overflow: ellipsis;
+          -webkit-box-orient: vertical;
+          -webkit-line-clamp: 2;
+        }
+        .labelList {
+          margin-top: pxtovw(11);
+          width: 100%;
+          display: flex;
+          overflow: hidden;
+          .label {
+            margin-left: pxtovw(10);
+            background:rgba(238,238,238,1);
+            border-radius: pxtovw(1);
+            box-sizing: content-box;
+            padding: pxtovw(5) pxtovw(10);
+            &:nth-child(1) {
+              margin-left: 0;
+            }
+            p {
+              height:pxtovw(16);
+              font-size:pxtovw(15);
+              font-weight:500;
+              color:rgba(102,102,102,1);
+              line-height:pxtovw(16);
+              transform: scale(0.733);
+              transform-origin: center;
+            }
+          }
+        }
+        .companyInfo {
+          margin-top: pxtovw(11);
+          padding-top: pxtovw(11);
+          display: flex;
+          width: 100%;
+          justify-content: flex-start;
+          align-items: center;
+          cursor: pointer;
+          border-top:pxtovw(1) solid rgba(136,136,136,0.1);;
+          .logo {
+            width:pxtovw(18);
+            height:pxtovw(18);
+            font-size: 0;
+            img {
+              width:pxtovw(18);
+              height:pxtovw(18);
+              border-radius: pxtovw(2);
+            }
+          }
+          .companyName {
+            margin-left: pxtovw(7);
+            height:pxtovw(16);
+            font-size:pxtovw(11);
+            font-weight:400;
+            color:rgba(102,102,102,1);
+            line-height:pxtovw(16);
+          }
+
+        }
+      }
+      .noneData {
+        min-height: pxtovw(100);
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        p {
+          text-align: center;
+        }
+      }
+    }
+  }
+}
+
 .main {
   margin-top: 0 !important;
   &.isMobile {
     width: 100vw;
   }
 }
+
+

+ 26 - 23
components/job/dealSeoIndex.js

@@ -8,6 +8,7 @@ export default class DealSeoData {
     this.selected = {
       city: 0,
       direction: 0, //职业角色 大
+      directionIndex: 0, //移动端索引
       directionSmall: 0,
       workType: 0,
     }
@@ -20,11 +21,11 @@ export default class DealSeoData {
     this.dataList = []
     this.provinces = []
   }
-  
+
   async dealData() {
     let { name, query: { page = 1 }, path, params, fullPath } = this.app.context.route
     this.page.page = page
-    
+
     //兼容APP 如果是带有 ${id}.html的,跳转到详情页
     let endStr = path.split('/').pop()
     console.log("endStr", endStr)
@@ -32,7 +33,7 @@ export default class DealSeoData {
       this.redirect(301, "/job/detail/"+endStr)
       return
     }
-    
+
     if (path && path[ path.length - 1 ] !== '/') {
       let reditUrl = fullPath
       reditUrl = reditUrl.replace(path, path + '/')
@@ -89,7 +90,7 @@ export default class DealSeoData {
             this.error({ statusCode: 404, message: "您要访问的页面不存在" })
             return
           }
-          
+
           if (this.selected[ "provice" ]) {
             let item = this.provinces.filter(item => item.id === this.selected[ "provice" ])[ 0 ]
             this.selected[ "proviceName" ] = item && item.name
@@ -115,7 +116,7 @@ export default class DealSeoData {
       breadcrumbList: this.dealBreadcrumbList()
     }
   }
-  
+
   async getTypeList() {
     let res = await this.$axios.get('/api/recruit/get_options')
     let typeList = {
@@ -130,16 +131,15 @@ export default class DealSeoData {
       },
       workType: {
         title: '工作方式',
-        list: [ { id: 0, name: "全部" }, { id: 1, name: "远程", slug: "yuancheng" }, {
-          id: 2,
-          name: "驻场",
-          slug: "zhuchang"
+        list: [ { id: 0, name: "全部",  value: 0, text: "全部方式",  },
+          { id: 1, name: "远程", value: 1, text: "远程",  slug: "yuancheng" }, {
+          id: 2, name: "驻场", value: 2, text: "驻场", slug: "zhuchang"
         } ]
       }
     }
-    
+
     if (Number(res.data.status) === 1) {
-      res.data.data.direction.unshift({ id: 0, name: "全部" })
+      res.data.data.direction.unshift({ id: 0, name: "全部", children:[] })
       res.data.data.cities.unshift({ id: 0, name: "全部" })
       Object.keys(res.data.data).forEach(key => {
         let item = res.data.data[ key ]
@@ -147,24 +147,31 @@ export default class DealSeoData {
           item.forEach(ii => {
             ii.name = ii.name || ii.occupation_name || ""
             ii.id = Number(ii.id || ii.occupation_id || 0)
+            ii.text = ii.name
+            ii.value = ii.id
             if (Array.isArray(ii.children)) {
               ii.children.forEach(jj => {
                 jj.name = jj.name || jj.direction_name || ""
                 jj.id = Number(jj.id || jj.direction_id || 0)
+                jj.text = jj.name
+                jj.value = jj.id
               })
-              if (ii.children.length > 1) {
-                ii.children.unshift({ id: 0, name: "全部" })
+              if (ii.children) {
+                ii.children.unshift({ id: 0, name: "全部", value: 0, text: "全部", })
               }
             }
           })
         }
       })
+      //单独设置百度app 选择器文案
+      res.data.data.direction[0] = {...res.data.data.direction[0], text: "全部职业", value: 0, }
+      res.data.data.cities[0] = {...res.data.data.cities[0], text: "全部地区", value: 0}
       typeList.direction.list = [ ...res.data.data.direction ]
       typeList.city.list = [ ...res.data.data.cities ]
     }
     return typeList
   }
-  
+
   async getList() {
     const { page, selected: {city, direction, directionSmall, workType} } = this
     let p = {
@@ -174,17 +181,13 @@ export default class DealSeoData {
     direction && (p.occupationId = direction) //一级
     workType && (p.workType = workType)
     directionSmall && (p.directionId = directionSmall) //耳二级
-    
+
     console.log("获取 /api/recruit/search", p)
     let res = await this.$axios.post('/api/recruit/search', p)
     if (Number(res.data.status) === 1) {
       let data = res.data.data
-      console.log("data***", data)
       this.page.total = data.total
       let dataList = data.list || []
-      dataList.forEach(item => {
-        item[ 'successCase' ] = ''
-      })
       this.dataList = [ ...dataList ]
       this.page.page += 1
       this.page.current = Number(data.page)
@@ -193,7 +196,7 @@ export default class DealSeoData {
       }
     }
   }
-  
+
   dealThisMeta() {
     const {
       city, cityName = "",
@@ -204,7 +207,7 @@ export default class DealSeoData {
     const { headers: { host }, url } = this.req
     let job = directionSmall || direction
     let jobName = directionSmallName === "全部" ?  directionName : (directionSmallName || directionName)
-    
+
     let head = {
       title: "", keyword: "", descrption: "", h1: "", canonical: "", metaLocation: ""
     }
@@ -240,7 +243,7 @@ export default class DealSeoData {
     }
     return head
   }
-  
+
   /** 处理面包屑导航 **/
   dealBreadcrumbList() {
     let list = [
@@ -251,7 +254,7 @@ export default class DealSeoData {
     let job = directionSmall || direction
     let jobName = directionSmallName === "全部" ?  directionName : (directionSmallName || directionName)
     let jobSlug = directionSmallSlug || directionSlug
-    
+
     if (city && job) {
       //兼职城市&岗位页  ${jobName}兼职招聘>${cityName}${jobName}兼职招聘,并赋予对应的url
       list.push({ name: `${jobName}兼职招聘`, url: `/job/${jobSlug}/` })

+ 190 - 72
pages/job/index.vue

@@ -1,43 +1,44 @@
 <template>
   <div :class="{isMobile: mobile}">
-    <div class="jobList">
-      <div class="topArea" v-if="!isSeoList">
-<!--{{JSON.stringify(typeList)}}-->
-      </div>
-      <div class="contentArea">
-        <div class="selectArea" v-if="!isSeoList">
-          <div class="selectContent" v-for="(key, i) in Object.keys(typeList)" :key="i + 'selectContent'">
-            <div class="content">
-              <div class="left"><p>{{typeList[key].title}}</p></div>
-              <div class="right">
+    <div v-if="!mobile">
+      <div class="jobList">
+        <div class="topArea" v-if="!isSeoList">
+          <!--{{JSON.stringify(typeList)}}-->
+        </div>
+        <div class="contentArea">
+          <div class="selectArea" v-if="!isSeoList">
+            <div class="selectContent" v-for="(key, i) in Object.keys(typeList)" :key="i + 'selectContent'">
+              <div class="content">
+                <div class="left"><p>{{typeList[key].title}}</p></div>
+                <div class="right">
+                  <div class="cell"
+                       v-for="(item, ii) in typeList[key].list"
+                       :class="{selected: item.id === selected[key], noneClick: !canSelectCity && key === 'city'}"
+                       @click="changeIndexSeo(key, item)"
+                       v-if="ii < 8 || expansion[key]"
+                       :key="ii+key+item.id"
+                  >
+                    <p>{{item.name}}</p>
+                  </div>
+                </div>
+                <div class="more" @click="changeExpansion(key)" v-if="typeList[key].list.length > 8">
+                  {{expansion[key] ? "收起" : "更多"}}
+                </div>
+              </div>
+              <div class="smallContent"
+                   v-if="key === 'direction' && typeList[key].smallList.length > 0"
+              >
                 <div class="cell"
-                  v-for="(item, ii) in typeList[key].list"
-                  :class="{selected: item.id === selected[key], noneClick: !canSelectCity && key === 'city'}"
-                  @click="changeIndexSeo(key, item)"
-                  v-if="ii < 8 || expansion[key]"
-                  :key="ii+key+item.id"
+                     v-for="(item) in typeList[key].smallList"
+                     :class="{selected: item.id === selected.directionSmall}"
+                     @click="changeIndexSeo('directionSmall', item)"
                 >
                   <p>{{item.name}}</p>
                 </div>
               </div>
-              <div class="more" @click="changeExpansion(key)" v-if="typeList[key].list.length > 8">
-                {{expansion[key] ? "收起" : "更多"}}
-              </div>
-            </div>
-            <div class="smallContent"
-              v-if="key === 'direction' && typeList[key].smallList.length > 0"
-            >
-              <div class="cell"
-                v-for="(item) in typeList[key].smallList"
-                :class="{selected: item.id === selected.directionSmall}"
-                @click="changeIndexSeo('directionSmall', item)"
-              >
-                <p>{{item.name}}</p>
-              </div>
             </div>
           </div>
-        </div>
-        <div class="breadcrumb">
+          <div class="breadcrumb">
             <a
               v-for="(item, index) in breadcrumbList"
               :key="'breadcrumb'+index"
@@ -47,55 +48,112 @@
               <p v-if="index!==breadcrumbList.length-1">{{item.name}} <span>&nbsp;>&nbsp;</span></p>
               <h1 v-else>{{item.name}}</h1>
             </a>
-        </div>
-        <div class="listArea">
-          <!--<h1 class="sTitle">{{head.h1 || '解决方案'}}</h1>-->
-          <div class="list" v-loading="loading">
-            <nuxt-link class="cell"
-              v-for="item in dataList"
-              :key="item.id"
-              :to="`/job/detail/${item.id}.html`"
-              target="_blank"
-              :title="item.name"
-            >
-              <div class="topArea">
-                <div class="left">{{item.title}}</div>
-                <div class="right">{{item.salaryName}}</div>
-              </div>
-              <div class="workDesc">{{item.description}}</div>
-              <div class="labelList">
-                <div class="label" v-for="skill in (item.skills || [])"><p>{{skill.name}}</p></div>
-              </div>
-              <div class="companyInfo" @click.stop="jumpToCompanyInfo(item)">
-                <div class="logo">
-                  <img :src="item.companyInfo.logo" alt=""/>
+          </div>
+          <div class="listArea">
+            <!--<h1 class="sTitle">{{head.h1 || '解决方案'}}</h1>-->
+            <div class="list" v-loading="loading">
+              <nuxt-link class="cell"
+                         v-for="item in dataList"
+                         :key="item.id"
+                         :to="`/job/detail/${item.id}.html`"
+                         target="_blank"
+                         :title="item.name"
+              >
+                <div class="topArea">
+                  <div class="left">{{item.title}}</div>
+                  <div class="right">{{item.salaryName}}</div>
                 </div>
-                <div class="companyName">{{item.companyInfo.name || item.companyInfo.shortName}}</div>
+                <div class="workDesc">{{item.description}}</div>
+                <div class="labelList">
+                  <div class="label" v-for="skill in (item.skills || [])"><p>{{skill.name}}</p></div>
+                </div>
+                <div class="companyInfo" @click.stop="jumpToCompanyInfo(item)">
+                  <div class="logo">
+                    <img :src="item.companyInfo.logo" alt=""/>
+                  </div>
+                  <div class="companyName">{{item.companyInfo.name || item.companyInfo.shortName}}</div>
+                </div>
+              </nuxt-link>
+              <div v-if="dataList.length === 0" class="noneData">
+                <p>没有数据</p>
               </div>
-            </nuxt-link>
-            <div v-if="dataList.length === 0" class="noneData">
-              <p>没有数据</p>
             </div>
           </div>
-        </div>
-        <div class="pagination">
-          <el-pagination v-if="!isSeoList" background layout="prev, pager, next" :total="page.total"
-            :page-size="page.pageSize" @current-change="pageChange" :current-page="Number(page.current
+          <div class="pagination">
+            <el-pagination v-if="!isSeoList" background layout="prev, pager, next" :total="page.total"
+                           :page-size="page.pageSize" @current-change="pageChange" :current-page="Number(page.current
             )"></el-pagination>
-          <div v-else>
-            <div class="list">
-              <nuxt-link v-for="(item,index) in new Array(Math.ceil(page.total / page.size))"
-                :to="`/job/?page=${index+1}`"
-                :key="(page)+index"
-              >
-                {{index+1}}
-              </nuxt-link>
+            <div v-else>
+              <div class="list">
+                <nuxt-link v-for="(item,index) in new Array(Math.ceil(page.total / page.size))"
+                           :to="`/job/?page=${index+1}`"
+                           :key="(page)+index"
+                >
+                  {{index+1}}
+                </nuxt-link>
+              </div>
             </div>
           </div>
         </div>
       </div>
+      <SeoFooter style="" :data="footer"/>
+    </div>
+    <div v-else class="jobListMobile">
+      <div class="topSelect">
+        <van-dropdown-menu>
+          <!--方式-->
+          <van-dropdown-item v-model="selected['workType']" :options="typeList['workType'].list" key="workType" @change="changeIndex('workType')"/>
+          <!--地区-->
+          <van-dropdown-item v-model="selected['city']" :options="typeList['city'].list" key="city"  @change="changeIndex('city')" :disabled="selected.workType===1"/>
+          <!--职业-->
+          <van-dropdown-item :title="calcName.text" key="direction" ref="directionSelect">
+            <van-tree-select
+              :items="typeList['direction'].list"
+              active-id="1123321100"
+              :main-active-index.sync="selected['directionIndex']"
+              @click-item="(data)=>{changeIndex('directionSmall', data)}"
+            />
+          </van-dropdown-item>
+        </van-dropdown-menu>
+      </div>
+      <van-pull-refresh v-model="refreshing" @refresh="onRefresh" class="listArea">
+        <div style="text-align: center" v-if="firstLoading">
+          <van-loading size="24px">加载中...</van-loading>
+        </div>
+        <van-list
+          v-else
+          v-model="loading"
+          :finished="finished"
+          finished-text="没有更多了"
+          @load="onLoad"
+          :immediate-check="false"
+          class="list"
+        >
+          <nuxt-link class="cell"
+                     v-for="item in dataList"
+                     :key="item.id"
+                     :to="`/job/detail/${item.id}.html`"
+                     target="_blank"
+                     :title="item.name"
+          >
+            <div class="topArea">
+              <div class="left">{{item.title}}</div>
+              <div class="right">{{item.salaryName}}</div>
+            </div>
+            <div class="workDesc">{{item.description}}</div>
+            <div class="labelList">
+              <div class="label" v-for="skill in (item.skills || [])"><p>{{skill.name}}</p></div>
+            </div>
+            <div class="companyInfo" @click.stop="jumpToCompanyInfo(item)">
+              <div class="logo">
+                <img :src="item.companyInfo.logo" alt=""/>
+              </div>
+              <div class="companyName">{{item.companyInfo.name || item.companyInfo.shortName}}</div>
+            </div>
+          </nuxt-link>
+        </van-list>
+      </van-pull-refresh>
     </div>
-    <SeoFooter style="" :data="footer"/>
   </div>
 </template>
 
@@ -173,6 +231,16 @@
       canSelectCity() {
         //远程无法选中地区
         return this.selected.workType !== 1
+      },
+      calcName() {
+        const {direction, directionSmall, directionName = "", directionSmallName = "", } = this.selected
+        let job = directionSmall || direction
+        let jobName = directionSmallName === "全部" ?  directionName : (directionSmallName || directionName)
+
+        return {
+          text: jobName || '全部职业',
+          value: job
+        }
       }
     },
     created() {
@@ -185,6 +253,44 @@
       }
     },
     methods: {
+      //移动端选择器
+      changeIndex(key, item) {
+        //级联选择 特殊处理一下
+        console.log(this.selected, this.typeList)
+        if (key === 'directionSmall') {
+          //当右侧选择的不是"全部"选项的时候,将大选项初始化
+          if (item.id) {
+            this.selected[ 'direction'] = 0
+            this.selected[ 'directionName'] = ''
+            this.selected[ 'directionSlug'] = ''
+            this.selected[ key] = item.id
+            this.selected[ key + 'Name' ] = item.name
+            this.selected[ key + 'Slug' ] = item.slug
+          } else {
+            //当右侧选择的是"全部"选项的时候, 将右侧数据初始化,只保留左侧数据
+            //左侧更改时 直接更改的是索引index,故这里要转换一下
+            let myItem = this.typeList.direction.list[this.selected.directionIndex]
+            this.selected[ 'direction'] = myItem.id
+            this.selected[ 'directionName'] = myItem.name
+            this.selected[ 'directionSlug'] = myItem.slug
+            this.selected[ key] = 0
+            this.selected[ key + 'Name' ] = ''
+            this.selected[ key + 'Slug' ] = ''
+          }
+        }
+        //如果选中的工作方式是远程,则初始化 城市选择
+        if (key === 'workType' && this.selected.workType === 1) {
+          this.selected.city = 0
+          this.selected.cityName = ''
+        }
+
+        this.page.page = 1
+        this.page.total = 0
+        this.firstLoading = true
+        this.getList()
+        this.$refs.directionSelect.toggle(false);
+      },
+      //web的选择器
       changeIndexSeo(key, item) {
         console.log("key:", key, "item:", item, "selected:", this.selected)
 
@@ -225,7 +331,9 @@
           url += (directionSmallSlug || directionSlug) + '/'
         }
         //驻场方式 不放到url里面
-        if (key === "workType") {
+        if (key === "workType" ) {
+          this.page.page = 1
+          this.page.total = 0
           this.getList()
           return
         }
@@ -277,7 +385,17 @@
       jumpToCompanyInfo(item) {
         const {companyInfo:{uid}} = item
         window.open(`/wo/${uid}`, `targetCompany${uid}`)
-      }
+      },
+      /** 移动端下拉刷新 **/
+      onRefresh() {
+        // 清空列表数据
+        this.finished = false;
+        this.loading = true;
+        this.onLoad();
+      },
+      onLoad() {
+        this.getList()
+      },
     }
   }
 </script>