项目日记day0314
一、账户冻结/解冻功能的实现
现在,我们开始做账户冻结/解冻的功能。
我们之前在数据库中的账户表(tbl_account)的用户状态字段(account_status)中定义了用户的几种状态,其中,如果用户状态字段的值为1表示用户被冻结,此时点击解冻按钮即可将其解冻;用户状态字段为0表示正常,此时点击冻结即可将这个账户冻结;用户字段为-1和2不可冻结也不可解冻。
也就是说,我们实现该功能的关键要素是实现用户状态字段的改变。
我们看一下如何实现这个功能:
我们首先要从前端开始进行:
添加冻结和解冻按钮的点击事件,当点击相应的按钮时,调用相应的处理函数,我们这里定义了两个函数,一个是解冻函数,一个是冻结函数,通过槽获取行数据的account_id,将其当作参数传入两个函数中:
以下是对应的功能函数:
/**账户冻结 */
account_freeze(account_id) {
this.$swal.fire({
title: "你确认要冻结该账户吗?",
text: "账户冻结后将无法使用本系统!",
icon: "warning",
showCancelButton: true,
confirmButtonColor: "#3085d6",
cancelButtonColor: "#d33",
confirmButtonText: "确认",
cancelButtonText:"取消"
})
.then((result) => {
if (result.isConfirmed) {
this.changeAccountStatus(account_id,1); //改变账户状态
}
});
},
/**账户解冻 */
account_thaw(account_id) {
this.$swal.fire({
title: "你确认要解冻该账户吗?",
text: "账户解冻后将可以访问本系统!",
icon: "warning",
showCancelButton: true,
confirmButtonColor: "#3085d6",
cancelButtonColor: "#d33",
confirmButtonText: "确认",
cancelButtonText:"取消"
})
.then((result) => {
if (result.isConfirmed) {
this.changeAccountStatus(account_id,0); //改变账户状态
}
});
},
/**修改账户状态 */
changeAccountStatus(account_id,status){
this.$axios.put(`/rabc/account/changeAccountStatus/${account_id}/${status}`) //使用路径传参,注意这里使用英文的单撇`
.then(response => {
let result =response.data;
if(result.success){
this.$swal.fire({
icon: "success",
title: result.message,
showConfirmButton: false,
timer: 1500,
onClose: () => {
this.getAccountList(); //刷新账户信息
},
});
}
})
.catch(err => {
console.log(err);
})
}
},
其中,account_freeze和account_thaw函数只是定义了界面的展示,真正的功能处理是changeAccountStatus函数实现的。
changeAccountStatus函数中的axios的传参方式,我们使用了路径传参的方式,注意是用的单撇(`)进行引用的,否则参数将传不过去。
接下来就是后端功能的实现了:
在AccountController类中加入一个changeAccountStatus的方法,改变账户的状态:
@PutMapping("/changeAccountStatus/{account_id}/{status}")
public Result changeAccountStatus(@PathVariable Integer account_id,@PathVariable Integer status){
return accountService.changeAccountStatus(account_id,status);
}
Service层:
接口:
/**
* 修改账户状态
* @param account_id
* @param status
* @return
*/
public Result changeAccountStatus(Integer account_id, Integer status);
实现类:
@Override
public Result changeAccountStatus(Integer account_id, Integer status) {
accountDao.updateAccountStatus(account_id,status);
if (status == 1){
return Result.success("账户冻结成功!");
}
return Result.success("账户解冻成功!");
}
Dao层:
接口:
/**
* 通过账户ID更新账户状态
* @param account_id 账户ID
* @param status 账户状态
*/
@Update("update tbl_account set account_status=#{status} where account_id=#{account_id}")
public void updateAccountStatus(@Param("account_id") Integer account_id, @Param("status") Integer status);
测试:
此处有个小BUG,因为不能冻结当前的这个账户,所以,要想办法实现不查询当前的账户。
二、账户授权的静态实现
我们使用element ui的穿梭框来实现账户授权。
Transfer(穿梭框)有两个部分,左边的备选框承载所有的数据,通过一个对象数组实现,每个对象有一个key属性和label属性,右面的备选框承载选择的数据,使用左边备选框中对象数组的key来区分选择与否。
下面我们来看一下是如何实现的:
效果:
tip:我们通过观察发现,穿梭框只适合数据少的情况下的数据处理,如果数据非常多(例如角色授权权限),则不适合用穿梭框来实现。
三、账户授权的动态实现
看完了静态的实现效果,现在我们来实现一下在数据库中查询角色对账户进行授权的动态实现方法。
我们在静态实现中了解到,我们定义了两个变量,一个是roleDatas,用来存储数据库中所有的角色,一个是accountRole,用来存储已经选择的角色。
我们初步设想,roleDatas中的key属性用数据库中的role_id来表示,label属性用role_name来表示,在数据库中直接查tbl_role的全部数据;accountRole中的值需要通过account_id查询role_id。
为了减少与数据库的交互次数,我们设想可以在首次点击授权按钮时查询tbl_role的全部数据,所以当点击授权按钮时,先判断roleDatas中的数据是否存在,如果不存在则对tbl_role的全部数据进行查询,如果存在则直接去通过account_id查询role_id。
所以我们先定义一个授权按钮点击事件的函数:
如果备选角色中不存在数据则从服务器中获取数据:
获取该账户的已有角色:
后端实现:
1.获取所有的角色
Controller层:
@GetMapping("/getRoles")
public List<Role> getRoles(){
return roleService.getRoles();
}
Service层:
新建RoleService接口:
/**
* 获取所有的角色
* @return
*/
public List<Role> getRoles();
新建RoleServiceImpl实现类:
@Override
public List<Role> getRoles() {
return roleDao.queryRoles();
}
Dao层:
接口:
/**
* 查询所有角色
* @return
*/
@Select("select * from tbl_role")
public List<Role> queryRoles();
2、通过账户ID获取角色ID
1.获取所有的角色
Controller层:
@GetMapping("/getRoleIdByAccountId")
public List<Integer> getRoleIdByAccountId(Integer account_id){
return roleService.getRoleIdByAccountId(account_id);
}
Service层:
接口:
/**
* 通过账户ID获取角色ID
* @param account_id
* @return
*/
public List<Integer> getRoleIdByAccountId(Integer account_id);
实现类:
@Override
public List<Integer> getRoleIdByAccountId(Integer account_id) {
return roleDao.queryRoleIdByAccountId(account_id);
}
Dao层:
接口:
/**
* 通过账户ID查询角色ID
* @param account_id
* @return
*/
@Select("select role_id from tbl_account_role where account_id=#{account_id}")
public List<Integer> queryRoleIdByAccountId(Integer account_id);
测试:
四、授权面板的按钮事件
首先给授权面板加上两个按钮:确认授权、取消授权。
前端代码:
当点击确认授权按钮时,先获取已选角色列表,如果为空,则设置账户为未启用状态,并清空账户原来的所有角色。
如果不为空,直接向后端发送请求,修改账户角色表相关的信息。
/**确认授权按钮点击 */
confirmAuthority() {
if (this.accountRoles.length == 0) {
//获取已选角色的列表,如果为空,则清空该账户的所有角色
this.clearAllAccountRole();
} else {
//在后端修改相关的信息(传账户ID、角色、用户状态)
this.$axios
.put(
"/rabc/account/changeAccountRole",
qs.stringify(//将Request Payload转为Form Data格式
{
account_id: this.authorityAccountId,
accountRoles: this.accountRoles,
isAccountEnable: this.isAccountEnable,
},
{
indices: false, //去除集合中的下标
}
)
)
.then((response) => {
let result = response.data;
if (result.success) {
this.dialogVisible = false; //关闭授权界面
this.$swal.fire({
//弹出提示信息
icon: "success",
title: result.message,
showConfirmButton: false,
timer: 1500,
onClose: () => {
this.getAccountList(); //刷新账户信息
},
});
}
})
.catch((err) => {
alert(err);
});
}
},
我们发现,如果没有加indices: false
,qs转换为Form Data格式的请求中的集合的格式是带下标的,所以我们可以用indices: false
将下标去掉。
带下标的List数组参数:
去掉下标后的参数:
清空账户角色函数:
/**清空账户所有角色 */
clearAllAccountRole() {
this.$axios
.delete("/rabc/account/clearAccountRole", {
params: {
account_id: this.authorityAccountId,
},
})
.then((response) => {
let result = response.data;
if (result.success) {
this.dialogVisible = false; //关闭授权界面
this.$swal.fire({
//弹出提示信息
icon: "success",
title: result.message,
showConfirmButton: false,
timer: 1500,
onClose: () => {
this.getAccountList(); //刷新账户信息
},
});
}
})
.catch((err) => {
alert(err);
});
},
后端代码:
1.已选角色列表不为空,直接改变账户角色信息:/rabc/account/changeAccountRole
**Controller层:**这里Controller只将数据传递给service层,相关的处理在service层进行处理。
@PutMapping("/changeAccountRole")
public Result changeAccountRole(@RequestParam("account_id") Integer account_id,
@RequestParam("accountRoles") List<Integer> accountRoles,
@RequestParam("isAccountEnable") Boolean isAccountEnable ){
return accountService.changeAccountRole(account_id,accountRoles,isAccountEnable);
}
Service层:
接口:
/**
* 改变用户状态
* @param account_id 账户ID
* @param accountRoles 最终要修改账户角色
* @param isAccountEnable 账户原来是否存在有角色 true表示存在,false表示不存在
* @return
*/
public Result changeAccountRole(Integer account_id, List<Integer> accountRoles, Boolean isAccountEnable);
实现类:这里实现了插入账户信息的不同,进行不同的提示处理
@Override
public Result changeAccountRole(Integer account_id, List<Integer> accountRoles, Boolean isAccountEnable) {
if (isAccountEnable){ //账户中拥有角色,账户为已启用的状态
accountDao.delRoleByAccountId(account_id);//删除已有的角色
accountDao.insertAccountRole(account_id,accountRoles); //插入账户角色信息
return Result.success("权限更新成功!");
}else { //账户不可用
accountDao.updateAccountStatus(account_id,0); //更改用户状态
accountDao.insertAccountRole(account_id,accountRoles); //插入账户角色信息
return Result.success("权限更新成功!该账户已启用!");
}
}
Dao层:
(1)删除已有的角色(delRoleByAccountId方法)
/**
* 通过账户ID删除角色
* @param account_id
*/
@Delete("delete from tbl_account_role where account_id=#{account_id}")
public void delRoleByAccountId(Integer account_id);
(2)插入账户角色信息(insertAccountRole方法)
/**
* 插入账户角色信息
* @param account_id 账户ID
* @param accountRoles 账户角色
*/
public void insertAccountRole(@Param("account_id") Integer account_id, @Param("accountRoles") List<Integer> accountRoles);
<insert id="insertAccountRole">
insert into tbl_account_role values
<foreach collection="accountRoles" item="role_id" separator=",">
(#{account_id},#{role_id})
</foreach>
</insert>
(3)更改用户状态之前已经写过(updateAccountStatus方法)
2、已选角色列表为空,设置账户为未启用状态,并清空账户原来的所有角色:/rabc/account/clearAccountRole
Controller层:
@DeleteMapping("/clearAccountRole")
public Result clearAccountRole(Integer account_id){
return accountService.clearAccountRole(account_id);
}
Service层:
接口:
/**
* 清空某个账户的角色
* @param account_id 账户ID
* @return
*/
public Result clearAccountRole(Integer account_id);
实现类:
@Override
public Result clearAccountRole(Integer account_id) {
//删除该账户所有角色
accountDao.delRoleByAccountId(account_id);
//更新该账户的状态为不启用
accountDao.updateAccountStatus(account_id,2);
return Result.success("账户权限更新成功!该账户已变为未启用状态!");
}
Dao层:之前都已经写过,此处省略。
测试: