提交 e8def861 authored 作者: 王鹏飞's avatar 王鹏飞

新增安全设置

上级 8f03fe34
...@@ -16,8 +16,8 @@ export function updatePassword(data) { ...@@ -16,8 +16,8 @@ export function updatePassword(data) {
export function resetPassword(data) { export function resetPassword(data) {
return httpRequest.post('/api/usercenter/user/update-pwd', data) return httpRequest.post('/api/usercenter/user/update-pwd', data)
} }
// 发送重置验证码 // 发送验证码
export function sendResetPasswordCode(data) { export function sendCode(data) {
return httpRequest.post('/api/usercenter/user/send-code', data) return httpRequest.post('/api/usercenter/user/send-code', data)
} }
// 登出 // 登出
...@@ -28,6 +28,10 @@ export function logout() { ...@@ -28,6 +28,10 @@ export function logout() {
export function getUser() { export function getUser() {
return httpRequest.get('/api/zy/user/getinfo') return httpRequest.get('/api/zy/user/getinfo')
} }
// 修改用户信息
export function updateUser(data) {
return httpRequest.post('/api/usercenter/user/update-user', data)
}
// 绑定游客 // 绑定游客
export function bindVisitor(data) { export function bindVisitor(data) {
return httpRequest.post('/api/zy/user/bind-account', data) return httpRequest.post('/api/zy/user/bind-account', data)
...@@ -40,3 +44,7 @@ export function getIsVip() { ...@@ -40,3 +44,7 @@ export function getIsVip() {
export function createGuestUser() { export function createGuestUser() {
return httpRequest.get('/api/zy/user/create-guest-user') return httpRequest.get('/api/zy/user/create-guest-user')
} }
// 校验验证码
export function checkCode(params) {
return httpRequest.get('/api/usercenter/user/check-code', { params })
}
...@@ -50,6 +50,6 @@ export default { ...@@ -50,6 +50,6 @@ export default {
position: sticky; position: sticky;
bottom: 0; bottom: 0;
padding-top: 30px; padding-top: 30px;
border-top: 1px solid #f1f1f1; border-top: 1px solid #ccc;
} }
</style> </style>
<template>
<el-button v-bind="$attrs" :disabled="currentDisabled" @click="start">{{ curretnValue }}</el-button>
</template>
<script>
export default {
name: 'Countdown',
props: {
step: { type: Number, default: 1000 },
disabled: { type: Boolean, default: false },
seconds: { type: Number, default: 60 },
defaultValue: { type: String, default: '获取验证码' }
},
data() {
return {
currentDisabled: false,
currentSeconds: 0,
timer: null
}
},
watch: {
disabled: {
immediate: true,
handler(value) {
this.currentDisabled = value
}
}
},
computed: {
curretnValue() {
const longTime = this.seconds - this.currentSeconds
return longTime < this.seconds ? `${longTime}S` : this.defaultValue
}
},
methods: {
genTimer() {
this.clearTimer()
this.timer = setInterval(() => {
this.currentSeconds++
if (this.currentSeconds === this.seconds) {
this.stop()
}
}, this.step)
},
clearTimer() {
this.timer && clearInterval(this.timer)
},
start() {
this.currentDisabled = true
this.genTimer()
this.$emit('start')
},
stop() {
this.clearTimer()
this.currentSeconds = 0
this.currentDisabled = false
this.$emit('stop')
}
}
}
</script>
...@@ -64,7 +64,9 @@ export default { ...@@ -64,7 +64,9 @@ export default {
{ {
title: '实训练习', title: '实训练习',
icon: 'icon-kaoshihong', icon: 'icon-kaoshihong',
children: [{ title: '实训案例练习', href: 'https://xtraining.ezijing.com/' }] children: [
{ title: '实训案例练习', path: 'https://xtraining.ezijing.com/', href: 'https://xtraining.ezijing.com/' }
]
}, },
{ {
title: '个人中心', title: '个人中心',
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
<el-dropdown> <el-dropdown>
<div class="user"> <div class="user">
<img :src="avatar" class="user-avatar" /> <img :src="avatar" class="user-avatar" />
<span class="user-name">{{ user.realname }}</span> <span class="user-name">{{ user.nickname }}</span>
</div> </div>
<el-dropdown-menu slot="dropdown"> <el-dropdown-menu slot="dropdown">
<el-dropdown-item icon="el-icon-user" @click.native="$router.push('/account')">个人中心</el-dropdown-item> <el-dropdown-item icon="el-icon-user" @click.native="$router.push('/account')">个人中心</el-dropdown-item>
......
<template>
<app-container title="安全设置">
<el-form :model="ruleForm" :rules="rules" label-width="130px" ref="ruleForm" class="form">
<el-form-item label="设置新手机号码" prop="account">
<el-input v-model="ruleForm.account"></el-input>
</el-form-item>
<el-form-item label="输入验证码" prop="code">
<el-input maxlength="4" v-model="ruleForm.code">
<countdown slot="suffix" size="mini" :disabled="disabledSend" @start="sendCode" ref="countdown"></countdown>
</el-input>
</el-form-item>
</el-form>
<template #footer>
<div class="app-container-ft">
<el-button type="primary" @click="handleSubmit">保存</el-button>
</div>
</template>
</app-container>
</template>
<script>
import AppContainer from '@/components/AppContainer'
import Countdown from '@/components/Countdown'
import * as api from '@/api/account'
export default {
components: { AppContainer, Countdown },
data() {
return {
ruleForm: { account: '', code: '' },
rules: {
account: [{ required: true, message: '请输入手机号码', trigger: 'blur' }],
code: [{ required: true, message: '请输入验证码', trigger: 'blur' }]
}
}
},
computed: {
disabledSend() {
return !/^1[3-9]\d{9}$/.test(this.ruleForm.account)
}
},
methods: {
handleSubmit() {
this.$refs.ruleForm.validate().then(this.checkCode)
},
sendCode() {
api
.sendCode({ account: this.ruleForm.account })
.then(response => {
if (response.code === 0) {
this.$message({ type: 'success', message: '验证码发送成功' })
} else {
// 停止计时
this.$refs.countdown.stop()
this.$message({ type: 'error', message: response.msg })
}
})
.catch(this.$refs.countdown.stop)
},
checkCode() {
api.checkCode(this.ruleForm).then(response => {
this.updateUser()
})
},
updateUser() {
api
.updateUser({ mobile: this.ruleForm.account })
.then(response => {
this.$message({ type: 'success', message: '手机号码修改成功' })
this.$store.dispatch('getUser')
this.$emit('success')
})
.catch(() => {
this.$refs.countdown.stop()
})
}
}
}
</script>
<style lang="scss" scoped>
.form {
max-width: 400px;
}
</style>
<template>
<app-container title="安全设置">
<el-form :model="ruleForm" :rules="rules" label-width="100px" ref="ruleForm" class="form">
<el-form-item label="手机号码">
<el-input v-model="user.mobile" disabled></el-input>
<el-button @click="toggleUpdate" class="button-change">{{ buttonText }}</el-button>
</el-form-item>
<el-form-item label="输入验证码" prop="code" v-if="isUpdate && !isEmail">
<el-input maxlength="4" v-model="ruleForm.code">
<countdown slot="suffix" size="mini" @start="handlePhoneCode" ref="countdown"></countdown>
</el-input>
</el-form-item>
<div>
<span>如手机无法收到验证码,请选择</span>
<el-button @click="handleEmailCode">注册邮箱接收验证码</el-button>
</div>
<template v-if="isEmail">
<p>请前往邮箱获取验证码后,</p>
<el-form-item label="输入验证码" prop="code">
<el-input maxlength="4" v-model="ruleForm.code"></el-input>
</el-form-item>
</template>
</el-form>
<template #footer>
<div class="app-container-ft">
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">提交</el-button>
</div>
</template>
</app-container>
</template>
<script>
import AppContainer from '@/components/AppContainer'
import Countdown from '@/components/Countdown'
import * as api from '@/api/account'
export default {
components: { AppContainer, Countdown },
data() {
return {
ruleForm: {
account: '',
code: ''
},
rules: {
code: [{ required: true, message: '请输入验证码', trigger: 'blur' }]
},
isUpdate: false,
isEmail: false,
submitLoading: false
}
},
computed: {
user() {
return this.$store.state.user
},
buttonText() {
return this.isUpdate ? '取消' : '更改'
}
},
methods: {
toggleUpdate() {
this.isUpdate = !this.isUpdate
this.isEmail = false
},
handlePhoneCode() {
const account = this.user.mobile
if (!account) {
this.$message({ message: '该账号尚未绑定手机号码', type: 'error' })
return
}
this.ruleForm.account = account
this.sendPhoneCode(account)
},
// 发送手机验证码
sendPhoneCode(account) {
api
.sendCode({ account })
.then(response => {
if (response.code === 0) {
this.$message({ type: 'success', message: '验证码发送成功' })
} else {
// 停止计时
this.$refs.countdown.stop()
this.$message({ type: 'error', message: response.msg })
}
})
.catch(this.$refs.countdown.stop)
},
// 获取邮箱验证码
handleEmailCode() {
const account = this.user.email
if (!account) {
this.$message({ message: '该账号尚未绑定邮箱', type: 'error' })
return
}
this.isEmail = true
this.ruleForm.account = account
this.sendEmailCode(account)
},
// 发送邮箱验证码
sendEmailCode(account) {
api.sendCode({ account }).then(response => {
this.$message({ message: '验证码发送成功', type: 'success' })
})
},
// 提交
handleSubmit() {
this.$refs.ruleForm.validate().then(this.checkCode)
},
// 校验验证码
checkCode() {
api.checkCode(this.ruleForm).then(response => {
this.$emit('success')
})
}
}
}
</script>
<style lang="scss" scoped>
.form {
max-width: 400px;
}
.button-change {
position: absolute;
right: -90px;
}
</style>
<template> <template>
<app-container title="个人信息"> <app-container title="个人信息">
<el-form :model="ruleForm" :rules="rules" label-width="120px" ref="ruleForm" class="form"> <el-form :model="ruleForm" :rules="rules" label-width="100px" ref="ruleForm" class="form">
<el-form-item label="所在院校" prop="phone"> <el-form-item label="所在院校" prop="college">
<el-input v-model="ruleForm.phone" readonly></el-input> <el-input v-model="ruleForm.college" disabled></el-input>
</el-form-item> </el-form-item>
<el-form-item label="学院名称" prop="phone"> <el-form-item label="学院名称" prop="school">
<el-input v-model="ruleForm.phone" readonly></el-input> <el-input v-model="ruleForm.school" disabled></el-input>
</el-form-item> </el-form-item>
<el-form-item label="专业名称" prop="phone"> <el-form-item label="专业名称" prop="major">
<el-input v-model="ruleForm.phone" readonly></el-input> <el-input v-model="ruleForm.major" disabled></el-input>
</el-form-item> </el-form-item>
<el-form-item label="考证等级" prop="phone"> <el-form-item label="考证等级" prop="grade">
<el-input v-model="ruleForm.phone" readonly></el-input> <el-input v-model="ruleForm.grade" disabled></el-input>
</el-form-item> </el-form-item>
<el-form-item label="用户真实姓名" prop="phone"> <el-form-item label="用户真实姓名" prop="realname">
<el-input v-model="ruleForm.phone" readonly></el-input> <el-input v-model="ruleForm.realname" disabled></el-input>
</el-form-item> </el-form-item>
<el-form-item label="身份证号码" prop="phone"> <el-form-item label="身份证号码" prop="id_number">
<el-input v-model="ruleForm.phone" readonly></el-input> <el-input v-model="ruleForm.id_number" disabled></el-input>
</el-form-item> </el-form-item>
<el-form-item label="身份" prop="phone"> <el-form-item label="身份" prop="phone">
<el-input v-model="ruleForm.phone" readonly></el-input> <el-input v-model="ruleForm.phone" disabled></el-input>
</el-form-item> </el-form-item>
<el-form-item label="登录帐号" prop="phone"> <el-form-item label="登录帐号" prop="mobile">
<el-input v-model="ruleForm.phone" readonly></el-input> <el-input v-model="ruleForm.mobile" disabled></el-input>
</el-form-item> </el-form-item>
<el-form-item label="账号名" prop="phone"> <el-form-item label="账号名" prop="username">
<el-input v-model="ruleForm.phone"></el-input> <el-input v-model="ruleForm.username"></el-input>
</el-form-item> </el-form-item>
<el-form-item label="常用邮箱" prop="email"> <el-form-item label="常用邮箱" prop="email">
<el-input v-model="ruleForm.email"></el-input> <el-input v-model="ruleForm.email"></el-input>
...@@ -47,11 +47,10 @@ export default { ...@@ -47,11 +47,10 @@ export default {
components: { AppContainer }, components: { AppContainer },
data() { data() {
return { return {
ruleForm: { ruleForm: { username: '', email: '' },
email: ''
},
rules: { rules: {
email: [{ required: true, message: '请输入手机号码', trigger: 'blur' }] username: [{ required: true, message: '请输入账号名', trigger: 'blur' }],
email: [{ required: true, type: 'email', message: '请输入邮箱', trigger: 'blur' }]
}, },
submitLoading: false submitLoading: false
} }
...@@ -61,16 +60,27 @@ export default { ...@@ -61,16 +60,27 @@ export default {
return this.$store.state.user return this.$store.state.user
} }
}, },
watch: {
user: {
immediate: true,
handler(value) {
this.ruleForm = value
}
}
},
methods: { methods: {
handleSubmit() { handleSubmit() {
this.$refs.ruleForm.validate().then(this.handleSubmitRequest) this.$refs.ruleForm.validate().then(this.handleSubmitRequest)
}, },
handleSubmitRequest() { handleSubmitRequest() {
this.submitLoading = true this.submitLoading = true
const params = { username: this.ruleForm.username, email: this.ruleForm.email }
api api
.updatePassword(this.ruleForm) .updateUser(params)
.then(response => { .then(response => {
this.$message({ message: '密码修改成功', type: 'success' }) this.ruleForm = response.data
this.$store.dispatch('getUser')
this.$message({ message: '修改成功', type: 'success' })
}) })
.finally(() => { .finally(() => {
this.submitLoading = false this.submitLoading = false
...@@ -82,6 +92,6 @@ export default { ...@@ -82,6 +92,6 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.form { .form {
max-width: 360px; max-width: 340px;
} }
</style> </style>
<template> <template>
<app-container title="安全设置"> <check-phone v-if="active === 1" @success="active = 2" />
<el-form :model="ruleForm" :rules="rules" label-width="90px" ref="ruleForm" class="form"> <bind-phone v-else @success="active = 1" />
<el-form-item label="手机号码" prop="phone">
<el-input type="password" v-model="ruleForm.phone"></el-input>
</el-form-item>
</el-form>
<template #footer>
<div class="app-container-ft">
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">保存</el-button>
</div>
</template>
</app-container>
</template> </template>
<script> <script>
import AppContainer from '@/components/AppContainer' import CheckPhone from './checkPhone'
import * as api from '@/api/account' import BindPhone from './bindPhone'
export default { export default {
components: { AppContainer }, components: { CheckPhone, BindPhone },
data() { data() {
return { return { active: 1 }
ruleForm: {
phone: ''
},
rules: {
phone: [{ required: true, message: '请输入手机号码', trigger: 'blur' }]
},
submitLoading: false
}
},
methods: {
handleSubmit() {
this.$refs.ruleForm.validate().then(this.handleSubmitRequest)
},
handleSubmitRequest() {
this.submitLoading = true
api
.updatePassword(this.ruleForm)
.then(response => {
this.$message({ message: '密码修改成功', type: 'success' })
// 重置表单
this.$refs.ruleForm.resetFields()
})
.finally(() => {
this.submitLoading = false
})
}
} }
} }
</script> </script>
<style lang="scss" scoped>
.form {
max-width: 340px;
}
</style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论