1
0
mirror of https://gitee.com/bookshelfplus/bookshelfplus synced 2025-09-01 22:53:29 +08:00
Code Issues Projects Releases Wiki Activity GitHub Gitee

添加账号注销功能

This commit is contained in:
2022-04-05 17:23:06 +08:00
parent 364566d6c1
commit 8598edc0f7
7 changed files with 186 additions and 2 deletions

View File

@@ -0,0 +1,90 @@
<style>
#account-cancellation-info>p {
text-align: left;
}
.btn-danger {
color: #fff;
background-color: #d9534f;
border: 0;
border-radius: 4px;
transition: all 0.3s;
padding: 5px 10px;
cursor: pointer;
}
.btn-danger:hover {
color: #fff;
background-color: #c9302c;
border-color: #ac2925;
border-radius: 10px;
}
.hide {
display: none;
}
#account-cancellation-password {
margin: 20px auto;
width: min(50%, 600px);
padding: 3px 5px;
font-size: large;
}
</style>
<div>
<!-- 注销账号 -->
<p style="font-size: 0.5em;">注销账号非退出登录,退出登录请点击右上角“<b>退出登录</b>”按钮</p>
<div id="account-cancellation-info" class="hide">
<h3>注销账号须知</h3>
<p>注销账号后,您将无法登录本网站,并且不能再次注册账号。</p>
<p>注销账号后,您的所有账号信息将被删除,包括您的账号名、密码、账号绑定信息等。</p>
<p>注销账号后,您的账号信息将被永久删除,并且不可恢复。</p>
<h3>注销账号流程</h3>
<p>1. 仔细阅读以上须知,并手动将您账号中有用信息保存下来,账号一旦注销,数据永久删除,无法找回。</p>
<p>2. 输入您的帐号密码并点击下方按钮,注销即刻完成。</p>
</div>
<div id="account-cancellation-buttons">
<button class="btn-danger" id="btn-account-cancellation">注销账号</button>
<input class="hide" type="password" id="account-cancellation-password" placeholder="请输入您的密码"
autocomplete="new-password" />
<button class="btn-danger hide" id="btn-account-cancellation-confirm" style="font-size: large;">
我已阅读以上须知,并知晓账号注销后果,愿意放弃账号内所有数据及权益,确认注销账号
</button>
</div>
</div>
<script>
$("#btn-account-cancellation").click(function () {
$("#account-cancellation-info").removeClass("hide");
$("#btn-account-cancellation").addClass("hide");
$("#account-cancellation-password").removeClass("hide");
$("#btn-account-cancellation-confirm").removeClass("hide");
});
$("#btn-account-cancellation-confirm").click(function () {
var accountCancellationPassword = $("#account-cancellation-password").val();
if (accountCancellationPassword == "") {
alert("请输入您的密码");
return;
}
postRequest("/user/cancelAccount", { token: localStorage.token, password: accountCancellationPassword })
.then(function (response) {
var axiosData = response.data;
var status = axiosData.status;
var data = axiosData.data;
if (status === "success") {
console.log(data);
if (data == "success") {
alert("注销成功!");
location.reload();
} else {
alert("出错啦,刷新页面重新试试吧");
}
} else {
alert(`出错啦!${data.errMsg} (错误码: ${data.errCode}) `);
$("#account-cancellation-password").val("");
}
}).catch(function (error) {
console.log(error);
alert("无法连接到服务器,请检查网络连接!");
});
});
</script>

View File

@@ -33,6 +33,7 @@
<script>
function getUserStatus() {
if(!localStorage) {
alert("浏览器不支持 localStorage ,请更换浏览器");
window.location.href = "/";
}
@@ -55,6 +56,11 @@
window.location.href = "/login";
}
} else {
if(data.errCode == "20004") { // 登陆过期
localStorage.clear("token");
localStorage.clear("is_admin");
window.location.href = "/login";
}
alert(`出错啦!${data.errMsg} (错误码: ${data.errCode}) `);
}
});

View File

@@ -1,4 +1,7 @@
<div>
<h2>第三方账号管理</h2>
<%- include("../component/third-party-manage.html"); %>
<hr>
<h2>注销账号</h2>
<%- include("../component/account-cancellation.html"); %>
</div>

View File

