springboot内测考试难点整理——商城后台管理系统
分类: springboot vue 专栏: 商城后台系统 标签: 难点整理
2024-03-17 16:49:03 1061浏览
难点整理
security配置类
@Configuration @EnableGlobalMethodSecurity(prePostEnabled = true) public class SpringSecurity { @Autowired UserServiceImpl userService; @Bean PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } @Bean WebSecurityCustomizer webSecurityCustomizer(){ return new WebSecurityCustomizer() { @Override public void customize(WebSecurity web) { web.ignoring().requestMatchers("/login"); } }; } @Bean SecurityFilterChain securityFilterChain(HttpSecurity security) throws java.lang.Exception { security.csrf().disable();//前后分离项目必须加这个,否则无法发送post请求 security.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); security.authorizeHttpRequests().anyRequest().authenticated(); security.addFilterBefore(new TokenFilter(userService), UsernamePasswordAuthenticationFilter.class); return security.build(); } }
递归查询
准备原始数据.根据你的实际情况来
//拿菜单
List<Menu> menus = menuService.getMenusByRole(rids);
//调用下面拿树的方法
getTree(menus)
最终拿到的tree
List<MenuVo> getTree( List<Menu> menus ){
List<MenuVo> menuVos = new ArrayList<>();
for (Menu menu : menus) {
MenuVo menuVo = new MenuVo();
BeanUtils.copyProperties(menu,menuVo);
menuVos.add(menuVo);
}
//menuVos
//递归找children
List<MenuVo> tree= new ArrayList<>();
for (MenuVo vo : menuVos) {
if (vo.getParentId()== 0 && vo.getHidden()==0) {
//一级目录
MenuVo vv = findChildren(vo, menuVos);
tree.add(vv);
}
}
return tree;
}
private MenuVo findChildren(MenuVo vo, List<MenuVo> menuVos) {
vo.setChildren(new ArrayList<>());
for (MenuVo menuVo : menuVos) {
if(menuVo.getParentId()==vo.getId()){
vo.getChildren().add(menuVo);
findChildren(menuVo,menuVos);
}
}
return vo;
}
mybatisPlus多表联查分页
配置类
@Configuration
public class MybatisPlusConfig {
@Bean
MybatisPlusInterceptor interceptor(){
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
service层
public IPage getPage(SearchUserDto userDto, Integer pageNum) {
Page<User> page = userInfoMapper.getPageByName(new Page(pageNum,3), userDto.getName());
return page;
}
mapper层
Page<User> getPageByName(Page page,String name);
sql映射文件
<resultMap id="UserWithInfo" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"/>
<result property="enabled2" column="enabled"/>
<association property="userInfo" javaType="userinfo">
<id property="id" column="id1"></id>
<result property="name" column="name"/>
<result property="gender" column="gender"/>
<result property="phone" column="phone"/>
</association>
</resultMap>
<select id="getPageByName" resultMap="UserWithInfo">
SELECT
u.*, ui.*
FROM
`user` u
LEFT JOIN user_info ui ON ui.user_id = u.id
<where>
<if test="name != null and name!=''">
ui.name like concat ('%',#{name},'%')
</if>
</where>
</select>
vue3+elementPlus表单数据校验
要实现的效果
核心代码
<el-form
ref="ruleFormRef"
:rules="rules"
:model="roleForm"
label-width="auto" style="max-width: 600px">
<el-form-item label="选择角色" prop="roleIds">
<el-select v-model="roleForm.roleIds"
multiple
placeholder="请选择角色">
<el-option v-for="(r,index) in roles"
:key="index"
:label="r.name"
:value="r.id" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onAllocate">确定</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
js部分
const roleForm=ref({
userId:'',
roleIds:''
})
const ruleFormRef = ref(null);
const rules = {
roleIds: [
{required: true, message: '必须至少选一个角色', trigger: 'blur'},
],
}
const onAllocate = () => {
ruleFormRef.value.validate((valid) => {
if (valid) {
console.log('Form submitted:', roleForm.value);
alert("提交")
} else {
console.log('Form validation failed');
alert("请按表单提交")
return false;
}
});
}
下拉多选并回显
前端核心代码
<el-form-item label="选择角色" prop="roleIds">
<el-select v-model="roleForm.roleIds"
multiple
placeholder="请选择角色">
<el-option v-for="(r,index) in roles"
:key="index"
:label="r.name"
:value="r.id" />
</el-select>
</el-form-item>
const roles=ref([])
const roleForm=ref({
userId:'',
roleIds:''
})
const rules = {
roleIds: [
{required: true, message: '必须至少选一个角色', trigger: 'blur'},
],
}
const ruleFormRef = ref(null);
//分配角色弹出框
const fenpei = (userid) => {
console.log(userid)
roleForm.value.userId=userid
//查当前用户的角色id数组
axios({
url:'/api/user/roles/'+userid,
method:'get'
}).then(res =>{
console.log(res)
roleForm.value.roleIds=res.data
})
//弹出框
data.value.dialogVisible=true
//发请求查所有角色信息
axios({
url:'/api/role/getPage',
method:'get'
}).then( res =>{
console.log(res)
roles.value=res.data.records
})
}
//提交选好的角色
const onAllocate = () => {
ruleFormRef.value.validate((valid) => {
if (valid) {
console.log('Form submitted:', roleForm.value);
alert("提交")
} else {
console.log('Form validation failed');
alert("请按表单提交")
return false;
}
});
}
后端主要Java代码
//根据用户id查该用户的所有角色id数据——目的是为了回显
@GetMapping("/user/roles/{uid}")
public ResultVo getUserRole(@PathVariable(value = "uid") Integer uid){
LambdaQueryWrapper<UserRole> queryWrapper=new LambdaQueryWrapper<>();
if (!ObjectUtils.isEmpty(uid)) {
queryWrapper.eq(UserRole::getUserId,uid);
}
List<UserRole> list = userRoleService.list(queryWrapper);
Integer[] rid=new Integer[list.size()];
for (int i = 0; i < list.size(); i++) {
rid[i]=list.get(i).getRoleId();
}
return ResultVo.success("",rid);
}
/**
* 分配角色
* @param userRoles
* @return
*/
@PostMapping("/role/allocate")
@PreAuthorize("hasAuthority('/role/allocate')")
@Transactional
public ResultVo allocate(@RequestBody UserRolesDto userRoles){
Integer[] roleIds = userRoles.getRoleIds();
if (roleIds.length>0 && userRoles.getUserId()!= null ) {
//查查之前的这个用户已经分配的角色记录(先删除)
LambdaQueryWrapper<UserRole> queryWrapper= new LambdaQueryWrapper<>();
queryWrapper.eq(UserRole::getUserId,userRoles.getUserId());
userRoleService.remove(queryWrapper);
for (int i = 0; i < roleIds.length; i++) {
UserRole userRole = new UserRole();
userRole.setRoleId(roleIds[i]);
userRole.setUserId(userRoles.getUserId());
userRoleService.saveOrUpdate(userRole);
}
return ResultVo.success("分配成功",null);
}else{
return ResultVo.error("角色必填,用户ID必传");
}
}
前端的话下拉多选关键的就是 multiple
至于回显很简单,只要roleForm.roleIds赋上对应的值就会选中那个
树形菜单回显和勾选
核心代码如下:
<el-dialog
v-model="dialogMenu"
title="分配菜单"
width="500"
>
<el-tree
ref="treeRef"
style="max-width: 600px"
:data="data"
show-checkbox
:default-expand-all="true"
node-key="id"
:default-checked-keys="form.menuIds"
:props="defaultProps"
/>
<el-button type="primary" @click="onSubmit">提交</el-button>
<el-button @click="dialogVisible=false">Cancel</el-button>
</el-dialog>
js部分
const dialogMenu=ref(false)
const data=ref([])
const treeRef=ref(null)
const defaultProps = {
children: 'children',
label: 'title',
}
const allocateMenu = (rid) => {
form.value.rid=rid
axios({
url: '/api/menu/list/'+rid,
}).then( res => {
console.log(res);
data.value=res.data.tree
//为了回显
form.value.menuIds=res.data.menuIds
dialogVisible.value=true
})
}
const onSubmit = () => {
var quan=treeRef.value.getCheckedKeys()
var ban=treeRef.value.getHalfCheckedKeys()
var menuIds=quan.concat(ban)
if(menuIds =="" ){
ElMessage.error("至少选一个菜单")
return
}
axios({
url: '/api/fenpei',
method:'post',
data:{"rid":form.value.rid,"menuIds":menuIds}
}).then(res => {
console.log(res)
if (res.code == 2000) {
getPage()
dialogVisible.value=false
}
})
}
后端Java核心代码
//分配菜单弹出框的时候 要查所有的菜单 (rid )
// 并且 把当前登陆者的菜单id数组也得返回(目的是为了回显选中,
// 其中半选的父级菜单要移除掉)
@GetMapping("/menu/list/{rid}")
public ResultVo getList(@PathVariable Integer rid){
Map map = new HashMap();
List<Menu> list = menuService.list();
List<Menu> tree= new ArrayList<>();
for (Menu menu : list) {
if(menu.getParentId() == 0 && menu.getHidden()==0){//说明是一级菜单
//开始找儿子 找二级菜单
menu=findChildren(menu,list);
tree.add(menu);
}
}
map.put("tree",tree);
//根据角色ids查菜单id数组
Integer[] menuIds=roleMenuService.getMenuIds(rid);
map.put("menuIds",menuIds);//回显使用 把当前登陆者的菜单id数组也得返回
return ResultVo.success("",map);
}
分配菜单核心代码
@PostMapping("/fenpei")
@Transactional
public ResultVo fenpei(@RequestBody RoleMenuDto dto){
LambdaQueryWrapper<RoleMenu> queryWrapper= new LambdaQueryWrapper();
queryWrapper.eq(RoleMenu::getRoleId,dto.getRid());
//删除原来的
roleMenuService.remove(queryWrapper);
//添加新的
Integer[] menuIds = dto.getMenuIds();
List<RoleMenu> list = new ArrayList<>();
for (int i = 0; i < menuIds.length; i++) {
list.add(new RoleMenu()
.setMenuId(menuIds[i])
.setRoleId(dto.getRid()));
}
roleMenuService.saveBatch(list);
return ResultVo.success();
}
开关修改状态
<el-table-column label="状态" >
<template #default="scope">
<el-switch v-model="scope.row.status"
:active-value="0"
:inactive-value="1"
@change="changeStatus"
/>
</template>
</el-table-column>
const changeStatus = (val) => {
console.log(val);
axios({
url: '/api/',
})
}
分配资源
弹出框实现复选框勾选是个难点
1. 分配资源弹出函数
const onFenResource = (rid) => {
reForm.value.roleId=rid
getResource(rid)
}
const getResource = (rid) => {
axios({
url: '/api/resource/getPage?roleId='+rid
}).then( res => {
resourceTableData.value = res.data.page.records
selectedResourceIds.value=res.data.selectedResourceIds
console.log(selectedResourceIds.value);
dialogResource.value=true
})
}
2. 弹出框vue代码,注意opened函数,必须等table加载完后multipleTableRef才不是null
<el-dialog
v-model="dialogResource"
title="分配资源"
width="800"
@opened="toggleSelection(resourceTableData)"
>
<el-table
ref="multipleTableRef"
:data="resourceTableData"
style="width: 100%"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column label="编号" prop="id" width="55" />
<el-table-column label="资源名称" prop="name" />
<el-table-column label="创建时间" width="120">
<template #default="scope">{{ scope.row.createTime }}</template>
</el-table-column>
<el-table-column label="资源权限标识符" prop="permission" />
<el-table-column label="描述" prop="description" />
</el-table>
<el-button type="primary" @click="onSubmitResource">提交</el-button>
<el-button @click="dialogResource=false">Cancel</el-button>
</el-dialog>
3. 弹出框涉及到的函数
const toggleSelection = (rows) => {
if (rows) {
rows.forEach(row => {
if(selectedResourceIds.value.includes(row.id)){
multipleTableRef.value.toggleRowSelection(row);
}
});
} else {
multipleTableRef.value.clearSelection();
}
}
const handleSelectionChange = (selection) => {
console.log('当前选中项:', selection);
let ids = selection.map(item => item.id);
reForm.value.resources=ids
}
4. 后端Java核心代码
@GetMapping("/getPage")
@PreAuthorize("hasAuthority('/resource/getPage')")
public ResultVo getPage(
@RequestParam(required = false) String name,
@RequestParam(required = false) Integer roleId,
@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = ""+Integer.MAX_VALUE) Integer pageSize){
Map map = new HashMap();
Page<Resource> page= resourceService.getPage(name,pageNum,pageSize);
if (!ObjectUtils.isEmpty(roleId)) {
LambdaQueryWrapper<RoleResource> queryWrapper= new LambdaQueryWrapper<>();
queryWrapper.eq(RoleResource::getRoleId,roleId);
List<RoleResource> roleResources = roleResourceService.list(queryWrapper);
List<Integer> collect = roleResources.stream().map(RoleResource::getResourceId).collect(Collectors.toList());
Integer[] resorceIds= collect.toArray(new Integer[0]);
map.put("selectedResourceIds",resorceIds);
}
map.put("page",page);
return ResultVo.success("",map);
}
5. 重点注意:
好博客就要一起分享哦!分享海报
此处可发布评论
评论(0)展开评论
暂无评论,快来写一下吧
展开评论
他的专栏
他感兴趣的技术