Browse Source

Merge branch 'Dev' into 'Test'

Dev

See merge request crowd-2019/crowd-test-service-front!78
郭超 5 years ago
parent
commit
26da492c0d
37 changed files with 1311 additions and 462 deletions
  1. 55 178
      package-lock.json
  2. 3 1
      package.json
  3. 16 3
      src/components/commons/Header2.0.vue
  4. 1 1
      src/constants/tabMenu.js
  5. 7 1
      src/js/api.js
  6. 2 1
      src/main.js
  7. 2 3
      src/pages/DetailPage/AgencyDetail.vue
  8. 6 3
      src/pages/DetailPage/ExpertDetail.vue
  9. 42 0
      src/pages/DetailPage/FieldDetail.vue
  10. 0 1
      src/pages/DetailPage/ResourceDetail.vue
  11. 41 0
      src/pages/DetailPage/TestTypeDetail.vue
  12. 0 1
      src/pages/DetailPage/UserDetail.vue
  13. 34 15
      src/pages/Homepage/Homepage.vue
  14. 9 11
      src/pages/Homepage/TestCard.vue
  15. 8 3
      src/pages/Homepage/TestMenu.vue
  16. 3 3
      src/pages/HomepageSearch/ExpertCard.vue
  17. 1 1
      src/pages/HomepageSearch/ExpertList.vue
  18. 1 1
      src/pages/HomepageSearch/ResourceList.vue
  19. 25 2
      src/pages/Square/PopularProject.vue
  20. 25 2
      src/pages/Square/PopularTask.vue
  21. 52 12
      src/pages/Square/Square2.0.vue
  22. 82 39
      src/pages/Square/SquareCard.vue
  23. 9 2
      src/pages/Technology/HotActicle.vue
  24. 1 3
      src/pages/Technology/Technology2.0.vue
  25. 176 0
      src/pages/Technology/TechnologyMore.vue
  26. 71 19
      src/pages/UserCenter/BankCard.vue
  27. 88 0
      src/pages/UserCenter/BindingMobile.vue
  28. 87 37
      src/pages/UserCenter/MailBinding.vue
  29. 16 7
      src/pages/UserCenter/Mine.vue
  30. 30 7
      src/pages/UserCenter/ModifyPsw.vue
  31. 53 17
      src/pages/UserCenter/MyBankCard.vue
  32. 112 29
      src/pages/UserCenter/MyQualification.vue
  33. 56 36
      src/pages/UserCenter/PhoneBinding.vue
  34. 36 22
      src/pages/UserCenter/QualificationCard.vue
  35. 114 0
      src/pages/UserCenter/ReBindingMobile.vue
  36. 38 1
      src/router/index.js
  37. 9 0
      src/style/main.scss

File diff suppressed because it is too large
+ 55 - 178
package-lock.json


+ 3 - 1
package.json

@@ -20,11 +20,13 @@
     "mockjs": "^1.0.1-beta3",
     "moment": "^2.27.0",
     "querystring": "^0.2.0",
+    "v-region": "^2.2.2",
     "vue": "^2.5.2",
     "vue-router": "^3.0.1",
     "vue-waterfall": "^1.0.6",
     "vue-waterfall-easy": "^2.4.4",
-    "vuex": "^3.1.1"
+    "vuex": "^3.1.1",
+    "webpack-dev-server": "^2.11.5"
   },
   "devDependencies": {
     "autoprefixer": "^7.1.2",

+ 16 - 3
src/components/commons/Header2.0.vue

@@ -3,7 +3,7 @@
     <div class="container">
         <div class="nav-location pull-left">
           <i class="el-icon-location-outline" style="margin-right: 5px"></i>
-          <span style="line-height: 34px">广州</span>
+          <span style="line-height: 34px">{{city}}</span>
         </div>
         <div class="nav-list pull-right">
           <ul>
@@ -76,7 +76,7 @@
                 </a>
               </router-link>
             </li>
-            &nbsp;&nbsp;&nbsp;<span v-if="isLogin">&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;</span>
+            <span v-if="isLogin">&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;</span>
             <li>
               <a @click="gotoHome" style="cursor: pointer">首页</a>
             </li>
@@ -107,6 +107,9 @@
       storageGet,
       storageSave
   } from '@/js/index'
