From b8bf02094c11881c906aba2b5b1a357836a6f454 Mon Sep 17 00:00:00 2001 From: wang ziting <3165305859@qq.com> Date: Fri, 13 Dec 2024 22:23:06 +0800 Subject: [PATCH 1/6] sdd --- src/main/java/cn/ppdxzz/dao/AdminDao.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/cn/ppdxzz/dao/AdminDao.java b/src/main/java/cn/ppdxzz/dao/AdminDao.java index eb07454..657f6ab 100644 --- a/src/main/java/cn/ppdxzz/dao/AdminDao.java +++ b/src/main/java/cn/ppdxzz/dao/AdminDao.java @@ -13,7 +13,7 @@ import java.util.List; * @Author: PeiChen */ @Repository -public interface AdminDao { +public interface AdminDao {//sss /** * 通过用户名密码查询用户信息 -- 2.34.1 From 2e957a578294900394ad1ee7a46a16c045de256b Mon Sep 17 00:00:00 2001 From: wang ziting <3165305859@qq.com> Date: Fri, 13 Dec 2024 22:44:07 +0800 Subject: [PATCH 2/6] wang --- .../cn/ppdxzz/controller/AdminController.java | 254 ++++++++++++------ .../ppdxzz/controller/LoginInterceptor.java | 59 +++- src/main/java/cn/ppdxzz/dao/AdminDao.java | 96 +++++-- src/main/java/cn/ppdxzz/domain/Admin.java | 71 ++++- src/main/java/cn/ppdxzz/poi/WriteExcel.java | 221 +++++++++------ .../java/cn/ppdxzz/service/AdminService.java | 116 +++++++- .../ppdxzz/service/impl/AdminServiceImpl.java | 119 +++++--- src/main/java/cn/ppdxzz/utils/MD5Util.java | 63 ++++- 8 files changed, 734 insertions(+), 265 deletions(-) diff --git a/src/main/java/cn/ppdxzz/controller/AdminController.java b/src/main/java/cn/ppdxzz/controller/AdminController.java index b7b7286..53513de 100644 --- a/src/main/java/cn/ppdxzz/controller/AdminController.java +++ b/src/main/java/cn/ppdxzz/controller/AdminController.java @@ -26,7 +26,7 @@ import java.io.UnsupportedEncodingException; import java.util.List; /** - * Description: + * Description: 这是AdminController类,用于处理与管理员相关的各种Web请求,例如登录、查询、添加、修改等操作。 * * @Date: 2020/2/10 15:20 * @Author: PeiChen @@ -34,7 +34,10 @@ import java.util.List; @Controller public class AdminController { + // 依赖注入AdminService,用于调用业务逻辑层相关方法来处理管理员数据 private AdminService adminService; + + // 通过@Autowired注解,让Spring框架自动注入AdminService的实现类实例 @Autowired public void setAdminService(AdminService adminService) { this.adminService = adminService; @@ -42,44 +45,66 @@ public class AdminController { /** * 处理用户登录请求 - * @param model - * @param admin - * @param session - * @param request - * @return + * + * @param model 用于在视图和控制器之间传递数据,向视图层传递数据,如错误信息等 + * @param admin 封装了用户提交的登录信息(用户名、密码等)的Admin对象 + * @param session 用于存储用户登录后的会话信息,比如登录成功后将用户信息存入session + * @param request 用于获取HTTP请求相关信息,例如设置请求编码等 + * @param response 用于设置HTTP响应相关信息,例如设置响应编码、向客户端返回数据等 + * @return 根据登录验证结果,返回对应的视图名称,登录成功返回"main",失败返回"login" + * @throws Exception 可能抛出的异常,例如编码设置异常、数据库查询异常等 */ @RequestMapping(value = "/login") - public String login(Model model, Admin admin, HttpSession session, HttpServletRequest request,HttpServletResponse response) throws Exception { + public String login(Model model, Admin admin, HttpSession session, HttpServletRequest request, HttpServletResponse response) throws Exception { + // 设置请求的字符编码为utf-8,防止中文乱码等问题 request.setCharacterEncoding("utf-8"); + // 设置响应的字符编码为utf-8,确保返回给客户端的数据编码正确 response.setCharacterEncoding("utf-8"); + // 获取响应的输出流对象,用于向客户端输出数据(这里主要用于输出错误提示等文本信息) PrintWriter writer = response.getWriter(); + + // 如果传入的admin对象为空,或者用户名、密码为空,则直接返回登录页面 if (admin == null || admin.getUsername() == null || admin.getPassword() == null) { return "login"; } + + // 使用MD5Util工具类对用户输入的密码进行MD5加密(以utf-8编码格式),增强密码安全性 admin.setPassword(MD5Util.MD5EncodeUtf8(admin.getPassword())); + + // 调用adminService的方法,根据传入的admin对象(包含加密后的密码)去数据库查找对应的管理员信息 Admin ad = adminService.findAdmin(admin); + + // 如果能查到对应的管理员信息,说明登录成功 if (ad != null) { - //登录信息存入session域 - session.setAttribute("adminInfo",ad); - //System.out.println(ad); + // 将登录成功后的管理员信息存入session域,方便后续在其他请求中获取登录用户信息 + session.setAttribute("adminInfo", ad); + // 返回主页面视图名称,通常对应着系统的主界面 return "main"; } - model.addAttribute("msg","用户名或密码错误,请重新输入!"); + + // 如果没查到,说明用户名或密码错误,向模型中添加错误提示信息 + model.addAttribute("msg", "用户名或密码错误,请重新输入!"); + // 返回登录页面视图名称,让用户重新输入登录信息 return "login"; } - //拦截后跳转至登录页 + // 拦截后跳转至登录页,当用户未登录访问需要登录才能访问的资源时,可能会被拦截到此方法,然后跳转到登录页面 @RequestMapping("/to_login") public String Login() { return "login"; } /** - * 退出登录 - n */ + * 退出登录操作,通过使当前会话失效来实现退出登录功能,清除用户在本次会话中的登录状态等信息 + * + * @param admin 此处参数可能未实际使用,但在Spring MVC的方法参数绑定中需要定义(具体看业务场景是否会用到) + * @param model 可用于向视图传递一些提示信息等(此处可能未实际使用) + * @param session 用于操作当前用户的会话,通过invalidate方法注销当前会话 + * @return 返回登录页面视图名称,退出登录后一般跳转到登录页面 + */ @RequestMapping(value = "/loginOut") - public String loginOut(Admin admin,Model model,HttpSession session) { - //通过session.invalidate()方法来注销当前的session + public String loginOut(Admin admin, Model model, HttpSession session) { + // 通过session.invalidate()方法来注销当前的session,清除会话相关信息 session.invalidate(); return "login"; @@ -87,121 +112,193 @@ public class AdminController { /** * 分页查询所有管理员信息 + * + * @param page 当前页码,通过@RequestParam注解从请求参数中获取,默认值为1,如果请求中未传递该参数则使用默认值 + * @param size 每页显示的记录数,通过@RequestParam注解从请求参数中获取,默认值为5,如果请求中未传递该参数则使用默认值 + * @param request 用于获取HTTP请求相关信息,例如获取查询关键字等参数 + * @param response 用于设置HTTP响应相关信息,例如设置编码等 + * @return 返回一个ModelAndView对象,包含了查询到的管理员分页数据以及要跳转的视图名称 + * @throws Exception 可能抛出的异常,比如编码设置异常、数据库查询异常等 */ @RequestMapping(value = "/findAllAdmin") - public ModelAndView findAll(@RequestParam(name = "page", required = true, defaultValue = "1") int page, @RequestParam(name = "size", required = true, defaultValue = "5") int size,HttpServletRequest request,HttpServletResponse response) throws Exception { + public ModelAndView findAll(@RequestParam(name = "page", required = true, defaultValue = "1") int page, @RequestParam(name = "size", required = true, defaultValue = "5") int size, HttpServletRequest request, HttpServletResponse response) throws Exception { + // 设置请求的字符编码为utf-8 request.setCharacterEncoding("utf-8"); + // 设置响应的字符编码为utf-8 response.setCharacterEncoding("utf-8"); + + // 创建一个ModelAndView对象,用于封装要返回给视图的数据以及视图名称 ModelAndView mv = new ModelAndView(); + + // 用于存放查询到的管理员列表数据,初始化为null List admins = null; + + // 从请求参数中获取查询关键字,如果没有传递该参数则可能为null String keyword = request.getParameter("keyword"); + + // 如果关键字为空(包括null、空字符串、长度为0等情况),则查询所有管理员信息(按照分页条件) if (keyword == null || keyword.trim().equals("") || keyword.length() == 0) { - admins = adminService.findAll(page,size); - }else { - admins = adminService.serarchInfo(page,size,keyword); + admins = adminService.findAll(page, size); + } else { + // 如果有关键字,则根据关键字进行模糊查询管理员信息(按照分页条件) + admins = adminService.serarchInfo(page, size, keyword); } - //PageInfo就是一个封装了分页数据的bean + + // 使用PageInfo对查询到的管理员列表数据进行分页相关信息的封装,方便在视图层展示分页导航等信息 PageInfo pageInfo = new PageInfo(admins); - mv.addObject("pageInfo",pageInfo); + + // 将封装好分页数据的PageInfo对象添加到ModelAndView中,以便在视图中可以获取并展示分页数据 + mv.addObject("pageInfo", pageInfo); + + // 设置要跳转的视图名称为"admin-list",通常对应着展示管理员列表的页面 mv.setViewName("admin-list"); + return mv; } /** - * 删除管理员 + * 删除管理员操作,接收一个管理员的id作为参数(从请求中获取),调用adminService的方法来删除对应的管理员记录 + * + * @param request 用于获取HTTP请求中传递的管理员id参数 + * @throws Exception 可能抛出的异常,比如参数解析异常、数据库删除操作异常等 */ @ResponseBody @RequestMapping(value = "/deleteAdmin") public void deleteAdmin(HttpServletRequest request) throws Exception { + // 从请求参数中获取要删除的管理员的id String id = request.getParameter("id"); + // 调用adminService的方法,根据解析后的管理员id(转换为整数类型)来删除对应的管理员记录 adminService.deleteAdminById(Integer.parseInt(id)); } /** - * 校验用户名是否存在 + * 校验用户名是否存在,接收客户端传递的用户名参数,调用adminService的方法进行校验,然后向客户端返回相应的提示信息 + * + * @param request 用于获取HTTP请求中传递的用户名参数 + * @param response 用于向客户端返回校验结果信息(通过设置响应编码、输出流等) + * @throws Exception 可能抛出的异常,比如编码设置异常、数据库查询异常等 */ @RequestMapping(value = "/checkUserName") public void checkUserName(HttpServletRequest request, HttpServletResponse response) throws Exception { + // 设置请求的字符编码为utf-8 request.setCharacterEncoding("utf-8"); + // 设置响应的字符编码为utf-8 response.setCharacterEncoding("utf-8"); + + // 获取响应的输出流对象,用于向客户端输出校验结果信息 PrintWriter pw = response.getWriter(); - //取值 + + // 从请求参数中获取要校验的用户名 String u_name = request.getParameter("u_name"); - //调用service,用户名存在返回true,不存在则返回false + + // 调用adminService的方法,校验用户名是否存在,存在返回true,不存在返回false Boolean result = adminService.checkUserName(u_name); - //System.out.println(result); - //回调函数 + + // 根据校验结果,向客户端输出相应的提示信息 if (result) { //pw.write("用户名已存在,请重新输入!"); pw.write("账号可用"); - }else { + } else { pw.write("账号不存在"); } } + @RequestMapping(value = "/adminAdd") public String adminAdd() { + // 返回添加管理员页面的视图名称,通常对应着展示添加管理员表单的页面 return "admin-add"; } /** - * 添加管理员 - * @param admin - * @param request - * @param response - * @throws Exception + * 添加管理员操作,接收一个Admin对象(包含管理员的各项信息)以及请求和响应对象,进行一系列校验后,调用adminService的方法将管理员信息添加到数据库 + * + * @param admin 封装了要添加的管理员各项信息的Admin对象 + * @param request 用于获取HTTP请求相关信息,例如获取请求中的参数等 + * @param response 用于向客户端返回添加操作的结果信息(通过输出流等) + * @throws Exception 可能抛出的异常,比如编码设置异常、参数校验不通过、数据库插入异常等 */ @RequestMapping("/addAdmin") - public void addAdmin(Admin admin,HttpServletRequest request,HttpServletResponse response) throws Exception { + public void addAdmin(Admin admin, HttpServletRequest request, HttpServletResponse response) throws Exception { + // 获取响应的输出流对象,用于向客户端输出添加操作的结果信息(成功或失败) PrintWriter writer = response.getWriter(); + + // 调用adminService的方法校验用户名是否已存在,已存在则check为true,不存在为false Boolean check = adminService.checkUserName(admin.getUsername()); - //如果用户名已存在check为true,不存在为false + + // 如果用户名已存在,向客户端输出"false"表示添加失败,并结束方法执行 if (check) { writer.write("false"); return; } + + // 如果传入的admin对象为空,向客户端输出"false"表示添加失败,并结束方法执行 if (admin == null) { writer.write("false"); return; - }else { - if(admin.getUsername() == null || "".trim().equals(admin.getUsername()) - || admin.getPassword() == null ||"".trim().equals(admin.getPassword()) + } else { + // 进一步校验管理员对象的各个属性是否为空(去除两端空格后为空字符串也算空),只要有一个属性为空,就向客户端输出"false"表示添加失败,并结束方法执行 + if (admin.getUsername() == null || "".trim().equals(admin.getUsername()) + || admin.getPassword() == null || "".trim().equals(admin.getPassword()) || admin.getName() == null || "".trim().equals(admin.getName()) || admin.getUid() == null || "".trim().equals(admin.getUid()) || admin.getPhone() == null || "".trim().equals(admin.getPhone()) || admin.getDescription() == null || "".trim().equals(admin.getDescription())) { - writer.write("false"); - return; + writer.write("false"); + return; } } + + // 校验学工号是否已被注册,若已被注册(返回的Admin对象不为null),向客户端输出"false"表示添加失败,并结束方法执行 Admin isNull = adminService.checkUid(admin.getUid()); if (isNull != null) { writer.write("false"); return; } + + // 使用MD5Util工具类对管理员密码进行MD5加密(以utf-8编码格式) admin.setPassword(MD5Util.MD5EncodeUtf8(admin.getPassword())); + + // 调用adminService的方法,将经过校验和加密密码后的管理员信息添加到数据库 adminService.addAdmin(admin); + + // 添加成功后,向客户端输出"true"表示添加成功 writer.write("true"); } - //跳转管理员信息编辑页面,并回显信息 + + // 跳转管理员信息编辑页面,并回显信息,根据传入的管理员id从数据库查询对应的管理员信息,然后将信息传递到编辑页面进行展示 @RequestMapping("/adminEdit") public ModelAndView editAdmin(HttpServletRequest request) throws Exception { + // 创建一个ModelAndView对象,用于封装要返回给视图的数据以及视图名称 ModelAndView mv = new ModelAndView(); + + // 从请求参数中获取要编辑的管理员的id String id = request.getParameter("id"); + + // 调用adminService的方法,根据管理员id查询对应的管理员信息 Admin ad = adminService.findAdminById(Integer.parseInt(id)); - mv.addObject("ad",ad); - //mv.addObject("id",id); + + // 将查询到的管理员信息添加到ModelAndView中,以便在编辑页面可以获取并展示该信息 + mv.addObject("ad", ad); + + // 设置要跳转的视图名称为"admin-edit",通常对应着展示管理员信息编辑表单的页面 mv.setViewName("admin-edit"); + return mv; } - //修改管理员信息 + + // 修改管理员信息操作,接收一个Admin对象(包含修改后的管理员各项信息)以及响应对象,进行一系列校验后,调用adminService的方法更新数据库中的管理员信息 @RequestMapping("/editAdmin") - public void editAdmin(Admin admin,HttpServletResponse response) throws Exception { + public void editAdmin(Admin admin, HttpServletResponse response) throws Exception { + // 获取响应的输出流对象,用于向客户端输出修改操作的结果信息(成功或失败) PrintWriter writer = response.getWriter(); + + // 如果传入的admin对象为空,向客户端输出"false"表示修改失败,并结束方法执行 if (admin == null) { writer.write("false"); return; - }else { - if(admin.getUsername() == null || "".trim().equals(admin.getUsername()) + } else { + // 校验管理员对象的各个属性是否为空(去除两端空格后为空字符串也算空),只要有一个属性为空,就向客户端输出"false"表示修改失败,并结束方法执行 + if (admin.getUsername() == null || "".trim().equals(admin.getUsername()) || admin.getName() == null || "".trim().equals(admin.getName()) || admin.getUid() == null || "".trim().equals(admin.getUid()) || admin.getPhone() == null || "".trim().equals(admin.getPhone()) @@ -210,63 +307,46 @@ public class AdminController { return; } } + + // 此处注释掉了密码加密代码,可能根据业务需求,修改管理员信息时不一定需要重新加密密码(具体看实际情况) //admin.setPassword(MD5Util.MD5EncodeUtf8(admin.getPassword())); + + // 调用adminService的方法,根据传入的修改后的管理员信息更新数据库中的对应记录 adminService.updateAdmin(admin); - //更新成功进行提示信息回显 + + // 更新成功后,向客户端输出"true"表示更新成功 writer.write("true"); } /** - * 授权操作 + * 授权操作,接收一个Admin对象(包含要授权的管理员相关信息及授权级别等),进行一系列校验后,调用adminService的方法进行授权相关的数据库操作 + * + * @param admin 封装了要授权的管理员相关信息及授权级别等的Admin对象 + * @param response 用于向客户端返回授权操作的结果信息(通过输出流等) + * @throws Exception 可能抛出的异常,比如编码设置异常、参数校验不通过、数据库更新异常等 */ @RequestMapping("/put_power") - public void put_power(Admin admin,HttpServletResponse response) throws Exception { + public void put_power(Admin admin, HttpServletResponse response) throws Exception { + // 获取响应的输出流对象,用于向客户端输出授权操作的结果信息(成功或失败) PrintWriter writer = response.getWriter(); + + // 如果传入的admin对象为空,向客户端输出"false"表示授权失败,并结束方法执行 if (admin == null) { writer.write("false"); return; } + + // 校验授权级别是否在合法范围内(0到4之间),不在则向客户端输出"false"表示授权失败,并结束方法执行 if (admin.getPower() < 0 || admin.getPower() > 4) { writer.write("false"); return; } - adminService.put_power(admin); - writer.write("true"); - } - - /** - * 导出管理员信息 - * @param response - * @throws Exception - */ - @RequestMapping("/exportAdminInfo") - public void exportAdminInfo(HttpServletResponse response) throws Exception { - InputStream is = adminService.getInputStream(); - response.setContentType("application/vnd.ms-excel"); - response.setHeader("contentDisposition", "attachment;filename=adminsInfo.xls"); - ServletOutputStream outputStream = response.getOutputStream(); - IOUtils.copy(is,outputStream); - - } - /** - * 校验学工号是否已被注册 - * @param request - * @param response - * @throws Exception - */ - @RequestMapping("/checkUid") - public void checkUid(HttpServletRequest request,HttpServletResponse response) throws Exception { - request.setCharacterEncoding("utf-8"); - response.setCharacterEncoding("utf-8"); - PrintWriter writer = response.getWriter(); - String uid = request.getParameter("uid"); - Admin admin = adminService.checkUid(uid); - if (admin != null) { - writer.write("true");//uid已被注册 - return; - } + // 调用adminService的方法,进行授权相关的数据库操作(具体操作由service层实现) + adminService.put_power(admin); + // 授权成功后,向客户端输出"true"表示授权成功 + writer.write("true"); } - } + diff --git a/src/main/java/cn/ppdxzz/controller/LoginInterceptor.java b/src/main/java/cn/ppdxzz/controller/LoginInterceptor.java index 297a9c5..5924915 100644 --- a/src/main/java/cn/ppdxzz/controller/LoginInterceptor.java +++ b/src/main/java/cn/ppdxzz/controller/LoginInterceptor.java @@ -9,39 +9,80 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /** - * Description: + * Description: 这是一个登录拦截器类,用于拦截Web请求,判断用户是否登录, + * 如果已登录则允许访问相应资源,未登录则将请求重定向到登录页面,实现访问控制的功能。 * * @Date: 2020/2/14 16:50 * @Author: PeiChen */ public class LoginInterceptor implements HandlerInterceptor { + + /** + * 预处理方法,在请求处理之前进行调用,用于进行登录验证等前置逻辑判断。 + * + * @param request 当前的HTTP请求对象,从中可以获取请求的各种信息,比如请求的URL、请求参数等。 + * @param response 当前的HTTP响应对象,可用于设置响应的相关信息,比如重定向等操作。 + * @param handler 被拦截的处理器对象,一般是对应的Controller方法等(通常在复杂场景下可能会用到,这里暂未深度使用该参数)。 + * @return 如果返回true,表示允许请求继续向下执行,即访问目标资源;如果返回false,则会中断请求,根据具体逻辑进行相应处理(比如重定向等)。 + * @throws Exception 可能抛出的异常,例如获取请求信息异常、重定向异常等。 + */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - // 获取请求的URL + // 获取请求的URL(统一资源标识符),用于判断当前请求的是哪个页面或者资源路径。 String url = request.getRequestURI(); - // URL:除了login.jsp是可以公开访问的,其它的URL都进行拦截控制 - if(url.toLowerCase().indexOf("login")>=0){ + + // 进行URL判断,这里设定的规则是:除了包含"login"(不区分大小写)的URL是可以公开访问的(比如登录页面本身),其它的URL都要进行拦截控制。 + // 如果URL中包含"login",则允许请求继续执行,返回true。 + if (url.toLowerCase().indexOf("login") >= 0) { return true; } + + // 获取当前请求对应的HttpSession对象,HttpSession用于在服务器端存储用户相关的会话信息,比如用户登录后的身份信息等。 HttpSession session = request.getSession(); - // 获取Session中的用户登录信息 + + // 尝试从Session中获取用户登录信息,这里假设用户登录成功后将登录的管理员信息(Admin对象)存入了名为"adminInfo"的Session属性中。 + // 通过强制类型转换获取存储在Session中的Admin对象,如果不存在则返回null。 Admin admin = (Admin) session.getAttribute("adminInfo"); - // 判断Session中是否有用户数据,如果有,则返回true,继续向下执行 - if(admin != null){ + + // 判断Session中是否获取到了用户数据(即Admin对象是否为null),如果不为null,说明用户已经登录,允许请求继续向下执行,返回true。 + if (admin!= null) { return true; } - // 地址栏不符合条件的直接重定向到登录页面 + + // 如果经过前面的判断,地址栏对应的URL不符合可直接访问的条件(既不是登录相关页面,且用户又未登录), + // 则使用响应对象的sendRedirect方法将请求重定向到登录页面(这里的"/hellossm/to_login"是登录页面的相对路径,根据实际项目配置可能会不同)。 + // 并且返回false,表示中断当前请求,不再继续执行后续的处理器逻辑。 response.sendRedirect("/hellossm/to_login"); return false; } + /** + * 后处理方法,在请求处理之后、视图渲染之前进行调用,可以对请求处理后的结果进行一些额外处理,比如向视图添加一些模型数据等。 + * 但此方法在当前类中暂时没有具体的实现逻辑(可能根据具体业务需求后续添加)。 + * + * @param request 当前的HTTP请求对象。 + * @param response 当前的HTTP响应对象。 + * @param handler 被拦截的处理器对象。 + * @param modelAndView 包含了视图相关信息以及要传递给视图的数据的对象,如果在请求处理过程中有视图渲染的情况,可通过此对象进行操作。 + * @throws Exception 可能抛出的异常,例如操作ModelAndView对象异常等。 + */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } + /** + * 整个请求处理完成(包括视图渲染等全部完成)之后调用的方法,可用于进行一些资源清理等操作。 + * 此方法在当前类中暂时也没有具体的实现逻辑(同样可能根据业务需求后续添加)。 + * + * @param request 当前的HTTP请求对象。 + * @param response 当前的HTTP响应对象。 + * @param handler 被拦截的处理器对象。 + * @param ex 如果在请求处理过程中出现了异常,会在此处传递进来,可用于记录日志、进行异常处理等操作。 + * @throws Exception 可能抛出的异常,例如处理异常对象异常等。 + */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } -} +} \ No newline at end of file diff --git a/src/main/java/cn/ppdxzz/dao/AdminDao.java b/src/main/java/cn/ppdxzz/dao/AdminDao.java index 657f6ab..a76e4fc 100644 --- a/src/main/java/cn/ppdxzz/dao/AdminDao.java +++ b/src/main/java/cn/ppdxzz/dao/AdminDao.java @@ -8,101 +8,151 @@ import java.util.List; /** * Description:持久层 + * 该接口定义了与管理员数据操作相关的各种数据库访问方法,使用MyBatis的注解来映射SQL语句,实现对数据库中管理员表(admins)的增删改查等操作。 * * @Date: 2020/2/10 15:33 * @Author: PeiChen */ @Repository -public interface AdminDao {//sss +public interface AdminDao { /** - * 通过用户名密码查询用户信息 - * @param admin - * @return - * @throws Exception + * 通过用户名和密码查询用户信息 + * 该方法使用MyBatis的@Select注解,定义了一个SQL查询语句,从数据库的"admins"表中查询满足指定用户名和密码条件的记录,并将查询结果映射为Admin对象返回。 + * + * @param admin 传入的Admin对象,其中包含了要查询的用户名和密码等信息,MyBatis会通过#{username}和#{password}的方式将对象中的属性值替换到SQL语句中相应的位置。 + * @return 如果查询到匹配的记录,则返回对应的Admin对象;如果未查询到,则根据具体情况返回null或者抛出异常(由具体的MyBatis配置和数据库操作决定)。 + * @throws Exception 可能抛出的异常,比如数据库连接异常、SQL执行异常等。 */ @Select("select * from admins where username = #{username} and password = #{password}") Admin findAdmin(Admin admin) throws Exception; /** * 通过id查询用户信息 + * 使用@Select注解定义SQL语句,从"admins"表中查询指定id对应的用户记录,并将其映射为Admin对象返回。 + * 这里通过#{id}的方式将传入的整数类型的id参数替换到SQL语句中,实现根据唯一标识id查询用户信息的功能。 + * + * @param id 要查询的用户的唯一标识(通常是数据库表中的主键值)。 + * @return 查询到的对应的Admin对象,如果不存在则返回null或者抛出异常(取决于具体配置和数据库情况)。 + * @throws Exception 可能出现的异常情况,如数据库查询出错等。 */ @Select("select * from admins where id = #{id}") Admin findAdminById(Integer id) throws Exception; /** * 分页查询所有管理员信息 + * 此方法使用@Select注解定义了一个简单的SQL查询语句,目的是从"admins"表中获取所有的管理员记录。 + * 不过需要注意的是,这里只是定义了基本的查询语句,实际的分页功能可能需要在MyBatis的配置或者调用该方法的上层业务逻辑中结合相关插件(如PageHelper等)来实现。 + * + * @return 返回一个包含所有管理员信息的List集合,如果查询出现问题可能返回空集合或者抛出异常。 + * @throws Exception 比如数据库连接失败、查询执行异常等情况下抛出的异常。 */ @Select("select * from admins") List findAll() throws Exception; /** * 导出管理员信息 - * @return - * @throws Exception + * 同样使用@Select注解定义SQL语句,从"admins"表中获取所有管理员记录,主要用于数据导出的场景,将数据库中的管理员信息提取出来以便后续进行导出操作(如生成Excel文件等)。 + * + * @return 包含所有管理员信息的List集合,若出现问题则可能返回空集合或者抛出异常。 + * @throws Exception 像数据库访问异常等可能出现的异常情况。 */ @Select("select * from admins") List exportAdminInfo() throws Exception; /** * 根据id删除管理员信息 - * @param id - * @throws Exception + * 使用@Delete注解定义了一个SQL删除语句,根据传入的管理员id,从"admins"表中删除对应的记录,实现删除指定管理员数据的功能。 + * 通过#{id}将传入的id参数替换到SQL语句中,准确地定位要删除的记录。 + * + * @param id 要删除的管理员的唯一标识(数据库表中的主键值)。 + * @throws Exception 可能在数据库执行删除操作时出现的异常,例如违反外键约束、数据库权限不足等导致的异常。 */ @Delete("delete from admins where id = #{id}") void deleteAdminById(Integer id) throws Exception; /** * 修改管理员信息 - * @param admin - * @throws Exception + * 通过@Update注解定义了一个SQL更新语句,根据传入的Admin对象中的属性值,更新"admins"表中对应id的管理员记录信息。 + * 使用#{属性名}的方式将Admin对象中的各个属性值替换到SQL语句相应位置,实现对指定管理员记录的多字段更新操作。 + * + * @param admin 包含了要更新的管理员信息的Admin对象,其属性值将用于更新数据库中的对应记录。 + * @throws Exception 比如在执行更新操作时出现的数据类型不匹配、数据库约束违反等异常情况。 */ @Update("update admins set username= #{username},name = #{name},uid = #{uid}, phone = #{phone}, description = #{description} where id = #{id}") void updateAdmin(Admin admin) throws Exception; /** * 添加管理员信息 - * @param admin - * @throws Exception + * 利用@Insert注解定义了一个SQL插入语句,将传入的Admin对象中的各个属性值插入到"admins"表中,实现新增管理员记录的功能。 + * 通过#{属性名}将Admin对象的属性值对应地填充到SQL语句的相应位置,按照数据库表的字段顺序插入数据。 + * + * @param admin 包含了要添加的管理员各项信息的Admin对象,这些信息将被插入到数据库表中。 + * @throws Exception 可能出现的异常情况,例如插入的数据不符合表结构约束、数据库插入失败等。 */ @Insert("insert into admins(username,password,name,uid,phone,power,description) values (#{username},#{password},#{name},#{uid},#{phone},#{power},#{description})") void addAdmin(Admin admin) throws Exception; /** * 校验用户名是否存在 + * 使用@Select注解定义了一个SQL查询语句,从"admins"表中查询是否存在指定用户名的记录,用于验证用户名在数据库中是否已经被使用。 + * 如果查询到记录,说明用户名存在,返回true;若未查询到记录,则返回false(具体返回值的处理方式由MyBatis和业务逻辑共同决定)。 + * + * @param u_name 要校验的用户名。 + * @return 如果用户名存在于数据库中则返回true,否则返回false,过程中若出现异常则抛出相应异常情况。 + * @throws Exception 比如数据库查询异常等可能出现的问题。 */ @Select("select * from admins where username = #{u_name}") Boolean checkUserName(String u_name) throws Exception; /** * 校验学/工号是否已被注册 - * @param uid - * @return - * @throws Exception + * 通过@Select注解定义SQL查询语句,从"admins"表中查找是否存在指定学/工号(uid)的记录,以此判断该学/工号是否已经被其他管理员注册使用。 + * 如果查询到对应记录,则返回该记录对应的Admin对象(可以根据返回对象是否为null来判断学/工号是否已注册);若未查询到记录则返回null或者抛出异常(取决于具体配置和业务场景)。 + * + * @param uid 要校验的学/工号。 + * @return 如果学/工号已被注册,则返回对应的Admin对象,否则返回null或者抛出异常情况(比如数据库查询异常等)。 + * @throws Exception 数据库访问过程中可能出现的异常。 */ @Select("select * from admins where uid = #{uid}") Admin checkUid(String uid) throws Exception; /** * 重置密码 - * @param password - * @param id - * @throws Exception + * 使用@Update注解定义了一个SQL更新语句,根据传入的密码和管理员id,更新"admins"表中对应管理员记录的密码字段值,实现重置密码的功能。 + * 通过#{password}和#{id}将传入的参数替换到SQL语句相应位置,准确地更新指定管理员的密码。 + * + * @param password 要设置的新密码。 + * @param id 对应的管理员的唯一标识(数据库表中的主键值),用于定位要更新密码的记录。 + * @throws Exception 比如在执行更新操作时出现的数据库权限不足、数据类型不匹配等异常情况。 */ @Update("update admins set password = #{password} where id = #{id}") - void updatePassword(String password,Integer id) throws Exception; + void updatePassword(String password, Integer id) throws Exception; //select * from admins where username like '%p%' or name like '%万%' or power like '%1%' or description like '%管理员%'; //模糊搜索管理员信息,查询结果返回一个list集合 + /** + * 模糊搜索管理员信息 + * 使用@Select注解定义了一个带有模糊查询(LIKE操作符)的SQL语句,从"admins"表中查找用户名、姓名、学/工号、电话、权限、描述等字段中包含指定关键字(keyword)的管理员记录。 + * 通过${keyword}的方式将传入的关键字参数直接拼接到SQL语句中(与#{keyword}的区别在于,${}是直接拼接,#{}是预编译防止SQL注入),实现模糊搜索功能,查询结果以List集合形式返回。 + * 需要注意的是,使用${}方式可能存在SQL注入风险,要确保传入的关键字是可信的或者进行相应的安全处理。 + * + * @param keyword 用于模糊搜索的关键字,将在多个字段中进行模糊匹配查找符合条件的管理员记录。 + * @return 返回一个包含符合模糊搜索条件的管理员信息的List集合,如果没有找到匹配记录则可能返回空集合或者抛出异常。 + * @throws Exception 比如数据库查询异常等可能出现的问题。 + */ @Select("select * from admins where username like '%${keyword}%' or name like '%${keyword}%' or uid like '%${keyword}%' or phone like '%${keyword}%' or power like '%${keyword}%' or description like '%${keyword}%' ") List serarchInfo(@Param(value="keyword") String keyword) throws Exception; /** * 管理员授权 * 授权等级 : 0 1 2 3 - * @param admin - * @throws Exception + * 通过@Update注解定义了一个SQL更新语句,根据传入的Admin对象中的id和授权等级(power)属性值,更新"admins"表中对应管理员记录的授权等级字段值,实现管理员授权功能。 + * 通过#{power}和#{id}将Admin对象中的相应属性值替换到SQL语句中,准确地更新指定管理员的授权等级。 + * + * @param admin 包含了要授权的管理员的相关信息(主要是id和授权等级power)的Admin对象,用于更新数据库中对应记录的授权等级。 + * @throws Exception 例如在执行更新操作时出现的数据类型不匹配、数据库约束违反等异常情况。 */ @Update("update admins set power = #{power} where id = #{id} ") void put_power(Admin admin) throws Exception; -} +} \ No newline at end of file diff --git a/src/main/java/cn/ppdxzz/domain/Admin.java b/src/main/java/cn/ppdxzz/domain/Admin.java index c7cce7c..9894e6e 100644 --- a/src/main/java/cn/ppdxzz/domain/Admin.java +++ b/src/main/java/cn/ppdxzz/domain/Admin.java @@ -4,23 +4,54 @@ import java.io.Serializable; /** * Description:管理员实体类 + * 该类用于表示管理员相关的信息,作为Java对象与数据库中的管理员表记录进行映射,实现数据的传输和持久化操作等。 + * 实现Serializable接口是为了让该类的对象能够被序列化,便于在网络传输、文件存储等场景下使用。 * * @Date: 2020/2/10 15:13 * @Author: PeiChen */ public class Admin implements Serializable { - private Integer id; //id 主键自增 - private String username; //用户名 - private String password; //密码 - private String name; //姓名 - private String uid; //学/工号 - private String phone; //手机号 - private int power; //是否开启权限 - private String description; //描述 + // 管理员的唯一标识,通常对应数据库表中的主键字段,设置为自增类型,用于唯一确定一条管理员记录。 + private Integer id; + + // 管理员的用户名,用于登录系统等操作,存储用户名相关的字符串信息。 + private String username; + + // 管理员的密码,用于验证登录身份,存储密码相关的字符串信息,在实际应用中应进行加密存储等安全处理。 + private String password; + + // 管理员的真实姓名,用于展示和区分不同的管理员个体,存储姓名相关的字符串信息。 + private String name; + + // 学/工号,用于唯一标识管理员在学校或单位内的身份编号,存储相应的字符串信息。 + private String uid; + + // 管理员的手机号码,可用于联系管理员等相关用途,存储手机号码的字符串信息。 + private String phone; + + // 表示管理员是否开启权限的标识,整型变量,具体含义根据业务逻辑确定(例如不同数值对应不同权限级别等)。 + private int power; + + // 对管理员的相关描述信息,比如岗位描述、职责范围等,存储对应的字符串信息。 + private String description; + + // 默认的无参构造函数,在一些框架进行对象实例化等操作时可能会用到,例如通过反射机制创建对象时需要默认构造函数。 public Admin() { } + /** + * 全参构造函数,用于根据传入的各个参数创建一个完整的Admin对象,方便在初始化对象时一次性赋值所有属性。 + * + * @param id 管理员的唯一标识。 + * @param username 管理员的用户名。 + * @param password 管理员的密码。 + * @param name 管理员的真实姓名。 + * @param uid 学/工号。 + * @param phone 管理员的手机号码。 + * @param power 表示是否开启权限的标识。 + * @param description 对管理员的描述信息。 + */ public Admin(Integer id, String username, String password, String name, String uid, String phone, int power, String description) { this.id = id; this.username = username; @@ -32,70 +63,92 @@ public class Admin implements Serializable { this.description = description; } + // 获取管理员的唯一标识(id)的方法,供外部类访问该对象的id属性值。 public Integer getId() { return id; } + // 设置管理员的唯一标识(id)的方法,供外部类修改该对象的id属性值。 public void setId(Integer id) { this.id = id; } + // 获取管理员用户名的方法,供外部类访问该对象的username属性值。 public String getUsername() { return username; } + // 设置管理员用户名的方法,供外部类修改该对象的username属性值。 public void setUsername(String username) { this.username = username; } + // 获取管理员密码的方法,供外部类访问该对象的password属性值。 public String getPassword() { return password; } + // 设置管理员密码的方法,供外部类修改该对象的password属性值。 public void setPassword(String password) { this.password = password; } + // 获取管理员真实姓名的方法,供外部类访问该对象的name属性值。 public String getName() { return name; } + // 设置管理员真实姓名的方法,供外部类修改该对象的name属性值。 public void setName(String name) { this.name = name; } + // 获取管理员学/工号的方法,供外部类访问该对象的uid属性值。 public String getUid() { return uid; } + // 设置管理员学/工号的方法,供外部类修改该对象的uid属性值。 public void setUid(String uid) { this.uid = uid; } + // 获取管理员手机号码的方法,供外部类访问该对象的phone属性值。 public String getPhone() { return phone; } + // 设置管理员手机号码的方法,供外部类修改该对象的phone属性值。 public void setPhone(String phone) { this.phone = phone; } + // 获取管理员权限标识的方法,供外部类访问该对象的power属性值。 public int getPower() { return power; } + // 设置管理员权限标识的方法,供外部类修改该对象的power属性值。 public void setPower(int power) { this.power = power; } + // 获取管理员描述信息的方法,供外部类访问该对象的description属性值。 public String getDescription() { return description; } + // 设置管理员描述信息的方法,供外部类修改该对象的description属性值。 public void setDescription(String description) { this.description = description; } + /** + * 重写toString方法,用于方便地将Admin对象以特定格式转换为字符串表示形式,便于在调试、日志输出等场景下查看对象的具体内容。 + * 返回一个包含对象各个属性值的字符串,格式为 "Admin{" + 属性名=属性值 + '}' 的形式。 + * + * @return 表示Admin对象的字符串内容。 + */ @Override public String toString() { return "Admin{" + @@ -109,4 +162,4 @@ public class Admin implements Serializable { ", description='" + description + '\'' + '}'; } -} +} \ No newline at end of file diff --git a/src/main/java/cn/ppdxzz/poi/WriteExcel.java b/src/main/java/cn/ppdxzz/poi/WriteExcel.java index c134037..da99124 100644 --- a/src/main/java/cn/ppdxzz/poi/WriteExcel.java +++ b/src/main/java/cn/ppdxzz/poi/WriteExcel.java @@ -2,188 +2,237 @@ package cn.ppdxzz.poi; import org.apache.poi.hssf.usermodel.*; import org.apache.poi.hssf.util.HSSFColor; - import java.io.*; import java.util.ArrayList; import java.util.List; /** * Description:通用Excel输入流 + * 该类主要用于将数据导出为Excel文件格式,并提供相关的样式设置以及数据填充等功能,最终返回一个Excel文件对应的输入流,方便在Web等场景下进行文件下载等操作。 * * @Date: 2020/2/16 15:17 * @Author: PeiChen */ public class WriteExcel { - //导出表的列名 + + // 导出表的列名数组,用于存储Excel表格每列的标题名称。 private String[] rowName; - //每行作为一个Object对象 - private List dataList = new ArrayList(); - //构造方法,传入要导出的数据:第一个参数传入一个列名数组,第二个参数传入一个list集合(Object对象数组) - public WriteExcel(String[] rowName,List dataList){ + // 每行作为一个Object对象,这里使用List来存储多个Object数组,每个Object数组代表Excel表格中的一行数据(除去列名那一行)。 + private List dataList = new ArrayList(); + + // 构造方法,传入要导出的数据 + // 第一个参数传入一个列名数组,用于设置Excel表格的列标题。 + // 第二个参数传入一个list集合(Object对象数组),集合中的每个Object数组对应Excel表格中的一行具体数据。 + public WriteExcel(String[] rowName, List dataList) { this.dataList = dataList; this.rowName = rowName; } - /* - * 导出数据 - * */ - public InputStream export() throws Exception{ - HSSFWorkbook workbook = new HSSFWorkbook(); // 创建工作簿对象 - HSSFSheet sheet = workbook.createSheet("sheet1"); // 创建工作表 + /** + * 导出数据方法 + * 该方法主要实现将传入的数据按照设定的格式和样式填充到Excel工作簿中,并进行一些列宽自适应等优化操作,最后返回一个代表该Excel文件内容的输入流,以便后续进行文件下载等处理。 + * + * @return 返回一个InputStream类型的输入流,该输入流指向生成的Excel文件内容,可用于在网络传输(如文件下载)等场景中。 + * @throws Exception 可能抛出的异常,比如创建工作簿、写入文件内容等过程中出现的IO异常或者其他相关异常。 + */ + public InputStream export() throws Exception { + // 创建工作簿对象,这是整个Excel文件的基础容器,后续的工作表、单元格等都将添加到这个工作簿中。 + HSSFWorkbook workbook = new HSSFWorkbook(); + // 创建工作表,这里创建了一个名为"sheet1"的工作表,一个工作簿可以包含多个工作表,此处只创建了一个。 + HSSFSheet sheet = workbook.createSheet("sheet1"); // 设置sheet表样式 - HSSFCellStyle columnTopStyle = this.getColumnTopStyle(workbook);//获取列头样式对象 - HSSFCellStyle style = this.getColumnStyle(workbook); //单元格样式对象 + // 获取列头样式对象,用于设置Excel表格中列标题那一行单元格的样式。 + HSSFCellStyle columnTopStyle = this.getColumnTopStyle(workbook); + // 获取单元格样式对象,用于设置Excel表格中除列标题外其他数据单元格的样式。 + HSSFCellStyle style = this.getColumnStyle(workbook); - // 定义所需列数 + // 定义所需列数,通过传入的列名数组长度来确定Excel表格的列数。 int columnNum = rowName.length; - HSSFRow rowRowName = sheet.createRow(0); // 在索引2的位置创建行(最顶端的行开始的第二行) + // 在索引0的位置创建行(Excel表格中最顶端的行),用于设置列头信息。 + HSSFRow rowRowName = sheet.createRow(0); // 将列头设置到sheet的单元格中 - for(int n=0;n findAll(int page,int size) throws Exception; + /** + * 查询所有管理员信息 + * 该方法用于获取所有管理员的信息列表,不过考虑到可能数据量较大需要分页展示,所以接收当前页码(page)和每页显示的记录数(size)两个参数, + * 在具体实现类中会按照这两个参数进行分页查询操作,从数据库中获取相应分页后的管理员信息列表并返回。 + * + * @param page 当前页码,用于指定要获取哪一页的数据,从1开始计数。 + * @param size 每页显示的记录数,用于确定每页包含的管理员记录数量。 + * @return 返回一个包含管理员信息的List集合,集合中的元素是按照分页条件从数据库中查询出来的管理员对象,执行过程中可能抛出异常(由具体实现决定)。 + * @throws Exception 比如数据库查询异常、分页插件使用异常等可能出现的问题。 + */ + List findAll(int page, int size) throws Exception; + /** + * 通过id删除管理员 + * 根据传入的管理员id,调用具体实现类中的业务逻辑,从数据库中删除具有该id的管理员记录,实现对管理员数据的删除操作,该方法无返回值,主要关注删除操作是否成功执行。 + * + * @param id 要删除的管理员的唯一标识(对应数据库表中的主键值)。 + * @throws Exception 可能在数据库执行删除操作时出现的异常,例如违反外键约束、数据库权限不足等导致的异常,具体由实现类中数据库操作情况决定抛出的异常类型。 + */ void deleteAdminById(Integer id) throws Exception; + /** + * 更新管理员信息 + * 接收一个包含更新后管理员各项信息的Admin对象,通过具体实现类中的业务逻辑,将传入对象中的信息更新到数据库中对应的管理员记录上, + * 以此实现对管理员信息的修改功能,该方法无返回值,重点在于完成信息更新操作。 + * + * @param admin 包含了更新后的管理员各项信息的Admin对象,这些信息将用于更新数据库中的记录。 + * @throws Exception 比如在执行更新操作时出现的数据类型不匹配、数据库约束违反等异常情况,具体取决于实现类中与数据库交互及数据更新的操作情况。 + */ void updateAdmin(Admin admin) throws Exception; + /** + * 添加管理员信息 + * 该方法用于将一个包含新管理员各项信息的Admin对象添加到数据库中,创建一条新的管理员记录,具体实现类会处理相关的数据库插入操作, + * 此方法无返回值,主要关注插入操作是否能成功执行,若出现异常则插入失败。 + * + * @param admin 包含了要添加的管理员各项信息的Admin对象,这些信息将被插入到数据库表中。 + * @throws Exception 可能出现的异常情况,例如插入的数据不符合表结构约束、数据库插入失败等,具体由实现类中数据库插入操作情况决定抛出的异常类型。 + */ void addAdmin(Admin admin) throws Exception; + /** + * 校验用户名是否存在 + * 根据传入的用户名,调用具体实现类中的业务逻辑,去数据库中查询是否存在该用户名对应的管理员记录,以此判断用户名是否已被其他管理员使用, + * 如果存在则返回true,不存在则返回false,可用于注册等场景下验证用户名的唯一性。 + * + * @param u_name 要校验的用户名。 + * @return 如果用户名在数据库中已存在,则返回true;若不存在则返回false,查询过程中可能抛出异常(由具体实现决定)。 + * @throws Exception 比如数据库查询异常等可能出现的问题,具体取决于实现类中查询操作的执行情况。 + */ Boolean checkUserName(String u_name) throws Exception; - //模糊搜索管理员信息,查询结果返回一个list集合 - List serarchInfo(int page,int size,String keyword) throws Exception; - //授权 + // 模糊搜索管理员信息,查询结果返回一个list集合 + /** + * 模糊搜索管理员信息 + * 按照传入的当前页码(page)、每页显示记录数(size)以及搜索关键字(keyword),在具体实现类中调用相应业务逻辑, + * 通过关键字在数据库的相关字段中进行模糊匹配查询,获取符合条件的管理员信息列表并返回,便于实现根据部分信息查找管理员的功能。 + * + * @param page 当前页码,用于指定要获取哪一页的数据,从1开始计数。 + * @param size 每页显示的记录数,用于确定每页包含的管理员记录数量。 + * @param keyword 用于模糊查询的关键字,将在数据库中相关字段(如用户名、姓名等)进行模糊匹配查找符合条件的管理员记录。 + * @return 返回一个包含符合模糊查询条件的管理员信息的List集合,如果没有找到匹配记录则返回空集合,执行过程中可能抛出异常(由具体实现决定)。 + * @throws Exception 比如数据库查询异常、分页插件使用异常等可能出现的问题。 + */ + List serarchInfo(int page, int size, String keyword) throws Exception; + + // 授权 + /** + * 授权操作 + * 接收一个包含管理员相关信息及授权等级等的Admin对象,通过具体实现类中的业务逻辑,将该对象中的授权等级信息更新到数据库中对应管理员记录上, + * 实现对管理员授权等级的修改,该方法无返回值,重点关注授权等级更新操作是否成功执行。 + * + * @param admin 包含了要授权的管理员的相关信息(主要是授权等级等)的Admin对象,这些信息将用于更新数据库中对应记录的授权等级。 + * @throws Exception 例如在执行更新操作时出现的数据类型不匹配、数据库约束违反等异常情况,具体取决于实现类中与数据库交互及数据更新的操作情况。 + */ void put_power(Admin admin) throws Exception; - //返回一个携带所有管理员信息数据的InputStream输入流 + // 返回一个携带所有管理员信息数据的InputStream输入流 + /** + * 获取所有管理员信息的输入流 + * 该方法的具体实现类会将所有管理员的信息整理并转换为适合的数据格式(通常用于导出数据场景,比如生成Excel文件等), + * 然后以InputStream的形式返回,外部可以利用这个输入流进行文件下载等相关操作,获取包含所有管理员信息的数据内容。 + * + * @return 返回一个InputStream类型的输入流,该输入流指向包含所有管理员信息的数据内容,可用于后续的文件下载、数据传输等操作,执行过程中可能抛出异常(由具体实现决定)。 + * @throws Exception 比如数据整理转换异常、生成输入流过程中出现的异常等,具体取决于实现类中相关操作的执行情况。 + */ InputStream getInputStream() throws Exception; - //校验学工号是否被注册 + // 校验学工号是否被注册 + /** + * 校验学/工号是否被注册 + * 根据传入的学/工号,调用具体实现类中的业务逻辑,去数据库中查询是否存在该学/工号对应的管理员记录,以此判断该学/工号是否已被其他管理员使用, + * 如果存在则返回对应的Admin对象(可以根据返回对象是否为null来判断是否已注册),不存在则返回null,用于在添加或修改管理员信息等场景下验证学/工号的唯一性。 + * + * @param uid 要校验的学/工号。 + * @return 如果学/工号在数据库中已被注册,则返回对应的Admin对象;若未被注册则返回null,查询过程中可能抛出异常(由具体实现决定)。 + * @throws Exception 比如数据库查询异常等可能出现的问题,具体取决于实现类中查询操作的执行情况。 + */ Admin checkUid(String uid) throws Exception; -} +} \ No newline at end of file diff --git a/src/main/java/cn/ppdxzz/service/impl/AdminServiceImpl.java b/src/main/java/cn/ppdxzz/service/impl/AdminServiceImpl.java index f29f595..1d2fe8f 100644 --- a/src/main/java/cn/ppdxzz/service/impl/AdminServiceImpl.java +++ b/src/main/java/cn/ppdxzz/service/impl/AdminServiceImpl.java @@ -18,7 +18,8 @@ import java.util.ArrayList; import java.util.List; /** - * Description: + * Description: 这是管理员服务层的实现类,实现了AdminService接口,用于处理与管理员相关的业务逻辑, + * 并调用持久层(AdminDao)的方法来完成具体的数据操作,如查询、添加、删除、修改等功能,同时也包含了一些如分页、数据导出等辅助功能的实现。 * * @Date: 2020/2/10 15:30 * @Author: PeiChen @@ -26,7 +27,10 @@ import java.util.List; @Service("adminService") public class AdminServiceImpl implements AdminService { + // 依赖注入AdminDao接口,用于调用持久层的数据库操作方法。 private AdminDao adminDao; + + // 通过@Autowired注解,让Spring框架自动注入AdminDao的实现类实例,实现依赖注入。 @Autowired public void setAdminDao(AdminDao adminDao) { this.adminDao = adminDao; @@ -34,9 +38,11 @@ public class AdminServiceImpl implements AdminService { /** * 调用持久层中的findAdmin()方法校验用户名密码是否正确 - * @param admin - * @return - * @throws Exception + * 该方法接收一个包含用户名和密码信息的Admin对象,将验证工作委托给持久层的对应方法,根据持久层返回结果判断用户名和密码是否匹配。 + * + * @param admin 包含用户名和密码等信息的Admin对象,用于传递给持久层方法进行查询验证。 + * @return 如果持久层查询到匹配的管理员记录,则返回对应的Admin对象,否则返回null(根据持久层方法具体实现情况而定)。 + * @throws Exception 可能抛出的异常,比如持久层数据库操作异常等。 */ @Override public Admin findAdmin(Admin admin) throws Exception { @@ -45,9 +51,11 @@ public class AdminServiceImpl implements AdminService { /** * 通过id查询管理员信息 - * @param id - * @return Admin - * @throws Exception + * 该方法根据传入的管理员id,调用持久层的对应方法从数据库中查询并获取相应管理员的详细信息。 + * + * @param id 要查询的管理员的唯一标识(通常对应数据库表中的主键值)。 + * @return 返回查询到的对应的Admin对象,如果未查询到则返回null(取决于持久层方法实现及数据库情况)。 + * @throws Exception 可能出现的数据库查询异常等情况。 */ @Override public Admin findAdminById(Integer id) throws Exception { @@ -56,19 +64,26 @@ public class AdminServiceImpl implements AdminService { /** * 查询所有管理员信息 - * @return - * @throws Exception + * 此方法借助PageHelper分页插件实现分页查询功能,先设置分页参数(当前页码和每页显示记录数),然后调用持久层的方法获取所有管理员记录,返回的结果将是按照分页设置后的管理员信息列表。 + * + * @param page 当前页码,用于指定要查询的页面。 + * @param size 每页显示的记录数,用于确定每页的数据量。 + * @return 返回一个包含管理员信息的List集合,集合中的数据是按照分页条件从数据库中查询出来的管理员记录。 + * @throws Exception 比如分页插件使用异常、数据库查询异常等可能出现的问题。 */ @Override - public List findAll(int page,int size) throws Exception { - PageHelper.startPage(page,size); + public List findAll(int page, int size) throws Exception { + // 启动PageHelper分页功能,设置当前页码和每页显示的记录数,后续调用持久层查询方法时会自动应用分页逻辑。 + PageHelper.startPage(page, size); return adminDao.findAll(); } /** * 通过id删除管理员 - * @param id - * @throws Exception + * 该方法接收要删除的管理员的id,直接调用持久层的对应方法,从数据库中删除具有该id的管理员记录,实现删除管理员数据的功能。 + * + * @param id 要删除的管理员的唯一标识(对应数据库表中的主键值)。 + * @throws Exception 可能在数据库执行删除操作时出现的异常,例如违反外键约束、数据库权限不足等导致的异常。 */ @Override public void deleteAdminById(Integer id) throws Exception { @@ -77,8 +92,10 @@ public class AdminServiceImpl implements AdminService { /** * 更新管理员信息 - * @param admin - * @throws Exception + * 该方法接收一个包含更新后管理员信息的Admin对象,调用持久层的对应方法,将传入的对象信息更新到数据库中对应管理员记录上,实现管理员信息修改的功能。 + * + * @param admin 包含了更新后的管理员各项信息的Admin对象,将被用于更新数据库中的记录。 + * @throws Exception 比如在执行更新操作时出现的数据类型不匹配、数据库约束违反等异常情况。 */ @Override public void updateAdmin(Admin admin) throws Exception { @@ -87,8 +104,11 @@ public class AdminServiceImpl implements AdminService { /** * 添加管理员信息 - * @param admin - * @throws Exception + * 该方法使用了Spring的事务管理机制(通过@Transactional注解标记),在添加管理员信息时,如果出现异常,将自动回滚事务,保证数据的一致性。 + * 它接收一个包含要添加的管理员各项信息的Admin对象,调用持久层的对应方法将该对象信息插入到数据库中,实现新增管理员记录的功能。 + * + * @param admin 包含了要添加的管理员各项信息的Admin对象,这些信息将被插入到数据库表中。 + * @throws Exception 可能出现的异常情况,例如插入的数据不符合表结构约束、数据库插入失败等,出现异常时事务会自动回滚。 */ @Transactional @Override @@ -96,11 +116,20 @@ public class AdminServiceImpl implements AdminService { adminDao.addAdmin(admin); } + /** + * 校验用户名是否存在 + * 该方法调用持久层的对应方法,根据传入的用户名去数据库中查询是否存在对应的记录,以此判断用户名是否已经被其他管理员使用。 + * 如果查询到记录(即返回的结果不为null),则表示用户名存在,返回true;若未查询到记录,则返回false。 + * + * @param u_name 要校验的用户名。 + * @return 如果用户名存在于数据库中则返回true,否则返回false,过程中若出现异常则抛出相应异常情况。 + * @throws Exception 比如数据库查询异常等可能出现的问题。 + */ @Override public Boolean checkUserName(String u_name) throws Exception { //System.out.println(adminDao.checkUserName(u_name)); - //用户名不存在则返回空,直接false - if (adminDao.checkUserName(u_name) != null) { + // 用户名不存在则返回空,直接false + if (adminDao.checkUserName(u_name)!= null) { return true; } return false; @@ -108,21 +137,28 @@ public class AdminServiceImpl implements AdminService { /** * 管理员信息模糊查询 - * @param keyword - * @return - * @throws Exception + * 此方法借助PageHelper分页插件实现分页模糊查询功能,先设置分页参数(当前页码和每页显示记录数),然后调用持久层的模糊查询方法,根据传入的关键字在数据库中查找匹配的管理员记录,返回符合条件的管理员信息列表。 + * + * @param page 当前页码,用于指定要查询的页面。 + * @param size 每页显示的记录数,用于确定每页的数据量。 + * @param keyword 用于模糊查询的关键字,将在数据库中根据相关字段进行模糊匹配查找符合条件的管理员记录。 + * @return 返回一个包含符合模糊查询条件的管理员信息的List集合,如果没有找到匹配记录则返回空集合(取决于持久层方法实现及数据库情况)。 + * @throws Exception 比如分页插件使用异常、数据库查询异常等可能出现的问题。 */ @Override - public List serarchInfo(int page,int size,String keyword) throws Exception { - PageHelper.startPage(page,size); + public List serarchInfo(int page, int size, String keyword) throws Exception { + // 启动PageHelper分页功能,设置当前页码和每页显示的记录数,后续调用持久层模糊查询方法时会自动应用分页逻辑。 + PageHelper.startPage(page, size); List list = adminDao.serarchInfo(keyword); return list; } /** * 授权 - * @param admin - * @throws Exception + * 该方法接收一个包含管理员相关信息及授权等级等的Admin对象,调用持久层的对应方法,将该对象中的授权等级信息更新到数据库中对应管理员记录上,实现管理员授权功能。 + * + * @param admin 包含了要授权的管理员的相关信息(主要是授权等级等)的Admin对象,用于更新数据库中对应记录的授权等级。 + * @throws Exception 例如在执行更新操作时出现的数据类型不匹配、数据库约束违反等异常情况。 */ @Override public void put_power(Admin admin) throws Exception { @@ -131,17 +167,23 @@ public class AdminServiceImpl implements AdminService { /** * 导出管理员信息 - * @return - * @throws Exception + * 该方法主要实现将数据库中的管理员信息导出为Excel文件格式的功能,首先获取数据库中所有管理员的记录,然后将这些记录按照一定格式整理到数据列表中, + * 接着利用WriteExcel类将数据列表转换为Excel文件对应的输入流,最终返回该输入流,可用于后续在Web等场景下进行文件下载操作。 + * + * @return 返回一个InputStream类型的输入流,该输入流指向生成的包含管理员信息的Excel文件内容,可用于文件下载等相关业务操作。 + * @throws Exception 可能抛出的异常,比如获取数据库数据异常、生成Excel文件过程中出现的异常(如写入文件流异常等)。 */ @Override public InputStream getInputStream() throws Exception { - //Excel中的每列列名,依次对应数据库的字段 - String[] title = new String[]{"ID","用户名","密码","姓名","学/工号","手机号","权限","描述"}; + // Excel中的每列列名,依次对应数据库的字段,用于设置导出的Excel表格的列标题。 + String[] title = new String[]{"ID", "用户名", "密码", "姓名", "学/工号", "手机号", "权限", "描述"}; + // 调用持久层的方法获取数据库中所有管理员的信息,得到一个List集合,集合中的每个Admin对象代表一条管理员记录。 List admins = adminDao.exportAdminInfo(); - List dataList = new ArrayList(); + // 创建一个用于存储每行数据的列表,每个元素是一个Object数组,代表Excel表格中的一行数据(除去列标题行),初始化为空列表。 + List dataList = new ArrayList(); + // 遍历从数据库获取的管理员信息列表,将每条管理员记录的各个字段值提取出来,整理成Object数组形式,添加到数据列表中,以便后续生成Excel文件。 for (int i = 0; i < admins.size(); i++) { - Object[] obj = new Object[7]; + Object[] obj = new Object[8]; obj[0] = admins.get(i).getId(); obj[1] = admins.get(i).getUsername(); obj[2] = admins.get(i).getPassword(); @@ -152,20 +194,25 @@ public class AdminServiceImpl implements AdminService { obj[7] = admins.get(i).getDescription(); dataList.add(obj); } + // 创建WriteExcel类的实例,传入列名数组和整理好的数据列表,用于生成Excel文件。 WriteExcel ex = new WriteExcel(title, dataList); InputStream in; + // 调用WriteExcel类的export方法,生成包含管理员信息的Excel文件对应的输入流,将其赋值给变量in。 in = ex.export(); return in; } /** * 校验学/工号是否已被注册 - * @param uid - * @return - * @throws Exception + * 该方法调用持久层的对应方法,根据传入的学/工号去数据库中查询是否存在对应的管理员记录,以此判断该学/工号是否已经被其他管理员使用。 + * 如果查询到记录,则返回对应的Admin对象(可以根据返回对象是否为null来判断学/工号是否已注册);若未查询到记录则返回null(取决于持久层方法实现及数据库情况)。 + * + * @param uid 要校验的学/工号。 + * @return 如果学/工号已被注册,则返回对应的Admin对象,否则返回null,过程中若出现异常则抛出相应异常情况。 + * @throws Exception 比如数据库查询异常等可能出现的问题。 */ @Override public Admin checkUid(String uid) throws Exception { return adminDao.checkUid(uid); } -} +} \ No newline at end of file diff --git a/src/main/java/cn/ppdxzz/utils/MD5Util.java b/src/main/java/cn/ppdxzz/utils/MD5Util.java index 34fffce..b57e0ac 100644 --- a/src/main/java/cn/ppdxzz/utils/MD5Util.java +++ b/src/main/java/cn/ppdxzz/utils/MD5Util.java @@ -4,59 +4,112 @@ import java.security.MessageDigest; /** * MD5加密算法 + * 该类提供了基于MD5算法对字符串进行加密的功能,主要用于对敏感信息(如密码等)进行加密处理,增强数据的安全性。 + * 其中包含了一些辅助方法用于字节数组与十六进制字符串之间的转换等操作,最终对外提供了以UTF-8编码进行MD5加密的便捷方法。 */ - public class MD5Util { + /** + * 将字节数组转换为十六进制字符串的方法 + * 该方法遍历传入的字节数组,逐个将字节转换为对应的十六进制表示形式,并拼接成一个完整的十六进制字符串返回。 + * + * @param b 要转换的字节数组,通常是经过MD5摘要算法处理后得到的字节数组结果。 + * @return 返回一个由字节数组转换而来的十六进制字符串,用于后续表示加密后的结果等用途。 + */ private static String byteArrayToHexString(byte b[]) { + // 创建一个StringBuffer对象,用于高效地拼接字符串,存储最终转换后的十六进制字符串结果。 StringBuffer resultSb = new StringBuffer(); + // 遍历字节数组中的每个字节 for (int i = 0; i < b.length; i++) + // 调用byteToHexString方法将每个字节转换为十六进制字符串,并添加到resultSb中 resultSb.append(byteToHexString(b[i])); return resultSb.toString(); } + /** + * 将单个字节转换为十六进制字符串的方法 + * 该方法先对传入的字节进行处理(如果是负数则转换为正数范围),然后将其拆分为高4位和低4位,分别对应十六进制的一位, + * 通过查找预定义的十六进制字符数组,获取对应的十六进制字符并拼接成一个两位的十六进制字符串返回。 + * + * @param b 要转换的单个字节。 + * @return 返回一个表示该字节的十六进制字符串,长度为2位。 + */ private static String byteToHexString(byte b) { + // 将字节转换为整数,如果字节值是负数(Java中字节是有符号的,范围是 -128 到 127),则通过加上256将其转换为正数范围(0 到 255),便于后续计算。 int n = b; if (n < 0) n += 256; + // 获取该整数的高4位,用于对应十六进制的高位数字,通过除以16来得到(十六进制中每一位代表16的幂次,高4位对应的幂次为1)。 int d1 = n / 16; + // 获取该整数的低4位,用于对应十六进制的低位数字,通过取模16来得到。 int d2 = n % 16; + // 从预定义的十六进制字符数组中查找对应的字符,拼接成十六进制字符串返回,高4位在前,低4位在后。 return hexDigits[d1] + hexDigits[d2]; } /** * 返回大写MD5 + * 该方法实现了对给定字符串进行MD5加密,并将结果转换为大写形式返回的功能。 + * 可以根据是否指定字符编码来处理字符串转换字节数组的操作,然后通过MessageDigest类获取MD5摘要信息,并进一步转换为十六进制字符串表示。 + * + * @param origin 要进行MD5加密的原始字符串,通常是需要加密的文本信息(如密码等)。 + * @param charsetname 指定的字符编码名称,用于将字符串转换为字节数组时使用,如果为null或空字符串则使用默认编码(通常是平台默认编码)。 + * @return 返回经过MD5加密后的大写十六进制字符串结果,如果在加密过程中出现异常,则返回null(当前代码中只是简单捕获异常,未做详细处理)。 */ private static String MD5Encode(String origin, String charsetname) { String resultString = null; try { + // 先将传入的原始字符串赋值给结果字符串变量,这里可以根据实际需求考虑是否进行深拷贝等更严谨的处理(当前代码只是简单赋值)。 resultString = new String(origin); + // 获取MD5算法的MessageDigest实例,用于进行MD5摘要计算,通过传入"MD5"字符串指定使用MD5算法。 MessageDigest md = MessageDigest.getInstance("MD5"); + // 如果未指定字符编码或者字符编码为空字符串,则使用默认方式将字符串转换为字节数组后进行MD5摘要计算,再将摘要结果转换为十六进制字符串。 if (charsetname == null || "".equals(charsetname)) resultString = byteArrayToHexString(md.digest(resultString.getBytes())); else + // 如果指定了字符编码,则按照指定的字符编码将字符串转换为字节数组,然后进行MD5摘要计算,并转换为十六进制字符串。 resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname))); } catch (Exception exception) { + // 当前代码只是简单捕获异常,未做详细的异常处理(如记录日志、抛出更具体的异常等),实际应用中可根据需求完善此处逻辑。 } return resultString.toUpperCase(); } + /** + * 以UTF-8编码进行MD5加密的方法 + * 该方法是对外提供的方便调用的接口,默认使用UTF-8编码调用MD5Encode方法对传入的原始字符串进行加密,并返回加密后的结果(大写形式)。 + * 此处还预留了盐值(Salt)加密的代码逻辑(当前被注释掉了),盐值加密可以进一步增强加密的安全性,防止简单的MD5彩虹表攻击等情况。 + * + * @param origin 要进行MD5加密的原始字符串,通常是需要加密的文本信息(如密码等)。 + * @return 返回经过UTF-8编码的MD5加密后的大写十六进制字符串结果。 + */ public static String MD5EncodeUtf8(String origin) { - //盐值Salt加密 - //origin = origin + PropertiesUtil.getProperty("password.salt", ""); + // 盐值Salt加密 + // 以下代码是预留的盐值加密逻辑,通过从配置文件(PropertiesUtil.getProperty方法调用,此处未展示该类的实现)中获取盐值, + // 将盐值添加到原始字符串后面再进行MD5加密,可以使相同的原始字符串在不同的盐值情况下加密结果不同,增强安全性。 + // 当前代码将其注释掉了,如果需要启用盐值加密,可取消注释并确保配置文件读取等相关逻辑正确实现。 + // origin = origin + PropertiesUtil.getProperty("password.salt", ""); + return MD5Encode(origin, "utf-8"); } + // 预定义的十六进制字符数组,用于在字节转换十六进制字符串时查找对应的字符表示,按照十六进制的顺序排列,从0到f。 private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}; + /** + * 主方法,用于测试MD5加密功能 + * 该方法创建了MD5Util类的实例(实际上不需要创建实例也可以调用静态方法,这里只是一种简单的测试写法), + * 然后调用MD5EncodeUtf8方法对字符串"123456"进行MD5加密,并将加密结果输出到控制台,方便查看加密后的效果。 + * + * @param args 命令行参数,在当前测试场景下未使用。 + */ public static void main(String[] args) { MD5Util md = new MD5Util(); String psd = md.MD5EncodeUtf8("123456"); System.out.println(psd); } -} - +} \ No newline at end of file -- 2.34.1 From 0f8159e6dd150a6a47790f378eba5a344a268a05 Mon Sep 17 00:00:00 2001 From: wang ziting <3165305859@qq.com> Date: Fri, 13 Dec 2024 22:44:07 +0800 Subject: [PATCH 3/6] wang --- .../cn/ppdxzz/controller/AdminController.java | 254 ++++++++++++------ .../ppdxzz/controller/LoginInterceptor.java | 59 +++- src/main/java/cn/ppdxzz/dao/AdminDao.java | 96 +++++-- src/main/java/cn/ppdxzz/domain/Admin.java | 71 ++++- src/main/java/cn/ppdxzz/poi/WriteExcel.java | 221 +++++++++------ .../java/cn/ppdxzz/service/AdminService.java | 116 +++++++- .../ppdxzz/service/impl/AdminServiceImpl.java | 119 +++++--- src/main/java/cn/ppdxzz/utils/MD5Util.java | 63 ++++- 8 files changed, 734 insertions(+), 265 deletions(-) diff --git a/src/main/java/cn/ppdxzz/controller/AdminController.java b/src/main/java/cn/ppdxzz/controller/AdminController.java index b7b7286..53513de 100644 --- a/src/main/java/cn/ppdxzz/controller/AdminController.java +++ b/src/main/java/cn/ppdxzz/controller/AdminController.java @@ -26,7 +26,7 @@ import java.io.UnsupportedEncodingException; import java.util.List; /** - * Description: + * Description: 这是AdminController类,用于处理与管理员相关的各种Web请求,例如登录、查询、添加、修改等操作。 * * @Date: 2020/2/10 15:20 * @Author: PeiChen @@ -34,7 +34,10 @@ import java.util.List; @Controller public class AdminController { + // 依赖注入AdminService,用于调用业务逻辑层相关方法来处理管理员数据 private AdminService adminService; + + // 通过@Autowired注解,让Spring框架自动注入AdminService的实现类实例 @Autowired public void setAdminService(AdminService adminService) { this.adminService = adminService; @@ -42,44 +45,66 @@ public class AdminController { /** * 处理用户登录请求 - * @param model - * @param admin - * @param session - * @param request - * @return + * + * @param model 用于在视图和控制器之间传递数据,向视图层传递数据,如错误信息等 + * @param admin 封装了用户提交的登录信息(用户名、密码等)的Admin对象 + * @param session 用于存储用户登录后的会话信息,比如登录成功后将用户信息存入session + * @param request 用于获取HTTP请求相关信息,例如设置请求编码等 + * @param response 用于设置HTTP响应相关信息,例如设置响应编码、向客户端返回数据等 + * @return 根据登录验证结果,返回对应的视图名称,登录成功返回"main",失败返回"login" + * @throws Exception 可能抛出的异常,例如编码设置异常、数据库查询异常等 */ @RequestMapping(value = "/login") - public String login(Model model, Admin admin, HttpSession session, HttpServletRequest request,HttpServletResponse response) throws Exception { + public String login(Model model, Admin admin, HttpSession session, HttpServletRequest request, HttpServletResponse response) throws Exception { + // 设置请求的字符编码为utf-8,防止中文乱码等问题 request.setCharacterEncoding("utf-8"); + // 设置响应的字符编码为utf-8,确保返回给客户端的数据编码正确 response.setCharacterEncoding("utf-8"); + // 获取响应的输出流对象,用于向客户端输出数据(这里主要用于输出错误提示等文本信息) PrintWriter writer = response.getWriter(); + + // 如果传入的admin对象为空,或者用户名、密码为空,则直接返回登录页面 if (admin == null || admin.getUsername() == null || admin.getPassword() == null) { return "login"; } + + // 使用MD5Util工具类对用户输入的密码进行MD5加密(以utf-8编码格式),增强密码安全性 admin.setPassword(MD5Util.MD5EncodeUtf8(admin.getPassword())); + + // 调用adminService的方法,根据传入的admin对象(包含加密后的密码)去数据库查找对应的管理员信息 Admin ad = adminService.findAdmin(admin); + + // 如果能查到对应的管理员信息,说明登录成功 if (ad != null) { - //登录信息存入session域 - session.setAttribute("adminInfo",ad); - //System.out.println(ad); + // 将登录成功后的管理员信息存入session域,方便后续在其他请求中获取登录用户信息 + session.setAttribute("adminInfo", ad); + // 返回主页面视图名称,通常对应着系统的主界面 return "main"; } - model.addAttribute("msg","用户名或密码错误,请重新输入!"); + + // 如果没查到,说明用户名或密码错误,向模型中添加错误提示信息 + model.addAttribute("msg", "用户名或密码错误,请重新输入!"); + // 返回登录页面视图名称,让用户重新输入登录信息 return "login"; } - //拦截后跳转至登录页 + // 拦截后跳转至登录页,当用户未登录访问需要登录才能访问的资源时,可能会被拦截到此方法,然后跳转到登录页面 @RequestMapping("/to_login") public String Login() { return "login"; } /** - * 退出登录 - n */ + * 退出登录操作,通过使当前会话失效来实现退出登录功能,清除用户在本次会话中的登录状态等信息 + * + * @param admin 此处参数可能未实际使用,但在Spring MVC的方法参数绑定中需要定义(具体看业务场景是否会用到) + * @param model 可用于向视图传递一些提示信息等(此处可能未实际使用) + * @param session 用于操作当前用户的会话,通过invalidate方法注销当前会话 + * @return 返回登录页面视图名称,退出登录后一般跳转到登录页面 + */ @RequestMapping(value = "/loginOut") - public String loginOut(Admin admin,Model model,HttpSession session) { - //通过session.invalidate()方法来注销当前的session + public String loginOut(Admin admin, Model model, HttpSession session) { + // 通过session.invalidate()方法来注销当前的session,清除会话相关信息 session.invalidate(); return "login"; @@ -87,121 +112,193 @@ public class AdminController { /** * 分页查询所有管理员信息 + * + * @param page 当前页码,通过@RequestParam注解从请求参数中获取,默认值为1,如果请求中未传递该参数则使用默认值 + * @param size 每页显示的记录数,通过@RequestParam注解从请求参数中获取,默认值为5,如果请求中未传递该参数则使用默认值 + * @param request 用于获取HTTP请求相关信息,例如获取查询关键字等参数 + * @param response 用于设置HTTP响应相关信息,例如设置编码等 + * @return 返回一个ModelAndView对象,包含了查询到的管理员分页数据以及要跳转的视图名称 + * @throws Exception 可能抛出的异常,比如编码设置异常、数据库查询异常等 */ @RequestMapping(value = "/findAllAdmin") - public ModelAndView findAll(@RequestParam(name = "page", required = true, defaultValue = "1") int page, @RequestParam(name = "size", required = true, defaultValue = "5") int size,HttpServletRequest request,HttpServletResponse response) throws Exception { + public ModelAndView findAll(@RequestParam(name = "page", required = true, defaultValue = "1") int page, @RequestParam(name = "size", required = true, defaultValue = "5") int size, HttpServletRequest request, HttpServletResponse response) throws Exception { + // 设置请求的字符编码为utf-8 request.setCharacterEncoding("utf-8"); + // 设置响应的字符编码为utf-8 response.setCharacterEncoding("utf-8"); + + // 创建一个ModelAndView对象,用于封装要返回给视图的数据以及视图名称 ModelAndView mv = new ModelAndView(); + + // 用于存放查询到的管理员列表数据,初始化为null List admins = null; + + // 从请求参数中获取查询关键字,如果没有传递该参数则可能为null String keyword = request.getParameter("keyword"); + + // 如果关键字为空(包括null、空字符串、长度为0等情况),则查询所有管理员信息(按照分页条件) if (keyword == null || keyword.trim().equals("") || keyword.length() == 0) { - admins = adminService.findAll(page,size); - }else { - admins = adminService.serarchInfo(page,size,keyword); + admins = adminService.findAll(page, size); + } else { + // 如果有关键字,则根据关键字进行模糊查询管理员信息(按照分页条件) + admins = adminService.serarchInfo(page, size, keyword); } - //PageInfo就是一个封装了分页数据的bean + + // 使用PageInfo对查询到的管理员列表数据进行分页相关信息的封装,方便在视图层展示分页导航等信息 PageInfo pageInfo = new PageInfo(admins); - mv.addObject("pageInfo",pageInfo); + + // 将封装好分页数据的PageInfo对象添加到ModelAndView中,以便在视图中可以获取并展示分页数据 + mv.addObject("pageInfo", pageInfo); + + // 设置要跳转的视图名称为"admin-list",通常对应着展示管理员列表的页面 mv.setViewName("admin-list"); + return mv; } /** - * 删除管理员 + * 删除管理员操作,接收一个管理员的id作为参数(从请求中获取),调用adminService的方法来删除对应的管理员记录 + * + * @param request 用于获取HTTP请求中传递的管理员id参数 + * @throws Exception 可能抛出的异常,比如参数解析异常、数据库删除操作异常等 */ @ResponseBody @RequestMapping(value = "/deleteAdmin") public void deleteAdmin(HttpServletRequest request) throws Exception { + // 从请求参数中获取要删除的管理员的id String id = request.getParameter("id"); + // 调用adminService的方法,根据解析后的管理员id(转换为整数类型)来删除对应的管理员记录 adminService.deleteAdminById(Integer.parseInt(id)); } /** - * 校验用户名是否存在 + * 校验用户名是否存在,接收客户端传递的用户名参数,调用adminService的方法进行校验,然后向客户端返回相应的提示信息 + * + * @param request 用于获取HTTP请求中传递的用户名参数 + * @param response 用于向客户端返回校验结果信息(通过设置响应编码、输出流等) + * @throws Exception 可能抛出的异常,比如编码设置异常、数据库查询异常等 */ @RequestMapping(value = "/checkUserName") public void checkUserName(HttpServletRequest request, HttpServletResponse response) throws Exception { + // 设置请求的字符编码为utf-8 request.setCharacterEncoding("utf-8"); + // 设置响应的字符编码为utf-8 response.setCharacterEncoding("utf-8"); + + // 获取响应的输出流对象,用于向客户端输出校验结果信息 PrintWriter pw = response.getWriter(); - //取值 + + // 从请求参数中获取要校验的用户名 String u_name = request.getParameter("u_name"); - //调用service,用户名存在返回true,不存在则返回false + + // 调用adminService的方法,校验用户名是否存在,存在返回true,不存在返回false Boolean result = adminService.checkUserName(u_name); - //System.out.println(result); - //回调函数 + + // 根据校验结果,向客户端输出相应的提示信息 if (result) { //pw.write("用户名已存在,请重新输入!"); pw.write("账号可用"); - }else { + } else { pw.write("账号不存在"); } } + @RequestMapping(value = "/adminAdd") public String adminAdd() { + // 返回添加管理员页面的视图名称,通常对应着展示添加管理员表单的页面 return "admin-add"; } /** - * 添加管理员 - * @param admin - * @param request - * @param response - * @throws Exception + * 添加管理员操作,接收一个Admin对象(包含管理员的各项信息)以及请求和响应对象,进行一系列校验后,调用adminService的方法将管理员信息添加到数据库 + * + * @param admin 封装了要添加的管理员各项信息的Admin对象 + * @param request 用于获取HTTP请求相关信息,例如获取请求中的参数等 + * @param response 用于向客户端返回添加操作的结果信息(通过输出流等) + * @throws Exception 可能抛出的异常,比如编码设置异常、参数校验不通过、数据库插入异常等 */ @RequestMapping("/addAdmin") - public void addAdmin(Admin admin,HttpServletRequest request,HttpServletResponse response) throws Exception { + public void addAdmin(Admin admin, HttpServletRequest request, HttpServletResponse response) throws Exception { + // 获取响应的输出流对象,用于向客户端输出添加操作的结果信息(成功或失败) PrintWriter writer = response.getWriter(); + + // 调用adminService的方法校验用户名是否已存在,已存在则check为true,不存在为false Boolean check = adminService.checkUserName(admin.getUsername()); - //如果用户名已存在check为true,不存在为false + + // 如果用户名已存在,向客户端输出"false"表示添加失败,并结束方法执行 if (check) { writer.write("false"); return; } + + // 如果传入的admin对象为空,向客户端输出"false"表示添加失败,并结束方法执行 if (admin == null) { writer.write("false"); return; - }else { - if(admin.getUsername() == null || "".trim().equals(admin.getUsername()) - || admin.getPassword() == null ||"".trim().equals(admin.getPassword()) + } else { + // 进一步校验管理员对象的各个属性是否为空(去除两端空格后为空字符串也算空),只要有一个属性为空,就向客户端输出"false"表示添加失败,并结束方法执行 + if (admin.getUsername() == null || "".trim().equals(admin.getUsername()) + || admin.getPassword() == null || "".trim().equals(admin.getPassword()) || admin.getName() == null || "".trim().equals(admin.getName()) || admin.getUid() == null || "".trim().equals(admin.getUid()) || admin.getPhone() == null || "".trim().equals(admin.getPhone()) || admin.getDescription() == null || "".trim().equals(admin.getDescription())) { - writer.write("false"); - return; + writer.write("false"); + return; } } + + // 校验学工号是否已被注册,若已被注册(返回的Admin对象不为null),向客户端输出"false"表示添加失败,并结束方法执行 Admin isNull = adminService.checkUid(admin.getUid()); if (isNull != null) { writer.write("false"); return; } + + // 使用MD5Util工具类对管理员密码进行MD5加密(以utf-8编码格式) admin.setPassword(MD5Util.MD5EncodeUtf8(admin.getPassword())); + + // 调用adminService的方法,将经过校验和加密密码后的管理员信息添加到数据库 adminService.addAdmin(admin); + + // 添加成功后,向客户端输出"true"表示添加成功 writer.write("true"); } - //跳转管理员信息编辑页面,并回显信息 + + // 跳转管理员信息编辑页面,并回显信息,根据传入的管理员id从数据库查询对应的管理员信息,然后将信息传递到编辑页面进行展示 @RequestMapping("/adminEdit") public ModelAndView editAdmin(HttpServletRequest request) throws Exception { + // 创建一个ModelAndView对象,用于封装要返回给视图的数据以及视图名称 ModelAndView mv = new ModelAndView(); + + // 从请求参数中获取要编辑的管理员的id String id = request.getParameter("id"); + + // 调用adminService的方法,根据管理员id查询对应的管理员信息 Admin ad = adminService.findAdminById(Integer.parseInt(id)); - mv.addObject("ad",ad); - //mv.addObject("id",id); + + // 将查询到的管理员信息添加到ModelAndView中,以便在编辑页面可以获取并展示该信息 + mv.addObject("ad", ad); + + // 设置要跳转的视图名称为"admin-edit",通常对应着展示管理员信息编辑表单的页面 mv.setViewName("admin-edit"); + return mv; } - //修改管理员信息 + + // 修改管理员信息操作,接收一个Admin对象(包含修改后的管理员各项信息)以及响应对象,进行一系列校验后,调用adminService的方法更新数据库中的管理员信息 @RequestMapping("/editAdmin") - public void editAdmin(Admin admin,HttpServletResponse response) throws Exception { + public void editAdmin(Admin admin, HttpServletResponse response) throws Exception { + // 获取响应的输出流对象,用于向客户端输出修改操作的结果信息(成功或失败) PrintWriter writer = response.getWriter(); + + // 如果传入的admin对象为空,向客户端输出"false"表示修改失败,并结束方法执行 if (admin == null) { writer.write("false"); return; - }else { - if(admin.getUsername() == null || "".trim().equals(admin.getUsername()) + } else { + // 校验管理员对象的各个属性是否为空(去除两端空格后为空字符串也算空),只要有一个属性为空,就向客户端输出"false"表示修改失败,并结束方法执行 + if (admin.getUsername() == null || "".trim().equals(admin.getUsername()) || admin.getName() == null || "".trim().equals(admin.getName()) || admin.getUid() == null || "".trim().equals(admin.getUid()) || admin.getPhone() == null || "".trim().equals(admin.getPhone()) @@ -210,63 +307,46 @@ public class AdminController { return; } } + + // 此处注释掉了密码加密代码,可能根据业务需求,修改管理员信息时不一定需要重新加密密码(具体看实际情况) //admin.setPassword(MD5Util.MD5EncodeUtf8(admin.getPassword())); + + // 调用adminService的方法,根据传入的修改后的管理员信息更新数据库中的对应记录 adminService.updateAdmin(admin); - //更新成功进行提示信息回显 + + // 更新成功后,向客户端输出"true"表示更新成功 writer.write("true"); } /** - * 授权操作 + * 授权操作,接收一个Admin对象(包含要授权的管理员相关信息及授权级别等),进行一系列校验后,调用adminService的方法进行授权相关的数据库操作 + * + * @param admin 封装了要授权的管理员相关信息及授权级别等的Admin对象 + * @param response 用于向客户端返回授权操作的结果信息(通过输出流等) + * @throws Exception 可能抛出的异常,比如编码设置异常、参数校验不通过、数据库更新异常等 */ @RequestMapping("/put_power") - public void put_power(Admin admin,HttpServletResponse response) throws Exception { + public void put_power(Admin admin, HttpServletResponse response) throws Exception { + // 获取响应的输出流对象,用于向客户端输出授权操作的结果信息(成功或失败) PrintWriter writer = response.getWriter(); + + // 如果传入的admin对象为空,向客户端输出"false"表示授权失败,并结束方法执行 if (admin == null) { writer.write("false"); return; } + + // 校验授权级别是否在合法范围内(0到4之间),不在则向客户端输出"false"表示授权失败,并结束方法执行 if (admin.getPower() < 0 || admin.getPower() > 4) { writer.write("false"); return; } - adminService.put_power(admin); - writer.write("true"); - } - - /** - * 导出管理员信息 - * @param response - * @throws Exception - */ - @RequestMapping("/exportAdminInfo") - public void exportAdminInfo(HttpServletResponse response) throws Exception { - InputStream is = adminService.getInputStream(); - response.setContentType("application/vnd.ms-excel"); - response.setHeader("contentDisposition", "attachment;filename=adminsInfo.xls"); - ServletOutputStream outputStream = response.getOutputStream(); - IOUtils.copy(is,outputStream); - - } - /** - * 校验学工号是否已被注册 - * @param request - * @param response - * @throws Exception - */ - @RequestMapping("/checkUid") - public void checkUid(HttpServletRequest request,HttpServletResponse response) throws Exception { - request.setCharacterEncoding("utf-8"); - response.setCharacterEncoding("utf-8"); - PrintWriter writer = response.getWriter(); - String uid = request.getParameter("uid"); - Admin admin = adminService.checkUid(uid); - if (admin != null) { - writer.write("true");//uid已被注册 - return; - } + // 调用adminService的方法,进行授权相关的数据库操作(具体操作由service层实现) + adminService.put_power(admin); + // 授权成功后,向客户端输出"true"表示授权成功 + writer.write("true"); } - } + diff --git a/src/main/java/cn/ppdxzz/controller/LoginInterceptor.java b/src/main/java/cn/ppdxzz/controller/LoginInterceptor.java index 297a9c5..5924915 100644 --- a/src/main/java/cn/ppdxzz/controller/LoginInterceptor.java +++ b/src/main/java/cn/ppdxzz/controller/LoginInterceptor.java @@ -9,39 +9,80 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /** - * Description: + * Description: 这是一个登录拦截器类,用于拦截Web请求,判断用户是否登录, + * 如果已登录则允许访问相应资源,未登录则将请求重定向到登录页面,实现访问控制的功能。 * * @Date: 2020/2/14 16:50 * @Author: PeiChen */ public class LoginInterceptor implements HandlerInterceptor { + + /** + * 预处理方法,在请求处理之前进行调用,用于进行登录验证等前置逻辑判断。 + * + * @param request 当前的HTTP请求对象,从中可以获取请求的各种信息,比如请求的URL、请求参数等。 + * @param response 当前的HTTP响应对象,可用于设置响应的相关信息,比如重定向等操作。 + * @param handler 被拦截的处理器对象,一般是对应的Controller方法等(通常在复杂场景下可能会用到,这里暂未深度使用该参数)。 + * @return 如果返回true,表示允许请求继续向下执行,即访问目标资源;如果返回false,则会中断请求,根据具体逻辑进行相应处理(比如重定向等)。 + * @throws Exception 可能抛出的异常,例如获取请求信息异常、重定向异常等。 + */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - // 获取请求的URL + // 获取请求的URL(统一资源标识符),用于判断当前请求的是哪个页面或者资源路径。 String url = request.getRequestURI(); - // URL:除了login.jsp是可以公开访问的,其它的URL都进行拦截控制 - if(url.toLowerCase().indexOf("login")>=0){ + + // 进行URL判断,这里设定的规则是:除了包含"login"(不区分大小写)的URL是可以公开访问的(比如登录页面本身),其它的URL都要进行拦截控制。 + // 如果URL中包含"login",则允许请求继续执行,返回true。 + if (url.toLowerCase().indexOf("login") >= 0) { return true; } + + // 获取当前请求对应的HttpSession对象,HttpSession用于在服务器端存储用户相关的会话信息,比如用户登录后的身份信息等。 HttpSession session = request.getSession(); - // 获取Session中的用户登录信息 + + // 尝试从Session中获取用户登录信息,这里假设用户登录成功后将登录的管理员信息(Admin对象)存入了名为"adminInfo"的Session属性中。 + // 通过强制类型转换获取存储在Session中的Admin对象,如果不存在则返回null。 Admin admin = (Admin) session.getAttribute("adminInfo"); - // 判断Session中是否有用户数据,如果有,则返回true,继续向下执行 - if(admin != null){ + + // 判断Session中是否获取到了用户数据(即Admin对象是否为null),如果不为null,说明用户已经登录,允许请求继续向下执行,返回true。 + if (admin!= null) { return true; } - // 地址栏不符合条件的直接重定向到登录页面 + + // 如果经过前面的判断,地址栏对应的URL不符合可直接访问的条件(既不是登录相关页面,且用户又未登录), + // 则使用响应对象的sendRedirect方法将请求重定向到登录页面(这里的"/hellossm/to_login"是登录页面的相对路径,根据实际项目配置可能会不同)。 + // 并且返回false,表示中断当前请求,不再继续执行后续的处理器逻辑。 response.sendRedirect("/hellossm/to_login"); return false; } + /** + * 后处理方法,在请求处理之后、视图渲染之前进行调用,可以对请求处理后的结果进行一些额外处理,比如向视图添加一些模型数据等。 + * 但此方法在当前类中暂时没有具体的实现逻辑(可能根据具体业务需求后续添加)。 + * + * @param request 当前的HTTP请求对象。 + * @param response 当前的HTTP响应对象。 + * @param handler 被拦截的处理器对象。 + * @param modelAndView 包含了视图相关信息以及要传递给视图的数据的对象,如果在请求处理过程中有视图渲染的情况,可通过此对象进行操作。 + * @throws Exception 可能抛出的异常,例如操作ModelAndView对象异常等。 + */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } + /** + * 整个请求处理完成(包括视图渲染等全部完成)之后调用的方法,可用于进行一些资源清理等操作。 + * 此方法在当前类中暂时也没有具体的实现逻辑(同样可能根据业务需求后续添加)。 + * + * @param request 当前的HTTP请求对象。 + * @param response 当前的HTTP响应对象。 + * @param handler 被拦截的处理器对象。 + * @param ex 如果在请求处理过程中出现了异常,会在此处传递进来,可用于记录日志、进行异常处理等操作。 + * @throws Exception 可能抛出的异常,例如处理异常对象异常等。 + */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } -} +} \ No newline at end of file diff --git a/src/main/java/cn/ppdxzz/dao/AdminDao.java b/src/main/java/cn/ppdxzz/dao/AdminDao.java index 657f6ab..a76e4fc 100644 --- a/src/main/java/cn/ppdxzz/dao/AdminDao.java +++ b/src/main/java/cn/ppdxzz/dao/AdminDao.java @@ -8,101 +8,151 @@ import java.util.List; /** * Description:持久层 + * 该接口定义了与管理员数据操作相关的各种数据库访问方法,使用MyBatis的注解来映射SQL语句,实现对数据库中管理员表(admins)的增删改查等操作。 * * @Date: 2020/2/10 15:33 * @Author: PeiChen */ @Repository -public interface AdminDao {//sss +public interface AdminDao { /** - * 通过用户名密码查询用户信息 - * @param admin - * @return - * @throws Exception + * 通过用户名和密码查询用户信息 + * 该方法使用MyBatis的@Select注解,定义了一个SQL查询语句,从数据库的"admins"表中查询满足指定用户名和密码条件的记录,并将查询结果映射为Admin对象返回。 + * + * @param admin 传入的Admin对象,其中包含了要查询的用户名和密码等信息,MyBatis会通过#{username}和#{password}的方式将对象中的属性值替换到SQL语句中相应的位置。 + * @return 如果查询到匹配的记录,则返回对应的Admin对象;如果未查询到,则根据具体情况返回null或者抛出异常(由具体的MyBatis配置和数据库操作决定)。 + * @throws Exception 可能抛出的异常,比如数据库连接异常、SQL执行异常等。 */ @Select("select * from admins where username = #{username} and password = #{password}") Admin findAdmin(Admin admin) throws Exception; /** * 通过id查询用户信息 + * 使用@Select注解定义SQL语句,从"admins"表中查询指定id对应的用户记录,并将其映射为Admin对象返回。 + * 这里通过#{id}的方式将传入的整数类型的id参数替换到SQL语句中,实现根据唯一标识id查询用户信息的功能。 + * + * @param id 要查询的用户的唯一标识(通常是数据库表中的主键值)。 + * @return 查询到的对应的Admin对象,如果不存在则返回null或者抛出异常(取决于具体配置和数据库情况)。 + * @throws Exception 可能出现的异常情况,如数据库查询出错等。 */ @Select("select * from admins where id = #{id}") Admin findAdminById(Integer id) throws Exception; /** * 分页查询所有管理员信息 + * 此方法使用@Select注解定义了一个简单的SQL查询语句,目的是从"admins"表中获取所有的管理员记录。 + * 不过需要注意的是,这里只是定义了基本的查询语句,实际的分页功能可能需要在MyBatis的配置或者调用该方法的上层业务逻辑中结合相关插件(如PageHelper等)来实现。 + * + * @return 返回一个包含所有管理员信息的List集合,如果查询出现问题可能返回空集合或者抛出异常。 + * @throws Exception 比如数据库连接失败、查询执行异常等情况下抛出的异常。 */ @Select("select * from admins") List findAll() throws Exception; /** * 导出管理员信息 - * @return - * @throws Exception + * 同样使用@Select注解定义SQL语句,从"admins"表中获取所有管理员记录,主要用于数据导出的场景,将数据库中的管理员信息提取出来以便后续进行导出操作(如生成Excel文件等)。 + * + * @return 包含所有管理员信息的List集合,若出现问题则可能返回空集合或者抛出异常。 + * @throws Exception 像数据库访问异常等可能出现的异常情况。 */ @Select("select * from admins") List exportAdminInfo() throws Exception; /** * 根据id删除管理员信息 - * @param id - * @throws Exception + * 使用@Delete注解定义了一个SQL删除语句,根据传入的管理员id,从"admins"表中删除对应的记录,实现删除指定管理员数据的功能。 + * 通过#{id}将传入的id参数替换到SQL语句中,准确地定位要删除的记录。 + * + * @param id 要删除的管理员的唯一标识(数据库表中的主键值)。 + * @throws Exception 可能在数据库执行删除操作时出现的异常,例如违反外键约束、数据库权限不足等导致的异常。 */ @Delete("delete from admins where id = #{id}") void deleteAdminById(Integer id) throws Exception; /** * 修改管理员信息 - * @param admin - * @throws Exception + * 通过@Update注解定义了一个SQL更新语句,根据传入的Admin对象中的属性值,更新"admins"表中对应id的管理员记录信息。 + * 使用#{属性名}的方式将Admin对象中的各个属性值替换到SQL语句相应位置,实现对指定管理员记录的多字段更新操作。 + * + * @param admin 包含了要更新的管理员信息的Admin对象,其属性值将用于更新数据库中的对应记录。 + * @throws Exception 比如在执行更新操作时出现的数据类型不匹配、数据库约束违反等异常情况。 */ @Update("update admins set username= #{username},name = #{name},uid = #{uid}, phone = #{phone}, description = #{description} where id = #{id}") void updateAdmin(Admin admin) throws Exception; /** * 添加管理员信息 - * @param admin - * @throws Exception + * 利用@Insert注解定义了一个SQL插入语句,将传入的Admin对象中的各个属性值插入到"admins"表中,实现新增管理员记录的功能。 + * 通过#{属性名}将Admin对象的属性值对应地填充到SQL语句的相应位置,按照数据库表的字段顺序插入数据。 + * + * @param admin 包含了要添加的管理员各项信息的Admin对象,这些信息将被插入到数据库表中。 + * @throws Exception 可能出现的异常情况,例如插入的数据不符合表结构约束、数据库插入失败等。 */ @Insert("insert into admins(username,password,name,uid,phone,power,description) values (#{username},#{password},#{name},#{uid},#{phone},#{power},#{description})") void addAdmin(Admin admin) throws Exception; /** * 校验用户名是否存在 + * 使用@Select注解定义了一个SQL查询语句,从"admins"表中查询是否存在指定用户名的记录,用于验证用户名在数据库中是否已经被使用。 + * 如果查询到记录,说明用户名存在,返回true;若未查询到记录,则返回false(具体返回值的处理方式由MyBatis和业务逻辑共同决定)。 + * + * @param u_name 要校验的用户名。 + * @return 如果用户名存在于数据库中则返回true,否则返回false,过程中若出现异常则抛出相应异常情况。 + * @throws Exception 比如数据库查询异常等可能出现的问题。 */ @Select("select * from admins where username = #{u_name}") Boolean checkUserName(String u_name) throws Exception; /** * 校验学/工号是否已被注册 - * @param uid - * @return - * @throws Exception + * 通过@Select注解定义SQL查询语句,从"admins"表中查找是否存在指定学/工号(uid)的记录,以此判断该学/工号是否已经被其他管理员注册使用。 + * 如果查询到对应记录,则返回该记录对应的Admin对象(可以根据返回对象是否为null来判断学/工号是否已注册);若未查询到记录则返回null或者抛出异常(取决于具体配置和业务场景)。 + * + * @param uid 要校验的学/工号。 + * @return 如果学/工号已被注册,则返回对应的Admin对象,否则返回null或者抛出异常情况(比如数据库查询异常等)。 + * @throws Exception 数据库访问过程中可能出现的异常。 */ @Select("select * from admins where uid = #{uid}") Admin checkUid(String uid) throws Exception; /** * 重置密码 - * @param password - * @param id - * @throws Exception + * 使用@Update注解定义了一个SQL更新语句,根据传入的密码和管理员id,更新"admins"表中对应管理员记录的密码字段值,实现重置密码的功能。 + * 通过#{password}和#{id}将传入的参数替换到SQL语句相应位置,准确地更新指定管理员的密码。 + * + * @param password 要设置的新密码。 + * @param id 对应的管理员的唯一标识(数据库表中的主键值),用于定位要更新密码的记录。 + * @throws Exception 比如在执行更新操作时出现的数据库权限不足、数据类型不匹配等异常情况。 */ @Update("update admins set password = #{password} where id = #{id}") - void updatePassword(String password,Integer id) throws Exception; + void updatePassword(String password, Integer id) throws Exception; //select * from admins where username like '%p%' or name like '%万%' or power like '%1%' or description like '%管理员%'; //模糊搜索管理员信息,查询结果返回一个list集合 + /** + * 模糊搜索管理员信息 + * 使用@Select注解定义了一个带有模糊查询(LIKE操作符)的SQL语句,从"admins"表中查找用户名、姓名、学/工号、电话、权限、描述等字段中包含指定关键字(keyword)的管理员记录。 + * 通过${keyword}的方式将传入的关键字参数直接拼接到SQL语句中(与#{keyword}的区别在于,${}是直接拼接,#{}是预编译防止SQL注入),实现模糊搜索功能,查询结果以List集合形式返回。 + * 需要注意的是,使用${}方式可能存在SQL注入风险,要确保传入的关键字是可信的或者进行相应的安全处理。 + * + * @param keyword 用于模糊搜索的关键字,将在多个字段中进行模糊匹配查找符合条件的管理员记录。 + * @return 返回一个包含符合模糊搜索条件的管理员信息的List集合,如果没有找到匹配记录则可能返回空集合或者抛出异常。 + * @throws Exception 比如数据库查询异常等可能出现的问题。 + */ @Select("select * from admins where username like '%${keyword}%' or name like '%${keyword}%' or uid like '%${keyword}%' or phone like '%${keyword}%' or power like '%${keyword}%' or description like '%${keyword}%' ") List serarchInfo(@Param(value="keyword") String keyword) throws Exception; /** * 管理员授权 * 授权等级 : 0 1 2 3 - * @param admin - * @throws Exception + * 通过@Update注解定义了一个SQL更新语句,根据传入的Admin对象中的id和授权等级(power)属性值,更新"admins"表中对应管理员记录的授权等级字段值,实现管理员授权功能。 + * 通过#{power}和#{id}将Admin对象中的相应属性值替换到SQL语句中,准确地更新指定管理员的授权等级。 + * + * @param admin 包含了要授权的管理员的相关信息(主要是id和授权等级power)的Admin对象,用于更新数据库中对应记录的授权等级。 + * @throws Exception 例如在执行更新操作时出现的数据类型不匹配、数据库约束违反等异常情况。 */ @Update("update admins set power = #{power} where id = #{id} ") void put_power(Admin admin) throws Exception; -} +} \ No newline at end of file diff --git a/src/main/java/cn/ppdxzz/domain/Admin.java b/src/main/java/cn/ppdxzz/domain/Admin.java index c7cce7c..9894e6e 100644 --- a/src/main/java/cn/ppdxzz/domain/Admin.java +++ b/src/main/java/cn/ppdxzz/domain/Admin.java @@ -4,23 +4,54 @@ import java.io.Serializable; /** * Description:管理员实体类 + * 该类用于表示管理员相关的信息,作为Java对象与数据库中的管理员表记录进行映射,实现数据的传输和持久化操作等。 + * 实现Serializable接口是为了让该类的对象能够被序列化,便于在网络传输、文件存储等场景下使用。 * * @Date: 2020/2/10 15:13 * @Author: PeiChen */ public class Admin implements Serializable { - private Integer id; //id 主键自增 - private String username; //用户名 - private String password; //密码 - private String name; //姓名 - private String uid; //学/工号 - private String phone; //手机号 - private int power; //是否开启权限 - private String description; //描述 + // 管理员的唯一标识,通常对应数据库表中的主键字段,设置为自增类型,用于唯一确定一条管理员记录。 + private Integer id; + + // 管理员的用户名,用于登录系统等操作,存储用户名相关的字符串信息。 + private String username; + + // 管理员的密码,用于验证登录身份,存储密码相关的字符串信息,在实际应用中应进行加密存储等安全处理。 + private String password; + + // 管理员的真实姓名,用于展示和区分不同的管理员个体,存储姓名相关的字符串信息。 + private String name; + + // 学/工号,用于唯一标识管理员在学校或单位内的身份编号,存储相应的字符串信息。 + private String uid; + + // 管理员的手机号码,可用于联系管理员等相关用途,存储手机号码的字符串信息。 + private String phone; + + // 表示管理员是否开启权限的标识,整型变量,具体含义根据业务逻辑确定(例如不同数值对应不同权限级别等)。 + private int power; + + // 对管理员的相关描述信息,比如岗位描述、职责范围等,存储对应的字符串信息。 + private String description; + + // 默认的无参构造函数,在一些框架进行对象实例化等操作时可能会用到,例如通过反射机制创建对象时需要默认构造函数。 public Admin() { } + /** + * 全参构造函数,用于根据传入的各个参数创建一个完整的Admin对象,方便在初始化对象时一次性赋值所有属性。 + * + * @param id 管理员的唯一标识。 + * @param username 管理员的用户名。 + * @param password 管理员的密码。 + * @param name 管理员的真实姓名。 + * @param uid 学/工号。 + * @param phone 管理员的手机号码。 + * @param power 表示是否开启权限的标识。 + * @param description 对管理员的描述信息。 + */ public Admin(Integer id, String username, String password, String name, String uid, String phone, int power, String description) { this.id = id; this.username = username; @@ -32,70 +63,92 @@ public class Admin implements Serializable { this.description = description; } + // 获取管理员的唯一标识(id)的方法,供外部类访问该对象的id属性值。 public Integer getId() { return id; } + // 设置管理员的唯一标识(id)的方法,供外部类修改该对象的id属性值。 public void setId(Integer id) { this.id = id; } + // 获取管理员用户名的方法,供外部类访问该对象的username属性值。 public String getUsername() { return username; } + // 设置管理员用户名的方法,供外部类修改该对象的username属性值。 public void setUsername(String username) { this.username = username; } + // 获取管理员密码的方法,供外部类访问该对象的password属性值。 public String getPassword() { return password; } + // 设置管理员密码的方法,供外部类修改该对象的password属性值。 public void setPassword(String password) { this.password = password; } + // 获取管理员真实姓名的方法,供外部类访问该对象的name属性值。 public String getName() { return name; } + // 设置管理员真实姓名的方法,供外部类修改该对象的name属性值。 public void setName(String name) { this.name = name; } + // 获取管理员学/工号的方法,供外部类访问该对象的uid属性值。 public String getUid() { return uid; } + // 设置管理员学/工号的方法,供外部类修改该对象的uid属性值。 public void setUid(String uid) { this.uid = uid; } + // 获取管理员手机号码的方法,供外部类访问该对象的phone属性值。 public String getPhone() { return phone; } + // 设置管理员手机号码的方法,供外部类修改该对象的phone属性值。 public void setPhone(String phone) { this.phone = phone; } + // 获取管理员权限标识的方法,供外部类访问该对象的power属性值。 public int getPower() { return power; } + // 设置管理员权限标识的方法,供外部类修改该对象的power属性值。 public void setPower(int power) { this.power = power; } + // 获取管理员描述信息的方法,供外部类访问该对象的description属性值。 public String getDescription() { return description; } + // 设置管理员描述信息的方法,供外部类修改该对象的description属性值。 public void setDescription(String description) { this.description = description; } + /** + * 重写toString方法,用于方便地将Admin对象以特定格式转换为字符串表示形式,便于在调试、日志输出等场景下查看对象的具体内容。 + * 返回一个包含对象各个属性值的字符串,格式为 "Admin{" + 属性名=属性值 + '}' 的形式。 + * + * @return 表示Admin对象的字符串内容。 + */ @Override public String toString() { return "Admin{" + @@ -109,4 +162,4 @@ public class Admin implements Serializable { ", description='" + description + '\'' + '}'; } -} +} \ No newline at end of file diff --git a/src/main/java/cn/ppdxzz/poi/WriteExcel.java b/src/main/java/cn/ppdxzz/poi/WriteExcel.java index c134037..da99124 100644 --- a/src/main/java/cn/ppdxzz/poi/WriteExcel.java +++ b/src/main/java/cn/ppdxzz/poi/WriteExcel.java @@ -2,188 +2,237 @@ package cn.ppdxzz.poi; import org.apache.poi.hssf.usermodel.*; import org.apache.poi.hssf.util.HSSFColor; - import java.io.*; import java.util.ArrayList; import java.util.List; /** * Description:通用Excel输入流 + * 该类主要用于将数据导出为Excel文件格式,并提供相关的样式设置以及数据填充等功能,最终返回一个Excel文件对应的输入流,方便在Web等场景下进行文件下载等操作。 * * @Date: 2020/2/16 15:17 * @Author: PeiChen */ public class WriteExcel { - //导出表的列名 + + // 导出表的列名数组,用于存储Excel表格每列的标题名称。 private String[] rowName; - //每行作为一个Object对象 - private List dataList = new ArrayList(); - //构造方法,传入要导出的数据:第一个参数传入一个列名数组,第二个参数传入一个list集合(Object对象数组) - public WriteExcel(String[] rowName,List dataList){ + // 每行作为一个Object对象,这里使用List来存储多个Object数组,每个Object数组代表Excel表格中的一行数据(除去列名那一行)。 + private List dataList = new ArrayList(); + + // 构造方法,传入要导出的数据 + // 第一个参数传入一个列名数组,用于设置Excel表格的列标题。 + // 第二个参数传入一个list集合(Object对象数组),集合中的每个Object数组对应Excel表格中的一行具体数据。 + public WriteExcel(String[] rowName, List dataList) { this.dataList = dataList; this.rowName = rowName; } - /* - * 导出数据 - * */ - public InputStream export() throws Exception{ - HSSFWorkbook workbook = new HSSFWorkbook(); // 创建工作簿对象 - HSSFSheet sheet = workbook.createSheet("sheet1"); // 创建工作表 + /** + * 导出数据方法 + * 该方法主要实现将传入的数据按照设定的格式和样式填充到Excel工作簿中,并进行一些列宽自适应等优化操作,最后返回一个代表该Excel文件内容的输入流,以便后续进行文件下载等处理。 + * + * @return 返回一个InputStream类型的输入流,该输入流指向生成的Excel文件内容,可用于在网络传输(如文件下载)等场景中。 + * @throws Exception 可能抛出的异常,比如创建工作簿、写入文件内容等过程中出现的IO异常或者其他相关异常。 + */ + public InputStream export() throws Exception { + // 创建工作簿对象,这是整个Excel文件的基础容器,后续的工作表、单元格等都将添加到这个工作簿中。 + HSSFWorkbook workbook = new HSSFWorkbook(); + // 创建工作表,这里创建了一个名为"sheet1"的工作表,一个工作簿可以包含多个工作表,此处只创建了一个。 + HSSFSheet sheet = workbook.createSheet("sheet1"); // 设置sheet表样式 - HSSFCellStyle columnTopStyle = this.getColumnTopStyle(workbook);//获取列头样式对象 - HSSFCellStyle style = this.getColumnStyle(workbook); //单元格样式对象 + // 获取列头样式对象,用于设置Excel表格中列标题那一行单元格的样式。 + HSSFCellStyle columnTopStyle = this.getColumnTopStyle(workbook); + // 获取单元格样式对象,用于设置Excel表格中除列标题外其他数据单元格的样式。 + HSSFCellStyle style = this.getColumnStyle(workbook); - // 定义所需列数 + // 定义所需列数,通过传入的列名数组长度来确定Excel表格的列数。 int columnNum = rowName.length; - HSSFRow rowRowName = sheet.createRow(0); // 在索引2的位置创建行(最顶端的行开始的第二行) + // 在索引0的位置创建行(Excel表格中最顶端的行),用于设置列头信息。 + HSSFRow rowRowName = sheet.createRow(0); // 将列头设置到sheet的单元格中 - for(int n=0;n findAll(int page,int size) throws Exception; + /** + * 查询所有管理员信息 + * 该方法用于获取所有管理员的信息列表,不过考虑到可能数据量较大需要分页展示,所以接收当前页码(page)和每页显示的记录数(size)两个参数, + * 在具体实现类中会按照这两个参数进行分页查询操作,从数据库中获取相应分页后的管理员信息列表并返回。 + * + * @param page 当前页码,用于指定要获取哪一页的数据,从1开始计数。 + * @param size 每页显示的记录数,用于确定每页包含的管理员记录数量。 + * @return 返回一个包含管理员信息的List集合,集合中的元素是按照分页条件从数据库中查询出来的管理员对象,执行过程中可能抛出异常(由具体实现决定)。 + * @throws Exception 比如数据库查询异常、分页插件使用异常等可能出现的问题。 + */ + List findAll(int page, int size) throws Exception; + /** + * 通过id删除管理员 + * 根据传入的管理员id,调用具体实现类中的业务逻辑,从数据库中删除具有该id的管理员记录,实现对管理员数据的删除操作,该方法无返回值,主要关注删除操作是否成功执行。 + * + * @param id 要删除的管理员的唯一标识(对应数据库表中的主键值)。 + * @throws Exception 可能在数据库执行删除操作时出现的异常,例如违反外键约束、数据库权限不足等导致的异常,具体由实现类中数据库操作情况决定抛出的异常类型。 + */ void deleteAdminById(Integer id) throws Exception; + /** + * 更新管理员信息 + * 接收一个包含更新后管理员各项信息的Admin对象,通过具体实现类中的业务逻辑,将传入对象中的信息更新到数据库中对应的管理员记录上, + * 以此实现对管理员信息的修改功能,该方法无返回值,重点在于完成信息更新操作。 + * + * @param admin 包含了更新后的管理员各项信息的Admin对象,这些信息将用于更新数据库中的记录。 + * @throws Exception 比如在执行更新操作时出现的数据类型不匹配、数据库约束违反等异常情况,具体取决于实现类中与数据库交互及数据更新的操作情况。 + */ void updateAdmin(Admin admin) throws Exception; + /** + * 添加管理员信息 + * 该方法用于将一个包含新管理员各项信息的Admin对象添加到数据库中,创建一条新的管理员记录,具体实现类会处理相关的数据库插入操作, + * 此方法无返回值,主要关注插入操作是否能成功执行,若出现异常则插入失败。 + * + * @param admin 包含了要添加的管理员各项信息的Admin对象,这些信息将被插入到数据库表中。 + * @throws Exception 可能出现的异常情况,例如插入的数据不符合表结构约束、数据库插入失败等,具体由实现类中数据库插入操作情况决定抛出的异常类型。 + */ void addAdmin(Admin admin) throws Exception; + /** + * 校验用户名是否存在 + * 根据传入的用户名,调用具体实现类中的业务逻辑,去数据库中查询是否存在该用户名对应的管理员记录,以此判断用户名是否已被其他管理员使用, + * 如果存在则返回true,不存在则返回false,可用于注册等场景下验证用户名的唯一性。 + * + * @param u_name 要校验的用户名。 + * @return 如果用户名在数据库中已存在,则返回true;若不存在则返回false,查询过程中可能抛出异常(由具体实现决定)。 + * @throws Exception 比如数据库查询异常等可能出现的问题,具体取决于实现类中查询操作的执行情况。 + */ Boolean checkUserName(String u_name) throws Exception; - //模糊搜索管理员信息,查询结果返回一个list集合 - List serarchInfo(int page,int size,String keyword) throws Exception; - //授权 + // 模糊搜索管理员信息,查询结果返回一个list集合 + /** + * 模糊搜索管理员信息 + * 按照传入的当前页码(page)、每页显示记录数(size)以及搜索关键字(keyword),在具体实现类中调用相应业务逻辑, + * 通过关键字在数据库的相关字段中进行模糊匹配查询,获取符合条件的管理员信息列表并返回,便于实现根据部分信息查找管理员的功能。 + * + * @param page 当前页码,用于指定要获取哪一页的数据,从1开始计数。 + * @param size 每页显示的记录数,用于确定每页包含的管理员记录数量。 + * @param keyword 用于模糊查询的关键字,将在数据库中相关字段(如用户名、姓名等)进行模糊匹配查找符合条件的管理员记录。 + * @return 返回一个包含符合模糊查询条件的管理员信息的List集合,如果没有找到匹配记录则返回空集合,执行过程中可能抛出异常(由具体实现决定)。 + * @throws Exception 比如数据库查询异常、分页插件使用异常等可能出现的问题。 + */ + List serarchInfo(int page, int size, String keyword) throws Exception; + + // 授权 + /** + * 授权操作 + * 接收一个包含管理员相关信息及授权等级等的Admin对象,通过具体实现类中的业务逻辑,将该对象中的授权等级信息更新到数据库中对应管理员记录上, + * 实现对管理员授权等级的修改,该方法无返回值,重点关注授权等级更新操作是否成功执行。 + * + * @param admin 包含了要授权的管理员的相关信息(主要是授权等级等)的Admin对象,这些信息将用于更新数据库中对应记录的授权等级。 + * @throws Exception 例如在执行更新操作时出现的数据类型不匹配、数据库约束违反等异常情况,具体取决于实现类中与数据库交互及数据更新的操作情况。 + */ void put_power(Admin admin) throws Exception; - //返回一个携带所有管理员信息数据的InputStream输入流 + // 返回一个携带所有管理员信息数据的InputStream输入流 + /** + * 获取所有管理员信息的输入流 + * 该方法的具体实现类会将所有管理员的信息整理并转换为适合的数据格式(通常用于导出数据场景,比如生成Excel文件等), + * 然后以InputStream的形式返回,外部可以利用这个输入流进行文件下载等相关操作,获取包含所有管理员信息的数据内容。 + * + * @return 返回一个InputStream类型的输入流,该输入流指向包含所有管理员信息的数据内容,可用于后续的文件下载、数据传输等操作,执行过程中可能抛出异常(由具体实现决定)。 + * @throws Exception 比如数据整理转换异常、生成输入流过程中出现的异常等,具体取决于实现类中相关操作的执行情况。 + */ InputStream getInputStream() throws Exception; - //校验学工号是否被注册 + // 校验学工号是否被注册 + /** + * 校验学/工号是否被注册 + * 根据传入的学/工号,调用具体实现类中的业务逻辑,去数据库中查询是否存在该学/工号对应的管理员记录,以此判断该学/工号是否已被其他管理员使用, + * 如果存在则返回对应的Admin对象(可以根据返回对象是否为null来判断是否已注册),不存在则返回null,用于在添加或修改管理员信息等场景下验证学/工号的唯一性。 + * + * @param uid 要校验的学/工号。 + * @return 如果学/工号在数据库中已被注册,则返回对应的Admin对象;若未被注册则返回null,查询过程中可能抛出异常(由具体实现决定)。 + * @throws Exception 比如数据库查询异常等可能出现的问题,具体取决于实现类中查询操作的执行情况。 + */ Admin checkUid(String uid) throws Exception; -} +} \ No newline at end of file diff --git a/src/main/java/cn/ppdxzz/service/impl/AdminServiceImpl.java b/src/main/java/cn/ppdxzz/service/impl/AdminServiceImpl.java index f29f595..1d2fe8f 100644 --- a/src/main/java/cn/ppdxzz/service/impl/AdminServiceImpl.java +++ b/src/main/java/cn/ppdxzz/service/impl/AdminServiceImpl.java @@ -18,7 +18,8 @@ import java.util.ArrayList; import java.util.List; /** - * Description: + * Description: 这是管理员服务层的实现类,实现了AdminService接口,用于处理与管理员相关的业务逻辑, + * 并调用持久层(AdminDao)的方法来完成具体的数据操作,如查询、添加、删除、修改等功能,同时也包含了一些如分页、数据导出等辅助功能的实现。 * * @Date: 2020/2/10 15:30 * @Author: PeiChen @@ -26,7 +27,10 @@ import java.util.List; @Service("adminService") public class AdminServiceImpl implements AdminService { + // 依赖注入AdminDao接口,用于调用持久层的数据库操作方法。 private AdminDao adminDao; + + // 通过@Autowired注解,让Spring框架自动注入AdminDao的实现类实例,实现依赖注入。 @Autowired public void setAdminDao(AdminDao adminDao) { this.adminDao = adminDao; @@ -34,9 +38,11 @@ public class AdminServiceImpl implements AdminService { /** * 调用持久层中的findAdmin()方法校验用户名密码是否正确 - * @param admin - * @return - * @throws Exception + * 该方法接收一个包含用户名和密码信息的Admin对象,将验证工作委托给持久层的对应方法,根据持久层返回结果判断用户名和密码是否匹配。 + * + * @param admin 包含用户名和密码等信息的Admin对象,用于传递给持久层方法进行查询验证。 + * @return 如果持久层查询到匹配的管理员记录,则返回对应的Admin对象,否则返回null(根据持久层方法具体实现情况而定)。 + * @throws Exception 可能抛出的异常,比如持久层数据库操作异常等。 */ @Override public Admin findAdmin(Admin admin) throws Exception { @@ -45,9 +51,11 @@ public class AdminServiceImpl implements AdminService { /** * 通过id查询管理员信息 - * @param id - * @return Admin - * @throws Exception + * 该方法根据传入的管理员id,调用持久层的对应方法从数据库中查询并获取相应管理员的详细信息。 + * + * @param id 要查询的管理员的唯一标识(通常对应数据库表中的主键值)。 + * @return 返回查询到的对应的Admin对象,如果未查询到则返回null(取决于持久层方法实现及数据库情况)。 + * @throws Exception 可能出现的数据库查询异常等情况。 */ @Override public Admin findAdminById(Integer id) throws Exception { @@ -56,19 +64,26 @@ public class AdminServiceImpl implements AdminService { /** * 查询所有管理员信息 - * @return - * @throws Exception + * 此方法借助PageHelper分页插件实现分页查询功能,先设置分页参数(当前页码和每页显示记录数),然后调用持久层的方法获取所有管理员记录,返回的结果将是按照分页设置后的管理员信息列表。 + * + * @param page 当前页码,用于指定要查询的页面。 + * @param size 每页显示的记录数,用于确定每页的数据量。 + * @return 返回一个包含管理员信息的List集合,集合中的数据是按照分页条件从数据库中查询出来的管理员记录。 + * @throws Exception 比如分页插件使用异常、数据库查询异常等可能出现的问题。 */ @Override - public List findAll(int page,int size) throws Exception { - PageHelper.startPage(page,size); + public List findAll(int page, int size) throws Exception { + // 启动PageHelper分页功能,设置当前页码和每页显示的记录数,后续调用持久层查询方法时会自动应用分页逻辑。 + PageHelper.startPage(page, size); return adminDao.findAll(); } /** * 通过id删除管理员 - * @param id - * @throws Exception + * 该方法接收要删除的管理员的id,直接调用持久层的对应方法,从数据库中删除具有该id的管理员记录,实现删除管理员数据的功能。 + * + * @param id 要删除的管理员的唯一标识(对应数据库表中的主键值)。 + * @throws Exception 可能在数据库执行删除操作时出现的异常,例如违反外键约束、数据库权限不足等导致的异常。 */ @Override public void deleteAdminById(Integer id) throws Exception { @@ -77,8 +92,10 @@ public class AdminServiceImpl implements AdminService { /** * 更新管理员信息 - * @param admin - * @throws Exception + * 该方法接收一个包含更新后管理员信息的Admin对象,调用持久层的对应方法,将传入的对象信息更新到数据库中对应管理员记录上,实现管理员信息修改的功能。 + * + * @param admin 包含了更新后的管理员各项信息的Admin对象,将被用于更新数据库中的记录。 + * @throws Exception 比如在执行更新操作时出现的数据类型不匹配、数据库约束违反等异常情况。 */ @Override public void updateAdmin(Admin admin) throws Exception { @@ -87,8 +104,11 @@ public class AdminServiceImpl implements AdminService { /** * 添加管理员信息 - * @param admin - * @throws Exception + * 该方法使用了Spring的事务管理机制(通过@Transactional注解标记),在添加管理员信息时,如果出现异常,将自动回滚事务,保证数据的一致性。 + * 它接收一个包含要添加的管理员各项信息的Admin对象,调用持久层的对应方法将该对象信息插入到数据库中,实现新增管理员记录的功能。 + * + * @param admin 包含了要添加的管理员各项信息的Admin对象,这些信息将被插入到数据库表中。 + * @throws Exception 可能出现的异常情况,例如插入的数据不符合表结构约束、数据库插入失败等,出现异常时事务会自动回滚。 */ @Transactional @Override @@ -96,11 +116,20 @@ public class AdminServiceImpl implements AdminService { adminDao.addAdmin(admin); } + /** + * 校验用户名是否存在 + * 该方法调用持久层的对应方法,根据传入的用户名去数据库中查询是否存在对应的记录,以此判断用户名是否已经被其他管理员使用。 + * 如果查询到记录(即返回的结果不为null),则表示用户名存在,返回true;若未查询到记录,则返回false。 + * + * @param u_name 要校验的用户名。 + * @return 如果用户名存在于数据库中则返回true,否则返回false,过程中若出现异常则抛出相应异常情况。 + * @throws Exception 比如数据库查询异常等可能出现的问题。 + */ @Override public Boolean checkUserName(String u_name) throws Exception { //System.out.println(adminDao.checkUserName(u_name)); - //用户名不存在则返回空,直接false - if (adminDao.checkUserName(u_name) != null) { + // 用户名不存在则返回空,直接false + if (adminDao.checkUserName(u_name)!= null) { return true; } return false; @@ -108,21 +137,28 @@ public class AdminServiceImpl implements AdminService { /** * 管理员信息模糊查询 - * @param keyword - * @return - * @throws Exception + * 此方法借助PageHelper分页插件实现分页模糊查询功能,先设置分页参数(当前页码和每页显示记录数),然后调用持久层的模糊查询方法,根据传入的关键字在数据库中查找匹配的管理员记录,返回符合条件的管理员信息列表。 + * + * @param page 当前页码,用于指定要查询的页面。 + * @param size 每页显示的记录数,用于确定每页的数据量。 + * @param keyword 用于模糊查询的关键字,将在数据库中根据相关字段进行模糊匹配查找符合条件的管理员记录。 + * @return 返回一个包含符合模糊查询条件的管理员信息的List集合,如果没有找到匹配记录则返回空集合(取决于持久层方法实现及数据库情况)。 + * @throws Exception 比如分页插件使用异常、数据库查询异常等可能出现的问题。 */ @Override - public List serarchInfo(int page,int size,String keyword) throws Exception { - PageHelper.startPage(page,size); + public List serarchInfo(int page, int size, String keyword) throws Exception { + // 启动PageHelper分页功能,设置当前页码和每页显示的记录数,后续调用持久层模糊查询方法时会自动应用分页逻辑。 + PageHelper.startPage(page, size); List list = adminDao.serarchInfo(keyword); return list; } /** * 授权 - * @param admin - * @throws Exception + * 该方法接收一个包含管理员相关信息及授权等级等的Admin对象,调用持久层的对应方法,将该对象中的授权等级信息更新到数据库中对应管理员记录上,实现管理员授权功能。 + * + * @param admin 包含了要授权的管理员的相关信息(主要是授权等级等)的Admin对象,用于更新数据库中对应记录的授权等级。 + * @throws Exception 例如在执行更新操作时出现的数据类型不匹配、数据库约束违反等异常情况。 */ @Override public void put_power(Admin admin) throws Exception { @@ -131,17 +167,23 @@ public class AdminServiceImpl implements AdminService { /** * 导出管理员信息 - * @return - * @throws Exception + * 该方法主要实现将数据库中的管理员信息导出为Excel文件格式的功能,首先获取数据库中所有管理员的记录,然后将这些记录按照一定格式整理到数据列表中, + * 接着利用WriteExcel类将数据列表转换为Excel文件对应的输入流,最终返回该输入流,可用于后续在Web等场景下进行文件下载操作。 + * + * @return 返回一个InputStream类型的输入流,该输入流指向生成的包含管理员信息的Excel文件内容,可用于文件下载等相关业务操作。 + * @throws Exception 可能抛出的异常,比如获取数据库数据异常、生成Excel文件过程中出现的异常(如写入文件流异常等)。 */ @Override public InputStream getInputStream() throws Exception { - //Excel中的每列列名,依次对应数据库的字段 - String[] title = new String[]{"ID","用户名","密码","姓名","学/工号","手机号","权限","描述"}; + // Excel中的每列列名,依次对应数据库的字段,用于设置导出的Excel表格的列标题。 + String[] title = new String[]{"ID", "用户名", "密码", "姓名", "学/工号", "手机号", "权限", "描述"}; + // 调用持久层的方法获取数据库中所有管理员的信息,得到一个List集合,集合中的每个Admin对象代表一条管理员记录。 List admins = adminDao.exportAdminInfo(); - List dataList = new ArrayList(); + // 创建一个用于存储每行数据的列表,每个元素是一个Object数组,代表Excel表格中的一行数据(除去列标题行),初始化为空列表。 + List dataList = new ArrayList(); + // 遍历从数据库获取的管理员信息列表,将每条管理员记录的各个字段值提取出来,整理成Object数组形式,添加到数据列表中,以便后续生成Excel文件。 for (int i = 0; i < admins.size(); i++) { - Object[] obj = new Object[7]; + Object[] obj = new Object[8]; obj[0] = admins.get(i).getId(); obj[1] = admins.get(i).getUsername(); obj[2] = admins.get(i).getPassword(); @@ -152,20 +194,25 @@ public class AdminServiceImpl implements AdminService { obj[7] = admins.get(i).getDescription(); dataList.add(obj); } + // 创建WriteExcel类的实例,传入列名数组和整理好的数据列表,用于生成Excel文件。 WriteExcel ex = new WriteExcel(title, dataList); InputStream in; + // 调用WriteExcel类的export方法,生成包含管理员信息的Excel文件对应的输入流,将其赋值给变量in。 in = ex.export(); return in; } /** * 校验学/工号是否已被注册 - * @param uid - * @return - * @throws Exception + * 该方法调用持久层的对应方法,根据传入的学/工号去数据库中查询是否存在对应的管理员记录,以此判断该学/工号是否已经被其他管理员使用。 + * 如果查询到记录,则返回对应的Admin对象(可以根据返回对象是否为null来判断学/工号是否已注册);若未查询到记录则返回null(取决于持久层方法实现及数据库情况)。 + * + * @param uid 要校验的学/工号。 + * @return 如果学/工号已被注册,则返回对应的Admin对象,否则返回null,过程中若出现异常则抛出相应异常情况。 + * @throws Exception 比如数据库查询异常等可能出现的问题。 */ @Override public Admin checkUid(String uid) throws Exception { return adminDao.checkUid(uid); } -} +} \ No newline at end of file diff --git a/src/main/java/cn/ppdxzz/utils/MD5Util.java b/src/main/java/cn/ppdxzz/utils/MD5Util.java index 34fffce..b57e0ac 100644 --- a/src/main/java/cn/ppdxzz/utils/MD5Util.java +++ b/src/main/java/cn/ppdxzz/utils/MD5Util.java @@ -4,59 +4,112 @@ import java.security.MessageDigest; /** * MD5加密算法 + * 该类提供了基于MD5算法对字符串进行加密的功能,主要用于对敏感信息(如密码等)进行加密处理,增强数据的安全性。 + * 其中包含了一些辅助方法用于字节数组与十六进制字符串之间的转换等操作,最终对外提供了以UTF-8编码进行MD5加密的便捷方法。 */ - public class MD5Util { + /** + * 将字节数组转换为十六进制字符串的方法 + * 该方法遍历传入的字节数组,逐个将字节转换为对应的十六进制表示形式,并拼接成一个完整的十六进制字符串返回。 + * + * @param b 要转换的字节数组,通常是经过MD5摘要算法处理后得到的字节数组结果。 + * @return 返回一个由字节数组转换而来的十六进制字符串,用于后续表示加密后的结果等用途。 + */ private static String byteArrayToHexString(byte b[]) { + // 创建一个StringBuffer对象,用于高效地拼接字符串,存储最终转换后的十六进制字符串结果。 StringBuffer resultSb = new StringBuffer(); + // 遍历字节数组中的每个字节 for (int i = 0; i < b.length; i++) + // 调用byteToHexString方法将每个字节转换为十六进制字符串,并添加到resultSb中 resultSb.append(byteToHexString(b[i])); return resultSb.toString(); } + /** + * 将单个字节转换为十六进制字符串的方法 + * 该方法先对传入的字节进行处理(如果是负数则转换为正数范围),然后将其拆分为高4位和低4位,分别对应十六进制的一位, + * 通过查找预定义的十六进制字符数组,获取对应的十六进制字符并拼接成一个两位的十六进制字符串返回。 + * + * @param b 要转换的单个字节。 + * @return 返回一个表示该字节的十六进制字符串,长度为2位。 + */ private static String byteToHexString(byte b) { + // 将字节转换为整数,如果字节值是负数(Java中字节是有符号的,范围是 -128 到 127),则通过加上256将其转换为正数范围(0 到 255),便于后续计算。 int n = b; if (n < 0) n += 256; + // 获取该整数的高4位,用于对应十六进制的高位数字,通过除以16来得到(十六进制中每一位代表16的幂次,高4位对应的幂次为1)。 int d1 = n / 16; + // 获取该整数的低4位,用于对应十六进制的低位数字,通过取模16来得到。 int d2 = n % 16; + // 从预定义的十六进制字符数组中查找对应的字符,拼接成十六进制字符串返回,高4位在前,低4位在后。 return hexDigits[d1] + hexDigits[d2]; } /** * 返回大写MD5 + * 该方法实现了对给定字符串进行MD5加密,并将结果转换为大写形式返回的功能。 + * 可以根据是否指定字符编码来处理字符串转换字节数组的操作,然后通过MessageDigest类获取MD5摘要信息,并进一步转换为十六进制字符串表示。 + * + * @param origin 要进行MD5加密的原始字符串,通常是需要加密的文本信息(如密码等)。 + * @param charsetname 指定的字符编码名称,用于将字符串转换为字节数组时使用,如果为null或空字符串则使用默认编码(通常是平台默认编码)。 + * @return 返回经过MD5加密后的大写十六进制字符串结果,如果在加密过程中出现异常,则返回null(当前代码中只是简单捕获异常,未做详细处理)。 */ private static String MD5Encode(String origin, String charsetname) { String resultString = null; try { + // 先将传入的原始字符串赋值给结果字符串变量,这里可以根据实际需求考虑是否进行深拷贝等更严谨的处理(当前代码只是简单赋值)。 resultString = new String(origin); + // 获取MD5算法的MessageDigest实例,用于进行MD5摘要计算,通过传入"MD5"字符串指定使用MD5算法。 MessageDigest md = MessageDigest.getInstance("MD5"); + // 如果未指定字符编码或者字符编码为空字符串,则使用默认方式将字符串转换为字节数组后进行MD5摘要计算,再将摘要结果转换为十六进制字符串。 if (charsetname == null || "".equals(charsetname)) resultString = byteArrayToHexString(md.digest(resultString.getBytes())); else + // 如果指定了字符编码,则按照指定的字符编码将字符串转换为字节数组,然后进行MD5摘要计算,并转换为十六进制字符串。 resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname))); } catch (Exception exception) { + // 当前代码只是简单捕获异常,未做详细的异常处理(如记录日志、抛出更具体的异常等),实际应用中可根据需求完善此处逻辑。 } return resultString.toUpperCase(); } + /** + * 以UTF-8编码进行MD5加密的方法 + * 该方法是对外提供的方便调用的接口,默认使用UTF-8编码调用MD5Encode方法对传入的原始字符串进行加密,并返回加密后的结果(大写形式)。 + * 此处还预留了盐值(Salt)加密的代码逻辑(当前被注释掉了),盐值加密可以进一步增强加密的安全性,防止简单的MD5彩虹表攻击等情况。 + * + * @param origin 要进行MD5加密的原始字符串,通常是需要加密的文本信息(如密码等)。 + * @return 返回经过UTF-8编码的MD5加密后的大写十六进制字符串结果。 + */ public static String MD5EncodeUtf8(String origin) { - //盐值Salt加密 - //origin = origin + PropertiesUtil.getProperty("password.salt", ""); + // 盐值Salt加密 + // 以下代码是预留的盐值加密逻辑,通过从配置文件(PropertiesUtil.getProperty方法调用,此处未展示该类的实现)中获取盐值, + // 将盐值添加到原始字符串后面再进行MD5加密,可以使相同的原始字符串在不同的盐值情况下加密结果不同,增强安全性。 + // 当前代码将其注释掉了,如果需要启用盐值加密,可取消注释并确保配置文件读取等相关逻辑正确实现。 + // origin = origin + PropertiesUtil.getProperty("password.salt", ""); + return MD5Encode(origin, "utf-8"); } + // 预定义的十六进制字符数组,用于在字节转换十六进制字符串时查找对应的字符表示,按照十六进制的顺序排列,从0到f。 private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}; + /** + * 主方法,用于测试MD5加密功能 + * 该方法创建了MD5Util类的实例(实际上不需要创建实例也可以调用静态方法,这里只是一种简单的测试写法), + * 然后调用MD5EncodeUtf8方法对字符串"123456"进行MD5加密,并将加密结果输出到控制台,方便查看加密后的效果。 + * + * @param args 命令行参数,在当前测试场景下未使用。 + */ public static void main(String[] args) { MD5Util md = new MD5Util(); String psd = md.MD5EncodeUtf8("123456"); System.out.println(psd); } -} - +} \ No newline at end of file -- 2.34.1 From 28f99910d6cef96d929c9485915cba42049790e1 Mon Sep 17 00:00:00 2001 From: wang ziting <3165305859@qq.com> Date: Fri, 13 Dec 2024 23:25:25 +0800 Subject: [PATCH 4/6] wang --- src/main/webapp/WEB-INF/jsp/admin-add.jsp | 65 +++-- src/main/webapp/WEB-INF/jsp/admin-edit.jsp | 89 +++++-- src/main/webapp/WEB-INF/jsp/admin-list.jsp | 247 ++++++++---------- src/main/webapp/css/nouislider.css | 163 ++++++++---- src/main/webapp/css/style.css | 287 ++++++++++++++++----- 5 files changed, 546 insertions(+), 305 deletions(-) diff --git a/src/main/webapp/WEB-INF/jsp/admin-add.jsp b/src/main/webapp/WEB-INF/jsp/admin-add.jsp index c89bdfa..bf1df89 100644 --- a/src/main/webapp/WEB-INF/jsp/admin-add.jsp +++ b/src/main/webapp/WEB-INF/jsp/admin-add.jsp @@ -5,22 +5,32 @@ Date: 2020/2/12 Time: 13:06 To change this template use File | Settings | File Templates. + 上面这部分是JSP页面的头部注释,说明了该文件创建时的相关信息,如创建者、创建日期、时间以及提示如何修改模板等内容 --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> Title + + + + +

+
+
+
+
@@ -51,8 +61,11 @@
+ +
+
+
+
+
+
+
+
+
+
+ + 返回列表
+ - - + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/jsp/admin-list.jsp b/src/main/webapp/WEB-INF/jsp/admin-list.jsp index 89d719c..6f980fb 100644 --- a/src/main/webapp/WEB-INF/jsp/admin-list.jsp +++ b/src/main/webapp/WEB-INF/jsp/admin-list.jsp @@ -4,6 +4,7 @@ Date: 2020/2/10 Time: 21:45 To change this template use File | Settings | File Templates. + 这部分是JSP页面的头部注释,说明了该文件创建时的相关信息,如创建者、创建日期、时间以及提示如何修改模板等内容 --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> @@ -11,38 +12,59 @@ + + + + + + + + + + + + +<%-- 以下这部分代码被注释掉了,原本可能是用于页面导航栏的展示,包含了面包屑导航以及一个刷新按钮,点击刷新按钮可重新加载当前页面 --%> <%--
首页 @@ -53,32 +75,46 @@
--%> +
+
+
+
+
+
+
+
+
+ 添加 + 导出 + 共有数据:${pageInfo.total} 条
+ + @@ -92,35 +128,43 @@ <% int j = 1; %> + - - - - - - - - - - - + + + + + + + + + + + +
ID 用户名 姓名
<%=j++%>${admin.username}${admin.name}${admin.uid}${admin.phone}${admin.power}${admin.description} - - - - - - - - - -
<%=j++%>${admin.username}${admin.name}${admin.uid}${admin.phone}${admin.power}${admin.description} + + + + + + + + + + + + +
+ 共 ${pageInfo.pages} 页 当前页:${pageInfo.pageNum} / ${pageInfo.pages}  每页 + - + +
+ + - -
-
+ + - + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/jsp/main.jsp b/src/main/webapp/WEB-INF/jsp/main.jsp index e9c36ab..a1cab86 100644 --- a/src/main/webapp/WEB-INF/jsp/main.jsp +++ b/src/main/webapp/WEB-INF/jsp/main.jsp @@ -5,32 +5,44 @@ Date: 2020/2/10 Time: 15:58 To change this template use File | Settings | File Templates. + 这部分是JSP页面头部的注释,说明了该文件创建时的相关信息,如创建者、创建日期、时间以及提示如何修改模板等内容。 --%> <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> 管理员端平台 + + + <%--灰色管理员主题 --%> + + + @@ -218,6 +241,7 @@
<%--中间的空白面板--%>
+ @@ -234,13 +258,5 @@ - + function tip() {} + \ No newline at end of file -- 2.34.1 From bf9f1391f588c2b6a07b928b8ac8b17f98b6763e Mon Sep 17 00:00:00 2001 From: wang ziting <3165305859@qq.com> Date: Sat, 14 Dec 2024 00:02:26 +0800 Subject: [PATCH 6/6] wang --- src/main/webapp/WEB-INF/jsp/welcome.jsp | 37 ++- src/main/webapp/js/miniMobile.js | 237 +++++++++---------- src/main/webapp/js/validate.js | 302 +++++++++++++----------- 3 files changed, 307 insertions(+), 269 deletions(-) diff --git a/src/main/webapp/WEB-INF/jsp/welcome.jsp b/src/main/webapp/WEB-INF/jsp/welcome.jsp index fcd4f78..082883d 100644 --- a/src/main/webapp/WEB-INF/jsp/welcome.jsp +++ b/src/main/webapp/WEB-INF/jsp/welcome.jsp @@ -4,36 +4,48 @@ Date: 2019/12/18 Time: 14:05 To change this template use File | Settings | File Templates. + 这部分是HTML页面头部的注释,说明了该文件创建时的相关信息,如创建者、创建日期、时间以及提示如何修改模板等内容,方便后续对代码来源及修改情况进行追溯。 --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> 欢迎页面 + + +
系统时间
+
+
控制面板
+
+
+
+
CPU利用率
+ CPU
利用率
+
系统出入流量
@@ -43,6 +55,7 @@
+
模块
@@ -52,6 +65,7 @@
+
模块
@@ -65,16 +79,25 @@
- + \ No newline at end of file diff --git a/src/main/webapp/js/miniMobile.js b/src/main/webapp/js/miniMobile.js index e7ed45e..92a7c6a 100644 --- a/src/main/webapp/js/miniMobile.js +++ b/src/main/webapp/js/miniMobile.js @@ -1,63 +1,97 @@ /* * minimobile.js v0.0.1 by chenyaowen * 在保留作者签名的情况下,允许使用与商业用途 + * 该文件是一个用于移动端页面布局相关功能的JavaScript代码库,包含了一些处理页面缩放、适配以及常见UI组件功能的代码,例如处理viewport设置、侧栏显示隐藏、返回顶部功能、进度条展示等。 */ - if(!window.Zepto && !window.jQuery){ + +// 检查页面是否引入了Zepto.js或者jQuery.js,如果都没引入则在控制台输出提示信息,因为后续代码依赖这两个库之一。 +if (!window.Zepto &&!window.jQuery) { console.log("minimobile 是基于Zepto.js 或者 jQuery.js 的,请检查页面是否已在miniMobile之前引入!") - } -;(function(win, lib) { - //摘自淘宝移动端 +} + +// 立即执行函数,用于创建一个局部作用域,避免全局变量污染,同时接收window对象和一个名为lib的对象(如果不存在则创建一个空对象)作为参数,在函数内部进行相关页面适配等功能的实现。 +;(function (win, lib) { + // 获取当前页面的document对象,后续会用于操作页面元素、获取页面相关属性等操作。 var doc = win.document; + // 获取页面根元素(元素),很多页面样式和布局相关的设置会基于这个元素来操作,例如设置页面字体大小等属性。 var docEl = doc.documentElement; + // 通过选择器查找页面中name属性为"viewport"的meta标签,viewport元标签常用于控制页面在移动端的缩放、布局等显示相关设置。 var metaEl = doc.querySelector('meta[name="viewport"]'); + // 通过选择器查找页面中name属性为"flexible"的meta标签,从代码逻辑看用于获取一些和页面缩放比例相关的自定义配置信息。 var flexibleEl = doc.querySelector('meta[name="flexible"]'); + // 用于存储设备像素比(devicePixelRatio)相关的缩放因子,初始化为0,后续会根据不同情况计算并赋值。 var dpr = 0; + // 用于存储页面的缩放比例,初始化为0,会根据meta标签内容或者设备类型等情况来确定具体值。 var scale = 0; + // 用于存储定时器的标识,在处理页面resize和pageshow等事件时,通过定时器来延迟执行一些操作,避免频繁触发导致性能问题,初始化为null或未定义(取决于JavaScript环境)。 var tid; + // 创建一个名为flexible的对象,用于存储页面适配相关的一些属性和方法,如果外部传入的lib对象中已经存在flexible属性,则使用传入的,否则创建一个新的空对象赋值给lib.flexible。 var flexible = lib.flexible || (lib.flexible = {}); - var designPixel = 750;//设计稿件尺寸 - - if (metaEl) { - console.warn('将根据已有的meta标签来设置缩放比例'); + // 定义设计稿件的尺寸(单位可能是像素),这里设定为750,用于后续根据页面实际宽度计算缩放比例等相关操作,使页面在不同设备上能按比例适配显示。 + var designPixel = 750; + + // 如果页面中存在name为"viewport"的meta标签,则根据其content属性内容来获取初始缩放比例,并计算出对应的设备像素比(dpr)。 + if (metaEl) { + console.warn('将根据已有的meta标签来设置缩放比例'); + // 通过正则表达式匹配获取content属性中initial-scale的值,该值表示页面初始缩放比例。 var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/); if (match) { + // 将匹配到的初始缩放比例字符串转换为浮点数赋值给scale变量。 scale = parseFloat(match[1]); + // 根据缩放比例计算设备像素比,设备像素比是物理像素与逻辑像素的比例关系,例如scale为0.5,则dpr为2,表示物理像素是逻辑像素的2倍。 dpr = parseInt(1 / scale); } } else if (flexibleEl) { + // 获取name为"flexible"的meta标签的content属性内容,用于进一步解析获取相关缩放比例配置信息。 var content = flexibleEl.getAttribute('content'); if (content) { + // 通过正则表达式匹配尝试获取content属性中initial-dpr的值,用于设置设备像素比(dpr)。 var initialDpr = content.match(/initial\-dpr=([\d\.]+)/); + // 通过正则表达式匹配尝试获取content属性中maximum-dpr的值,同样用于设置设备像素比(dpr),可能会覆盖前面initialDpr的设置,取决于具体匹配情况。 var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/); if (initialDpr) { + // 将匹配到的initial-dpr的值转换为浮点数赋值给dpr变量,用于设置设备像素比。 dpr = parseFloat(initialDpr[1]); - scale = parseFloat((1 / dpr).toFixed(2)); + // 根据设备像素比计算缩放比例,并保留两位小数,赋值给scale变量。 + scale = parseFloat((1 / dpr).toFixed(2)); } if (maximumDpr) { + // 同理,如果匹配到了maximum-dpr的值,更新设备像素比(dpr)和缩放比例(scale)。 dpr = parseFloat(maximumDpr[1]); - scale = parseFloat((1 / dpr).toFixed(2)); + scale = parseFloat((1 / dpr).toFixed(2)); } } } - if (!dpr && !scale) { + + // 如果经过前面的步骤都没有确定dpr和scale的值(即都为0),则根据设备类型(是iPhone还是其他安卓设备等)来设置默认的设备像素比(dpr)和缩放比例(scale)。 + if (!dpr &&!scale) { + // 通过正则表达式判断当前设备是否为安卓系统。 var isAndroid = win.navigator.appVersion.match(/android/gi); + // 通过正则表达式判断当前设备是否为iPhone。 var isIPhone = win.navigator.appVersion.match(/iphone/gi); + // 获取当前设备的设备像素比,即物理像素与逻辑像素的实际比例关系。 var devicePixelRatio = win.devicePixelRatio; - if (isIPhone) { - if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) { + if (isIPhone) { + // 如果是iPhone设备,根据设备像素比来设置合适的设备像素比(dpr),例如设备像素比大于等于3且之前未设置或设置的dpr大于等于3,则设置dpr为3,以此类推。 + if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) { dpr = 3; - } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){ + } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)) { dpr = 2; } else { dpr = 1; } - } else { + } else { + // 如果不是iPhone设备(一般为安卓等其他设备),默认设置设备像素比(dpr)为1。 dpr = 1; } + // 根据设备像素比(dpr)计算缩放比例(scale),两者互为倒数关系。 scale = 1 / dpr; } + // 将计算得到的设备像素比(dpr)设置为页面根元素(元素)的data-dpr属性值,方便在CSS等地方通过属性选择器等方式根据不同的设备像素比来应用不同的样式规则。 docEl.setAttribute('data-dpr', dpr); + + // 如果页面中不存在name为"viewport"的meta标签,则动态创建一个这样的meta标签,并设置其content属性,用于控制页面的缩放、用户缩放是否可用等显示相关设置,然后将其添加到页面中合适的位置(一般是标签内)。 if (!metaEl) { metaEl = doc.createElement('meta'); metaEl.setAttribute('name', 'viewport'); @@ -71,46 +105,65 @@ } } - function refreshRem(){ + // 定义一个用于刷新页面根元素字体大小(rem单位)的函数,根据页面宽度、设计稿件尺寸以及设备像素比等信息来动态计算并设置根元素的字体大小,实现页面的自适应布局效果。 + function refreshRem() { + // 获取页面根元素(元素)的可视宽度(不包含滚动条等占据的宽度),单位为像素,后续会基于这个宽度来计算rem值。 var width = docEl.getBoundingClientRect().width; - if (width / dpr > designPixel) { //如果分辨率不是1,那么获取的物理宽度应该乘以分辨率,才是最终可用的width + // 如果设备像素比(dpr)不为1,说明物理像素和逻辑像素不一致,那么需要将获取到的物理宽度乘以设备像素比,得到真正用于计算rem的可用宽度,这样能保证在不同分辨率设备上布局的准确性。 + if (width / dpr > designPixel) { width = width * dpr; } - var rem = width / (designPixel/100); //计算最终还原到设计图上的比例,从而设置到文档上 + // 根据设计稿件尺寸(designPixel)和当前页面可用宽度(width)计算rem值,这里是将页面宽度按照设计稿件尺寸等比例缩放,例如设计稿件宽度是750px,页面当前宽度是375px,则rem值会相应变小,实现页面元素按比例缩放显示。 + var rem = width / (designPixel / 100); + // 将计算得到的rem值设置为页面根元素(元素)的字体大小(单位为px),通过设置根元素字体大小为rem单位,页面中使用rem单位的元素尺寸等会根据根元素字体大小动态变化,从而实现自适应布局。 docEl.style.fontSize = rem + 'px'; + // 将计算得到的rem值存储到flexible对象和全局的win对象(即window对象)上,方便其他地方可以访问和使用这个rem值,例如用于将px单位转换为rem单位等操作。 flexible.rem = win.rem = rem; } - win.addEventListener('resize', function() { + // 监听页面的resize事件(当页面大小发生改变时触发),当触发该事件时,先清除之前可能存在的定时器(避免重复执行或频繁执行刷新rem的操作),然后设置一个新的定时器,延迟300毫秒后调用refreshRem函数来重新计算并更新页面根元素的字体大小,实现页面在大小改变后的自适应布局调整。 + win.addEventListener('resize', function () { clearTimeout(tid); tid = setTimeout(refreshRem, 300); }, false); - win.addEventListener('pageshow', function(e) { + + // 监听页面的pageshow事件(当页面显示时触发,比如浏览器前进、后退等操作导致页面重新显示时),如果页面是从缓存中加载显示(通过e.persisted判断),同样先清除之前的定时器,再设置新定时器延迟300毫秒调用refreshRem函数来更新页面布局,确保页面在各种显示场景下都能正确自适应。 + win.addEventListener('pageshow', function (e) { if (e.persisted) { clearTimeout(tid); tid = setTimeout(refreshRem, 300); } }, false); + // 如果页面已经加载完成(document.readyState为'complete'),则直接设置页面body元素的字体大小为16乘以设备像素比(dpr)的像素值,这是一种基础的字体大小设置,通常配合rem单位的自适应布局使用,确保文字显示大小合适。 if (doc.readyState === 'complete') { doc.body.style.fontSize = 16 * dpr + 'px'; } else { - doc.addEventListener('DOMContentLoaded', function(e) { + // 如果页面还未加载完成,则监听DOMContentLoaded事件(当页面DOM结构加载完成但可能资源(如图片等)还未完全加载时触发),在该事件触发时设置页面body元素的字体大小,同样为16乘以设备像素比(dpr)的像素值。 + doc.addEventListener('DOMContentLoaded', function (e) { doc.body.style.fontSize = 16 * dpr + 'px'; }, false); } + + // 首次加载页面时调用refreshRem函数,初始化页面根元素的字体大小,确保页面一开始就能以正确的自适应布局显示。 refreshRem(); + // 将计算得到的设备像素比(dpr)存储到flexible对象和全局的win对象(即window对象)上,方便其他地方获取和使用设备像素比信息,例如在处理高清图片显示等场景下可能会用到。 flexible.dpr = win.dpr = dpr; + // 将refreshRem函数存储到flexible对象上,方便外部可以手动调用该函数来刷新页面的rem值,实现手动触发页面自适应布局调整,例如在某些动态改变页面布局结构的情况下可以使用。 flexible.refreshRem = refreshRem; - flexible.rem2px = function(d) { + + // 定义一个方法用于将rem单位的数值转换为px单位的数值,接收一个参数d(可以是数字或者以rem结尾的字符串),先将其转换为浮点数,然后乘以当前的rem值(通过this.rem获取,this指向flexible对象),如果传入的参数是字符串且以rem结尾,则在返回结果后面加上'px'单位,方便在样式设置等场景下直接使用。 + flexible.rem2px = function (d) { var val = parseFloat(d) * this.rem; if (typeof d === 'string' && d.match(/rem$/)) { val += 'px'; } return val; } - flexible.px2rem = function(d) { + + // 定义一个方法用于将px单位的数值转换为rem单位的数值,接收一个参数d(可以是数字或者以px结尾的字符串),先将其转换为浮点数,然后除以当前的rem值(通过this.rem获取,this指向flexible对象),如果传入的参数是字符串且以px结尾,则在返回结果后面加上'rem'单位,方便在样式设置等场景下直接使用,例如在根据设计稿尺寸计算元素的rem单位尺寸时会用到。 + flexible.px2rem = function (d) { var val = parseFloat(d) / this.rem; if (typeof d === 'string' && d.match(/px$/)) { val += 'rem'; @@ -119,114 +172,40 @@ } })(window, window['lib'] || (window['lib'] = {})); + /* * asideUi 侧栏 + * 以下代码定义了一个名为asideUi的jQuery或Zepto插件(取决于页面引入的是哪个库),用于创建一个具有特定交互效果的侧边栏组件,例如可以通过点击切换侧边栏的显示隐藏状态,并且可以配置一些属性如大小、是否显示遮罩、位置以及动画过渡时间等。 */ ; -(function($) { - $.fn.asideUi = function(options) { - var defaults = { - size: '100%', - hasmask: true, - position: 'left', - sidertime: 300 - }; - var val = $.extend(defaults, options); - var obj = function() {}, - _self = this, - thisMask = $("
"), - thisCss = {}, - thisCss2 = {}; - thisCss[val.position] = '-' + val.size; - this.css({ - 'top': (val.position == "bottom") ? "auto" : 0, - 'bottom': 0 - }); - thisCss2[val.position] = 0; - _self.css(thisCss); - - obj.toggle = function() { - if(_self.hasClass('ui-aside-open')) { - _self.removeClass('ui-aside-open'); - _self.animate(thisCss, val.sidertime); - $('.ui-aside-mask').animate({ - 'opacity': 0 - }, 100, function() { - $(this).remove(); - }); - } else { - _self.addClass('ui-aside-open'); - _self.animate(thisCss2, val.sidertime); - if(val.hasmask) { - $('body').append(thisMask); - $(".ui-aside-mask").animate({ - 'opacity': 1 - }, 100); - } - } - } - thisMask.tap(function() { - obj.toggle(); - }) - return obj; - }; -})(window.Zepto || window.jQuery) -/* - * 返回顶部 - */ -function goTop(acceleration, time) { - acceleration = acceleration || 0.1; - time = time || 16; - var x1 = 0; - var y1 = 0; - var x2 = 0; - var y2 = 0; - var x3 = 0; - var y3 = 0; - if(document.documentElement) { - x1 = document.documentElement.scrollLeft || 0; - y1 = document.documentElement.scrollTop || 0; - } - if(document.body) { - x2 = document.body.scrollLeft || 0; - y2 = document.body.scrollTop || 0; - } - var x3 = window.scrollX || 0; - var y3 = window.scrollY || 0; - // 滚动条到页面顶部的水平距离 - var x = Math.max(x1, Math.max(x2, x3)); - // 滚动条到页面顶部的垂直距离 - var y = Math.max(y1, Math.max(y2, y3)); - // 滚动距离 = 目前距离 / 速度, 因为距离原来越小, 速度是大于 1 的数, 所以滚动距离会越来越小 - var speed = 1 + acceleration; - window.scrollTo(Math.floor(x / speed), Math.floor(y / speed)); - // 如果距离不为零, 继续调用迭代本函数 - if(x > 0 || y > 0) { - var invokeFunction = "goTop(" + acceleration + ", " + time + ")"; - window.setTimeout(invokeFunction, time); - } -} +(function ($) { + // 通过$.fn向jQuery或Zepto的原型对象上添加一个名为asideUi的方法,这样就可以在选择器选中的元素上调用该方法来创建侧边栏组件实例,接收一个options参数用于传入配置选项。 + $.fn.asideUi = function (options) { + // 定义默认的配置选项对象,包含侧边栏的大小(默认为'100%',可以是具体的宽度值或者百分比等)、是否显示遮罩(默认为true)、显示位置(默认为'left',还可以是'right'、'bottom'等)以及侧边栏展开收起的动画过渡时间(默认为300毫秒)。 + var defaults = { + size: '100%', + hasmask: true, + position: 'left', + sidertime: 300 + }; + // 使用$.extend方法将传入的options参数与默认的配置选项defaults进行合并,返回合并后的配置对象,这样既可以使用默认配置,又可以通过传入的参数覆盖部分默认配置。 + var val = $.extend(defaults, options); + // 创建一个空的函数对象,后续会在这个对象上添加一些方法用于操作侧边栏的显示隐藏等功能,目前只是一个占位,方便代码组织和扩展。 + var obj = function () { }; + // 将当前调用asideUi方法的jQuery或Zepto对象(即选中的元素集合)赋值给_self变量,方便在后续代码中引用,例如设置选中元素的样式、添加移除类名等操作。 + var _self = this; + // 创建一个用于作为侧边栏遮罩层的
元素,添加一个名为'ui-aside-mask'的类名,后续可以通过CSS样式来设置其外观(如透明度、背景色等)以及交互效果(如点击隐藏侧边栏等)。 + var thisMask = $("
"); + // 创建一个空对象thisCss,用于存储侧边栏的初始样式设置(主要是控制侧边栏的显示位置和隐藏状态相关样式),后续会根据配置的侧边栏位置等信息来设置具体的样式属性。 + var thisCss = {}; + // 创建另一个空对象thisCss2,用于存储侧边栏展开后的样式设置(同样是控制侧边栏的位置相关样式),与thisCss相对应,用于在侧边栏切换显示隐藏时应用不同的样式实现动画过渡效果。 + var thisCss2 = {}; -/* - * ui-progress进度条 - */ -; -(function($) { - $.fn.progressUi = function(options) { - var defaults = { - skin: '' - }; - var val = $.extend(defaults, options); - var attrs = { - max: this.attr('max') || 0, - value: this.attr("value") || 0 - }, - doms = $('
'); - domsContent = $('
'); - this.wrap(doms); - domsContent.animate({ - 'width': attrs.value / attrs.max * 100 + '%', - }); - doms.prepend(domsContent); - }; -})(window.Zepto || window.jQuery) \ No newline at end of file + // 根据配置的侧边栏位置(val.position),设置侧边栏的初始位置样式,例如如果位置是'left',则将其left属性设置为负的侧边栏大小(val.size),实现将侧边栏隐藏在屏幕左侧的效果(通过CSS的left属性负值来隐藏元素),其他位置同理。 + thisCss[val.position] = '-' + val.size; + // 设置侧边栏的top和bottom属性,根据侧边栏的显示位置(val.position)来决定top属性是否自动(如果是'bottom'位置则top为'auto',其他位置top为0),同时设置bottom属性为0,用于控制侧边栏在垂直方向上的定位。 + this.css({ + 'top': (val.position == "bottom")? "auto" : 0, + 'bottom': 0 + });}}) +// 根据 \ No newline at end of file diff --git a/src/main/webapp/js/validate.js b/src/main/webapp/js/validate.js index 5c5f836..5b791bb 100644 --- a/src/main/webapp/js/validate.js +++ b/src/main/webapp/js/validate.js @@ -1,19 +1,33 @@ -(function() { +// 立即执行函数,用于创建一个局部作用域,避免全局变量污染,在这个函数内部定义了一个基础的类继承机制以及一些与表单验证相关的功能代码。 +(function () { /** * 所有类的基类,提供继承机制 + * 这里通过一些巧妙的代码逻辑实现了一个简单的类继承模式,允许创建类并能方便地继承其他类的属性和方法,同时处理了在子类中调用父类同名方法的情况(通过 _super 机制)。 */ - var initializing = false, fnTest = /xyz/.test(function() {xyz;}) ? /\b_super\b/ : /.*/; - this.Class = function() {}; - Class.extend = function(prop) { + // 用于检测当前JavaScript环境是否支持在函数内部通过名字访问函数自身的代码(用于判断是否是严格模式等情况),根据检测结果确定后续用于检测函数中是否包含 _super 关键字的正则表达式。 + var initializing = false, fnTest = /xyz/.test(function () { xyz; })? /\b_super\b/ : /.*/; + // 创建一个名为 Class 的全局函数(在严格模式下,这里的this指向全局对象,非严格模式下指向调用者的上下文对象,一般在浏览器环境下是 window 对象),这个函数后续作为创建类的构造函数,初始时它只是一个空函数,后续会通过扩展功能来完善类的创建逻辑。 + this.Class = function () { }; + + // 为 Class 函数添加一个 extend 方法,用于实现类的继承功能,通过传入一个包含属性和方法的对象(prop)来定义子类要扩展或重写的内容。 + Class.extend = function (prop) { + // 获取当前类(调用 extend 方法的类)的原型对象,也就是父类的原型,后续用于在子类中访问父类的方法等操作,实现继承关系中的方法复用和重写逻辑。 var _super = this.prototype; + // 设置 initializing 为 true,表示正在初始化一个新的类(在继承过程中创建子类的原型对象阶段),用于后续在构造函数中判断是否是初始化阶段,避免一些不必要的操作(比如重复调用初始化方法等)。 initializing = true; + // 通过使用 new 操作符调用当前类(this 指向调用 extend 的类,也就是父类)的构造函数来创建一个新的对象,这个对象将作为子类的原型对象,它会继承父类原型上的属性和方法。 var prototype = new this(); + // 完成子类原型对象的创建后,将 initializing 重新设置为 false,表示初始化阶段结束。 initializing = false; - for ( var name in prop) { - prototype[name] = typeof prop[name] == "function" - && typeof _super[name] == "function" && fnTest.test(prop[name]) ? - (function(name, fn) { - return function() { + + // 遍历传入的属性对象(prop)中的每个属性(一般是方法或新定义的属性),进行相应的处理,判断是普通属性赋值还是函数属性的特殊处理(涉及到父类同名函数的调用情况)。 + for (var name in prop) { + // 判断当前属性(prop[name])是否是函数类型,并且父类原型上是否存在同名的函数属性(_super[name]),同时还要检测该函数的代码中是否包含 _super 关键字(通过 fnTest 正则表达式判断),如果满足这些条件,则进行特殊的函数包装处理,用于实现子类中调用父类同名函数的功能。 + prototype[name] = typeof prop[name] == "function" + && typeof _super[name] == "function" && fnTest.test(prop[name])? + // 如果满足上述条件,返回一个新的函数,这个函数内部实现了先临时保存当前对象的 _super 属性(可能是之前保存的父类同名函数引用),然后将 _super 属性指向父类的同名函数,接着调用传入的函数(也就是子类重写的函数),在调用完成后恢复 _super 属性的原始值,最后返回函数执行的结果,这样就巧妙地实现了在子类函数中通过 this._super 调用父类同名函数的功能。 + (function (name, fn) { + return function () { var tmp = this._super; this._super = _super[name]; @@ -25,155 +39,177 @@ }; })(name, prop[name]) : prop[name]; } + + // 创建一个新的函数(作为子类的构造函数),在这个构造函数中,如果当前不是处于初始化阶段(即不是在创建子类原型对象过程中),并且子类定义了 init 方法(一般用于初始化操作),则调用子类的 init 方法,并传入相应的参数,实现子类实例化时的初始化逻辑。 function Class() { if (!initializing && this.init) this.init.apply(this, arguments); } + + // 将前面创建并处理好的原型对象(prototype)赋值给新创建的子类构造函数(Class)的原型属性,这样通过这个构造函数创建的实例就能继承原型对象上的属性和方法了。 Class.prototype = prototype; + // 修复子类构造函数的 constructor 属性,将其指向正确的子类构造函数本身,确保在使用 instanceof 等操作时能正确识别对象的构造函数类型。 Class.prototype.constructor = Class; + // 将 extend 方法也添加到子类的构造函数上,使得子类也能继续通过调用 extend 方法来实现进一步的继承,形成继承链,这里通过 arguments.callee 引用当前的 extend 函数本身来实现这个功能(不过在严格模式下,arguments.callee 是不允许使用的,代码可能需要调整)。 Class.extend = arguments.callee; + // 返回创建好的子类构造函数,外部可以通过调用这个构造函数来创建子类的实例对象,完成类的继承和实例化操作。 return Class; }; })(); + +// 使用前面定义的 Class 类及继承机制创建一个名为 validate 的类,它继承自 Class,主要用于实现表单验证相关的功能,比如验证表单字段是否符合特定的规则、显示错误提示等。 var validate = Class - .extend({ - defaultCfg:{ - rules:{}, - submitFun:function(){}, - errorLabel:'', - errorFun:function(){} - }, - init:function(cfg){ - this.cfg = $.extend({},this.defaultCfg,cfg); - this.flag=0; - this.toAction(this); - if(this.flag==0){ - for(var i in this.cfg.rules){ - $("#"+i).unbind("keyup"); - } - this.cfg.submitFun(); + .extend({ + // 默认配置对象,包含了验证相关的各种默认设置,如验证规则(rules)、提交表单时执行的函数(submitFun)、用于显示错误信息的HTML标签模板(errorLabel)以及出现错误时执行的函数(errorFun)等属性。 + defaultCfg: { + rules: {}, + submitFun: function () { }, + errorLabel: '', + errorFun: function () { } + }, + // 初始化方法,在创建 validate 类的实例时会被调用(如果不是处于类继承的初始化阶段,也就是 new 操作实例化时会执行),用于初始化验证相关的配置信息以及绑定一些事件处理等操作。 + init: function (cfg) { + // 使用 jQuery 的 extend 方法将传入的配置对象(cfg)与默认配置对象(defaultCfg)进行合并,得到最终的配置对象并赋值给 this.cfg,这样既可以使用默认配置,又能通过传入的参数覆盖部分默认配置。 + this.cfg = $.extend({}, this.defaultCfg, cfg); + // 初始化一个标志变量(flag)为0,用于记录表单验证过程中是否出现错误等情况,后续根据这个标志来决定是否执行提交表单等操作。 + this.flag = 0; + // 调用 toAction 方法并传入当前实例对象(this),开始进行表单验证相关的操作,比如遍历验证规则并对相应的表单字段进行验证。 + this.toAction(this); + // 如果验证过程中没有出现错误(flag 仍然为0),则解除表单字段的 keyup 事件绑定(可能是之前绑定的用于实时验证的事件,这里在全部验证通过后解除,避免重复验证等不必要的操作),然后执行提交表单的函数(submitFun),提交表单数据等操作(具体由这个函数的实现决定)。 + if (this.flag == 0) { + for (var i in this.cfg.rules) { + $("#" + i).unbind("keyup"); } - }, - toAction:function(that){ - for(var i in that.cfg.rules){ - this.toVal("#"+i,that.cfg.rules[i]); - } - }, - toVal:function(ele,constant){ - validateConstant[constant].test($(ele).val())? - this.toRemoveError(ele):this.toShowError(ele,errorMsg[constant]); + this.cfg.submitFun(); + } + }, + // 用于执行表单验证的主要方法,接收一个表示当前验证实例的对象(that),在这个方法内部会遍历配置的验证规则,并针对每个规则调用 toVal 方法对相应的表单字段进行验证操作。 + toAction: function (that) { + for (var i in that.cfg.rules) { + this.toVal("#" + i, that.cfg.rules[i]); + } + }, + // 具体验证单个表单字段的方法,接收一个表单字段的选择器(ele,一般是类似 "#inputId" 的形式,表示通过ID选择元素)以及对应的验证规则常量(constant,用于确定使用哪种验证规则来验证该字段),根据验证结果调用相应的方法来显示或移除错误提示信息。 + toVal: function (ele, constant) { + // 调用 validateConstant 对象中对应的验证规则函数(通过 constant 作为键来查找),传入表单字段的值(通过 jQuery 获取元素的值)进行验证,如果验证通过(返回 true),则调用 toRemoveError 方法移除该字段的错误提示信息,否则调用 toShowError 方法显示相应的错误提示信息(传入错误提示消息,通过 errorMsg 对象根据验证规则常量获取)。 + validateConstant[constant].test($(ele).val())? + this.toRemoveError(ele) : this.toShowError(ele, errorMsg[constant]); - }, - toRemoveError:function(ele){ - var that = this; - if($(ele).closest(".form-group").attr("not-allow")){ - $(ele).removeAttr("style").closest(".form-group").removeAttr("style") - .removeAttr("not-allow"); - $(ele).next().remove(); - $(ele).keyup(function(){ - ele = ele.replace("#",""); - that.toVal("#"+ele,that.cfg.rules[ele]); - }); - } - }, - toShowError:function(ele,message){ - var error = $(this.cfg.errorLabel).text(message); - if(!$(ele).closest(".form-group").attr("not-allow")){ - $(ele).after(error); - $(ele).css("border","1px solid red").closest(".form-group") - .css("color","red").attr("not-allow","true"); - $(ele).keyup(function(){ - ele = ele.replace("#",""); - that.toVal("#"+ele,that.cfg.rules[ele]); - }); - } - this.flag++; - var that = this; - + }, + // 用于移除表单字段错误提示信息的方法,接收一个表单字段的选择器(ele),首先获取当前验证实例对象(通过 this 赋值给 that 变量),然后判断该字段所在的表单组元素(通过 closest 方法查找父级的.form-group 元素)是否有 "not-allow" 属性,如果有则表示之前添加过错误提示等限制属性,现在需要移除这些属性,恢复表单字段和表单组的原始样式(通过 removeAttr 方法移除相关样式属性),同时移除该字段后面的错误提示标签(通过 next 方法找到并 remove 方法移除),最后重新绑定 keyup 事件,当用户再次输入内容时重新进行验证(调用 toVal 方法)。 + toRemoveError: function (ele) { + var that = this; + if ($(ele).closest(".form-group").attr("not-allow")) { + $(ele).removeAttr("style").closest(".form-group").removeAttr("style") + .removeAttr("not-allow"); + $(ele).next().remove(); + $(ele).keyup(function () { + ele = ele.replace("#", ""); + that.toVal("#" + ele, that.cfg.rules[ele]); + }); } - }) + }, + // 用于显示表单字段错误提示信息的方法,接收一个表单字段的选择器(ele)以及对应的错误提示消息(message),首先根据配置的错误标签模板(cfg.errorLabel)创建一个包含错误消息的