mirror of
https://gitee.com/bookshelfplus/bookshelfplus
synced 2025-09-01 22:53:29 +08:00
添加账号注销功能
This commit is contained in:
@@ -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>
|
@@ -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}) `);
|
||||
}
|
||||
});
|
||||
|
@@ -1,4 +1,7 @@
|
||||
<div>
|
||||
<h2>第三方账号管理</h2>
|
||||
<%- include("../component/third-party-manage.html"); %>
|
||||
<hr>
|
||||
<h2>注销账号</h2>
|
||||
<%- include("../component/account-cancellation.html"); %>
|
||||
</div>
|
@@ -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;
|
||||
|
@@ -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 {
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user