+  import Http from '@/js/http.js'
+  import Apis from '@/js/api.js'
+
   export default {
     name: "Header2.0",
     data(){
@@ -124,7 +127,8 @@
         defaultValue: defaultValue,
         userIdentity: '',
         isLogin: false,
-        rolesPermissions: {}
+        rolesPermissions: {},
+        city: ''
       }
     },
     watch: {
@@ -142,6 +146,14 @@
         openNavBarFunc () {
             this.openNavBar = !this.openNavBar
         },
+        getAddress(){
+            Http.get(Apis.USER.GET_ADDRESS).then((res) => {
+                this.city = res.city
+            }).catch((error) => {
+                this.hideLoading()
+                notify('error', '获取定位失败:' + error.data)
+            })
+        },
         setUserInfo () {
             if (storageGet('user') == null) {
                 storageSave('rolesPermissions', {
@@ -365,6 +377,7 @@
         // if (storageGet('user' != null)){
         //   this.isLogin = true
         // }
+        this.getAddress();
         console.log(this.isLogin)
     }
   }

+ 1 - 1
src/constants/tabMenu.js

@@ -22,7 +22,7 @@ const homeTabArr = {
   ],
   menuArr3:[
     {label: "找机构", name: "findInstitution"},
-    {label: "找专家", name: "finfExpert"},
+    {label: "找专家", name: "findExpert"},
   ],
 };
 

+ 7 - 1
src/js/api.js

@@ -10,7 +10,8 @@ export default {
     ACCEPT_PROJECT: '/api/project/{projectId}/regionManager/{userId}',
     REJECT_PROJECT: '/api/project/{projectId}/status/rejected',
     SUBMIT_PROJECT: '/api/project/{projectId}/status/committed',
-    END_PROJECT: '/api/project/{projectId}/status/finished'
+    END_PROJECT: '/api/project/{projectId}/status/finished',
+    MORE_HOT_PROJECT: '/api/square/hotProject/list/more',
   },
   TASK: {
     GET_TASK: '/api/project/{projectId}/task/{taskId}/',
@@ -21,6 +22,7 @@ export default {
     REJECT_TASK: '/api/project/{projectId}/task/{taskId}/status/reject',
     SUBMIT_TASK: '/api/project/{projectId}/task/{taskId}/status/commit',
     END_TASK: '/api/project/{projectId}/task/{taskId}/status/finished',
+    MORE_HOT_TASK: '/api/square/hotTasks/list/more',
   },
   REPORT: {
     GET_TASK_REPORT: '/api/project/{projectId}/task/{taskId}/report/{reportId}/',
@@ -65,6 +67,7 @@ export default {
     REJECT_ENTERPRISE_AUTH:'/api/user/{userId}/enterpriseAuth/status/reject',
     REJECT_INDIVIDUAL_AUTH:'/api/user/{userId}/personalAuth/status/reject',
     GET_DETAIL: "/api/user/detail/{userId}",
+    GET_ADDRESS: "/api/index/address",
   },
   PAGE: {
     HOME_PAGE: '/api/common/index/',
@@ -83,6 +86,9 @@ export default {
   EXPERT: {
     GET_DETAIL: '/api/common/index/expert/{id}',
   },
+  TECHNOLOGY: {
+    GET_MORE: '/api/technical/more',
+  },
   GENERAL: {
     GET_ALL_INSTITUTIONS: '/api/regionalManager',
     GET_ALL_AGENCIES: '/api/agency/list',

+ 2 - 1
src/main.js

@@ -9,6 +9,7 @@ import {getAuthUrls, getCurrentUser, getRolesPermissions, storageGet, storageSav
 import {notify} from '@/constants/index'
 import store from './store'
 import moment from 'moment'
+import vRegion from 'v-region'
 import {
   Avatar,
   Badge,
@@ -189,7 +190,7 @@ Vue.use(Popover)
 Vue.use(Progress)
 Vue.use(Steps)
 Vue.use(Step)
-
+Vue.use(vRegion)
 Vue.prototype.$msgbox = MessageBox
 Vue.prototype.$alert = MessageBox.alert
 Vue.prototype.$confirm = MessageBox.confirm

+ 2 - 3
src/pages/DetailPage/AgencyDetail.vue

@@ -3,7 +3,7 @@
     <div class="create-body" v-loading="loading" style="width: 100%">
       <div class="title" v-if="this.type == 0">测评机构信息</div>
       <div class="title" v-else>入驻品牌机构信息</div>
-      <el-form :model="authentication" :rules="rules" ref="authentication" label-width="12%" class="demo-report">
+      <el-form :model="authentication" ref="authentication" label-width="12%" class="demo-report">
         <el-form-item prop="agencyPhoto" label="机构logo">
           <span >
           <el-image
@@ -18,7 +18,7 @@
         <el-form-item  label="认证状态" prop="name">
           <el-tag :type="authentication.authStatus.style">{{authentication.authStatus.text}}</el-tag>
         </el-form-item>
-        <el-form-item v-if="!isModifyMode && authentication.authStatus.text == '认证失败'" label="失败原因" prop="name">
+        <el-form-item v-if="authentication.authStatus.text == '认证失败'" label="失败原因" prop="name">
           <el-link v-if="authentication.explain!=null&&authentication.explain!=''" type="danger" disabled>
             {{authentication.explain}}
           </el-link>
@@ -160,6 +160,5 @@
 
   .el-form-item {
     max-height: 120px !important;
-    overflow: auto;
   }
 </style>

+ 6 - 3
src/pages/DetailPage/ExpertDetail.vue

@@ -12,8 +12,11 @@
 <!--        <el-form-item label="性别" prop="count">-->
 <!--          <span>{{expert.gender}}</span>-->
 <!--        </el-form-item>-->
+        <el-form-item label="头衔" prop="address">
+          <span>{{expert.title}}</span>
+        </el-form-item>
         <el-form-item label="简介" prop="address">
-          <span class="badge">{{expert.introduction}}</span>
+          <span>{{expert.introduction}}</span>
         </el-form-item>
 <!--        <el-form-item label="接包次数" prop="count">-->
 <!--          <span>{{expert.taskCount}}</span>-->
@@ -44,7 +47,7 @@
                     name: '',
                     photo: '',
                     introduction: '',
-                    // gender: '',
+                    title: '',
                 },
             }
         },
@@ -70,6 +73,7 @@
                     this.expert.name = res.data.name
                     this.expert.photo = res.data.photo
                     // this.expert.gender = res.data.gender
+                    this.expert.title = res.data.title
                     this.expert.introduction = res.data.introduction
                     // this.expert.address = res.data.address
                     this.hideLoading()
@@ -103,6 +107,5 @@
 
   .el-form-item {
     max-height: 120px !important;
-    overflow: auto;
   }
 </style>

+ 42 - 0
src/pages/DetailPage/FieldDetail.vue

@@ -0,0 +1,42 @@
+<template>
+  <div class="home-wrapper">
+    <div class="container" style="margin: 20px auto;">
+      <div class="create-body" v-for="item in fields">
+        <div class="title h2">{{item.name}}</div>
+        <div class="h3">{{item.introduction}}</div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+    import {storageGet, getAllFields} from '@/js/index.js'
+    import {notify} from "../../constants";
+
+    export default {
+        name: "FieldDetail",
+        data() {
+            return {
+                isLogin: false,
+                fields: [],
+            }
+        },
+        methods: {
+            setFields(){
+                getAllFields().then((res) => {
+                    this.fields = res
+                    console.log(res);
+                })
+            },
+        },
+        mounted() {
+            this.setFields();
+        }
+    }
+</script>
+
+<style scoped>
+  .item-template {
+    height: 80px;
+  }
+</style>

+ 0 - 1
src/pages/DetailPage/ResourceDetail.vue

@@ -105,6 +105,5 @@
 
   .el-form-item {
     max-height: 120px !important;
-    overflow: auto;
   }
 </style>

+ 41 - 0
src/pages/DetailPage/TestTypeDetail.vue

@@ -0,0 +1,41 @@
+<template>
+  <div class="home-wrapper">
+    <div class="container" style="margin: 20px auto;">
+      <div class="create-body" v-for="item in fields">
+        <div class="title h2">{{item.name}}</div>
+        <div class="h3">{{item.introduction}}</div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+    import {getAllServiceTypes, getAllFields} from '@/js/index.js'
+
+    export default {
+        name: "TestTypeDetail",
+        data() {
+            return {
+                isLogin: false,
+                fields: [],
+            }
+        },
+        methods: {
+            setFields(){
+                getAllServiceTypes().then((res) => {
+                    this.fields = res
+                    console.log(res);
+                })
+            },
+        },
+        mounted() {
+            this.setFields();
+        }
+    }
+</script>
+
+<style scoped>
+  .item-template {
+    height: 80px;
+  }
+</style>

+ 0 - 1
src/pages/DetailPage/UserDetail.vue

@@ -104,6 +104,5 @@
 
   .el-form-item {
     max-height: 120px !important;
-    overflow: auto;
   }
 </style>

+ 34 - 15
src/pages/Homepage/Homepage.vue

@@ -41,19 +41,19 @@
       <el-row>
         <el-col :span="19" class="test-type-wrapper">
           <TestMenu :testTypeList="homeData.testTypeList"></TestMenu>
-          <TestCard :homeData="homeData"></TestCard>
+          <TestCard :applicationTypeList="homeData.applicationTypeList"></TestCard>
         </el-col>
         <el-col :span="5"  class="homepage-right-modules">
           <LoginCard/>
-          <HotCrowd :applicationTypeRank="homeData.applicationTypeRank"/>
-          <HotAgency :agencyRank="homeData.agencyRank"/>
-          <HotUser :userRank="homeData.userRank"/>
+          <HotCrowd :applicationTypeRank="homeDataNoCache.applicationTypeRank"/>
+          <HotAgency :agencyRank="homeDataNoCache.agencyRank"/>
+          <HotUser :userRank="homeDataNoCache.userRank"/>
           <HotContest :competitionList="homeData.competitionList"/>
         </el-col>
       </el-row>
       <el-row :gutter="15">
         <el-col :span="12">
-          <ResourceAndTool :resourceList="homeData.resourceList"></ResourceAndTool>
+          <ResourceAndTool :resourceList="homeDataNoCache.resourceList"></ResourceAndTool>
         </el-col>
         <el-col :span="12">
           <BrandCard :residentAgencyList = homeData.residentAgencyList></BrandCard>
@@ -140,11 +140,12 @@
             {code: '', name: ''}
           ],
           menuArr3:[
-            {label: "找机构", name: "findInstitution"},
-            {label: "找专家", name: "finfExpert"},
+            {label: "找机构", name: "findInstitution",linkTo:'/agency/list/show'},
+            {label: "找专家", name: "findExpert",linkTo:'/expert/list'},
           ],
         },
         homeData:{},
+        homeDataNoCache: {},
         currTab:'homepage'
       }
     },
@@ -154,20 +155,25 @@
             this.isLogin = true;
         }
         this.setFields();
-        Http.get('/api/common/index/info').then((res)=>{
+
+        Http.get('/api/common/index/info/cache').then((res)=>{
+          console.log(res.data);
           this.homeData = res.data;
-          this.homeData.applicationTypeList.map((item)=>{
-            item.height = (item.testTypeList.length / 2) * 24 + 100;
-            return item;
-          })
+          // this.homeData.applicationTypeList.map((item)=>{
+          //   item.height = (item.testTypeList.length / 2) * 24 + 100;
+          //   return item;
+          // })
+        })
+
+        Http.get('/api/common/index/info/nocache').then((res)=>{
+            this.homeDataNoCache = res.data;
         })
       },
       setFields(){
           getAllFields().then((res) => {
               this.homeTabArr.menuArr2 = res
-              console.log(this.homeTabArr.menuArr2)
+              // console.log(this.homeTabArr.menuArr2)
           })
-
       },
       checkLogin(){
         if(!this.isLogin){
@@ -180,6 +186,19 @@
       },
       handleTabClick(tab){
         this.currTab = tab.name;
+        // console.log(this.currTab +  "  "  + tab.index +  "  "  + tab.name );
+        for(let i = 0; i < this.homeTabArr.menuArr3.length; i++){
+            if (this.currTab === this.homeTabArr.menuArr3[i].name){
+                this.$router.push(this.homeTabArr.menuArr3[i].linkTo);
+            }
+        }
+
+        for(let i = 0; i < this.homeTabArr.menuArr2.length; i++){
+            if (this.currTab === this.homeTabArr.menuArr2[i].code){
+                this.$router.push('/field/detail');
+            }
+        }
+
         this.$router.push(this.homeTabArr.menuArr1[Number(tab.index)].linkTo);
       },
       handleTypeClick(tab){
@@ -187,7 +206,7 @@
       },
       handleSearchData(){
         if(this.searchType == 0){
-            // this.$router.push({name: 'Square2.0', params: {searchVal: this.searchVal, searchType: "project"}});
+            this.$router.push({name: 'Square', params: {searchVal: this.searchVal, searchType: "project", currTab: "project"}});
         }else if(this.searchType == 1){
             this.$router.push({name: 'AgencyList', params: {searchVal: this.searchVal}});
         }else if(this.searchType == 2){

+ 9 - 11
src/pages/Homepage/TestCard.vue

@@ -6,25 +6,21 @@
                         :min-line-gap="150"
                         :max-line-gap="220"
                         :single-max-width="300"
-        :watch="homeData.applicationTypeList">
+        :watch="applicationTypeList">
         <!-- each component is wrapped by a waterfall slot -->
         <waterfall-slot
-          v-for="(item, index) in homeData.applicationTypeList"
+          v-for="(item, index) in applicationTypeList"
           width="300"
-          :height="item.height"
+          :height="200"
           :order="index"
           :key="item.code"
         >
-          <el-card class="test-card" :body-style="{width:'300'}">
+          <el-card class="test-card" :body-style="{width:'300'}" >
             <div slot="header" class="clearfix test-card-header">
               <span>{{item.name}}</span>
             </div>
             <div>
-              <el-row :gutter="20">
-                <el-col :span="12"v-for="type in item.testTypeList" :key="type.code">
-                  <span>{{type.name}}</span>
-                </el-col>
-              </el-row>
+              <span>{{item.introduction}}</span>
             </div>
           </el-card>
         </waterfall-slot>
@@ -39,7 +35,7 @@
   import {mapGetters} from  'vuex'
   export default {
     name: "TestCard",
-    props:['homeData'],
+    props:['applicationTypeList'],
     data(){
       return{
       }
@@ -48,8 +44,10 @@
       Waterfall,
       WaterfallSlot
     },
+    methods:{
+    },
     mounted() {
-
+      console.log(this.applicationTypeList)
     }
   }
 

+ 8 - 3
src/pages/Homepage/TestMenu.vue

@@ -1,12 +1,12 @@
 <template>
   <div class="test-menu-wrapper">
     <div class="test-menu-item-wrapper">
-      <div class="test-menu-item" v-for="(item,index) in testTypeList" :key="item.code" v-if="index<8">
+      <div class="test-menu-item" v-for="(item,index) in testTypeList" :key="item.code" v-if="index<8"  @click="geToDetail">
         <img src="../../assets/img/testType.png" alt="testType" class="test-menu-item-img">
         {{item.name}}
       </div>
       <div class="more-test-wrapper">
-        <i class="el-icon-arrow-right more-test"></i>更多分类
+        <i class="el-icon-arrow-right more-test" @click="geToDetail"></i>更多分类
       </div>
     </div>
   </div>
@@ -20,7 +20,12 @@
       return {
 
       }
-    }
+    },
+    methods:{
+        geToDetail(){
+            this.$router.push("/test/type/detail");
+        }
+    },
   }
 </script>
 

+ 3 - 3
src/pages/HomepageSearch/ExpertCard.vue

@@ -1,12 +1,12 @@
 <template>
   <el-card class="expert-card">
     <div>
-      <div class="card-img"><img src="../../assets/img/logo-blue.png"/></div>
+      <div class="card-img"><img :src="card.photo" style="height: 50px; width: 50px;"/></div>
       <div class="card-title">
-        {{card.name ? card.name :card.introduction}}
+        {{card.name}}
       </div>
       <div class="card-content">
-        {{card.introduction}}
+        {{card.title}}
       </div>
       <el-divider></el-divider>
       <div class="card-detail">

+ 1 - 1
src/pages/HomepageSearch/ExpertList.vue

@@ -117,7 +117,7 @@
             },
             handleSearchData() {
                 if(this.searchType == 0){
-                    // this.$router.push({name: 'Square2.0', params: {searchVal: this.searchVal, searchType: "project"}});
+                    this.$router.push({name: 'Square', params: {searchVal: this.searchVal, searchType: "project", currTab: "project"}});
                 }else if(this.searchType == 1){
                     this.$router.push({name: 'AgencyList', params: {searchVal: this.searchVal}});
                 }else if(this.searchType == 2){

+ 1 - 1
src/pages/HomepageSearch/ResourceList.vue

@@ -150,7 +150,7 @@
             },
             handleSearchData() {
                 if(this.searchType == 0){
-                    // this.$router.push({name: 'Square2.0', params: {searchVal: this.searchVal, searchType: "project"}});
+                    this.$router.push({name: 'Square', params: {searchVal: this.searchVal, searchType: "project", currTab: "project"}});
                 }else if(this.searchType == 1){
                     this.$router.push({name: 'AgencyList', params: {searchVal: this.searchVal}});
                 }else if(this.searchType == 2){

+ 25 - 2
src/pages/Square/PopularProject.vue

@@ -4,7 +4,7 @@
     <div slot="header" class="popular-header">
       <img src="../../assets/img/popular-project.png" alt="popular-project" class="popular-header-img"/>
       <span class="popular-header-title">热门项目</span>
-      <el-button style="float: right; padding: 3px 0" type="text">more>></el-button>
+      <el-button style="float: right; padding: 3px 0;line-height: 25px" type="text" @click="goToMore()">more>></el-button>
     </div>
     <div class="popular-list">
       <el-row class="popular-list-item" v-for="item in hotCrowdTestProjectVOs" :key="item.id">
@@ -32,9 +32,32 @@
 </template>
 
 <script>
+    import Http from '@/js/http.js';
+    import Apis from '@/js/api.js';
+    import {notify} from "../../constants";
   export default {
     name: 'PopularProject',
-    props:['hotCrowdTestProjectVOs']
+    props:['hotCrowdTestProjectVOs'],
+    methods:{
+        goToMore(){
+            console.log("goToMoreProject");
+            let params = {
+                "keyword": '',//搜索关键字
+                "activePage": 1,//指定页面
+                "columnFilters":
+                [
+
+                ]
+            };
+            Http.post(Apis.PROJECT.MORE_HOT_PROJECT, params).then((res) => {
+                console.log(res)
+                this.$router.push({
+                    name: 'Square',
+                    params: {projectAndTaskArr: res.data.content, type: 1}
+                })
+            })
+        },
+    }
   }
 </script>
 

+ 25 - 2
src/pages/Square/PopularTask.vue

@@ -3,7 +3,7 @@
     <div slot="header" class="popular-header">
       <img src="../../assets/img/popularTask.png" alt="popular-project" class="popular-header-img"/>
       <span class="popular-header-title">热门任务</span>
-      <el-button style="float: right; padding: 3px 0" type="text" class="pull-right">more>></el-button>
+      <el-button style="float: right; padding: 3px 0" type="text" class="pull-right"  @click="goToMore()">more>></el-button>
     </div>
     <div class="popular-list">
       <el-row class="popular-list-item" v-for="item in hotCrowdTaskVOs" :key="item.id">
@@ -29,9 +29,32 @@
 </template>
 
 <script>
+  import Http from '@/js/http.js';
+  import Apis from '@/js/api.js';
+  import {notify} from "../../constants";
   export default {
     name: 'PopularTask',
-    props:['hotCrowdTaskVOs']
+    props:['hotCrowdTaskVOs'],
+      methods:{
+          goToMore(){
+              console.log("goToMoreTask");
+              let params = {
+                  "keyword": '',//搜索关键字
+                  "activePage": 1,//指定页面
+                  "columnFilters":
+                      [
+
+                      ]
+              };
+              Http.post(Apis.TASK.MORE_HOT_TASK, params).then((res) => {
+                  console.log(res)
+                  this.$router.push({
+                      name: 'Square',
+                      params: {projectAndTaskArr: res.data.content, type: 0}
+                  })
+              })
+          },
+      }
   }
 </script>
 

+ 52 - 12
src/pages/Square/Square2.0.vue

@@ -46,7 +46,7 @@
           </el-row>
           <el-pagination
             v-if="currTab!=='squareHome'&&projectAndTaskArr&&projectAndTaskArr.length"
-            :page-size="9"
+            :page-size="12"
             layout="prev, pager, next"
             :total="totalElements"
             :current-page = "activePage"
@@ -91,6 +91,7 @@
           {label:"测试任务",name:"task"}
         ],
         projectAndTaskArr:[],
+        type: 0,
         hotCrowdTestProjectVOs:[],
         hotCrowdTaskVOs:[],
         activePage:1,
@@ -110,14 +111,19 @@
         this.$router.push('/home');
       },
       handleTabClick(tab){
+          console.log("handleTabClick ");
         this.currTab = tab.name
         this.activePage = 1;
         this.searchVal = '';
         this.searchData()
       },
+      handleTabClickSearch(){
+          this.activePage = 1;
+          this.searchData()
+      },
       searchData(index){
         if(this.currTab === 'squareHome'){
-          this.loadData();
+          this.getData();
         }else{
           this.searchType = this.currTab;
           this.handleSearchData();
@@ -132,16 +138,50 @@
         if (storageGet('user') != null) {
             this.isLogin = true;
         }
-        this.searchVal = this.$route.params.searchVal;
-        this.searchType = this.$route.params.searchType;
-        Http.get('/api/square/list').then((res)=>{
-          let crowdTestProjectVOs = res.data.crowdTestProjectVOs;
-          let crowdTestTaskVOS = res.data.crowdTestTaskVOS;
-          let projectAndTaskArr = crowdTestProjectVOs.concat(crowdTestTaskVOS);
-          this.hotCrowdTestProjectVOs = res.data.hotCrowdTestProjectVOs;
-          this.hotCrowdTaskVOs = res.data.hotCrowdTaskVOs;
-          this.projectAndTaskArr = projectAndTaskArr;
-        })
+
+        this.projectAndTaskArr = this.$route.params.projectAndTaskArr;
+        this.type = this.$route.params.type;
+
+        // 从首页项目搜索框跳转过来
+        this.currTab = this.$route.params.currTab;
+        if(this.currTab === "project"){
+            this.searchVal = this.$route.params.searchVal;
+            this.searchType = this.$route.params.searchType;
+            this.getHotData();
+            this.handleTabClickSearch();
+        }
+
+        // 从热门项目和任务跳转过来
+        else if(this.type == 1){
+            console.log("type " + this.type);
+            this.getHotData();
+        }
+
+        // 正常点击众测广场跳转过来
+        else{
+            this.searchVal = this.$route.params.searchVal;
+            this.searchType = this.$route.params.searchType;
+            this.currTab = "squareHome"
+            this.getData();
+        }
+      },
+
+      getData(){
+          Http.get('/api/square/list').then((res)=>{
+              let crowdTestProjectVOs = res.data.crowdTestProjectVOs;
+              let crowdTestTaskVOS = res.data.crowdTestTaskVOS;
+              let projectAndTaskArr = crowdTestProjectVOs.concat(crowdTestTaskVOS);
+              this.hotCrowdTestProjectVOs = res.data.hotCrowdTestProjectVOs;
+              this.hotCrowdTaskVOs = res.data.hotCrowdTaskVOs;
+              this.projectAndTaskArr = projectAndTaskArr;
+          })
+      },
+
+      getHotData(){
+          Http.get('/api/square/list').then((res)=>{
+              this.hotCrowdTestProjectVOs = res.data.hotCrowdTestProjectVOs;
+              this.hotCrowdTaskVOs = res.data.hotCrowdTaskVOs;
+          })
       },
       checkLogin(){
           if(!this.isLogin){

+ 82 - 39
src/pages/Square/SquareCard.vue

@@ -1,6 +1,6 @@
 <template>
   <el-card class="square-card">
-    <div class="card-title" >
+    <div class="card-title">
       {{card.name ? card.name :card.title}}
     </div>
     <div class="card-content">
@@ -11,7 +11,7 @@
         <el-col :lg="6" :md="24">
           <span class="card-detail-money" v-if="card.quotedPrice||card.quotedPrice === 0">¥{{card.quotedPrice > 10000 ? Math.floor(card.quotedPrice/10000) + 'w+' : card.quotedPrice}}</span>
           <span class="card-detail-money" v-else>¥{{card.quotePrice > 10000 ? Math.floor(card.quotePrice/10000)+'w+' : card.quotePrice}}</span>
-<!--          <span class="card-detail-money">¥{{(card.quotedPrice||card.quotedPrice === 0) ? card.quotedPrice : card.quotePrice}}</span>-->
+          <!--          <span class="card-detail-money">¥{{(card.quotedPrice||card.quotedPrice === 0) ? card.quotedPrice : card.quotePrice}}</span>-->
         </el-col>
         <el-col :lg="18" :md="24">
           <span class="card-detail-info pull-right">{{card.time_interval}}/{{card.joinCount > 10000 ? Math.floor(card.joinCount/10000)+'w+': card.joinCount}}人参与</span>
@@ -21,10 +21,15 @@
     <div class="card-footer">
       <el-row class="card-footer-row">
         <el-col :span="12" class="pull-left">
-          {{card.platform || card.serviceType}}
+          {{card.applicationType || card.serviceType}}
         </el-col>
         <el-col :span="12" class=" test-btn">
-          <el-button type="primary" round size="mini" class="pull-right">我要众测</el-button>
+          <el-button type="primary" round size="mini" class="pull-right" v-if="card.applicationType"
+                     @click="goToProjectDetail(card.code)">我要众测
+          </el-button>
+          <el-button type="primary" round size="mini" class="pull-right" v-else
+                     @click="goToTaskDetail(card.projectId, card.code)">我要众测
+          </el-button>
         </el-col>
       </el-row>
     </div>
@@ -32,76 +37,114 @@
 </template>
 
 <script>
-  export default {
-    name: 'SquareCard',
-    props: ['card'],
-    mounted() {
+    import {notify} from "../../constants";
+    import {storageGet} from '@/js/index.js'
 
+    export default {
+        name: 'SquareCard',
+        props: ['card'],
+        data() {
+            return {
+                isLogin: false,
+            }
+        },
+        methods: {
+            onload() {
+                if (storageGet('user') != null) {
+                    this.isLogin = true;
+                }
+            },
+            goToProjectDetail(id) {
+                if (!this.isLogin) {
+                    console.log("请登录后访问");
+                    notify('warning', '请登录后访问');
+                } else {
+                    console.log("已登录");
+                    this.$router.push({name: 'Project', params: {projectId: id}})
+                }
+            },
+            goToTaskDetail(projectId, taskId) {
+                if (!this.isLogin) {
+                    console.log("请登录后访问");
+                    notify('warning', '请登录后访问');
+                } else {
+                    console.log("已登录");
+                    this.$router.push({
+                        name: 'Task',
+                        params: {projectId: projectId, taskId: taskId}
+                    })
+                }
+            },
+        },
+        mounted() {
+            this.onload();
+        }
     }
-  }
 </script>
 
 <style lang="less">
-  .square-card .el-card__body{
+  .square-card .el-card__body {
     padding: 0 !important;
   }
 
   .square-card {
     .card-title {
-      font-size:16px;
-      font-family:Source Han Sans CN;
-      font-weight:500;
-      color:rgba(0,0,0,1);
-      line-height:30px;
+      font-size: 16px;
+      font-family: Source Han Sans CN;
+      font-weight: 500;
+      color: rgba(0, 0, 0, 1);
+      line-height: 30px;
       margin: 10px 0;
-      overflow:hidden; //超出的文本隐藏
-      text-overflow:ellipsis; //溢出用省略号显示
-      white-space:nowrap; //溢出不换行
+      overflow: hidden; //超出的文本隐藏
+      text-overflow: ellipsis; //溢出用省略号显示
+      white-space: nowrap; //溢出不换行
     }
 
     .card-content {
-      font-size:14px;
-      font-family:Source Han Sans CN;
-      font-weight:400;
-      color:rgba(0,0,0,1);
+      font-size: 14px;
+      font-family: Source Han Sans CN;
+      font-weight: 400;
+      color: rgba(0, 0, 0, 1);
       height: 70px;
       overflow: hidden;
       text-overflow: ellipsis;
-      display:-webkit-box; //作为弹性伸缩盒子模型显示。
-      -webkit-box-orient:vertical; //设置伸缩盒子的子元素排列方式--从上到下垂直排列
-      -webkit-line-clamp:3; //显示的行
+      display: -webkit-box; //作为弹性伸缩盒子模型显示。
+      -webkit-box-orient: vertical; //设置伸缩盒子的子元素排列方式--从上到下垂直排列
+      -webkit-line-clamp: 3; //显示的行
     }
 
     .card-detail {
       margin: 10px 0;
-      .card-detail-money{
-        font-size:14px;
-        font-family:Source Han Sans CN;
-        font-weight:bold;
-        color:rgba(0,117,203,1);
+
+      .card-detail-money {
+        font-size: 14px;
+        font-family: Source Han Sans CN;
+        font-weight: bold;
+        color: rgba(0, 117, 203, 1);
       }
+
       .card-detail-info {
-        font-size:14px;
-        font-family:Roboto;
-        font-weight:400;
-        color:rgba(153,153,153,1);
+        font-size: 14px;
+        font-family: Roboto;
+        font-weight: 400;
+        color: rgba(153, 153, 153, 1);
       }
     }
   }
 
-  .card-title,.card-content,.card-detail{
+  .card-title, .card-content, .card-detail {
     padding: 0 10px !important;
   }
 
   .card-footer {
-    background:rgba(233,239,249,1);
+    background: rgba(233, 239, 249, 1);
     /*height: 40px;*/
 
     .card-footer-row {
       padding: 15px 10px;
-      font-size:14px;
-      font-family:Source Han Sans CN;
-      font-weight:bold;
+      font-size: 14px;
+      font-family: Source Han Sans CN;
+      font-weight: bold;
     }
   }
 

+ 9 - 2
src/pages/Technology/HotActicle.vue

@@ -4,7 +4,7 @@
       <div slot="header" class="popular-header">
         <img src="../../assets/img/hot-article.jpg" alt="hot-crowd" class="popular-header-img"/>
         <span class="popular-header-title">热门文章</span>
-        <el-button style="float: right; padding: 3px 0;line-height: 25px" type="text">more>></el-button>
+        <el-button style="float: right; padding: 3px 0;line-height: 25px" type="text" @click="goToMore()">more>></el-button>
       </div>
       <div class="popular-list">
         <el-row class="popular-list-item" v-for="(item,index) in articleArr" :key="item.id" v-if="index<7">
@@ -28,6 +28,7 @@
 
 <script>
   import Http from '@/js/http.js'
+  import Apis from '@/js/api.js';
 
   export default {
     name: 'HotArticle',
@@ -43,7 +44,13 @@
           this.$emit('refreshHotArticle');
           window.open(item.articlesUrl);
         });
-      }
+
+      },
+      goToMore(){
+          this.$router.push({
+              name: 'TechnologyMore',
+          })
+      },
     },
     mounted() {
     }

+ 1 - 3
src/pages/Technology/Technology2.0.vue

@@ -12,14 +12,12 @@
         <el-col :span="12">
           <div class="search-nav">
             <div id="search-block " class="">
-              <div class="search-input">
                 <el-tabs v-model="searchType" type="card" @tab-click="handleTypeClick">
                   <el-tab-pane v-for="item in searchTypeArr" :label="item.label" :name="item.value" :key="item.value"></el-tab-pane>
                 </el-tabs>
                 <el-input placeholder="请输入内容" v-model="searchVal" class="input-with-select">
                   <el-button class="search-button" slot="append"  type="primary" @click="loadTechnologyArticles(1)">搜索</el-button>
                 </el-input>
-              </div>
             </div>
           </div>
         </el-col>
@@ -45,7 +43,7 @@
           <TechnologyMG :techArticleList = techArticleList.content v-if="searchType=='1'"></TechnologyMG>
           <el-pagination
             v-if="techArticleList.content&&techArticleList.content.length"
-            :page-size="10"
+            :page-size="5"
             layout="prev, pager, next"
             :total="techArticleList.totalElements"
             @current-change="handlePageChange"

+ 176 - 0
src/pages/Technology/TechnologyMore.vue

@@ -0,0 +1,176 @@
+<template>
+  <div class="technology-container">
+    <div class="nav" stype="height:500px">
+      <!--搜索框-->
+      <el-row class="search-nav" style="padding: 30px 0 20px 0">
+        <el-col :span="6">
+          <div class="pull-left" @click="gotoHome" style="cursor: pointer">
+            <img class="logo-img" src="../../assets/img/logo-blue.png" />
+            <span class="logo-title">群智众测平台</span>
+          </div>
+        </el-col>
+        <el-col :span="12">
+          <div class="search-nav">
+            <div id="search-block " class="">
+                <el-tabs v-model="searchType" type="card" @tab-click="handleTypeClick">
+                  <el-tab-pane v-for="item in searchTypeArr" :label="item.label" :name="item.value" :key="item.value"></el-tab-pane>
+                </el-tabs>
+                <el-input placeholder="请输入内容" v-model="searchVal" class="input-with-select">
+                  <el-button class="search-button" slot="append"  type="primary" @click="loadTechnologyArticles(1)">搜索</el-button>
+                </el-input>
+            </div>
+          </div>
+        </el-col>
+        <el-col :span="6">
+          <el-button type="primary pull-right" class="releaseBtn" @click="checkLogin()">免费发布众测需求</el-button>
+        </el-col>
+      </el-row>
+      <!--TabNav-->
+<!--      <el-tabs v-model="searchType" @tab-click="handleTabClick" class="square-tab">-->
+<!--        <el-tab-pane v-for="item in searchTypeArr" :name="item.value" :key="item.value">-->
+<!--          <span slot="label" style="font-size: 18px">{{item.name}}</span>-->
+<!--        </el-tab-pane>-->
+<!--      </el-tabs>-->
+      <div>
+      </div>
+    </div>
+    <div class="container" style="margin: 15px auto">
+      <el-row>
+        <el-col :span="18" class="project-task">
+          <TechnologyCard
+            :techArticleList = techArticleList.content v-if="searchType=='0'" @refreshList="loadTechnologyArticles(activePage)">
+          </TechnologyCard>
+          <TechnologyMG :techArticleList = techArticleList.content v-if="searchType=='1'"></TechnologyMG>
+          <el-pagination
+            v-if="techArticleList.content&&techArticleList.content.length"
+            :page-size="5"
+            layout="prev, pager, next"
+            :total="techArticleList.totalElements"
+            @current-change="handlePageChange"
+            :current-page = activePage
+            class="pull-right"
+          >
+          </el-pagination>
+        </el-col>
+<!--        <el-col :span="6"  class="popular-modules">-->
+<!--          <HotActicle :articleArr="articleArr" @refreshHotArticle="loadHotArticles"/>-->
+<!--        </el-col>-->
+      </el-row>
+    </div>
+  </div>
+</template>
+
+<script>
+  import Http from '@/js/http.js'
+  import Apis from '@/js/api.js'
+  import SearchBar from '../../components/commons/SearchBar'
+  import TechnologyCard from './TechnologyCard'
+  import TechnologyMG from './TechnologyMG'
+  import {storageGet} from '@/js/index.js'
+  import {notify} from "../../constants";
+
+  export default {
+    name: 'TechnologyMore',
+    components: {
+      SearchBar,
+      TechnologyCard,
+      TechnologyMG,
+    },
+    data(){
+      return {
+        isLogin: false,
+        searchVal: '',
+        searchType:'',
+        searchTypeArr:[
+          {
+            "name": "技术文章",
+            "value": "0",
+            "label":'文章'
+          }
+        ],
+        articleArr:[],
+        keyword:"",
+        activePage:1,
+        techArticleList:{},
+      }
+    },
+    methods:{
+      loadData(){
+          if (storageGet('user') != null) {
+              this.isLogin = true;
+          }
+      },
+      checkLogin(){
+          if(!this.isLogin){
+              console.log("请登录后访问");
+              notify('warning','请登录后访问');
+          }else{
+              console.log("已登录");
+              this.$router.push('/project/create');
+          }
+      },
+      gotoHome(){
+        this.$router.push('/home');
+      },
+      handleTypeClick(tab){
+        this.handleTabClick(tab);
+      },
+      handleTabClick(tab){
+        this.searchType = tab.name
+        this.activePage = 1;
+        this.searchVal = '';
+        this.loadTechnologyArticles(1);
+      },
+      loadTechnologyArticles(index){
+        this.activePage = index;
+        let params = {
+          "keyword": this.searchVal,//查询条件,分页展示时就不填
+          "activePage": this.activePage,//指定页数
+          "columnFilters": [
+            {
+              "field": "type",
+              "type": "enums",
+              "enums": this.searchTypeArr,
+              "value": this.searchType//展示技术文章value为0
+            }
+          ]
+        }
+        Http.post(Apis.TECHNOLOGY.GET_MORE, params).then((res) => {
+            console.log(res.data.technicalArticlesPage)
+            if(res.data.technicalArticlesPage){
+                this.techArticleList = res.data.technicalArticlesPage;
+                this.searchType = '0';
+            }
+            else if(res.data.publicationsPage){
+                this.techArticleList = res.data.publicationsPage;
+                this.searchType = '1';
+            }
+            console.log(this.techArticleList)
+        })
+      },
+      handlePageChange(index){
+        this.activePage = index;
+        this.loadTechnologyArticles(index);
+      }
+    },
+    mounted() {
+      this.loadData();
+      this.loadTechnologyArticles(1);
+    }
+  }
+</script>
+
+<style lang="less">
+  @import "../../style/search-nav";
+  .technology-container {
+    /deep/ .search-input,/deep/ .releaseBtn{
+      margin: 20px 0 0 0 !important;
+    }
+
+    .popular-modules {
+      padding-left: 15px;
+    }
+
+  }
+
+</style>

+ 71 - 19
src/pages/UserCenter/BankCard.vue

@@ -1,28 +1,72 @@
 <template>
-  <div class="bank-card">
-    <div class="bank-card-title" style="padding: 10px;height:43px">
-      <img src="../../assets/img/bankimg.png">
-      <span class="" style="font-size: 16px;font-weight: bold;line-height: 43px">建设银行</span>
-      <el-button type="primary" plain class="pull-right" size="mini">编辑</el-button>
-    </div>
-    <div class="bank-card-detail-wrapper">
-      <div class="bank-card-detail">
-        <div class="bank-card-detail-info">张晓楠</div>
-        <div class="bank-card-detail-info">********************5656</div>
-      </div>
-    </div>
+  <div>
+    <el-row :gutter="15">
+      <el-col :span="8" v-for="item in bankCardVOList" :key="item.id">
+        <div class="bank-card">
+          <div class="bank-card-title" style="padding: 10px;height:43px">
+            <img :src="item.logoUrl" class="bank-card-logo">
+            <span class="" style="font-size: 16px;font-weight: bold;line-height: 43px">{{item.name}}</span>
+            <el-button type="primary" plain class="pull-right" size="mini" @click="requestUntieBankCard(item)">解绑
+            </el-button>
+          </div>
+          <div class="bank-card-detail-wrapper">
+            <div class="bank-card-detail">
+              <div class="bank-card-detail-info">{{item.user}}</div>
+              <div class="bank-card-detail-info">{{item.number}}</div>
+            </div>
+          </div>
+        </div>
+      </el-col>
+    </el-row>
+    <el-dialog
+      title="提示"
+      :visible.sync="untieBankCard"
+      width="30%"
+    >
+      <span>确定解绑{{nowCard.name}},卡号为:{{nowCard.number}}的银行卡吗?</span>
+      <span slot="footer" class="dialog-footer">
+    <el-button @click="untieBankCard = false">取 消</el-button>
+    <el-button type="primary" @click="handleUntieBankCard">确 定</el-button>
+  </span>
+    </el-dialog>
+
   </div>
 
 </template>
 
 <script>
+  import {storageGet} from '@/js/index'
+  import Http from '@/js/http.js'
+  import BankCard from './BankCard'
+
   export default {
     name: "BankCard",
-    data(){
+    props: ['bankCardVOList'],
+    data() {
       return {
-        addBankCard:false,
-
+        untieBankCard: false,
+        nowCard: {},
+        user: {}
       }
+    },
+    methods: {
+      setUserInfo() {
+        this.user = storageGet('user') && storageGet('user').userVO;
+      },
+      requestUntieBankCard(item) {
+        this.untieBankCard = true;
+        this.nowCard = item;
+      },
+      handleUntieBankCard() {
+        Http.delete(`/api/personal/deletebankcard/${this.nowCard.id}/${this.user.id}`,{}).then((res) => {
+          //调用父组件的loadData方法
+          this.$emit('loadData');
+          this.untieBankCard = false
+        })
+      },
+    },
+    mounted() {
+      this.setUserInfo();
     }
   }
 </script>
@@ -30,16 +74,24 @@
 <style scoped lang="less">
   .bank-card {
     /*width:285px;*/
-    height:160px;
-    background:rgba(255,255,255,1);
-    box-shadow:0px 1px 6px 0px rgba(8,6,6,0.13);
+    height: 160px;
+    background: rgba(255, 255, 255, 1);
+    box-shadow: 0px 1px 6px 0px rgba(8, 6, 6, 0.13);
+    margin-bottom: 10px;
+  .bank-card-logo {
+    width: 42px;
+    height: 42px;
+  }
     .bank-card-detail-wrapper {
       padding: 10px;
-      .bank-card-detail{
+
+      .bank-card-detail {
         margin-bottom: 5px;
+
         .bank-card-detail-title {
           font-size: 14px;
         }
+
         .bank-card-detail-info {
           margin-left: 43px;
         }

+ 88 - 0
src/pages/UserCenter/BindingMobile.vue

@@ -0,0 +1,88 @@
+<template>
+  <div>
+    <el-form label-width="80px" style="width:400px">
+      <el-form-item label="手机号码" >
+        <el-input v-model="phoneBindingForm.phone"></el-input>
+      </el-form-item>
+      <el-form-item label="验证码">
+        <el-input placeholder="验证码内容" v-model="phoneBindingForm.verifyCode" class="input-with-select">
+          <el-button slot="append" @click="getVerifyCode">{{hasVerifyCode ? codeTime : '获取验证码'}}</el-button>
+        </el-input>
+        <span v-if="hasVerifyCode">验证码已发送到您手机上</span>
+      </el-form-item>
+    </el-form>
+    <el-button type="primary" plain style="margin-left: 80px" @click="bindingMobile">完成绑定</el-button>
+  </div>
+
+</template>
+
+<script>
+  import Http from '@/js/http.js'
+  import {storageGet} from '@/js/index'
+  import {notify} from '@/constants/index'
+  export default {
+    name: "BindingMobile",
+    data(){
+      return{
+        phoneBindingForm:{
+          phone:'',
+          verifyCode:''
+        },
+        hasVerifyCode:false,
+        codeTime:10,
+        user:{}
+      }
+    },
+    methods:{
+      setUserInfo() {
+        this.user = storageGet('user') && storageGet('user').userVO;
+      },
+      getVerifyCode(){
+        let params = {
+          id:this.user.id,
+          mobile:this.phoneBindingForm.phone
+        }
+        Http.put('/api/verify/mobile',params).then((res)=>{
+          this.hasVerifyCode = true;
+          let _this = this;
+          let codeTimer = setInterval(function () {
+            if(_this.codeTime > 0 ){
+              _this.codeTime--;
+            }else{
+              clearInterval(codeTimer);
+              _this.hasVerifyCode = false;
+              this.codeTime = 10;
+            }
+          },1000)
+        }).catch(err=> {
+          notify('error', '绑定手机失败:' + err.data);
+        })
+      },
+      bindingMobile(){
+        let params = {
+          id:this.user.id,
+          mobile:this.phoneBindingForm.phone,
+          verifyCode: this.phoneBindingForm.verifyCode
+        };
+        Http.put('/api/user/mobile',params).then(res=>{
+          if(res.code === 20000){
+            notify('success', '绑定成功');
+            this.$router.push({path:'/personal/phoneBinding'});
+            //需要更改vuex和storage中得user
+            console.log(storageGet(user));
+         }
+        }).catch(err=> {
+          notify('error', err.data);
+        })
+      }
+    },
+    mounted() {
+      this.setUserInfo()
+
+    }
+  }
+</script>
+
+<style scoped>
+
+</style>

+ 87 - 37
src/pages/UserCenter/MailBinding.vue

@@ -1,60 +1,110 @@
 <template>
   <div>
     <div class="right-modifyPsw">
-      <div class="right-modifyPsw-title">
-        <span style="font-size: 18px;font-weight: bold">邮箱绑定</span>
+      <div v-if="showBindWranning">
+        <div class="right-modifyPsw-title">
+          <span style="font-size: 18px;font-weight: bold">邮箱绑定</span>
+        </div>
+        <div style="background-color: rgba(233,239,249,1);padding: 10px;margin-bottom: 30px">
+          <span style="font-size: 16px">您还未绑定邮箱,为保护您帐号,建议您</span>
+          <el-button type="primary" plain size="mini" @click="bindingEmail = true;showBindWranning = false">立即绑定
+          </el-button>
+        </div>
+        <div>
+          邮箱绑定成功后,您将享受以下服务:
+        </div>
+        <div>①邮箱地址登录 可直接使用“邮箱地址”登录到众测服务平台</div>
+        <div>②重要事件提醒 进行(支付/提现/众测/中标)时,可及时收到邮件提醒</div>
+        <div>③找回账号密码 忘记密码时,可使用邮件找回密码</div>
       </div>
-      <div style="background-color: rgba(233,239,249,1);padding: 10px;margin-bottom: 30px">
-        <span style="font-size: 16px">您还未绑定邮箱,为保护您帐号,建议您</span>
-        <el-button type="primary" plain size="mini">立即绑定</el-button>
+      <div v-if="!showBindWranning">
+        <div style="background-color: rgba(233,239,249,1);padding: 10px;margin-bottom: 30px">
+          <span style="font-size: 16px">您绑定的邮箱是:{{this.user.email}}</span>
+        </div>
       </div>
-      <div>
-        邮箱绑定成功后,您将享受以下服务:
+      <div v-if="bindingEmail">
+        <el-form label-width="80px">
+          <el-form-item label="邮箱号">
+            <el-input v-model="emailBindingForm.email"></el-input>
+          </el-form-item>
+          <el-form-item label="验证码">
+            <el-input placeholder="验证码内容" v-model="emailBindingForm.verifyCode" class="input-with-select">
+              <el-button slot="append" @click="getVerifyCode">{{hasVerifyCode ? codeTime : '获取验证码'}}</el-button>
+            </el-input>
+            <span v-if="hasVerifyCode">验证码已发送到您手机上</span>
+          </el-form-item>
+        </el-form>
+        <el-button type="primary" plain style="margin-left: 80px" @click="handleBindingEmail">完成绑定</el-button>
       </div>
-      <div>①邮箱地址登录 可直接使用“邮箱地址”登录到众测服务平台</div>
-      <div>②重要事件提醒 进行(支付/提现/众测/中标)时,可及时收到邮件提醒</div>
-      <div>③找回账号密码 忘记密码时,可使用邮件找回密码</div>
 
-      <el-steps :active="active" process-status="finish" style="margin-bottom: 20px">
-        <el-step title="添加邮箱"></el-step>
-        <el-step title="完成绑定"></el-step>
-      </el-steps>
-
-<!--      <el-form  label-width="80px"  v-if="active===0">-->
-<!--        <el-form-item label="邮箱号">-->
-<!--          <span v-model="mailBindingForm.mail">135****6699</span>-->
-<!--        </el-form-item>-->
-<!--        <el-form-item label="验证码">-->
-<!--          <span v-model="mailBindingForm.phone">135****6699</span>-->
-<!--        </el-form-item>-->
-<!--      </el-form>-->
-
-      <el-form  label-width="80px"  v-if="active===0">
-        <el-form-item label="邮箱号">
-          <el-input v-model="mailBindingForm.mail"></el-input>
-        </el-form-item>
-        <el-form-item label="验证码">
-          <span v-model="mailBindingForm.phone">135****6699</span>
-        </el-form-item>
-      </el-form>
     </div>
   </div>
 </template>
 
 <script>
+  import Http from '@/js/http.js'
+  import {storageGet} from '@/js/index'
+  import {notify} from '@/constants/index'
 
   export default {
     name: "MailBinding",
     data() {
       return {
-        active: 0,
-        mailBindingForm:{
-          mail:''
-        }
+        showBindWranning: true,
+        hasVerifyCode: false,
+        bindingEmail: false,
+        codeTime: 10,
+        emailBindingForm: {
+          email: '',
+          verifyCode: ''
+        },
+        user: {}
       }
     },
     methods: {
-
+      setUserInfo() {
+        this.user = storageGet('user') && storageGet('user').userVO;
+      },
+      handleBindingEmail() {
+        let params = {
+          "id": this.user.id,
+          "email": this.emailBindingForm.email,
+          'verifyCode': this.emailBindingForm.verifyCode
+        }
+        Http.put('/api/user/email', params).then(res => {
+          if (res.code === 20000) {
+            notify('success', '绑定邮箱成功');
+            //vuex  storage 存数据
+          }
+        }).catch(err => {
+          notify('error', '绑定邮箱失败:' + err.data);
+        })
+      },
+      getVerifyCode() {
+        let params = {
+          id: this.user.id,
+          email: this.emailBindingForm.email
+        }
+        Http.put('/api/verify/email', params).then((res) => {
+          this.hasVerifyCode = true;
+          let _this = this;
+          let codeTimer = setInterval(function () {
+            if (_this.codeTime > 0) {
+              _this.codeTime--;
+            } else {
+              clearInterval(codeTimer);
+              _this.hasVerifyCode = false;
+              this.codeTime = 10;
+            }
+          }, 1000)
+        }).catch(err => {
+          notify('error', '获取验证码失败:' + err.data);
+        })
+      }
+    },
+    mounted() {
+      this.showBindWranning = !!this.user.email;
+      this.setUserInfo();
     }
   }
 </script>

File diff suppressed because it is too large
+ 16 - 7
src/pages/UserCenter/Mine.vue


+ 30 - 7
src/pages/UserCenter/ModifyPsw.vue

@@ -10,16 +10,16 @@
       </div>
       <el-form ref="modifyForm" :model="modifyForm" label-width="80px" style="margin-top: 20px">
         <el-form-item label="当前密码">
-          <el-input v-model="modifyForm.password"></el-input>
+          <el-input v-model="modifyForm.oldPassword" type="password"></el-input>
         </el-form-item>
         <el-form-item label="新密码">
-          <el-input v-model="modifyForm.newpassword"></el-input>
+          <el-input v-model="modifyForm.password" type="password"></el-input>
         </el-form-item>
         <el-form-item label="确认密码">
-          <el-input v-model="modifyForm.password"></el-input>
+          <el-input v-model="modifyForm.password2" type="password"></el-input>
         </el-form-item>
         <el-form-item>
-          <el-button type="primary">确认修改</el-button>
+          <el-button type="primary" @click="ModifyPassword">确认修改</el-button>
         </el-form-item>
       </el-form>
     </div>
@@ -27,17 +27,40 @@
 </template>
 
 <script>
-
+  import Http from '@/js/http.js'
+  import {storageGet} from '@/js/index'
+  import {notify} from '@/constants/index'
   export default {
     name: "ModifyPsw",
     data(){
       return {
+        user:{},
         modifyForm: {
+          oldPassword:'',
           password:'',
-          newpassword: '',
-          repassword:'',
+          password2:'',
         },
       }
+    },
+    methods:{
+      setUserInfo() {
+        this.user = storageGet('user') && storageGet('user').userVO;
+      },
+      ModifyPassword(){
+        let params = {
+          id:this.user.id.toString(),
+          ...this.modifyForm
+        }
+        Http.put(`/api/password/reset`,params).then(res=>{
+          window.alert('修改密码成功,跳转至登录页重新登录');
+          window.location.href = process.env.LOGIN_URL;
+        }).catch(err=>{
+          notify('error', '修改密码失败:' + err.data)
+        })
+      }
+    },
+    mounted() {
+      this.setUserInfo();
     }
   }
 </script>

+ 53 - 17
src/pages/UserCenter/MyBankCard.vue

@@ -5,17 +5,9 @@
         <span style="font-size: 18px;font-weight: bold">我的银行卡</span>
         <el-button type="primary" size="mini" class="pull-right" @click="addBankCard = true">添加</el-button>
       </div>
-      <el-row :gutter="15" style="margin-bottom: 15px">
-        <el-col :span="8">
-          <BankCard></BankCard>
-        </el-col>
-        <el-col :span="8">
-          <BankCard></BankCard>
-        </el-col>
-        <el-col :span="8">
-          <BankCard></BankCard>
-        </el-col>
-      </el-row>
+      <div style="margin-bottom: 15px">
+        <BankCard :bankCardVOList="bankCardVOList" @loadData="loadData"></BankCard>
+      </div>
     </div>
     <el-dialog
       title="新增银行卡"
@@ -24,10 +16,20 @@
     >
       <el-form ref="bankCardForm" :model="bankCardForm" label-width="80px">
         <el-form-item label="持卡人">
-          <el-input v-model="bankCardForm.username"></el-input>
+          <el-input v-model="bankCardForm.user"></el-input>
         </el-form-item>
         <el-form-item label="卡号">
-          <el-input v-model="bankCardForm.cardNumber"></el-input>
+          <el-input v-model="bankCardForm.number"></el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-select v-model="value" placeholder="请选择银行卡种类">
+            <el-option
+              v-for="item in bankCardType"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id">
+            </el-option>
+          </el-select>
         </el-form-item>
       </el-form>
       <div>
@@ -38,14 +40,17 @@
       <div>③可以申请平台的收益</div>
       <span slot="footer" class="dialog-footer">
     <el-button @click="addBankCard = false">取 消</el-button>
-    <el-button type="primary" @click="addBankCard = false">确认添加</el-button>
+    <el-button type="primary" @click="handleAddBankCard">确认添加</el-button>
   </span>
     </el-dialog>
+
   </div>
 
 </template>
 
 <script>
+  import {storageGet} from '@/js/index'
+  import Http from '@/js/http.js'
   import BankCard from './BankCard'
   export default {
     name: "MyBankCard",
@@ -55,6 +60,7 @@
     data(){
       return {
         addBankCard: false,
+        UntieBankCard:false,
         form: {
           name: '',
           number:'',
@@ -63,10 +69,40 @@
           isPublic:''
         },
         bankCardForm:{
-          username:'',
-          cardNumber:''
-        }
+          user:'',
+          number:''
+        },
+        user:{},
+        bankCardVOList:[],
+        bankCardType:[]
       }
+    },
+    methods:{
+      loadData() {
+        Http.get(`/api/personal/displaybankcard/${this.user.id}`).then((res) => {
+          this.bankCardVOList = res.bankCardVOList;
+        })
+      },
+      setUserInfo(){
+        this.user = storageGet('user') && storageGet('user').userVO;
+      },
+      handleAddBankCard(){
+        Http.post(`/api/personal/addbankcard/${this.user.id}`,this.bankCardForm).then(res=>{
+          console.log(res);
+        })
+        this.addBankCard = false
+        this.loadData();
+      },
+      getBankType(){
+        Http.get('/api/personal/banktype').then(res=>{
+          this.bankCardType = res.bankLogoVOList;
+        })
+      }
+    },
+    mounted() {
+      this.setUserInfo();
+      this.loadData();
+      this.getBankType();
     }
   }
 </script>

+ 112 - 29
src/pages/UserCenter/MyQualification.vue

@@ -3,22 +3,15 @@
     <div class="right-qualification">
       <div class="right-qualification-title">
         <span style="font-size: 18px;font-weight: bold">我的资质</span>
-        <el-button type="primary" size="mini" class="pull-right" @click="addQualification = true">添加</el-button>
+        <el-button type="primary" size="mini" class="pull-right" @click="handleEditQualification">添加</el-button>
+      </div>
+      <div style="margin-bottom: 15px">
+        <QualificationCard :qualificationVOList="qualificationVOList"
+                           @handleEditQualification="handleEditQualification"></QualificationCard>
       </div>
-      <el-row :gutter="15" style="margin-bottom: 15px">
-        <el-col :span="8">
-          <QualificationCard></QualificationCard>
-        </el-col>
-        <el-col :span="8">
-          <QualificationCard></QualificationCard>
-        </el-col>
-        <el-col :span="8">
-          <QualificationCard></QualificationCard>
-        </el-col>
-      </el-row>
     </div>
     <el-dialog
-      title="新增资质"
+      :title="modalTitle"
       :visible.sync="addQualification"
       width="30%"
     >
@@ -30,21 +23,34 @@
           <el-input v-model="form.number"></el-input>
         </el-form-item>
         <el-form-item label="发证机构">
-          <el-input v-model="form.institution"></el-input>
+          <el-input v-model="form.licensingAuthority"></el-input>
         </el-form-item>
         <el-form-item label="发证时间">
-          <el-input v-model="form.date"></el-input>
+          <el-input v-model="form.time"></el-input>
         </el-form-item>
         <el-form-item label="是否公开">
           <el-radio-group v-model="form.isPublic">
-            <el-radio label="公开"></el-radio>
-            <el-radio label="不公开"></el-radio>
+            <el-radio :label="1">公开</el-radio>
+            <el-radio :label="0">不公开</el-radio>
           </el-radio-group>
         </el-form-item>
       </el-form>
       <span slot="footer" class="dialog-footer">
+        <el-button type="danger" @click="requireDeleteQualification">删 除</el-button>
     <el-button @click="addQualification = false">取 消</el-button>
-    <el-button type="primary" @click="addQualification = false">确 定</el-button>
+    <el-button type="primary" @click="handleAddQualification">确 定</el-button>
+  </span>
+    </el-dialog>
+
+    <el-dialog
+      title="删除资质提示"
+      :visible.sync="deleteQualification"
+      width="30%"
+    >
+      <span>确定删除资质“{{form.name}}”吗?</span>
+      <span slot="footer" class="dialog-footer">
+    <el-button @click="deleteQualification = false">取 消</el-button>
+    <el-button type="primary" @click="handleDeleteQualification">确 定</el-button>
   </span>
     </el-dialog>
   </div>
@@ -53,22 +59,99 @@
 
 <script>
   import QualificationCard from './QualificationCard'
+  import {storageGet} from '@/js/index'
+  import Http from '@/js/http.js'
+
   export default {
     name: "MyQualification",
-    components:{
+    components: {
       QualificationCard
     },
-    data(){
+    data() {
       return {
+        deleteQualification:false,
         addQualification: false,
         form: {
           name: '',
-          number:'',
-          institution:'',
-          date:'',
-          isPublic:''
+          number: '',
+          licensingAuthority: '',
+          time: '',
+          isPublic: ''
+        },
+        user: {},
+        qualificationVOList: [],
+        // qualificationVO: {},
+        modalTitle: '新增资质'
+      }
+    },
+    methods: {
+      loadData() {
+        Http.get(`/api/personal/displayqualification/${this.user.id}`).then((res) => {
+          this.qualificationVOList = res.qualificationVOList;
+        })
+      },
+      setUserInfo() {
+        this.user = storageGet('user') && storageGet('user').userVO;
+      },
+      handleAddQualification() {
+        if (!this.form.id) {
+          //新增
+          Http.post(`/api/personal/addqualification/${this.user.id}`, this.form).then(res => {
+            this.addQualification = false;
+            this.loadData();
+          })
+        } else {
+          //编辑
+          let newForm = {
+            name: this.form.name,
+            number: this.form.number,
+            licensingAuthority: this.form.licensingAuthority,
+            time: this.form.time,
+            isPublic: this.form.isPublic
+          };
+          Http.put(`/api/personal/updatequalification/${this.form.id}/${this.user.id}`,newForm).then(res=>{
+            this.form = newForm;
+            this.addQualification = false;
+            this.loadData();
+          })
+        }
+      },
+      requireDeleteQualification(item){
+        this.deleteQualification = true;
+      },
+      handleDeleteQualification(item){
+        console.log('delete')
+        Http.delete(`/api/personal/deletequalification/${this.form.id}/${this.user.id}`,{}).then((res) => {
+          this.deleteQualification = false;
+          this.addQualification = false;
+          this.loadData();
+        })
+      },
+      handleEditQualification(item) {
+        if(!item.id){
+          //新增
+          this.form = {
+            name: '',
+            number: '',
+            licensingAuthority: '',
+            time: '',
+            isPublic: ''
+          },
+          this.modalTitle = '新增资质';
+          this.addQualification = true;
+        }else{
+          //编辑
+          Http.get(`/api/personal/displayone/${item.id}`).then((res) => {
+            this.form = res.qualificationVO;
+          })
+          this.modalTitle = '编辑资质';
+          this.addQualification = true;
         }
       }
+    },
+    mounted() {
+      this.setUserInfo();
+      this.loadData()
     }
   }
 </script>
@@ -79,10 +162,10 @@
     background: rgba(255, 255, 255, 1);
     box-shadow: 0px 1px 6px 0px rgba(8, 6, 6, 0.13);
 
-  .right-qualification-title {
-    padding: 10px;
-    border-bottom: 1px solid #ccc;
-    margin-bottom: 20px;
-  }
+    .right-qualification-title {
+      padding: 10px;
+      border-bottom: 1px solid #ccc;
+      margin-bottom: 20px;
+    }
   }
 </style>

+ 56 - 36
src/pages/UserCenter/PhoneBinding.vue

@@ -4,57 +4,77 @@
       <div class="right-modifyPsw-title">
         <span style="font-size: 18px;font-weight: bold">手机绑定</span>
       </div>
-      <div style="background-color: rgba(233,239,249,1);padding: 10px;margin-bottom: 30px">
-        <img src="../../assets/img/phoneBinding.png"></img>
-        <span style="font-size: 16px">您已绑定的手机号码是138****1380</span>
-        <el-button type="primary" plain size="mini">修改号码</el-button>
-    </div>
-      <div style="background-color: rgba(233,239,249,1);padding: 10px">
-        <img src="../../assets/img/phoneUnbinding.png"></img>
-        <span style="font-size: 16px">您未绑定的手机号码是138****1380</span>
-          <el-button type="danger" plain size="mini">立即绑定</el-button>
+      <div>
+        <div style="background-color: rgba(233,239,249,1);padding: 10px;margin-bottom: 30px" v-if="user.mobile">
+          <img src="../../assets/img/phoneBinding.png"></img>
+          <span style="font-size: 16px">您已绑定的手机号码是{{this.user.mobile}}</span>
+          <el-button type="primary" plain size="mini" @click="changePhoneNumber" style="margin-left: 20px">修改号码</el-button>
+        </div>
+        <div style="background-color: rgba(233,239,249,1);padding: 10px" v-if="!user.mobile">
+          <img src="../../assets/img/phoneUnbinding.png"></img>
+          <span style="font-size: 16px">您尚未绑定手机号</span>
+          <el-button type="danger" plain size="mini" style="margin-left: 20px" @click="bindPhoneNumber">立即绑定</el-button>
+        </div>
       </div>
-      <el-steps :active="active" process-status="finish" style="margin-bottom: 20px">
-        <el-step title="验证原手机"></el-step>
-        <el-step title="绑定新手机"></el-step>
-        <el-step title="完成绑定"></el-step>
-      </el-steps>
+      <router-view></router-view>
 
-      <el-form  label-width="80px"  v-if="active===0">
-        <el-form-item label="原手机号">
-          <span v-model="phoneBindingForm.phone">135****6699</span>
-        </el-form-item>
-        <el-form-item label="验证码">
-          <span v-model="phoneBindingForm.phone">135****6699</span>
-        </el-form-item>
-      </el-form>
 
-      <el-form  label-width="80px"  v-if="active===1">
-        <el-form-item label="新手机号">
-          <el-input v-model="phoneBindingForm.phone"></el-input>
-        </el-form-item>
-        <el-form-item label="验证码">
-          <span v-model="phoneBindingForm.phone">135****6699</span>
-        </el-form-item>
-      </el-form>
+<!--      <el-form label-width="80px" v-if="active===1">-->
+<!--        <el-form-item label="新手机号">-->
+<!--          <el-input v-model="phoneBindingForm.phone"></el-input>-->
+<!--        </el-form-item>-->
+<!--        <el-form-item label="验证码">-->
+<!--          <el-input placeholder="验证码内容" v-model="input3" class="input-with-select">-->
+<!--            <el-button slot="append">{{hasVerifyCode ? codeTime :'获取验证码'}}</el-button>-->
+<!--          </el-input>-->
+<!--        </el-form-item>-->
+<!--      </el-form>-->
     </div>
   </div>
 </template>
 
 <script>
-
+  import BindingMobile from './BindingMobile'
+  import ReBindingMobile from './ReBindingMobile'
+  import {storageGet} from '@/js/index'
+  import Http from '@/js/http.js'
   export default {
     name: "PhoneBinding",
+    components:{
+      BindingMobile,
+      ReBindingMobile
+    },
     data() {
       return {
-        active: 1,
-        phoneBindingForm:{
-          phone:''
-        }
+        active: 0,
+        showBingWranning:false,
+        user:{},
+        phoneBindingForm: {
+          phone: '',
+          verifyCode: ''
+        },
+
       }
     },
     methods: {
-
+      changePhoneNumber(){
+        this.showBingWranning = false;
+        this.$router.push({
+          path: '/personal/phoneBinding/rebinding',
+        });
+      },
+      bindPhoneNumber(){
+        this.showBingWranning = false;
+        this.$router.push({
+          path: '/personal/phoneBinding/binding',
+        });
+      },
+      setUserInfo() {
+        this.user = storageGet('user') && storageGet('user').userVO;
+      },
+    },
+    mounted() {
+      this.setUserInfo();
     }
   }
 </script>

+ 36 - 22
src/pages/UserCenter/QualificationCard.vue

@@ -1,29 +1,42 @@
 <template>
-  <div class="qualification-card">
-    <div class="qualification-card-title" style="padding: 10px;height:28px">
-      <span class="pull-left" style="font-size: 16px;font-weight: bold;line-height: 28px">信息安全工程师</span>
-      <el-button type="primary" plain class="pull-right" size="mini">编辑</el-button>
-    </div>
-    <div class="qualification-card-detail-wrapper">
-      <div class="qualification-card-detail">
-        <div class="qualification-card-detail-title">证书编号:</div>
-        <div class="qualification-card-detail-info">314020191144011401528</div>
-      </div>
-      <div class="qualification-card-detail">
-        <div class="qualification-card-detail-title">发证机关:</div>
-        <div class="qualification-card-detail-info">314020191144011401528</div>
-      </div>
-      <div class="qualification-card-detail">
-        <div class="qualification-card-detail-title">发证时间:</div>
-        <div class="qualification-card-detail-info">2020-06-30</div>
-      </div>
-    </div>
+  <div>
+    <el-row :gutter="15">
+      <el-col :span="8" v-for="item in qualificationVOList" :key="item.id">
+        <div class="qualification-card" @click="showQualificationDetail(item)">
+          <div class="qualification-card-title" style="padding: 10px;height:28px">
+            <span class="pull-left" style="font-size: 16px;font-weight: bold;line-height: 28px">{{item.name}}</span>
+            <el-button type="primary" plain class="pull-right" size="mini">编辑</el-button>
+          </div>
+          <div class="qualification-card-detail-wrapper">
+            <div class="qualification-card-detail">
+              <div class="qualification-card-detail-title">证书编号:</div>
+              <div class="qualification-card-detail-info">{{item.number}}</div>
+            </div>
+            <div class="qualification-card-detail">
+              <div class="qualification-card-detail-title">发证机关:</div>
+              <div class="qualification-card-detail-info">{{item.licensingAuthority}}</div>
+            </div>
+            <div class="qualification-card-detail">
+              <div class="qualification-card-detail-title">发证时间:</div>
+              <div class="qualification-card-detail-info">{{item.time}}</div>
+            </div>
+          </div>
+        </div>
+      </el-col>
+    </el-row>
   </div>
 </template>
 
 <script>
   export default {
-    name: "QualifucationCard"
+    name: "QualifucationCard",
+    props:['qualificationVOList'],
+    methods:{
+      showQualificationDetail(item){
+        console.log('item')
+        this.$emit('handleEditQualification',item);
+      }
+    }
   }
 </script>
 
@@ -33,17 +46,18 @@
   height:160px;
   background:rgba(255,255,255,1);
   box-shadow:0px 1px 6px 0px rgba(8,6,6,0.13);
+  margin-bottom: 10px;
   .qualification-card-detail-wrapper {
     padding: 10px;
     .qualification-card-detail{
       display: flex;
       margin-bottom: 5px;
       .qualification-card-detail-title {
-        font-size: 14px;
+        font-size: 13px;
       }
       .qualification-card-detail-info {
         color: rgba(153, 153, 153, 1);
-        font-size: 14px;
+        font-size: 13px;
       }
     }
   }

+ 114 - 0
src/pages/UserCenter/ReBindingMobile.vue

@@ -0,0 +1,114 @@
+<template>
+  <div>
+          <el-steps :active="active" process-status="finish" style="margin: 20px">
+            <el-step title="验证原手机"></el-step>
+            <el-step title="绑定新手机"></el-step>
+          </el-steps>
+
+          <el-form label-width="80px"  style="with:400px;">
+            <el-form-item label="原手机号" v-if="active===0">
+              <span v-model="phoneBindingForm.phone">{{this.user.mobile}}</span>
+            </el-form-item>
+            <el-form-item label="新手机号" v-if="active===1">
+              <el-input v-model="phoneBindingForm.phone"></el-input>
+            </el-form-item>
+            <el-form-item label="验证码">
+              <el-input placeholder="验证码内容" v-model="phoneBindingForm.verifyCode" class="input-with-select">
+                <el-button slot="append" @click="getVerifyCode">{{hasVerifyCode ? codeTime : '获取验证码'}}</el-button>
+              </el-input>
+              <span v-if="hasVerifyCode">验证码已发送到您手机上</span>
+            </el-form-item>
+          </el-form>
+    <el-button type="primary" plain style="margin-left: 80px" @click="reBindingMobile">{{this.active===0  ? '下一步':'完成绑定'}}</el-button>
+
+  </div>
+
+</template>
+
+<script>
+  import Http from '@/js/http.js'
+  import {storageGet} from '@/js/index'
+  import {notify} from '@/constants/index'
+  export default {
+    name: "ReBindingMobile",
+    data(){
+      return{
+        active: 1,
+        user:{},
+        phoneBindingForm: {
+          phone: '',
+          verifyCode: ''
+        },
+        hasVerifyCode:false,
+        codeTime:10,
+      }
+    },
+    methods:{
+      setUserInfo() {
+        this.user = storageGet('user') && storageGet('user').userVO;
+      },
+      reBindingMobile(){
+          if(this.active === 0){
+            //1.验证原手机
+            let params = {
+              "id": this.user.id,
+              "mobile": this.user.mobile
+            }
+            Http.put('/api/verify/mobile',params).then(res=>{
+              if(res.code === 20000){
+                notify('success', '验证成功');
+                this.active = 1;
+              }
+            }).catch(err=> {
+              notify('error', '验证原手机失败:' + err.data);
+            })
+          }else{
+            let params = {
+              "id": this.user.id,
+              "mobile": this.phoneBindingForm.phone,
+              "verifyCode": this.phoneBindingForm.verifyCode
+            };
+            Http.put('/api/user/mobile',params).then(res=>{
+              if(res.code === 20000){
+                notify('success', '重新绑定成功');
+                this.$router.push({path:'/personal/phoneBinding'});
+              }
+            }).catch(err=> {
+              notify('error', '重新绑定失败:' + err.data);
+            })
+          }
+
+      },
+      getVerifyCode(){
+        let params = {
+          id:this.user.id,
+          mobile:this.phoneBindingForm.phone
+        }
+        Http.put('/api/verify/mobile',params).then((res)=>{
+          this.hasVerifyCode = true;
+          let _this = this;
+          let codeTimer = setInterval(function () {
+            if(_this.codeTime > 0 ){
+              _this.codeTime--;
+            }else{
+              clearInterval(codeTimer);
+              _this.hasVerifyCode = false;
+              this.codeTime = 10;
+            }
+          },1000)
+        }).catch(err=> {
+          notify('error', '获取验证码失败:' + err.data);
+        })
+      }
+    },
+    mounted() {
+      this.phoneBindingForm.phone = this.user.mobile;
+      this.setUserInfo();
+      console.log(storageGet('user'));
+    }
+  }
+</script>
+
+<style scoped>
+
+</style>

+ 38 - 1
src/router/index.js

@@ -264,6 +264,15 @@ export default new Router({
       }
     },
     {
+      path: '/technology/more',
+      name: 'TechnologyMore',
+      component: resolve => require(['@/pages/Technology/TechnologyMore.vue'], resolve),
+      meta: {
+        title: '',
+        requireAuth: false,
+      }
+    },
+    {
       path: '/expert/list',
       name: 'ExpertList',
       component: resolve => require(['@/pages/HomepageSearch/ExpertList.vue'], resolve),
@@ -273,7 +282,7 @@ export default new Router({
       }
     },
     {
-      path: '/agency/list',
+      path: '/agency/list/show',
       name: 'AgencyList',
       component: resolve => require(['@/pages/HomepageSearch/AgencyList.vue'], resolve),
       meta: {
@@ -363,6 +372,24 @@ export default new Router({
       }
     },
     {
+      path: '/field/detail',
+      name: 'FieldDetail',
+      component: resolve => require(['@/pages/DetailPage/FieldDetail.vue'], resolve),
+      meta: {
+        title: '',
+        requireAuth: false,
+      }
+    },
+    {
+      path: '/test/type/detail',
+      name: 'TestTypeDetail',
+      component: resolve => require(['@/pages/DetailPage/TestTypeDetail.vue'], resolve),
+      meta: {
+        title: '',
+        requireAuth: false,
+      }
+    },
+    {
       path: '/personal',
       name: 'UserCenter',
       component: resolve => require(['@/pages/UserCenter/UserCenter.vue'], resolve),
@@ -390,6 +417,16 @@ export default new Router({
         {
           path: '/personal/phoneBinding',
           component: resolve => require(['@/pages/UserCenter/PhoneBinding.vue'], resolve),
+          children: [
+            {
+              path:'/personal/phoneBinding/binding',
+              component:resolve => require(['@/pages/UserCenter/BindingMobile.vue'], resolve),
+            },
+            {
+              path:'/personal/phoneBinding/rebinding',
+              component:resolve => require(['@/pages/UserCenter/ReBindingMobile.vue'], resolve),
+            },
+          ]
         },
         {
           path: '/personal/mailBinding',

+ 9 - 0
src/style/main.scss

@@ -360,3 +360,12 @@ a {
   height: 178px;
   display: block;
 }
+.rg-select {
+  padding:0 !important;
+  width: 110px !important;
+  height: 38px !important;
+}
+.rg-select__content {
+  padding: 0 8px !important;
+  height: 38px !important;
+}

Some files were not shown because too many files changed in this diff