ソースを参照

Merge branch 'dev' of www.gitinn.com:proginn/proginn-frontend into dev

xinfeng 6 年 前
コミット
5de4962d0a
6 ファイル変更614 行追加511 行削除
  1. 0 328
      pages/job/_id.vue
  2. 302 0
      pages/job/_post/_id.vue
  3. 304 182
      pages/recruit/_id.vue
  4. 0 0
      pages/job/index.vue
  5. 1 0
      plugins/common.js
  6. 7 1
      plugins/nuxtAxios.js

+ 0 - 328
pages/job/_id.vue

@@ -1,328 +0,0 @@
-<template>
-  <div class="wrapper" v-if="job">
-    <div class="loading" v-if="applying">
-      <i class="el-icon-loading"></i>
-      提交申请中
-    </div>
-    <div class="header">
-      <div class="title-wrapper">
-        <div class="title">{{job.title}}</div>
-        <div v-bind:class="title_class">{{job.status_name}}</div>
-      </div>
-      <div class="price">¥ {{job.salary_from}}-{{job.salary_to}}</div>
-    </div>
-    <div class="info-wrapper">
-      <div class="info">
-        <p>发布时间: {{job.created_at}}</p>
-        <p>工作经验: {{job.work_year}}年</p>
-        <p>要求: {{job.skills_name}}</p>
-        <p>驻场地点: {{job.city}}</p>
-      </div>
-      <div class="btn-wrapper">
-        <template v-if="job.status===1">
-          <template v-if="job.apply.status===-1">
-
-            <button class="btn-first" @click="login">请先登陆</button>
-          </template>
-          <template v-else-if="job.apply.status===-2"><a href="/sign/new" class="btn-first">请先签约</a></template>
-          <template v-else>
-            <button v-bind:class="!applying?'btn-first':'btn-second'" v-if="job.apply.status===0" @click="apply()">
-              {{applying?'提交申请中':'立即申请 '}} <i v-if="applying" class="el-icon-loading"></i>
-            </button>
-            <div class="btn-second" v-else-if="job.apply.status===1">筛选中</div>
-            <div class="btn-second" v-else-if="job.apply.status===2">待面试</div>
-            <div class="btn-third" v-else-if="job.apply.status===3">面试不通过</div>
-            <div class="btn-third" v-else-if="job.apply.status===4">不合适</div>
-            <div class="btn-fourth" v-else-if="job.apply.status===5">对接成功</div>
-          </template>
-
-        </template>
-        <template v-else>
-          <div class="btn-third" v-if="job.status>1">{{job.status_name}}</div>
-        </template>
-
-        <div class="btn-tips">当前已经有 <span>{{job.apply_count}}</span> 人申请</div>
-      </div>
-    </div>
-    <div class="content">
-      <div>工作内容:</div>
-      <div>{{job.job_description}}</div>
-    </div>
-    <div class="file-list">
-      <div class="file-item" v-for="file in job.files">
-        <a v-bind:href="file.url"><img src="~@/assets/img/job/icon_file.png" alt=""></a>
-        <a v-bind:href="file.url" v-bind:title="file.file_name" class="file">{{file.file_name}}</a>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-    export default {
-        head() {
-            return {
-                title: '驻场工作招聘,2019年最新驻场工作招聘信息-程序员客栈',
-                meta: [{
-                    'name': 'keywords',
-                    'content': '驻场招聘,驻场工作招聘,2019年最新驻场招聘信息'
-                }, {
-                    'name': 'descrption',
-                    'content': '程序员客栈提供全国各地城市IT驻场工作最新招聘信息,核实企业资质,让有工作需求的程序员能得到一份满意的驻场工作;对程序员从业者能力进行严格把关,保障企业能在驻场招聘平台找到靠谱的程序员,确保项目正常进行。找工作、招聘合格的程序员,就上程序员客栈驻场招聘平台!'
-                }]
-            }
-        },
-        data() {
-            return {
-                has_login: false,
-                city: '',
-                total: 0,
-                job: null,
-                status: 1,
-                title_class: "status-first",
-                applying: false,
-            }
-        },
-        mounted() {
-            this.getData();
-        },
-        methods: {
-            getData() {
-                this.$axios.$post('/api/present_job/detail', {id: this.$route.params.id}).then(res => {
-                    this.job = res.data;
-                    switch (this.job.status) {
-                        case 1:
-                            this.title_class = 'status-first';
-                            break;
-                        case 3:
-                            this.title_class = 'status-second';
-                            break;
-                        default:
-                            this.title_class = 'status-third';
-                    }
-                })
-            },
-            login() {
-                location.href = `https://www.proginn.com/?loginbox=show`
-            },
-            apply() {
-                if (this.applying) {
-                    return false;
-                }
-                this.applying = true;
-                this.$axios.$post('/api/present_job/apply', {id: this.$route.params.id}).then(res => {
-                    if (res.status === 1) {
-                        this.$message.success(res.info);
-                        this.getData();
-                    } else {
-                        this.$message.error(res.info);
-                        this.getData();
-                    }
-                    this.applying = false;
-                }).catch(res => {
-                    this.applying = false;
-                })
-            }
-        }
-    }
-</script>
-
-<style lang="scss" scope>
-  .wrapper {
-    overflow: hidden;
-    margin-top: 10px;
-    width: 1000px;
-    background-color: #ffffff;
-  }
-
-  .header {
-    margin-top: 45px;
-    display: flex;
-    align-items: center;
-  }
-
-  .title-wrapper {
-    flex: 1;
-    display: flex;
-    align-items: center;
-  }
-
-  .title {
-    margin-left: 20px;
-    margin-right: 9px;
-    font-weight: 500;
-    font-size: 17px;
-    color: #222222;
-  }
-
-  .status-first {
-    padding: 3px 9px;
-    border-radius: 1px;
-    border: 1px solid #27BB6F;
-    text-align: center;
-    font-size: 11px;
-    color: #27BB6F;
-  }
-
-  .status-second {
-    padding: 3px 9px;
-    border-radius: 1px;
-    border: 1px solid #FF6600;
-    text-align: center;
-    font-size: 11px;
-    color: #FF6600;
-  }
-
-  .status-third {
-    padding: 3px 9px;
-    border-radius: 1px;
-    border: 1px solid #666666;
-    text-align: center;
-    font-size: 11px;
-    color: #666666;
-  }
-
-  .price {
-    margin-right: 20px;
-    font-weight: 600;
-    font-size: 16px;
-    color: #FF331E;
-  }
-
-  .info-wrapper {
-    margin-top: 9px;
-    display: flex;
-  }
-
-  .info {
-    flex: 1;
-    margin-left: 20px;
-  }
-
-  .info p {
-    margin-top: 15px;
-    line-height: 18px;
-    font-weight: 500;
-    font-size: 13px;
-    color: #333333;
-  }
-
-  .btn-wrapper {
-    margin-top: 19px;
-    margin-right: 20px;
-  }
-
-  .btn-first {
-    display: block;
-    width: 125px;
-    height: 40px;
-    border-radius: 2px;
-    background-color: #308EFF;
-    line-height: 40px;
-    text-align: center;
-    font-size: 14px;
-    color: #FFFFFF;
-  }
-
-  .btn-second {
-    width: 125px;
-    height: 40px;
-    border-radius: 2px;
-    background-color: #308EFF;
-    line-height: 40px;
-    text-align: center;
-    font-size: 14px;
-    color: #FFFFFF;
-    opacity: 0.5;
-  }
-
-  .btn-third {
-    width: 125px;
-    height: 40px;
-    border-radius: 2px;
-    background-color: #ECECEC;
-    line-height: 40px;
-    text-align: center;
-    font-size: 14px;
-    color: #666666;
-  }
-
-  .btn-fourth {
-    width: 125px;
-    height: 40px;
-    border-radius: 2px;
-    border: 1px solid #10B96A;
-    line-height: 40px;
-    text-align: center;
-    font-size: 14px;
-    color: #10B96A;
-  }
-
-  .btn-tips {
-    margin-top: 13px;
-    line-height: 20px;
-    font-size: 13px;
-    color: #666666;
-  }
-
-  .btn-tips span {
-    color: #308EFF;
-  }
-
-  .content {
-    margin: 61px 20px 0;
-    line-height: 27px;
-    font-weight: 500;
-    font-size: 13px;
-    color: #333333;
-  }
-
-  .file-list {
-    margin-top: 45px;
-    padding-bottom: 61px;
-    display: flex;
-    align-items: center;
-  }
-
-  .file-item {
-    margin-left: 47px;
-    margin-right: 30px;
-    text-align: center;
-  }
-
-  .file-item img {
-    width: 25px;
-    height: 30px;
-  }
-
-  .file-item a {
-    margin-top: 6px;
-    display: block;
-    line-height: 30px;
-    font-size: 13px;
-    color: #308EFF;
-    text-decoration: underline;
-    display: -webkit-box;
-    -webkit-box-orient: vertical;
-    -webkit-line-clamp: 1;
-    overflow: hidden;
-  }
-
-  .loading {
-    display: flex;
-    justify-content: center;
-    align-items: center;
-  }
-
-  .mask {
-    position: absolute;
-    width: 100%;
-    height: 100%;
-    left: 0px;
-    top: 0px;
-    background: #EEEEEE;
-    opacity: 0.5;
-    filter: alpha(opacity=40);
-    z-index: 5;
-  }
-
-</style>

