hare8999@163.com 2 rokov pred
rodič
commit
dce584f7e2

+ 1 - 1
src/api/login.js

@@ -83,7 +83,7 @@ export function sendSmsNoValidation(params){
   return request({
     url: '/common/shortMessage/sendSmsNoValidation',
     method: 'get',
-    data: params
+    params
   })
 }
 

+ 10 - 0
src/api/system/user.js

@@ -106,6 +106,16 @@ export function updateUserProfile(data) {
   })
 }
 
+// 手机号变更
+export function updatePhonenumber(params) {
+  return request({
+    url: '/system/user/profile/updatePhonenumber',
+    method: 'get',
+    params
+  })
+}
+
+
 // 用户密码重置
 export function updateUserPwd(oldPassword, newPassword) {
   const data = {

+ 74 - 74
src/components/Breadcrumb/index.vue

@@ -1,74 +1,74 @@
-<template>
-  <el-breadcrumb class="app-breadcrumb" separator="/">
-    <transition-group name="breadcrumb">
-      <el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
-        <span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span>
-        <a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
-      </el-breadcrumb-item>
-    </transition-group>
-  </el-breadcrumb>
-</template>
-
-<script>
-export default {
-  data() {
-    return {
-      levelList: null
-    }
-  },
-  watch: {
-    $route(route) {
-      // if you go to the redirect page, do not update the breadcrumbs
-      if (route.path.startsWith('/redirect/')) {
-        return
-      }
-      this.getBreadcrumb()
-    }
-  },
-  created() {
-    this.getBreadcrumb()
-  },
-  methods: {
-    getBreadcrumb() {
-      // only show routes with meta.title
-      let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
-      const first = matched[0]
-
-      if (!this.isDashboard(first)) {
-        matched = [{ path: '/index', meta: { title: '首页' }}].concat(matched)
-      }
-
-      this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
-    },
-    isDashboard(route) {
-      const name = route && route.name
-      if (!name) {
-        return false
-      }
-      return name.trim() === '首页'
-    },
-    handleLink(item) {
-      const { redirect, path } = item
-      if (redirect) {
-        this.$router.push(redirect)
-        return
-      }
-      this.$router.push(path)
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-.app-breadcrumb.el-breadcrumb {
-  display: inline-block;
-  font-size: 14px;
-  line-height: 50px;
-  margin-left: 8px;
-
-  .no-redirect {
-    color: #97a8be;
-    cursor: text;
-  }
-}
-</style>
+<template>
+  <el-breadcrumb class="app-breadcrumb" separator="/">
+    <transition-group name="breadcrumb">
+      <el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
+        <span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span>
+        <a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
+      </el-breadcrumb-item>
+    </transition-group>
+  </el-breadcrumb>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      levelList: null
+    }
+  },
+  watch: {
+    $route(route) {
+      // if you go to the redirect page, do not update the breadcrumbs
+      if (route.path.startsWith('/redirect/')) {
+        return
+      }
+      this.getBreadcrumb()
+    }
+  },
+  created() {
+    this.getBreadcrumb()
+  },
+  methods: {
+    getBreadcrumb() {
+      // only show routes with meta.title
+      let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
+      const first = matched[0]
+
+      if (!this.isDashboard(first)) {
+        matched = [{ path: '/', meta: { title: '首页' }}].concat(matched)
+      }
+
+      this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
+    },
+    isDashboard(route) {
+      const name = route && route.name
+      if (!name) {
+        return false
+      }
+      return name.trim() === '首页'
+    },
+    handleLink(item) {
+      const { redirect, path } = item
+      if (redirect) {
+        this.$router.push(redirect)
+        return
+      }
+      this.$router.push(path)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.app-breadcrumb.el-breadcrumb {
+  display: inline-block;
+  font-size: 14px;
+  line-height: 50px;
+  margin-left: 8px;
+
+  .no-redirect {
+    color: #97a8be;
+    cursor: text;
+  }
+}
+</style>

+ 1 - 1
src/layout/components/Navbar.vue

@@ -100,7 +100,7 @@ export default {
         type: 'warning'
       }).then(() => {
         this.$store.dispatch('LogOut').then(() => {
-          location.href = '/index';
+          location.href = '/';
         })
       })
     }

+ 1 - 1
src/views/career/components/CareerMbtiReportList.vue

@@ -3,7 +3,7 @@
     <div class="mb10">
       <el-card style="color: #5E5E5E;" ref="navBar">
         <el-breadcrumb separator-class="el-icon-arrow-right">
-          <el-breadcrumb-item :to="{ path: '/index' }">首页</el-breadcrumb-item>
+          <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
           <el-breadcrumb-item :to="{ path: '/career/plan/CareerEva'}">生涯规划</el-breadcrumb-item>
           <el-breadcrumb-item>测评记录</el-breadcrumb-item>
         </el-breadcrumb>

+ 1 - 1
src/views/career/components/UniversityDetail.vue

@@ -2,7 +2,7 @@
     <div ref="universityDetail" id="universityDetail" style="padding:24px 8%;background-color:#f7f7f7;">
       <el-card style="color: #5E5E5E;" ref="navBar">
         <el-breadcrumb separator-class="el-icon-arrow-right">
-          <el-breadcrumb-item :to="{ path: '/index' }">首页</el-breadcrumb-item>
+          <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
           <el-breadcrumb-item :to="{ path: '/career/plan/UniversitiesColleges'}">校园库</el-breadcrumb-item>
           <el-breadcrumb-item>校院详情</el-breadcrumb-item>
         </el-breadcrumb>

+ 1 - 1
src/views/career/plan/ProfessLibDetail.vue

@@ -4,7 +4,7 @@
       <!--<div style="width: 1180px;height: 22px;margin: 10px auto;">-->
         <el-card style="width: 1180px;margin: 10px auto;">
           <el-breadcrumb separator-class="el-icon-arrow-right">
-            <el-breadcrumb-item :to="{ path: '/index' }">首页</el-breadcrumb-item>
+            <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
             <!--<el-breadcrumb-item :to="{ path: '/career/plan/index'}">生涯·志愿</el-breadcrumb-item>-->
             <el-breadcrumb-item :to="{ path: '/career/plan/ProfessLib'}">专业库</el-breadcrumb-item>
             <el-breadcrumb-item>专业库详情</el-breadcrumb-item>

+ 1 - 1
src/views/career/plan/new-major-detail.vue

@@ -28,7 +28,7 @@
           <el-card style="color: #5E5E5E;" ref="navBar">
             <div class="fx-row jc-between ai-center">
               <el-breadcrumb separator-class="el-icon-arrow-right">
-                <el-breadcrumb-item :to="{ path: '/index' }">首页</el-breadcrumb-item>
+                <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
                 <el-breadcrumb-item :to="{ path: '/new-gaokao/three/ProfessLib'}">专业库</el-breadcrumb-item>
                 <el-breadcrumb-item>专业详情</el-breadcrumb-item>
               </el-breadcrumb>

+ 1 - 1
src/views/career/vocation/new-detail.vue

@@ -29,7 +29,7 @@
         <el-card style="color: #5E5E5E;" ref="navBar">
           <div class="fx-row jc-between ai-center">
             <el-breadcrumb separator-class="el-icon-arrow-right">
-              <el-breadcrumb-item :to="{ path: '/index' }">首页</el-breadcrumb-item>
+              <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
               <el-breadcrumb-item :to="{ path: '/new-gaokao/three/Vocation'}">职业库</el-breadcrumb-item>
               <el-breadcrumb-item>职业详情</el-breadcrumb-item>
             </el-breadcrumb>

+ 1 - 1
src/views/career/vocation/old-detail.vue

@@ -2,7 +2,7 @@
   <div id="jobDetail" ref="jobDetail" style="padding:24px 8%;background-color:#f7f7f7;" v-loading="loading">
     <el-card style="color: #5E5E5E;" ref="navBar">
       <el-breadcrumb separator-class="el-icon-arrow-right">
-        <el-breadcrumb-item :to="{ path: '/index' }">首页</el-breadcrumb-item>
+        <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
         <el-breadcrumb-item :to="{ path: '/career/vocation/index'}">职业库</el-breadcrumb-item>
         <el-breadcrumb-item>职业详情</el-breadcrumb-item>
       </el-breadcrumb>

+ 92 - 0
src/views/system/user/profile/components/ResetMobileForm.vue

@@ -0,0 +1,92 @@
+<template>
+  <el-form ref="form" :model="form" :rules="rules" label-position="right" label-width="120px">
+    <el-form-item label="新手机号码" prop="phonenumber">
+      <el-input v-model="form.phonenumber"></el-input>
+    </el-form-item>
+    <el-form-item label="验证码" prop="code">
+      <div class="fx-row fx-bet-cen">
+        <el-input v-model="form.code" class="mr15"></el-input>
+        <el-button type="primary" size="small" :disabled="countdown>0" @click="handleSendSms" style="width: 112px">
+          <template v-if="countdown">重新发送({{ countdown }}s)</template>
+          <template v-else>发送验证码</template>
+        </el-button>
+      </div>
+    </el-form-item>
+    <el-form-item>
+      <el-button type="primary" size="mini" @click="handleSubmit">保存</el-button>
+      <el-button size="mini" @click="$emit('cancel')">取消</el-button>
+    </el-form-item>
+  </el-form>
+</template>
+
+<script>
+import { sendSms } from '@/api/login'
+import { updatePhonenumber } from '@/api/system/user'
+
+export default {
+  name: 'ResetMobileForm',
+  data() {
+    return {
+      loading: false,
+      countdown: 0,
+      timer: null,
+      form: {
+        phonenumber: '',
+        code: ''
+      },
+      rules: {
+        phonenumber: [
+          { required: true, message: '请输入要变更的手机号码' },
+          { pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: '请输入正确的手机号码', trigger: 'blur' }],
+        code: { required: true, message: '请输入验证码' }
+      }
+    }
+  },
+  beforeDestroy() {
+    this.releaseTimer()
+  },
+  methods: {
+    releaseTimer() {
+      if (this.timer) {
+        clearInterval(this.timer)
+        this.timer = null
+      }
+    },
+    beginCountDown() {
+      this.releaseTimer()
+      this.countdown = 90
+      this.timer = setInterval((_) => {
+        if (this.countdown == 0) {
+          this.releaseTimer()
+        } else {
+          this.countdown -= 1
+        }
+      }, 1000)
+    },
+    async handleSendSms() {
+      if (this.countdown > 0) return // in lock
+      this.$refs.form.clearValidate() // 需要传空数组
+      this.$refs.form.validateField(['phonenumber'], async err => {
+        if (err) return
+        this.beginCountDown()
+        await sendSms({
+          mobile: this.form.phonenumber,
+          smsType: 1
+        })
+        this.msgSuccess('验证码已发送')
+      })
+    },
+    async handleSubmit() {
+      await this.$refs.form.validate()
+      const res = await updatePhonenumber(this.form)
+      Object.assign(this.$data, this.$options.data()) // reset
+      this.msgSuccess('手机号码变更成功')
+      this.$emit('completed')
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 1 - 1
src/views/system/user/profile/resetPwd.vue

@@ -65,7 +65,7 @@ export default {
     },
     close() {
       this.$store.dispatch("tagsView/delView", this.$route);
-      this.$router.push({ path: "/index" });
+      this.$router.push({ path: "/" });
     }
   }
 };

+ 61 - 63
src/views/system/user/profile/userInfo.vue

@@ -1,96 +1,94 @@
 <template>
-  <el-form ref="form" :model="user" :rules="rules" label-width="80px">
-    <el-form-item label="用户名称" prop="userName">
-      <el-input v-model="user.userName" disabled="disabled" maxlength="50" />
-    </el-form-item>
-    <el-form-item label="创建时间" prop="createTime">
-      <el-input v-model="user.createTime" disabled="disabled" maxlength="50" />
-    </el-form-item>
-    <el-form-item label="用户姓名" prop="nickName">
-      <el-input v-model="user.nickName" />
-    </el-form-item>
-    <el-form-item label="手机号码" prop="phonenumber">
-      <el-input v-model="user.phonenumber" disabled="disabled" maxlength="11" />
-    </el-form-item>
-    <el-form-item v-if="isFrontStudent" label="学号" prop="sno">
-      <el-input v-model="user.sno" />
-    </el-form-item>
-    <el-form-item label="性别">
-      <el-radio-group v-model="user.sex">
-        <el-radio label="0">男</el-radio>
-        <el-radio label="1">女</el-radio>
-      </el-radio-group>
-    </el-form-item>
-    <el-form-item>
-      <el-button type="primary" size="mini" @click="submit">保存</el-button>
-      <!--<el-button type="danger" size="mini" @click="close">关闭</el-button>-->
-    </el-form-item>
-  </el-form>
+  <div>
+    <el-form ref="form" :model="user" :rules="rules" label-width="80px">
+      <el-form-item label="用户名称" prop="userName">
+        <el-input v-model="user.userName" disabled="disabled" maxlength="50"/>
+      </el-form-item>
+      <el-form-item label="创建时间" prop="createTime">
+        <el-input v-model="user.createTime" disabled="disabled" maxlength="50"/>
+      </el-form-item>
+      <el-form-item label="用户姓名" prop="nickName">
+        <el-input v-model="user.nickName"/>
+      </el-form-item>
+      <div class="fx-row">
+        <el-form-item label="手机号码" prop="phonenumber" class="width100">
+          <div class="fx-row fx-bet-cen">
+            <el-input v-model="user.phonenumber" disabled="disabled" maxlength="11" class="fx-1 mr15"/>
+            <el-button type="warning" plain @click="dialogVisible=true">变更手机号码</el-button>
+          </div>
+        </el-form-item>
+      </div>
+      <el-form-item v-if="isFrontStudent" label="学号" prop="sno">
+        <el-input v-model="user.sno"/>
+      </el-form-item>
+      <el-form-item label="性别">
+        <el-radio-group v-model="user.sex">
+          <el-radio label="0">男</el-radio>
+          <el-radio label="1">女</el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" size="mini" @click="submit">保存</el-button>
+        <!--<el-button type="danger" size="mini" @click="close">关闭</el-button>-->
+      </el-form-item>
+    </el-form>
+    <el-dialog :visible.sync="dialogVisible" title="变更手机号" width="450px">
+      <reset-mobile-form @cancel="dialogVisible=false" @completed="dialogVisible=false,GetInfo()"></reset-mobile-form>
+    </el-dialog>
+  </div>
 </template>
 
 <script>
-import { updateUserProfile, getUserProfile } from "@/api/system/user";
+import { updateUserProfile } from '@/api/system/user'
 import { mapActions, mapGetters } from 'vuex'
+import ResetMobileForm from '@/views/system/user/profile/components/ResetMobileForm'
 
 export default {
+  components: { ResetMobileForm },
   props: {
     user: {
-      type: Object,
-    },
+      type: Object
+    }
   },
   computed: {
     ...mapGetters(['isFrontStudent'])
   },
   data() {
     return {
+      dialogVisible: false,
       // 表单校验
       rules: {
         nickName: [
-          { required: true, message: "用户昵称不能为空", trigger: "blur" },
-        ],
-        // email: [
-        //   { required: true, message: "邮箱地址不能为空", trigger: "blur" },
-        //   {
-        //     type: "email",
-        //     message: "'请输入正确的邮箱地址",
-        //     trigger: ["blur", "change"]
-        //   }
-        // ],
-        phonenumber: [
-          { required: true, message: "手机号码不能为空", trigger: "blur" },
-          {
-            pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
-            message: "请输入正确的手机号码",
-            trigger: "blur",
-          },
-        ],
-      },
-    };
+          { required: true, message: '用户昵称不能为空', trigger: 'blur' }
+        ]
+      }
+    }
   },
   methods: {
-    ...mapActions(["GetInfo"]),
+    ...mapActions(['GetInfo']),
     submit() {
-      this.$refs["form"].validate((valid) => {
+      this.$refs['form'].validate((valid) => {
         if (valid) {
           updateUserProfile(this.user).then((response) => {
-            this.msgSuccess("修改成功");
-            this.GetInfo();
-          });
+            this.msgSuccess('修改成功')
+            this.GetInfo()
+          })
         }
-      });
+      })
     },
     close() {
-      this.$store.dispatch("tagsView/delView", this.$route);
-      this.$router.push({ path: "/index" });
-    },
-  },
-};
+      this.$store.dispatch('tagsView/delView', this.$route)
+      this.$router.push({ path: '/' })
+    }
+  }
+}
 </script>
 <style scoped>
-/deep/.el-radio__label {
+/deep/ .el-radio__label {
   display: inline-block;
 }
-/deep/.el-radio {
+
+/deep/ .el-radio {
   display: inline-block;
 }
 </style>