若是您有幸能看到,请认阅读如下内容;php
一、首先来看全部业务异常的枚举类,看异常大概就能知道这个系统主要完成那些业务逻辑。java
/** * 全部业务异常的枚举 */ public enum BizExceptionEnum { /** * 字典 */ DICT_EXISTED(400,"字典已经存在"), ERROR_CREATE_DICT(500,"建立字典失败"), ERROR_WRAPPER_FIELD(500,"包装字典属性失败"), /** * 文件上传 */ FILE_READING_ERROR(400,"FILE_READING_ERROR!"), FILE_NOT_FOUND(400,"FILE_NOT_FOUND!"), UPLOAD_ERROR(500,"上传图片出错"), /** * 权限和数据问题 */ DB_RESOURCE_NULL(400,"数据库中没有该资源"), NO_PERMITION(405, "权限异常"), REQUEST_INVALIDATE(400,"请求数据格式不正确"), INVALID_KAPTCHA(400,"验证码不正确"), CANT_DELETE_ADMIN(600,"不能删除超级管理员"), CANT_FREEZE_ADMIN(600,"不能冻结超级管理员"), CANT_CHANGE_ADMIN(600,"不能修改超级管理员角色"), /** * 帐户问题 */ USER_ALREADY_REG(401,"该用户已经注册"), NO_THIS_USER(400,"没有此用户"), USER_NOT_EXISTED(400, "没有此用户"), ACCOUNT_FREEZED(401, "帐号被冻结"), OLD_PWD_NOT_RIGHT(402, "原密码不正确"), TWO_PWD_NOT_MATCH(405, "两次输入密码不一致"), /** * 错误的请求 */ MENU_PCODE_COINCIDENCE(400,"菜单编号和副编号不能一致"), EXISTED_THE_MENU(400,"菜单编号重复,不能添加"), DICT_MUST_BE_NUMBER(400,"字典的值必须为数字"), REQUEST_NULL(400, "请求有错误"), SESSION_TIMEOUT(400, "会话超时"), SERVER_ERROR(500, "服务器异常"); BizExceptionEnum(int code, String message) { this.friendlyCode = code; this.friendlyMsg = message; } private int friendlyCode; private String friendlyMsg; private String urlPath; //Setter,Getter,Constractor略 BizExceptionEnum(int code, String message) { this.friendlyCode = code; this.friendlyMsg = message; } }
二、对业务异常的封装,首先须要注意的是继承自RuntimeException,以前讲过了点这里node
/** * 业务异常的封装 */ public class BussinessException extends RuntimeException { //友好提示的code码 private int friendlyCode; //友好提示 private String friendlyMsg; //业务异常调整页面 private String urlPath; public BussinessException(BizExceptionEnum bizExceptionEnum) { this.friendlyCode = bizExceptionEnum.getCode(); this.friendlyMsg = bizExceptionEnum.getMessage(); this.urlPath = bizExceptionEnum.getUrlPath(); } }
三、接下来是工具类初始化异常,须要注意serialVersionUID的做用:jquery
这个中定义异常和PayMap中定义方式几乎同样。git
/** * 工具类初始化 */ public class ToolBoxException extends RuntimeException { //serialVersionUID 是 Java 为每一个序列化类产生的版本标识,可用来保证在反序列时,发送方发送的和接受方接收的是可兼容的对象。 // 若是接收方接收的类的 serialVersionUID 与发送方发送的 serialVersionUID 不一致,进行反序列时会抛出 InvalidClassException。序列化的类可显式声明 serialVersionUID 的值, private static final long serialVersionUID = 8247610319171014183L; public ToolBoxException(Throwable e) { super(e.getMessage(),e); } public ToolBoxException(String message) { super(message); } public ToolBoxException(String message, Throwable throwable) { super(message,throwable); } public ToolBoxException(String messageTemplate, Object...params) { super(StrKit.format(messageTemplate,params)); } } -------------------------------------------------------------------------------- /** * 验证码错误异常 * * @Author guo //这个模板不错 * @Date 2018-03-04 12:04. */ public class InvalidKaptchaException extends RuntimeException { }
四、最后在看下自定义注解github
元注解:数据库
元注解的做用就是负责注解其余注解。Java5.0定义了4个标准的meta-annotation类型,它们被用提供对其余annotation类型的说明。服务器
-
@Targetasync
做用:用于描述注解的使用范围(即:被描述的注解能够用在什么地方)ide
取值(ElementType)有:
@Retention
做用:表示须要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)
取值(RetentionPoicy)有:
@Documented
做用:用于描述其它类型的annotation应该被做为被标注的程序成员的公共API,所以能够被例如javadoc此类的工具文档化。
@Inherited
@Inherited元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。若是一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。
接下来,咱们在看自定义注解
/** * 权限注解,用于检查权限 规定访问权限 */ @Inherited @Retention(RetentionPolicy.RUNTIME) //运行时有效 @Target({ElementType.METHOD}) //方法范围 public @interface Permission { String[] value() default {}; } ------------------------------------------------------- /** * 多数据源标识 */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD }) public @interface DataSource { } --------------------------------------------------------- /** * 标记须要作业务日志的方法 */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface BussinessLog { /** * 业务的名称,例如:"修改菜单" */ String value() default ""; /** * 被修改的实体的惟一标识,例如:菜单实体的惟一标识为"id" */ String key() default "id"; /** * 字典(用于查找key的中文名称和字段的中文名称) */ String dict() default "SystemDict"; }
五、先来看Node类的定义吧,
ZTree is an advanced jQuery 'tree plug-in'. The performance is excellent, it is easy to configurw (with a full set of options), and has many advanced features (that usually only come with paid software).
zTree is open source and uses the MIT license.
The most important is the official document to the very full(English is very important, important and important.)
ZTreeNode定义:
/** * jquery ztree 插件的节点 */ public class ZTreeNode { /** * 节点id */ private Integer id; /** * 父节点id */ private Integer pId; /** * 节点名称 */ private String name; /** * 是否打开节点 */ private Boolean open; /** * 是否被选中 */ private Boolean checked; //Setter、Getter、Constructor、toString忽略 }
MenuNode实现了Compareable接口,重写了compareTo()方法完整代码在这
@Override public int compareTo(Object o) { MenuNode menuNode = (MenuNode) o; Integer num = menuNode.getNum(); if (num == null) { num = 0; } return this.num.compareTo(num); }
/** * * 菜单的节点 */ public class MenuNode implements Comparable { /** * 节点id */ private Integer id; /** * 父节点 */ private Integer parentId; /** * 节点名称 */ private String name; /** * 按钮级别 */ private Integer levels; /** * 按钮级别 */ private Integer ismenu; /** * 按钮的排序 */ private Integer num; /** * 节点的url */ private String url; /** * 节点图标 */ private String icon; /** * 子节点的集合 */ private List<MenuNode> children; /** * 查询子节点时候的临时集合 */ private List<MenuNode> linkedList = new ArrayList<MenuNode>(); }
为了方便之后查看,方法单独提出来。
/** * 构建整个菜单树 */ public void buildNodeTree(List<MenuNode> nodeList) { for (MenuNode treeNode : nodeList) { List<MenuNode> linkedList = treeNode.findChildNodes(nodeList, treeNode.getId()); if (linkedList.size() > 0) { treeNode.setChildren(linkedList); } } } /** * 查询子节点的集合 */ public List<MenuNode> findChildNodes(List<MenuNode> nodeList, Integer parentId) { if (nodeList == null && parentId == null) return null; for (Iterator<MenuNode> iterator = nodeList.iterator(); iterator.hasNext(); ) { MenuNode node = (MenuNode) iterator.next(); // 根据传入的某个父节点ID,遍历该父节点的全部子节点 if (node.getParentId() != 0 && parentId.equals(node.getParentId())) { recursionFn(nodeList, node, parentId); } } return linkedList; } -------------------------------------------------------------------------------- /** * 遍历一个节点的子节点 */ public void recursionFn(List<MenuNode> nodeList, MenuNode node, Integer pId) { List<MenuNode> childList = getChildList(nodeList, node);// 获得子节点列表 if (childList.size() > 0) {// 判断是否有子节点 if (node.getParentId().equals(pId)) { linkedList.add(node); } Iterator<MenuNode> it = childList.iterator(); while (it.hasNext()) { MenuNode n = (MenuNode) it.next(); recursionFn(nodeList, n, pId); } } else { if (node.getParentId().equals(pId)) { linkedList.add(node); } } } /** * 获得子节点列表 */ private List<MenuNode> getChildList(List<MenuNode> list, MenuNode node) { List<MenuNode> nodeList = new ArrayList<MenuNode>(); Iterator<MenuNode> it = list.iterator(); while (it.hasNext()) { MenuNode n = (MenuNode) it.next(); if (n.getParentId().equals(node.getId())) { nodeList.add(n); } } return nodeList; } -------------------------------------------------------------------------------- /** * 清除掉按钮级别的资源 * * @param nodes * @return */ public static List<MenuNode> clearBtn(List<MenuNode> nodes) { ArrayList<MenuNode> noBtns = new ArrayList<MenuNode>(); for (MenuNode node : nodes) { if(node.getIsmenu() == IsMenu.YES.getCode()){ noBtns.add(node); } } return noBtns; } /** * 清除全部二级菜单 * * @param nodes * @return */ public static List<MenuNode> clearLevelTwo(List<MenuNode> nodes) { ArrayList<MenuNode> results = new ArrayList<MenuNode>(); for (MenuNode node : nodes) { Integer levels = node.getLevels(); if (levels.equals(1)) { results.add(node); } } return results; } -------------------------------------------------------------------------------- /** * 构建菜单列表 */ public static List<MenuNode> buildTitle(List<MenuNode> nodes) { List<MenuNode> clearBtn = clearBtn(nodes); new MenuNode().buildNodeTree(clearBtn); List<MenuNode> menuNodes = clearLevelTwo(clearBtn); //对菜单排序 Collections.sort(menuNodes); //对菜单的子菜单进行排序 for (MenuNode menuNode : menuNodes) { if (menuNode.getChildren() != null && menuNode.getChildren().size() > 0) { Collections.sort(menuNode.getChildren()); } } //若是关闭了接口文档,则不显示接口文档菜单 GunsProperties gunsProperties = SpringContextHolder.getBean(GunsProperties.class); if (!gunsProperties.getSwaggerOpen()) { List<MenuNode> menuNodesCopy = new ArrayList<>(); for (MenuNode menuNode : menuNodes) { if (Const.API_MENU_NAME.equals(menuNode.getName())) { continue; } else { menuNodesCopy.add(menuNode); } } menuNodes = menuNodesCopy; } return menuNodes; }
获取全部的选择节点、获取子节点
// 经过id号来获取这个树 var treeObj2 = $.fn.zTree.getZTreeObj("treeDemo"); // 获取全部已经选择了的节点,得到一个node列表 var nodes2 = treeObj2.getCheckedNodes(true); // 若是是叶子节点就把id拿出来 var idlist = []; $.each(nodes2, function (i, item) { if (!item.isParent) { //alert(item.id + "," + item.name); idlist.push(item.id); } }); console.log(idlist);
六、接下来,咱们看看pagehelper,Mybatis通用分页插件这个插件也是本项目大佬写的。若是非要本身封装也能够,可是你用过的话就不会在本身封装了。主要是PageInfo类。
package com.guo.guns.common.page; import com.github.pagehelper.Page; import java.util.List; /** * 分页结果的封装(for Bootstrap Table) * * @Author guo * @Date 2018-03-04 13:47 */ public class PageInfoBT<T> { /** * 结果集 */ private List<T> rows; /** * 总数 */ private long total; public PageInfoBT(List<T> page) { this.rows = page; if (page instanceof Page) { this.total = ((Page) page).getTotal(); } else { this.total = page.size(); } } //Setter、Getter略 }
(1)一、查出第一页的数据,每页5条:
PageHelper.offsetPage(0, 5);
(2)、获取总数:
PageInfo pageInfo = new PageInfo<>(cs); System.out.println("总数:"+pageInfo.getTotal()); System.out.println(pageInfo);