+ 302 - 0
pages/job/_post/_id.vue

@@ -0,0 +1,302 @@
+<template>
+  <div class="wrapper mobile">
+    <div class="header">
+      <div class="title-wrapper">
+        <div class="title">{{recruitData.title}}</div>
+        <div class="price">{{recruitData.salaryName}}</div>
+      </div>
+      <div class="require-list">
+        <div class="require-item">
+          <span class="require-label">技能要求:</span>
+          <span class="require-text">
+            <span v-for="(item,index) in recruitData.skills" :key="item.index">
+              <span>{{item.name}}</span><span v-if="index">,</span>
+            </span>
+          </span>
+        </div>
+        <div class="require-item">
+          <span class="require-label">经验要求:</span>
+          <span class="require-text">{{recruitData.experienceName}}</span>
+        </div>
+      </div>
+    </div>
+    <div class="detail-wrapper">
+      <div class="detail-title">详情描述</div>
+      <div class="detail-text">{{recruitData.description}}</div>
+    </div>
+    <div class="tips-wrapper">
+      <div class="tips-title">温馨提示</div>
+      <div class="tips-text">如沟通过程中,发现需求方有不当行为,请立即联系客服处理!</div>
+    </div>
+
+    <template v-if="recruitData.role==='owner'">
+      <div class="btn" v-if="recruitData.status==='2'">正在审核中</div>
+      <div class="btn-list" v-else-if="recruitData.status==='3'">
+        <div class="btn-item" v-if="recruitData.canRefresh>0" @click="handleRefreshClick()">刷新</div>
+        <div class="btn-item" style="background-color: #999999;" v-else>刷新</div>
+        <div class="btn-item" @click="handleOfflineClick()">关闭岗位</div>
+      </div>
+      <div class="btn-list" v-else-if="recruitData.status==='4' || recruitData.status==='6'">
+        <div class="btn-item" @click="handleEditClick()">编辑</div>
+        <div class="btn-item" @click="handleReopenClick()">申请开放岗位</div>
+      </div>
+    </template>
+    <template v-else-if="recruitData.role==='developer'">
+      <div class="contact-wrapper" v-if="recruitData.status==='3'" @click="handleContactClick()">
+        <img src="~@/assets/img/icon_contact.png" alt="">
+        <span>立即沟通</span>
+      </div>
+      <div class="contact-wrapper" :style="{backgroundColor: recruitData.statusColor}" v-else>
+        <span>{{recruitData.statusName}}</span>
+      </div>
+    </template>
+  </div>
+</template>
+
+<script>
+  export default {
+    data() {
+      return {
+        recruitId: '',
+        recruitData: ''
+      }
+    },
+    mounted() {
+      const path = this.$route.path
+      const string = path.split('.')[0]
+      this.recruitId = string.split('/')[3]
+      this.getRecruit()
+    },
+    methods: {
+      async getRecruit() {
+        const recruitId = this.recruitId
+        const params = {
+          recruitId
+        }
+        let res = await this.$axios.$post("/api/recruit/getRecruit", params)
+        if (res.status === 1) {
+          this.recruitData = res.data
+          if (this.recruitData.status === '-99') {
+            location.href = 'proginn://login'
+          }
+        }
+      },
+      async handleRefreshClick() {
+        const recruitId = this.recruitId
+        const params = {
+          recruitId
+        }
+        let res = await this.$axios.$post("/api/recruit/refresh", params)
+        if (res.status === 1) {
+          console.log(res)
+          this.$message({
+            message: '岗位刷新成功!',
+            type: 'success'
+          })
+          this.getRecruit()
+        }
+      },
+      async handleOfflineClick() {
+        const recruitId = this.recruitId
+        const params = {
+          recruitId
+        }
+        let res = await this.$axios.$post("/api/recruit/offline", params)
+        if (res.status === 1) {
+          console.log(res)
+          this.$message({
+            message: '岗位关闭成功!',
+            type: 'success'
+          })
+          this.getRecruit()
+        }
+      },
+      async handleReopenClick() {
+        const recruitId = this.recruitId
+        const params = {
+          recruitId
+        }
+        let res = await this.$axios.$post("/api/recruit/reopen", params)
+        if (res.status === 1) {
+          console.log(res)
+          this.$message({
+            message: '岗位已提交审核,请您耐心等待!',
+            type: 'success'
+          })
+          this.getRecruit()
+        }
+      },
+      async handleEditClick() {
+        const recruitId = this.recruitId
+        location.href = `proginn://recruit/edit?id=${recruitId}`
+      },
+      async handleContactClick() {
+        const recruitId = this.recruitId
+        const params = {
+          recruitId
+        }
+        let res = await this.$axios.$post("/api/recruit/chat", params)
+        if (res.status === 1) {
+          const uid = this.recruitData.uid
+          location.href = `proginn://recruit/chat?uid=${uid}`
+        }
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scope>
+  .wrapper {
+    overflow: hidden;
+  }
+
+  .main {
+    margin: 0;
+    width: 100%;
+  }
+  .mobile {
+    .header {
+      overflow: hidden;
+      padding-top: .72rem;
+      padding-bottom: .72rem;
+      background-color: #ffffff;
+    }
+    .title-wrapper {
+      display: flex;
+      align-items: center;
+    }
+    .title {
+      flex: 1;
+      margin-left: .2rem;
+      line-height: .44rem;
+      font-weight: 600;
+      font-size: .32rem;
+      color: #222222;
+    }
+    .price {
+      margin-right: .2rem;
+      line-height: .42rem;
+      font-weight: 600;
+      font-size: .3rem;
+      color: #308EFF;
+    }
+    .require-list {
+      margin-top: .16rem;
+    }
+    .require-item {
+      margin-left: .2rem;
+      margin-right: .2rem;
+      display: flex;
+      align-items: center;
+    }
+    .require-label {
+      line-height: .46rem;
+      font-weight: 600;
+      font-size: .25rem;
+      color: #666666;
+    }
+    .require-text {
+      line-height: .46rem;
+      font-size: .25rem;
+      color: #666666;
+    }
+    .detail-wrapper {
+      overflow: hidden;
+      margin-top: .2rem;
+      padding-top: .48rem;
+      padding-bottom: .44rem;
+      background-color: #ffffff;
+    }
+    .detail-title {
+      margin-left: .26rem;
+      line-height: .44rem;
+      font-weight: 600;
+      font-size: .32rem;
+      color: #333333;
+    }
+    .detail-text {
+      margin: .18rem auto 0;
+      width: 6.98rem;
+      line-height: .56rem;
+      font-size: .28rem;
+      color: #444444;
+    }
+    .tips-wrapper {
+      overflow: hidden;
+      margin: .2rem auto 0;
+      width: 7rem;
+      padding-top: .38rem;
+      padding-bottom: .36rem;
+      background-color: #ffffff;
+    }
+    .tips-title {
+      margin-left: .24rem;
+      line-height: .42rem;
+      font-weight: 600;
+      font-size: .26rem;
+      color: #EE3F21;
+    }
+    .tips-text {
+      margin: 0 auto;
+      width: 6.5rem;
+      line-height: .42rem;
+      font-size: .26rem;
+      color: #999999;
+    }
+    .contact-wrapper {
+      position: fixed;
+      bottom: 50px;
+      padding-top: .26rem;
+      padding-bottom: .26rem;
+      width: 100%;
+      background-color: #308EFF;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+    .contact-wrapper img {
+      margin-right: .02rem;
+      width: .44rem;
+      height: .44rem;
+    }
+    .contact-wrapper span {
+      line-height: .44rem;
+      font-weight: 500;
+      font-size: .32rem;
+      color: #ffffff;
+    }
+    .btn {
+      position: fixed;
+      left: .25rem;
+      bottom: 50px;
+      width: 7rem;
+      height: .96rem;
+      background-color: #308EFF;
+      line-height: .96rem;
+      text-align: center;
+      font-weight: 500;
+      font-size: .32rem;
+      color: #ffffff;
+    }
+    .btn-list {
+      position: fixed;
+      bottom: 50px;
+      width: 100%;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+    .btn-item {
+      margin-left: .25rem;
+      margin-right: .25rem;
+      width: 3rem;
+      height: .96rem;
+      background-color: #308EFF;
+      line-height: .96rem;
+      text-align: center;
+      font-weight: 500;
+      font-size: .32rem;
+      color: #ffffff;
+    }
+  }
+</style>

+ 304 - 182
pages/recruit/_id.vue

@@ -1,206 +1,328 @@
 <template>
-  <div class="wrapper mobile">
+  <div class="wrapper" v-if="job">
+    <div class="loading" v-if="applying">
+      <i class="el-icon-loading"></i>
+      提交申请中
+    </div>
     <div class="header">
       <div class="title-wrapper">
-        <div class="title">{{recruitData.title}}</div>
-        <div class="price">{{recruitData.salaryName}}</div>
-      </div>
-      <div class="require-list">
-        <div class="require-item">
-          <span class="require-label">技能要求:</span>
-          <span class="require-text">
-            <span v-for="(item,index) in recruitData.skills" :key="item.index">
-              <span>{{item.name}}</span><span v-if="index">,</span>
-            </span>
-          </span>
-        </div>
-        <div class="require-item">
-          <span class="require-label">经验要求:</span>
-          <span class="require-text">{{recruitData.experienceName}}</span>
-        </div>
+        <div class="title">{{job.title}}</div>
+        <div v-bind:class="title_class">{{job.status_name}}</div>
       </div>
+      <div class="price">¥ {{job.salary_from}}-{{job.salary_to}}</div>
     </div>
-    <div class="detail-wrapper">
-      <div class="detail-title">详情描述</div>
-      <div class="detail-text">{{recruitData.description}}</div>
-    </div>
-    <div class="tips-wrapper">
-      <div class="tips-title">温馨提示</div>
-      <div class="tips-text">如沟通过程中,发现需求方有不当行为,请立即联系客服处理!</div>
-    </div>
-
-    <template v-if="recruitData.role==='owner'">
-      <div class="">
-        
+    <div class="info-wrapper">
+      <div class="info">
+        <p>发布时间: {{job.created_at}}</p>
+        <p>工作经验: {{job.work_year}}年</p>
+        <p>要求: {{job.skills_name}}</p>
+        <p>驻场地点: {{job.city}}</p>
       </div>
-    </template>
-    <template v-else-if="recruitData.role==='developer'">
-      <div class="contact-wrapper" v-if="recruitData.status==='1'" @click="handleContactClick()">
-        <img src="~@/assets/img/icon_contact.png" alt="">
-        <span>立即沟通</span>
+      <div class="btn-wrapper">
+        <template v-if="job.status===1">
+          <template v-if="job.apply.status===-1">
+
+            <button class="btn-first" @click="login">请先登陆</button>
+          </template>
+          <template v-else-if="job.apply.status===-2"><a href="/sign/new" class="btn-first">请先签约</a></template>
+          <template v-else>
+            <button v-bind:class="!applying?'btn-first':'btn-second'" v-if="job.apply.status===0" @click="apply()">
+              {{applying?'提交申请中':'立即申请 '}} <i v-if="applying" class="el-icon-loading"></i>
+            </button>
+            <div class="btn-second" v-else-if="job.apply.status===1">筛选中</div>
+            <div class="btn-second" v-else-if="job.apply.status===2">待面试</div>
+            <div class="btn-third" v-else-if="job.apply.status===3">面试不通过</div>
+            <div class="btn-third" v-else-if="job.apply.status===4">不合适</div>
+            <div class="btn-fourth" v-else-if="job.apply.status===5">对接成功</div>
+          </template>
+
+        </template>
+        <template v-else>
+          <div class="btn-third" v-if="job.status>1">{{job.status_name}}</div>
+        </template>
+
+        <div class="btn-tips">当前已经有 <span>{{job.apply_count}}</span> 人申请</div>
       </div>
-      <div class="contact-wrapper" :style="{backgroundColor: recruitData.statusColor}" v-else>
-        <span>{{recruitData.statusName}}</span>
+    </div>
+    <div class="content">
+      <div>工作内容:</div>
+      <div>{{job.job_description}}</div>
+    </div>
+    <div class="file-list">
+      <div class="file-item" v-for="file in job.files">
+        <a v-bind:href="file.url"><img src="~@/assets/img/job/icon_file.png" alt=""></a>
+        <a v-bind:href="file.url" v-bind:title="file.file_name" class="file">{{file.file_name}}</a>
       </div>
-    </template>
+    </div>
   </div>
 </template>
 
 <script>
-  export default {
-    data() {
-      return {
-        recruitId: '',
-        recruitData: ''
-      }
-    },
-    mounted() {
-      this.recruitId = this.$route.query.id
-      this.getRecruit()
-    },
-    methods: {
-      async getRecruit() {
-        const recruitId = this.recruitId
-        const params = {
-          recruitId
-        }
-        let res = await this.$axios.$post("/api/recruit/getRecruit", params)
-        this.recruitData = res.data
-      },
-      async handleContactClick() {
-        const recruitId = this.recruitId
-        const params = {
-          recruitId
-        }
-        let res = await this.$axios.$post("/api/recruit/chat", params)
-        if (res.status === 1) {
-          const uid = this.recruitData.uid
-          location.href = `proginn://chat?userId=${uid}`
+    export default {
+        head() {
+            return {
+                title: '驻场工作招聘,2019年最新驻场工作招聘信息-程序员客栈',
+                meta: [{
+                    'name': 'keywords',
+                    'content': '驻场招聘,驻场工作招聘,2019年最新驻场招聘信息'
+                }, {
+                    'name': 'descrption',
+                    'content': '程序员客栈提供全国各地城市IT驻场工作最新招聘信息,核实企业资质,让有工作需求的程序员能得到一份满意的驻场工作;对程序员从业者能力进行严格把关,保障企业能在驻场招聘平台找到靠谱的程序员,确保项目正常进行。找工作、招聘合格的程序员,就上程序员客栈驻场招聘平台!'
+                }]
+            }
+        },
+        data() {
+            return {
+                has_login: false,
+                city: '',
+                total: 0,
+                job: null,
+                status: 1,
+                title_class: "status-first",
+                applying: false,
+            }
+        },
+        mounted() {
+            this.getData();
+        },
+        methods: {
+            getData() {
+                this.$axios.$post('/api/present_job/detail', {id: this.$route.params.id}).then(res => {
+                    this.job = res.data;
+                    switch (this.job.status) {
+                        case 1:
+                            this.title_class = 'status-first';
+                            break;
+                        case 3:
+                            this.title_class = 'status-second';
+                            break;
+                        default:
+                            this.title_class = 'status-third';
+                    }
+                })
+            },
+            login() {
+                location.href = `https://www.proginn.com/?loginbox=show`
+            },
+            apply() {
+                if (this.applying) {
+                    return false;
+                }
+                this.applying = true;
+                this.$axios.$post('/api/present_job/apply', {id: this.$route.params.id}).then(res => {
+                    if (res.status === 1) {
+                        this.$message.success(res.info);
+                        this.getData();
+                    } else {
+                        this.$message.error(res.info);
+                        this.getData();
+                    }
+                    this.applying = false;
+                }).catch(res => {
+                    this.applying = false;
+                })
+            }
         }
-      }
     }
-  }
 </script>
 
 <style lang="scss" scope>
   .wrapper {
     overflow: hidden;
+    margin-top: 10px;
+    width: 1000px;
+    background-color: #ffffff;
   }
 
-  .main {
-    margin: 0;
-    width: 100%;
+  .header {
+    margin-top: 45px;
+    display: flex;
+    align-items: center;
   }
-  .mobile {
-    .header {
-      overflow: hidden;
-      padding-top: .72rem;
-      padding-bottom: .72rem;
-      background-color: #ffffff;
-    }
-    .title-wrapper {
-      display: flex;
-      align-items: center;
-    }
-    .title {
-      flex: 1;
-      margin-left: .2rem;
-      line-height: .44rem;
-      font-weight: 600;
-      font-size: .32rem;
-      color: #222222;
-    }
-    .price {
-      margin-right: .2rem;
-      line-height: .42rem;
-      font-weight: 600;
-      font-size: .3rem;
-      color: #308EFF;
-    }
-    .require-list {
-      margin-top: .16rem;
-    }
-    .require-item {
-      margin-left: .2rem;
-      margin-right: .2rem;
-      display: flex;
-      align-items: center;
-    }
-    .require-label {
-      line-height: .46rem;
-      font-weight: 600;
-      font-size: .25rem;
-      color: #666666;
-    }
-    .require-text {
-      line-height: .46rem;
-      font-size: .25rem;
-      color: #666666;
-    }
-    .detail-wrapper {
-      overflow: hidden;
-      margin-top: .2rem;
-      padding-top: .48rem;
-      padding-bottom: .44rem;
-      background-color: #ffffff;
-    }
-    .detail-title {
-      margin-left: .26rem;
-      line-height: .44rem;
-      font-weight: 600;
-      font-size: .32rem;
-      color: #333333;
-    }
-    .detail-text {
-      margin: .18rem auto 0;
-      width: 6.98rem;
-      line-height: .56rem;
-      font-size: .28rem;
-      color: #444444;
-    }
-    .tips-wrapper {
-      overflow: hidden;
-      margin: .2rem auto 0;
-      width: 7rem;
-      padding-top: .38rem;
-      padding-bottom: .36rem;
-      background-color: #ffffff;
-    }
-    .tips-title {
-      margin-left: .24rem;
-      line-height: .42rem;
-      font-weight: 600;
-      font-size: .26rem;
-      color: #EE3F21;
-    }
-    .tips-text {
-      margin: 0 auto;
-      width: 6.5rem;
-      line-height: .42rem;
-      font-size: .26rem;
-      color: #999999;
-    }
-    .contact-wrapper {
-      position: fixed;
-      bottom: 0;
-      padding-top: .26rem;
-      padding-bottom: .26rem;
-      width: 100%;
-      background-color: #308EFF;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-    }
-    .contact-wrapper img {
-      margin-right: .02rem;
-      width: .44rem;
-      height: .44rem;
-    }
-    .contact-wrapper span {
-      line-height: .44rem;
-      font-weight: 500;
-      font-size: .32rem;
-      color: #ffffff;
-    }
+
+  .title-wrapper {
+    flex: 1;
+    display: flex;
+    align-items: center;
+  }
+
+  .title {
+    margin-left: 20px;
+    margin-right: 9px;
+    font-weight: 500;
+    font-size: 17px;
+    color: #222222;
+  }
+
+  .status-first {
+    padding: 3px 9px;
+    border-radius: 1px;
+    border: 1px solid #27BB6F;
+    text-align: center;
+    font-size: 11px;
+    color: #27BB6F;
+  }
+
+  .status-second {
+    padding: 3px 9px;
+    border-radius: 1px;
+    border: 1px solid #FF6600;
+    text-align: center;
+    font-size: 11px;
+    color: #FF6600;
+  }
+
+  .status-third {
+    padding: 3px 9px;
+    border-radius: 1px;
+    border: 1px solid #666666;
+    text-align: center;
+    font-size: 11px;
+    color: #666666;
+  }
+
+  .price {
+    margin-right: 20px;
+    font-weight: 600;
+    font-size: 16px;
+    color: #FF331E;
+  }
+
+  .info-wrapper {
+    margin-top: 9px;
+    display: flex;
+  }
+
+  .info {
+    flex: 1;
+    margin-left: 20px;
+  }
+
+  .info p {
+    margin-top: 15px;
+    line-height: 18px;
+    font-weight: 500;
+    font-size: 13px;
+    color: #333333;
+  }
+
+  .btn-wrapper {
+    margin-top: 19px;
+    margin-right: 20px;
+  }
+
+  .btn-first {
+    display: block;
+    width: 125px;
+    height: 40px;
+    border-radius: 2px;
+    background-color: #308EFF;
+    line-height: 40px;
+    text-align: center;
+    font-size: 14px;
+    color: #FFFFFF;
+  }
+
+  .btn-second {
+    width: 125px;
+    height: 40px;
+    border-radius: 2px;
+    background-color: #308EFF;
+    line-height: 40px;
+    text-align: center;
+    font-size: 14px;
+    color: #FFFFFF;
+    opacity: 0.5;
+  }
+
+  .btn-third {
+    width: 125px;
+    height: 40px;
+    border-radius: 2px;
+    background-color: #ECECEC;
+    line-height: 40px;
+    text-align: center;
+    font-size: 14px;
+    color: #666666;
+  }
+
+  .btn-fourth {
+    width: 125px;
+    height: 40px;
+    border-radius: 2px;
+    border: 1px solid #10B96A;
+    line-height: 40px;
+    text-align: center;
+    font-size: 14px;
+    color: #10B96A;
+  }
+
+  .btn-tips {
+    margin-top: 13px;
+    line-height: 20px;
+    font-size: 13px;
+    color: #666666;
+  }
+
+  .btn-tips span {
+    color: #308EFF;
+  }
+
+  .content {
+    margin: 61px 20px 0;
+    line-height: 27px;
+    font-weight: 500;
+    font-size: 13px;
+    color: #333333;
+  }
+
+  .file-list {
+    margin-top: 45px;
+    padding-bottom: 61px;
+    display: flex;
+    align-items: center;
+  }
+
+  .file-item {
+    margin-left: 47px;
+    margin-right: 30px;
+    text-align: center;
+  }
+
+  .file-item img {
+    width: 25px;
+    height: 30px;
+  }
+
+  .file-item a {
+    margin-top: 6px;
+    display: block;
+    line-height: 30px;
+    font-size: 13px;
+    color: #308EFF;
+    text-decoration: underline;
+    display: -webkit-box;
+    -webkit-box-orient: vertical;
+    -webkit-line-clamp: 1;
+    overflow: hidden;
+  }
+
+  .loading {
+    display: flex;
+    justify-content: center;
+    align-items: center;
   }
+
+  .mask {
+    position: absolute;
+    width: 100%;
+    height: 100%;
+    left: 0px;
+    top: 0px;
+    background: #EEEEEE;
+    opacity: 0.5;
+    filter: alpha(opacity=40);
+    z-index: 5;
+  }
+
 </style>

+ 0 - 0
pages/job/index.vue


+ 1 - 0
plugins/common.js

@@ -26,6 +26,7 @@ Vue.mixin({
   },
   methods: {
     async needLogin() {
+      Vue.hasMessage = true
       const userInfo = await this.getUserInfo();
       if (!userInfo.nickname) {
         this.goLogin();

+ 7 - 1
plugins/nuxtAxios.js

@@ -113,7 +113,13 @@ export default function({ $axios, redirect, req, ...args }) {
 			// }
 			// return {code: '401', message: '请登录!'};
 		} else {
-			Vue.prototype.$message.error(data.info);
+			if (!Vue.hasMessage) {
+				Vue.prototype.$message.error(data.info)
+				Vue.hasMessage = true
+				setTimeout(() => {
+					Vue.hasMessage = false
+				}, 3000)
+			}
 			// return data;
 		}
 		return res;