权限管理与menu菜

权限管理

首先从数据库取出权限交给shiro管理

//从数据库拿到权限
       List<Permission> permissions=permissionService.findAll();
       for (Permission permission : permissions) {
           mp.put(permission.getUrl(),"aisellPerms["+permission.getSn()+"]");
       }

根据用户的id拿到权限

public interface PermissionRepository extends BaseRepository<Permission,Long> {
   @Query("select distinct p.sn from Employee e join e.roles r join r.permissions p where e.id = ?1")
   Set<String> findSnByEmp(Long employeeId);
}

public interface IPermissionService extends IBaseService<Permission,Long> {
  Set<String> findSnByEmp(Long employeeId);
}

@Service
public class PermissionServiceImpl extends BaseServiceImpl<Permission,Long> implements IPermissionService {
 @Autowired
 private PermissionRepository permissionRepository;
 @Override
 public Set<String> findSnByEmp(Long employeeId) {
     return permissionRepository.findSnByEmp(employeeId);
 }
}

进行权限比对:

@Override
  protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
      //授权方法
      Employee employee = (Employee)principalCollection.getPrimaryPrincipal();
      System.out.println(employee);
      //根据用户名得到权限代码
      //Set<String> permissionsByUsername = getPermissionsByUsername(username);

      Set<String> snByEmp = permissionService.findSnByEmp(employee.getId());
      //shiro就会自己取进行权限的比较
      SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
      simpleAuthorizationInfo.setStringPermissions(snByEmp);
      return simpleAuthorizationInfo;
  }

因为shiro底层判断会返回一个页面所以要判断是否是Ajax请求如果是则返回json

继承PermissionsAuthorizationFilter复写里面的onAccessDenied方法

public class AisellPermssionFilter extends PermissionsAuthorizationFilter {
   @Override
   protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
       Subject subject = this.getSubject(request, response);
       if (subject.getPrincipal()==null){
           //没有登录成功后的操作
           this.saveRequestAndRedirectToLogin(request, response);
       }else{
           HttpServletRequest req = (HttpServletRequest)request;
           HttpServletResponse resp = (HttpServletResponse)response;
           //判断请求是否是ajax请求。如果是ajax请求,直接返回json格式
           String header = req.getHeader("X-Requested-With");
           if (header!=null&&"XMLHttpRequest".equals(header)){
               //返回json格式的数据
               resp.setContentType("text/json; charset=UTF-8");
               resp.getWriter().print("{\"success\":false,\"msg\":\"没有权限\"}");
           }else{
               String unauthorizedUrl = this.getUnauthorizedUrl();
               if (StringUtils.hasText(unauthorizedUrl)) {
                   WebUtils.issueRedirect(request, response, unauthorizedUrl);
               } else {
                   WebUtils.toHttp(response).sendError(401);
               }
           }
       }
       return false;
   }
}

然后告诉applicationContext-shiro.xml用我们自己写的拦截器:

<!-- 定义自定义过滤器-->
   <bean id="aisellPermsFilter" class="cn.itsource.shiro.AisellPermssionFilter"></bean>
<!--引用自定义过滤器-->
       <property name="filters">
           <map>
               <entry key="aisellPerms" value-ref="aisellPermsFilter"></entry>
           </map>
       </property>

如果没有权限就隐藏按钮:

//引用shiro的插件
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

 <!-- 新增修改删除-->
        <shiro:hasPermission name="employee:save">
            <a href="#" data-method="add" plain="true"  class="easyui-linkbutton" iconCls="icon-add">新增</a>
        </shiro:hasPermission>
        <shiro:hasPermission name="employee:update">
            <a href="#" data-method="edit" plain="true"   class="easyui-linkbutton" iconCls="icon-edit">修改</a>
        </shiro:hasPermission>
        <shiro:hasPermission name="employee:delete">
            <a href="#" data-method="delete" plain="true"   class="easyui-linkbutton" iconCls="icon-remove">删除</a>
        </shiro:hasPermission>

menu菜单

创建menu类

package cn.itsource.domain;

import com.fasterxml.jackson.annotation.JsonIgnore;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name="menu")
public class Menu extends BaseDaomain {

   private String name;//菜单名称
   private String url; //路径
   private String icon; //图标

   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(name="parent_id")
   @JsonIgnore //忽略json 在展示json格式的 parent不会展示出来
   private Menu parent;

   @Transient //这个是临时属性,不交给jpa管理 ,自己来维护
   private List<Menu> children = new ArrayList();

   //兼容esayui的菜单树[id:1,text:'xxx']
   public String getText(){
       return this.name;
   }

   public List<Menu> getChildren() {
       return children;
   }

   public void setChildren(List<Menu> children) {
       this.children = children;
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public String getUrl() {
       return url;
   }

   public void setUrl(String url) {
       this.url = url;
   }

   public String getIcon() {
       return icon;
   }

   public void setIcon(String icon) {
       this.icon = icon;
   }

   public Menu getParent() {
       return parent;
   }

   public void setParent(Menu parent) {
       this.parent = parent;
   }
}

perission 与menu的关系多对一

@ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(name="menu_id")
   private Menu menu;

从数据库拿到子菜单:

public interface MenuRepository extends BaseRepository<Menu,Long> {

   //根据用户id 查询菜单--查询所有的子菜单
   @Query("select distinct m from Employee e join e.roles er join er.permissions p join p.menu m where e.id = ?1")
   List<Menu> findByLoginUser(Long id);
}

public interface IMenuService extends IBaseService<Menu,Long> {