@@ -56,7 +56,7 @@ public class UserController extends BaseController {
}
String encryptPwd = DigestUtils.sha1Hex(password);
if(!userService.userRegister(username, encryptPwd)){
if (!userService.userRegister(username, encryptPwd)) {
throw new BusinessException(BusinessErrorCode.UNKNOWN_ERROR, "未知错误,注册失败");
}
// 注册成功后,进行登录
@@ -91,6 +91,35 @@ public class UserController extends BaseController {
return CommonReturnType.create(userVO);
}
@ApiOperation(value = "账号注销", notes = "传入用户 token 以及密码明文后台计算密码SHA1值进行注销")
@RequestMapping(value = "cancelAccount", method = {RequestMethod.POST}, consumes = {CONTENT_TYPE_FORMED})
@ResponseBody
public CommonReturnType cancelAccount(@RequestParam(value = "token", required = false) String token,
@RequestParam(value = "password", required = false) String password) throws BusinessException {
// 已经在 getUserByToken 方法中判断了 token 为空、不合法;用户不存在情况,此处无需再判断
UserModel userModel = userService.getUserByToken(redisTemplate, token);
if(password == null || "".equals(password)){
throw new BusinessException(BusinessErrorCode.PARAMETER_VALIDATION_ERROR, "参数不合法,缺少密码");
}
// 验证用户密码是否输入正确
if (!userModel.getEncriptPwd().equals(DigestUtils.sha1Hex(password))) {
throw new BusinessException(BusinessErrorCode.PARAMETER_VALIDATION_ERROR, "密码错误");
}
// 进行用户账号注销流程
Boolean isSuccess = userService.cancelAccount(userModel);
if (!isSuccess) {
throw new BusinessException(BusinessErrorCode.UNKNOWN_ERROR, "系统未知错误,注销失败,请联系网站管理员");
}
// 用户退出登录
onLogout(token);
return CommonReturnType.create("success");
}
public static UserVO convertFromService(UserModel userModel) {
if (userModel == null) {
return null;

View File

@@ -22,7 +22,6 @@ import plus.bookshelf.Service.Service.ThirdPartyUserService;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
@Service
public class ThirdPartyUserServiceImpl implements ThirdPartyUserService {

View File

@@ -10,10 +10,14 @@ import plus.bookshelf.Common.SessionManager.RedisSessionManager;
import plus.bookshelf.Controller.VO.UserVO;
import plus.bookshelf.Dao.DO.ThirdPartyUserDO;
import plus.bookshelf.Dao.DO.UserDO;
import plus.bookshelf.Dao.Mapper.ThirdPartyUserAuthDOMapper;
import plus.bookshelf.Dao.Mapper.ThirdPartyUserDOMapper;
import plus.bookshelf.Dao.Mapper.UserDOMapper;
import plus.bookshelf.Service.Model.UserModel;
import plus.bookshelf.Service.Service.UserService;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Service
@@ -22,6 +26,12 @@ public class UserServiceImpl implements UserService {
@Autowired
UserDOMapper userDOMapper;
@Autowired
ThirdPartyUserDOMapper thirdPartyUserDOMapper;
@Autowired
ThirdPartyUserAuthDOMapper thirdPartyUserAuthDOMapper;
@Override
public UserModel userLogin(String username, String encryptPwd) {
UserDO userDO = userDOMapper.selectByUsernameAndEncryptpwd(username, encryptPwd);
@@ -79,6 +89,44 @@ public class UserServiceImpl implements UserService {
return userDOMapper.insertSelective(userDO) > 0;
}
@Override
@Transactional
public Boolean cancelAccount(UserModel userModel) throws BusinessException {
// 用户Id
Integer userId = userModel.getId();
ThirdPartyUserDO[] userBindThirdParties = thirdPartyUserDOMapper.getUserBindThirdParties(userModel.getId());
List<Integer> thirdPartyIds = new ArrayList<>();
for (ThirdPartyUserDO thirdPartyUserDO : userBindThirdParties) {
Integer thirdPartyUserId = thirdPartyUserDO.getId();
// 删除第三方账号与用户的关联
// 首先在 Auth 表中删除
int affectRows = thirdPartyUserAuthDOMapper.deleteByUserIdAndThirdPartyUserId(userId, thirdPartyUserId);
if (affectRows == 0) {
// 删除失败
return false;
}
// 第三方账号与用户关联删除成功,删除第三方账号信息
int affectRows2 = thirdPartyUserDOMapper.deleteByPrimaryKey(thirdPartyUserId);
if (affectRows2 == 0) {
// 删除失败
return false;
}
}
// 删除用户信息
int affectRows3 = userDOMapper.deleteByPrimaryKey(userModel.getId());
if (affectRows3 == 0) {
// 删除失败
return false;
}
// 注销成功
return true;
}
private UserModel convertFromDataObject(UserDO userDO) {
if (userDO == null) {
return null;

View File

@@ -38,4 +38,13 @@ public interface UserService {
* @return 注册成功返回true否则返回false
*/
Boolean userRegister(String username, String encryptPwd) throws BusinessException;
/**
* 账号注销
*
* @param userModel
* @return
* @throws BusinessException
*/
Boolean cancelAccount(UserModel userModel) throws BusinessException;
}