feat:个人信息功能修改
This commit is contained in:
parent
a960ca062f
commit
d8c6aefd13
@ -17,7 +17,7 @@ import javax.validation.constraints.Pattern;
|
|||||||
@Data
|
@Data
|
||||||
public class EmailUpdateBody {
|
public class EmailUpdateBody {
|
||||||
@NotNull(message = "参数不为空")
|
@NotNull(message = "参数不为空")
|
||||||
private String actionId;
|
private String oldPassword;
|
||||||
@Email(message = "请输入有效邮箱地址")
|
@Email(message = "请输入有效邮箱地址")
|
||||||
private String email;
|
private String email;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ import javax.validation.constraints.Pattern;
|
|||||||
@Data
|
@Data
|
||||||
public class UpdatePasswordBody {
|
public class UpdatePasswordBody {
|
||||||
|
|
||||||
private String actionId;
|
private String oldPassword;
|
||||||
@Pattern(regexp = ValidatedConstant.PASSWORD_REG, message = ValidatedConstant.PASSWORD_MESSAGE)
|
@Pattern(regexp = ValidatedConstant.PASSWORD_REG, message = ValidatedConstant.PASSWORD_MESSAGE)
|
||||||
private String password;
|
private String password;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.fanxb.bookmark.business.user.service;
|
package com.fanxb.bookmark.business.user.service;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.fanxb.bookmark.business.user.constant.RedisConstant;
|
import com.fanxb.bookmark.business.user.constant.RedisConstant;
|
||||||
import com.fanxb.bookmark.business.user.dao.UserDao;
|
import com.fanxb.bookmark.business.user.dao.UserDao;
|
||||||
import com.fanxb.bookmark.business.user.entity.EmailUpdateBody;
|
import com.fanxb.bookmark.business.user.entity.EmailUpdateBody;
|
||||||
@ -39,10 +40,9 @@ public class BaseInfoService {
|
|||||||
|
|
||||||
public void changePassword(UpdatePasswordBody body) {
|
public void changePassword(UpdatePasswordBody body) {
|
||||||
int userId = UserContextHolder.get().getUserId();
|
int userId = UserContextHolder.get().getUserId();
|
||||||
String checkAuthKey = com.fanxb.bookmark.common.constant.RedisConstant.getPasswordCheckKey(userId, body.getActionId());
|
String password = userDao.selectByUserId(userId).getPassword();
|
||||||
String str = RedisUtil.get(checkAuthKey, String.class);
|
if (!StrUtil.equals(password, HashUtil.getPassword(body.getOldPassword()))) {
|
||||||
if (str == null) {
|
throw new CustomException("旧密码错误");
|
||||||
throw new CustomException("密码校验失败,无法更新密码");
|
|
||||||
}
|
}
|
||||||
userDao.updatePasswordByUserId(userId, HashUtil.getPassword(body.getPassword()));
|
userDao.updatePasswordByUserId(userId, HashUtil.getPassword(body.getPassword()));
|
||||||
}
|
}
|
||||||
@ -69,12 +69,10 @@ public class BaseInfoService {
|
|||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void updateEmail(EmailUpdateBody body) {
|
public void updateEmail(EmailUpdateBody body) {
|
||||||
int userId = UserContextHolder.get().getUserId();
|
int userId = UserContextHolder.get().getUserId();
|
||||||
String checkAuthKey = com.fanxb.bookmark.common.constant.RedisConstant.getPasswordCheckKey(userId, body.getActionId());
|
String oldPassword = userDao.selectByUserId(userId).getPassword();
|
||||||
String str = RedisUtil.get(checkAuthKey, String.class);
|
if (!StrUtil.equals(oldPassword, HashUtil.getPassword(body.getOldPassword()))) {
|
||||||
if (str == null) {
|
|
||||||
throw new CustomException("密码校验失败,无法更新email");
|
throw new CustomException("密码校验失败,无法更新email");
|
||||||
}
|
}
|
||||||
RedisUtil.delete(checkAuthKey);
|
|
||||||
String secret = UUID.randomUUID().toString().replaceAll("-", "");
|
String secret = UUID.randomUUID().toString().replaceAll("-", "");
|
||||||
String url = VERIFY_EMAIL.replaceAll("XXXX", Constant.serviceAddress + VERIFY_EMAIL_PATH + secret);
|
String url = VERIFY_EMAIL.replaceAll("XXXX", Constant.serviceAddress + VERIFY_EMAIL_PATH + secret);
|
||||||
log.debug(url);
|
log.debug(url);
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
<!-- <meta name="viewport" content="width=device-width,initial-scale=1.0" /> -->
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
|
||||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<div>bottom</div>
|
<div>开源地址:<a href="https://github.com/FleyX/bookmark">github.com/FleyX/bookmark</a>  <a href="https://github.com/FleyX/bookmark/issues">反馈/建议</a></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: "Bottom"
|
name: "Bottom",
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@import "../../global";
|
@import "../../global";
|
||||||
.main {
|
.main {
|
||||||
background-color: gray;
|
background-color: rgb(207, 198, 198);
|
||||||
height: @bottomHeight;
|
height: @bottomHeight;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<img class="ico" src="/static/img/bookmarkLogo.png" />
|
<a class="ico" href="/"><img src="/static/img/bookmarkLogo.png" /></a>
|
||||||
<a-dropdown>
|
<a-dropdown>
|
||||||
<div class="user">
|
<div class="user">
|
||||||
<img :src="userInfo.icon" class="userIcon" />
|
<img :src="userInfo.icon" class="userIcon" />
|
||||||
@ -52,6 +52,7 @@ export default {
|
|||||||
background-color: rgba(197, 190, 198, 0.4);
|
background-color: rgba(197, 190, 198, 0.4);
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
.ico {
|
.ico {
|
||||||
|
display: flex;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
.user {
|
.user {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import localforage from "localforage";
|
import localforage from "localforage";
|
||||||
|
import HttpUtil from "../../util/HttpUtil";
|
||||||
/**
|
/**
|
||||||
* 存储全局配置
|
* 存储全局配置
|
||||||
*/
|
*/
|
||||||
@ -36,6 +37,11 @@ const actions = {
|
|||||||
context.commit("isInit", true);
|
context.commit("isInit", true);
|
||||||
context.commit("isPhone", /Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent));
|
context.commit("isPhone", /Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent));
|
||||||
},
|
},
|
||||||
|
async refreshUserInfo({ commit }) {
|
||||||
|
let userInfo = await HttpUtil.get("/user/currentUserInfo");
|
||||||
|
await localforage.setItem("userInfo", userInfo);
|
||||||
|
commit("setUserInfo", userInfo);
|
||||||
|
},
|
||||||
//登出清除数据
|
//登出清除数据
|
||||||
async clear(context) {
|
async clear(context) {
|
||||||
await localforage.removeItem("userInfo");
|
await localforage.removeItem("userInfo");
|
||||||
|
@ -11,9 +11,50 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="baseInfo">
|
<div class="baseInfo">
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<span>昵称</span>
|
|
||||||
<span>{{userInfo.name}}</span>
|
<a-tooltip title="点击修改" v-if="currentAction!='name'">
|
||||||
|
<span style="font-size:2em;cursor: pointer;" @click="()=>this.currentAction='name'">{{userInfo.username}}</span>
|
||||||
|
</a-tooltip>
|
||||||
|
<div class="inputGroup" v-else-if="currentAction==='name'">
|
||||||
|
<a-input type="text" v-model="name" placeholder="修改昵称" />
|
||||||
|
<div style="padding-top:0.2em">
|
||||||
|
<a-button style="margin-right:2em" type="warn" @click="()=>this.currentAction=null">取消</a-button>
|
||||||
|
<a-button type="primary" @click="submit">确定</a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="item">
|
||||||
|
<span style="width:5em">密码</span>
|
||||||
|
<a-tooltip title="点击修改" v-if="currentAction!='password'">
|
||||||
|
<span style="cursor: pointer;" @click="()=>this.currentAction='password'">**********</span>
|
||||||
|
</a-tooltip>
|
||||||
|
<div class="inputGroup" v-else-if="currentAction==='password'">
|
||||||
|
<a-input type="password" v-model="oldPassword" placeholder="旧密码" />
|
||||||
|
<a-input type="password" v-model="password" placeholder="新密码" />
|
||||||
|
<a-input type="password" v-model="rePassword" placeholder="重复新密码" />
|
||||||
|
<div style="padding-top:0.2em">
|
||||||
|
<a-button style="margin-right:2em" type="warn" @click="()=>this.currentAction=null">取消</a-button>
|
||||||
|
<a-button type="primary" @click="submit">确定</a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="item">
|
||||||
|
<span style="width:5em">邮箱</span>
|
||||||
|
<a-tooltip title="点击修改" v-if="currentAction!='email'">
|
||||||
|
<span style="cursor: pointer;" @click="()=>this.currentAction='email'">{{userInfo.email}}</span>
|
||||||
|
</a-tooltip>
|
||||||
|
<div class="inputGroup" v-else-if="currentAction==='email'">
|
||||||
|
<a-input type="password" v-model="oldPassword" placeholder="旧密码" />
|
||||||
|
<a-input type="email" v-model="email" placeholder="email" />
|
||||||
|
<div style="padding-top:0.2em">
|
||||||
|
<a-button style="margin-right:2em" type="warn" @click="()=>this.currentAction=null">取消</a-button>
|
||||||
|
<a-button type="primary" @click="submit">确定</a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -23,15 +64,24 @@ import { mapState } from "vuex";
|
|||||||
import HttpUtil from "../../../../util/HttpUtil";
|
import HttpUtil from "../../../../util/HttpUtil";
|
||||||
export default {
|
export default {
|
||||||
name: "UserInfo",
|
name: "UserInfo",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
currentAction: null, //当前操作,name,password,email
|
||||||
|
name: "",
|
||||||
|
oldPassword: "",
|
||||||
|
password: "",
|
||||||
|
rePassword: "",
|
||||||
|
email: "",
|
||||||
|
};
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState("globalConfig", ["userInfo"]),
|
...mapState("globalConfig", ["userInfo"]),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async changeIcon(e) {
|
async changeIcon(e) {
|
||||||
let file = e.target.files[0];
|
let file = e.target.files[0];
|
||||||
console.log(file);
|
if (!file || file.size > 200 * 1024) {
|
||||||
if (!file || file.size > 500 * 1024 * 8) {
|
message.error("文件大小请勿超过200KB");
|
||||||
message.error("文件大小请勿超过500KB");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let formData = new FormData();
|
let formData = new FormData();
|
||||||
@ -39,6 +89,30 @@ export default {
|
|||||||
let res = await HttpUtil.post("/user/icon", null, formData, true);
|
let res = await HttpUtil.post("/user/icon", null, formData, true);
|
||||||
this.$set(this.userInfo, "icon", res);
|
this.$set(this.userInfo, "icon", res);
|
||||||
},
|
},
|
||||||
|
async submit() {
|
||||||
|
let url, body;
|
||||||
|
if (this.currentAction === "name") {
|
||||||
|
url = "/baseInfo/username";
|
||||||
|
body = { username: this.name };
|
||||||
|
} else if (this.currentAction === "password") {
|
||||||
|
if (!this.password === this.rePassword) {
|
||||||
|
this.$message.error("新密码两次输入不一致");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
url = "/baseInfo/password";
|
||||||
|
body = {
|
||||||
|
oldPassword: this.oldPassword,
|
||||||
|
password: this.password,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
url = "/baseInfo/email";
|
||||||
|
body = { oldPassword: this.oldPassword, email: this.email };
|
||||||
|
}
|
||||||
|
await HttpUtil.post(url, null, body);
|
||||||
|
await this.$store.dispatch("globalConfig/refreshUserInfo");
|
||||||
|
this.$message.success("操作成功");
|
||||||
|
this.currentAction = null;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
@ -54,6 +128,7 @@ export default {
|
|||||||
position: relative;
|
position: relative;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
|
cursor: pointer;
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
width: 150px;
|
width: 150px;
|
||||||
height: 150px;
|
height: 150px;
|
||||||
@ -85,6 +160,18 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
font-size: 1.5em;
|
||||||
|
padding-top: 1em;
|
||||||
|
padding-bottom: 1em;
|
||||||
|
border-bottom: 1px solid #ebebeb;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
.inputGroup {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.baseInfo {
|
.baseInfo {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user