   List<Menu> findMenuByLoginUser(Long employeeId);
}

通过子菜单的父id拿到父菜单然后把子菜单放到父菜单里面

@Service
public class MenuServiceImpl extends BaseServiceImpl<Menu,Long> implements IMenuService {

    @Autowired
    private MenuRepository menuRepository;

    //[name{1},children:[2,3,4,5]]  list封装
    @Override
    public List<Menu> findMenuByLoginUser(Long employeeId) {
        List<Menu> menus = new ArrayList();
        //查询当前用户的所有的子菜单
        List<Menu> subMenus = menuRepository.findByLoginUser(employeeId);
        //循环子菜单  2,3,4,5    1   (7 8)  6
        for (Menu subMenu : subMenus) {
            //从子菜单里面拿到父菜单 6
            Menu parentMenu = subMenu.getParent();
            //判断是否有重复的父菜单没有就添加
            if(!menus.contains(parentMenu)) {
            //添加父菜单
                menus.add(parentMenu);
            }
            //在父菜单里面添加子菜单
            parentMenu.getChildren().add(subMenu);//[1,[2,3,4,5],6 [7,8]]
        }
        return menus;
    }
}

通过controller层返回json数据:

@RequestMapping("/findMenuByUserId")
   @ResponseBody
   public List<Menu> findMenuByUserId() {
       //当前用户ID
       Employee employee = (Employee)UserContent.getuser();

       return menuService.findMenuByLoginUser(employee.getId());
   }

然后将menu菜单界面的地址改为controller的

url:'/util/findMenuByUserId',
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会尽力回答你的问题。 首先,我来简单介绍一下这个酒店点系统的功能: 1. 管理员权限管理:管理员可以添加、修改和删除用户信息、谱信息等。 2. 用户点餐功能:用户可以浏览单、点餐、修改订单等。 3. 管理员订单管理:管理员可以查看所有订单信息、修改订单状态等。 4. 管理员结账管理:管理员可以结算订单并打印账单。 5. 查看历史:用户和管理员可以查看历史订单信息。 6. 谱评分:用户可以对品进行评分和评论。 下面是使用C++语言实现这个酒店点系统的代码: ```c++ #include <iostream> #include <string> #include <vector> using namespace std; // 品类 class Dish { public: Dish() {} Dish(string name, int price) { this->name = name; this->price = price; } string getName() { return name; } int getPrice() { return price; } private: string name; int price; }; // 单类 class Menu { public: Menu() {} void addDish(Dish dish) { dishes.push_back(dish); } void showMenu() { cout << "------------------" << endl; cout << "单:" << endl; for (int i = 0; i < dishes.size(); i++) { cout << i + 1 << ". " << dishes[i].getName() << " " << dishes[i].getPrice() << "元" << endl; } cout << "------------------" << endl; } Dish getDish(int index) { return dishes[index - 1]; } private: vector<Dish> dishes; }; // 订单类 class Order { public: Order() {} void addDish(Dish dish) { dishes.push_back(dish); } void showOrder() { cout << "------------------" << endl; cout << "订单:" << endl; for (int i = 0; i < dishes.size(); i++) { cout << i + 1 << ". " << dishes[i].getName() << " " << dishes[i].getPrice() << "元" << endl; } cout << "------------------" << endl; } int getPrice() { int price = 0; for (int i = 0; i < dishes.size(); i++) { price += dishes[i].getPrice(); } return price; } private: vector<Dish> dishes; }; // 用户类 class User { public: User() {} void setName(string name) { this->name = name; } string getName() { return name; } void setOrder(Order order) { this->order = order; } Order getOrder() { return order; } private: string name; Order order; }; // 管理员类 class Admin { public: Admin() {} void addDish(Dish dish) { menu.addDish(dish); } void showMenu() { menu.showMenu(); } void showOrders() { cout << "------------------" << endl; cout << "所有订单:" << endl; for (int i = 0; i < orders.size(); i++) { cout << i + 1 << ". " << orders[i].getPrice() << "元" << endl; } cout << "------------------" << endl; } void showOrder(int index) { orders[index - 1].showOrder(); } void checkout(int index) { int price = orders[index - 1].getPrice(); cout << "订单总价:" << price << "元" << endl; orders.erase(orders.begin() + index - 1); } private: Menu menu; vector<Order> orders; }; // 主函数 int main() { Admin admin; admin.addDish(Dish("宫保鸡丁", 20)); admin.addDish(Dish("鱼香肉丝", 18)); admin.addDish(Dish("回锅肉", 22)); User user; user.setName("张三"); admin.showMenu(); int dishIndex; do { cout << "请选择品编号(0表示结束):" << endl; cin >> dishIndex; if (dishIndex != 0) { Dish dish = admin.getDish(dishIndex); user.getOrder().addDish(dish); user.getOrder().showOrder(); } } while (dishIndex != 0); admin.showOrders(); int orderIndex; cout << "请选择订单编号:" << endl; cin >> orderIndex; admin.showOrder(orderIndex); admin.checkout(orderIndex); admin.showOrders(); return 0; } ``` 以上是一个简单的酒店点系统的实现,其中包括了品类、单类、订单类、用户类和管理员类等多个类,通过这些类的协作实现了点、下单、结账等功能。 代码中还有一些注释和解释,希望能对你有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值