springboot内测考试难点整理——商城后台管理系统

飞一样的编程
飞一样的编程
擅长邻域:Java,MySQL,Linux,nginx,springboot,mongodb,微信小程序,vue

分类: springboot vue 专栏: 商城后台系统 标签: 难点整理

2024-03-17 16:49:03 738浏览

难点整理

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展开评论

暂无评论,快来写一下吧

展开评论

您可能感兴趣的博客

客服QQ 1913284695