仰望星空——冲刺日志Day6
Part1 各个成员今日完成的任务
- 20211302:继续开发公文传输功能,实现公文的归档和检索。
- 20211304:进行权限控制功能的综合测试。
- 20211308:进行用户管理功能的最终测试和修复。
- 20211317:完成日志记录功能的开发,确保完整性和安全性。
- 20211318:处理国密算法的性能测试和评估反馈。
日志记录功能:
控制层:LogController
package cn.edu.nuc.article.controller; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import cn.edu.nuc.article.entity.Log; import cn.edu.nuc.article.service.LogService; /** * 日志Controller * @author 仰望星空 * */ @Controller @RequestMapping("/log") public class LogController { /** * 日志Service */ @Autowired private LogService logService; /** * 分页+模糊查询 * @param pageNo 当前页 * @param pageCount 每页记录数 * @param function 待查参数 * @return */ @RequestMapping("/logs") public String logs(Map<String, Object> map, @RequestParam(value="pageNo", defaultValue="1", required=false) Integer pageNo, @RequestParam(value="pageCount", defaultValue="10", required=false) Integer pageCount, @RequestParam(value="keyword", required=false) String keyword) { // 引入PageHelper分页插件 // 在查询之前只需要调用,传入页码,以及每页的大小 PageHelper.startPage(pageNo, pageCount); // 分页查询得到结果集 List<Log> logs; if (StringUtils.hasText(keyword)) { Log log = new Log(); log.setOptname(keyword); logs = logService.findByKeyword(log); } else { logs = logService.findByKeyword(null); } // 使用pageInfo包装查询后的结果,只需要将pageInfo交给页面就行了。 // 封装了详细的分页信息,包括有我们查询出来的数据,传入连续显示的页数 PageInfo<Log> page = new PageInfo<Log>(logs, 5); //保存结果集带到页面显示 map.put("page", page); map.put("pageNo", pageNo); map.put("pageCount", pageCount); //保存模糊查询条件以便回显 map.put("keyword", keyword); return "log/logManage"; } }
服务层:LogService.java
package cn.edu.nuc.article.service; import java.util.Date; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import cn.edu.nuc.article.dao.LogMapper; import cn.edu.nuc.article.entity.Log; /** * 日志逻辑 * @author 仰望星空 * */ @Service public class LogService { /** * 日志Mapper */ @Autowired private LogMapper logMapper; /** * 模糊查询 * @param log * @return */ public List<Log> findByKeyword(Log log) { return logMapper.selectByKeyword(log); } /** * 添加一条日志记录 * @param log * @return */ @Transactional public boolean addLog(Log log) { log.setOpttime(new Date()); return logMapper.insertSelective(log) > 0; } }
数据访问对象:LogMapper.java
package cn.edu.nuc.article.dao; import java.util.List; import cn.edu.nuc.article.entity.Log; /** * 日志Mapper * @author 仰望星空 * */ public interface LogMapper { /** * 选择性插入 * @param record * @return */ int insertSelective(Log record); /** * 模糊查询 * @param log * @return */ List<Log> selectByKeyword(Log log); }
实体类:Log.java
package cn.edu.nuc.article.entity; import java.io.Serializable; import java.util.Date; /** * 系统日志 * @author 仰望星空 * */ public class Log implements Serializable { /** * 序列化id */ private static final long serialVersionUID = 1L; /** * 日志id */ private Integer logid; /** * 操作名称 */ private String optname; /** * 业务id(非物理外键,但是却起到了物理外键的作用) */ private Integer bussinessId; /** * 操作人id(物理外键) */ private Integer operatorId; /** * 操作人(级联出来的对象,不是真实的数据库列) */ private User operator; /** * 操作时间(就是取添加日志时候服务器当前系统的时间) */ private Date opttime; /** * 操作人登陆的ip地址 */ private String ipaddress; public Integer getLogid() { return logid; } public void setLogid(Integer logid) { this.logid = logid; } public String getOptname() { return optname; } public void setOptname(String optname) { this.optname = optname == null ? null : optname.trim(); } public Integer getBussinessId() { return bussinessId; } public void setBussinessId(Integer bussinessId) { this.bussinessId = bussinessId; } public Integer getOperatorId() { return operatorId; } public void setOperatorId(Integer operatorId) { this.operatorId = operatorId; } public Date getOpttime() { return opttime; } public void setOpttime(Date opttime) { this.opttime = opttime; } public String getIpaddress() { return ipaddress; } public void setIpaddress(String ipaddress) { this.ipaddress = ipaddress == null ? null : ipaddress.trim(); } public User getOperator() { return operator; } public void setOperator(User operator) { this.operator = operator; } @Override public String toString() { return "Log [logid=" + logid + ", optname=" + optname + ", bussinessId=" + bussinessId + ", operatorId=" + operatorId + ", operator=" + operator + ", opttime=" + opttime + ", ipaddress=" + ipaddress + "]"; } //以logid作为唯一标示 @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((logid == null) ? 0 : logid.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Log other = (Log) obj; if (logid == null) { if (other.logid != null) return false; } else if (!logid.equals(other.logid)) return false; return true; } }
用户管理功能:
控制器:UserController.java
package cn.edu.nuc.article.controller; import java.io.InputStream; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import cn.edu.nuc.article.util.SM4Utils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.util.StringUtils; import org.springframework.validation.BindingResult; import org.springframework.validation.ObjectError; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import cn.edu.nuc.article.entity.Institution; import cn.edu.nuc.article.entity.Role; import cn.edu.nuc.article.entity.User; import cn.edu.nuc.article.service.InstitutionService; import cn.edu.nuc.article.service.RoleService; import cn.edu.nuc.article.service.UserService; import cn.edu.nuc.article.util.MD5Helper; import cn.edu.nuc.article.validategroup.UserValidateGroupForInsert; import cn.edu.nuc.article.validategroup.UserValidateGroupForPasswordModify; import cn.edu.nuc.article.validategroup.UserValidateGroupForUpdate; import cn.edu.nuc.article.validategroup.UserValidateGroupForUserModify; /** * 用户Controller * @author 仰望星空 * */ @Controller @RequestMapping("/user") public class UserController { /** * 用户Service */ @Autowired private UserService userService; /** * 角色Service */ @Autowired private RoleService roleService; /** * 机构service */ @Autowired private InstitutionService institutionService; /** * 执行批量添加操作 * @param map 回传参数用的map * @param file 用户上传的Excel工作簿 * @return * @throws Exception */ @RequestMapping("/addBatch") public String addBatch(Map<String, Object> map, MultipartFile file) throws Exception { //1.检测文件是否上传 if (file != null && file.getSize() == 0) { //文件没上传 map.put("result", false); map.put("msg", "您没有上传Excel工作簿文件!"); return "forward:/user/toAddBatch"; } //2.判断是否是Excel文件,如果不是就打回去 if ("application/vnd.ms-excel".equals(file.getContentType()) == false) { map.put("result", false); map.put("msg", "您上传的不是Excel工作簿文件!"); return "forward:/user/toAddBatch"; } //3.解析excel保存用户信息 if (userService.addUserBatch(file.getInputStream()) == false) { map.put("result", false); map.put("msg", "批量添加失败!"); return "forward:/user/toAddBatch"; } //4.如果操作成功,跳回到列表 map.put("result", true); map.put("msg", "批量添加成功!"); return "forward:/user/users"; } /** * 下载用户信息填写模板使用说明 * @param httpServletResponse response对象 * @return * @throws Exception */ @RequestMapping("/downloadReadFile") public ResponseEntity<byte[]> downloadReadFile( HttpServletResponse httpServletResponse) throws Exception { byte [] body = null; //获得输入流 InputStream in = this.getClass().getClassLoader().getResourceAsStream("excel/说明.docx"); body = new byte[in.available()]; in.read(body); HttpHeaders headers = new HttpHeaders(); headers.add("Content-Disposition", "attachment;filename=" + new String("说明.docx".getBytes(), "ISO-8859-1")); HttpStatus statusCode = HttpStatus.OK; ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(body, headers, statusCode); return response; } /** * 下载用户信息填写模板 * @param httpServletResponse response对象 * @return * @throws Exception */ @RequestMapping("/downloadExcel") public ResponseEntity<byte[]> downloadExcel( HttpServletResponse httpServletResponse) throws Exception { byte [] body = null; //获得输入流 InputStream in = this.getClass().getClassLoader().getResourceAsStream("excel/用户模板.xls"); body = new byte[in.available()]; in.read(body); HttpHeaders headers = new HttpHeaders(); headers.add("Content-Disposition", "attachment;filename=" + new String("用户模板.xls".getBytes(), "ISO-8859-1")); HttpStatus statusCode = HttpStatus.OK; ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(body, headers, statusCode); return response; } /** * 进入批量添加界面 * @return */ @RequestMapping("/toAddBatch") public String toAddBatch() { return "user/useraddBatch"; } /** * 进入修改用户密码的界面 * @param map * @param userid * @return */ @RequestMapping("/toPasswordModify") public String toPasswordModify(Map<String, Object> map) { return "user/usermodifypassword-self"; } /** * 用户修改自己的密码 * @param map * @param userid * @return */ @RequestMapping("/modifyPassword") public String modifyPassword(Map<String, Object> map, HttpSession session, //指定由哪个校验组校验 @Validated(value=UserValidateGroupForPasswordModify.class) User user, BindingResult bindingResult) { //检查校验是否出错 if(bindingResult.hasErrors()){ List<ObjectError> list = bindingResult.getAllErrors(); ObjectError oe = list.get(0); //校验失败信息 map.put("result", false); map.put("msg", oe.getDefaultMessage() + "修改密码失败!"); } else { //检查用户的原密码输对没有 User sessionUser = (User) session.getAttribute("user"); if (sessionUser.getPassword().equals(user.getOldPassword())) { //用户输对了旧密码 if (sessionUser.getPassword().equals(user.getPassword())) { //用户输入的新密码和原密码一致 map.put("msg", "新密码不能与旧密码相同!"); } else { //对新密码加密 if (StringUtils.hasText(user.getPassword())) { String original = user.getPassword(); MD5Helper md5Helper = new MD5Helper(); String afterEncodepassword = md5Helper.getTwiceMD5ofString(original); user.setPassword(afterEncodepassword); } user.setUserid(sessionUser.getUserid()); //保存用户信息,拿到修改操作的结果 boolean result = userService.updateUser(user); map.put("result", result); //根据操作结果生成提示信息 if (result == true) { //修改成功且无重复 //更新Session数据 session.setAttribute("user", userService.findbyId(sessionUser.getUserid())); map.put("msg", "修改密码成功!"); } else { map.put("msg", "系统出现错误,修改密码失败!"); } } } else { //用户没输对 map.put("msg", "您输入的旧密码不正确,修改密码失败!"); } } return "forward:/user/viewSelf"; } /** * 进入修改用户个人信息的界面 * @param map * @param userid * @return */ @RequestMapping("/toModifySelf") public String toModifySelf(Map<String, Object> map) { return "user/usermodify-self"; } /** * 用户修改自己的信息 * @param map * @param userid * @return */ @RequestMapping("/modifyself") public String modifyself(Map<String, Object> map, HttpSession session, //指定由哪个校验组校验 @Validated(value=UserValidateGroupForUserModify.class) User user, BindingResult bindingResult) { //检查校验是否出错 if(bindingResult.hasErrors()){ List<ObjectError> list = bindingResult.getAllErrors(); ObjectError oe = list.get(0); //校验失败信息 map.put("result", false); map.put("msg", oe.getDefaultMessage() + "修改个人信息失败!"); } else { //保存用户信息,拿到修改操作的结果 boolean result = userService.updateUser(user); map.put("result", result); //根据操作结果生成提示信息 if (result == true) { //修改成功且无重复 //更新Session的数据 session.setAttribute("user", userService.findbyId(user.getUserid())); map.put("msg", "修改个人信息成功!"); } else { map.put("msg", "修改个人信息失败!"); } } return "forward:/user/viewSelf"; } /** * 用户查看自己信息 * @param map * @param userid * @return */ @RequestMapping("/viewSelf") public String viewSelf(Map<String, Object> map, HttpSession session) { //加载出所有没有被禁用的机构 Institution institution = new Institution(); institution.setInststate(1); List<Institution> institutions = institutionService.findByKeyword(institution); map.put("institutionList", institutions); return "user/userview-self"; } /** * 管理员查看用户详细信息 * @param map * @param userid * @return */ @RequestMapping("/toView") public String toView(Map<String, Object> map, Integer userid) { loadUserInfo(map, userid); return "user/userview"; } /** * 进入修改用户界面 * @param map * @return */ @RequestMapping("/toModify") public String toModify(Map<String, Object> map, Integer userid) { loadUserInfo(map, userid); return "user/usermodify"; } /** * 抽取出来的方法:加载用户信息 * @param map * @param userid */ private void loadUserInfo(Map<String, Object> map, Integer userid) { //1.加载出所有没有被禁用的角色供用户选择 Role role = new Role(); role.setRolestate(1); List<Role> roles = roleService.getByKeyword(role); map.put("roleList", roles); //2.加载出所有没有被禁用的机构 Institution institution = new Institution(); institution.setInststate(1); List<Institution> institutions = institutionService.findByKeyword(institution); map.put("institutionList", institutions); //3.加载出待修改记录 User user = userService.findbyId(userid); map.put("user", user); } /** * 修改用户信息 * @param map * @param user * @param bindingResult * @return */ @RequestMapping("/modify") public String modify(Map<String, Object> map, //指定由哪个校验组校验 @Validated(value=UserValidateGroupForUpdate.class) User user, BindingResult bindingResult) { //检查校验是否出错 if(bindingResult.hasErrors()){ List<ObjectError> list = bindingResult.getAllErrors(); ObjectError oe = list.get(0); //校验失败信息 map.put("result", false); map.put("msg", oe.getDefaultMessage() + "修改用户[" + user.getUsertruename() + "]失败!"); } else { //登录名查重 boolean hasSame = userService.hasSameName(user.getUserid(), user.getLoginname()); if (hasSame == false) { //登录名名称不重复 //如果设置了新密码则需要对其加密 if (StringUtils.hasText(user.getPassword())) { // String original = user.getPassword(); // MD5Helper md5Helper = new MD5Helper(); String key = "975C7238C3824FB0"; System.out.println("ECB模式加密"); String afterEncode = SM4Utils.encryptSm4(user.getPassword(),key); // String afterEncodepassword = md5Helper.getTwiceMD5ofString(original); user.setPassword(afterEncode); } //保存用户信息,拿到修改操作的结果 boolean result = userService.updateUser(user); map.put("result", result); //根据操作结果生成提示信息 if (result == true) { //修改成功且无重复 map.put("msg", "修改用户[" + user.getUsertruename() + "]成功!"); } else { map.put("msg", "修改用户[" + user.getUsertruename() + "]失败!"); } } else { map.put("result", false); map.put("msg", "用户登录名[" + user.getUsertruename() + "]重复,修改用户失败!"); } } return "forward:/user/users"; } /** * 进入添加单个用户界面 * @param map * @return */ @RequestMapping("/toAdd") public String toAdd(Map<String, Object> map) { //1.加载出所有没有被禁用的角色供用户选择 Role role = new Role(); role.setRolestate(1); List<Role> roles = roleService.getByKeyword(role); map.put("roleList", roles); //2.加载出所有没有被禁用的机构 Institution institution = new Institution(); institution.setInststate(1); List<Institution> institutions = institutionService.findByKeyword(institution); map.put("institutionList", institutions); return "user/useradd"; } @RequestMapping("/add") public String add(Map<String, Object> map, //指定由固定的校验组校验 @Validated(value = UserValidateGroupForInsert.class) User user, BindingResult bindingResult) { //检查校验是否出错 if(bindingResult.hasErrors()){ List<ObjectError> list = bindingResult.getAllErrors(); ObjectError oe = list.get(0); //校验失败信息 map.put("result", false); map.put("msg", oe.getDefaultMessage() + "添加用户[" + user.getUsertruename() + "]失败!"); } else { //登录名查重 boolean hasSame = userService.hasSameName(null, user.getLoginname()); if (hasSame == false) { //登录名不重复 //如果设置了新密码则需要对其加密 if (StringUtils.hasText(user.getPassword())) { String original = user.getPassword(); MD5Helper md5Helper = new MD5Helper(); String afterEncodepassword = md5Helper.getTwiceMD5ofString(original); user.setPassword(afterEncodepassword); } //保存用户信息,拿到添加操作的结果 boolean result = userService.addUser(user); map.put("result", result); //根据操作结果生成提示信息 if (result == true) { //添加成功且无重复 map.put("msg", "添加用户[" + user.getUsertruename() + "]成功!"); } else { map.put("msg", "添加用户[" + user.getUsertruename() + "]失败!"); } } else { map.put("result", false); map.put("msg", "用户登录名[" + user.getUsertruename() + "]重复,添加用户失败!"); } } return "forward:/user/users"; } /** * 系统管理员查看用户列表 * @param map 携带查询结果和参数 * @param pageNo 目标页 * @param pageCount 每页显示多少记录 * @param keyword 查询关键字 * @return */ @RequestMapping("/users") public String users(Map<String, Object> map, @RequestParam(value="pageNo", defaultValue="1", required=false) Integer pageNo, @RequestParam(value="pageCount", defaultValue="10", required=false) Integer pageCount, @RequestParam(value="keyword", required=false) String keyword) { // 引入PageHelper分页插件 // 在查询之前只需要调用,传入页码,以及每页的大小 PageHelper.startPage(pageNo, pageCount); // 分页查询得到结果集 List<User> users; if (StringUtils.hasText(keyword)) { User user = new User(); user.setUsertruename(keyword); users = userService.findByKeyword(user); } else { users = userService.findByKeyword(null); } // 使用pageInfo包装查询后的结果,只需要将pageInfo交给页面就行了。 // 封装了详细的分页信息,包括有我们查询出来的数据,传入连续显示的页数 PageInfo<User> page = new PageInfo<User>(users, 5); //保存结果集带到页面显示 map.put("page", page); map.put("pageNo", pageNo); map.put("pageCount", pageCount); //保存模糊查询条件以便回显 map.put("keyword", keyword); return "user/userManage"; } }
服务层:UserService.java
package cn.edu.nuc.article.service; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.apache.ibatis.session.ExecutorType; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import cn.edu.nuc.article.dao.RoleMapper; import cn.edu.nuc.article.dao.UserMapper; import cn.edu.nuc.article.entity.Institution; import cn.edu.nuc.article.entity.Role; import cn.edu.nuc.article.entity.User; import cn.edu.nuc.article.util.ExcelTools; import cn.edu.nuc.article.util.MD5Helper; /** * 用户service * @author 仰望星空 * */ @Service public class UserService { /** * 用户Mapper */ @Autowired private UserMapper userMapper; /** * 角色Mapper */ @Autowired private RoleMapper roleMapper; /** * 机构Service */ @Autowired private InstitutionService institutionService; /** * 角色Service */ @Autowired private RoleService roleService; /** * 创建SqlSession的工厂 */ @Autowired private SqlSessionFactory sqlSessionFactory; /** * 修改用户 * @param user * @return */ @Transactional public boolean updateUser(User user) { return userMapper.updateByPrimaryKeySelective(user) > 0; } /** * 逐个添加用户 * @param user * @return */ @Transactional public boolean addUser(User user) { return userMapper.insertSelective(user) > 0; } /** * 批量添加用户(读取Excel并添加到数据库) * @param inputStream 读取上传的Excel数据表格的InputStream * @return 操作结果:true表示操作成功, false表示操作失败 */ @Transactional public boolean addUserBatch(InputStream inputStream){ //1.从Excel表格读取数据,数据存放在map中,键是从1开始的数字,代表行号,值是读取的数据,是字符串格式,以"-"作为分隔符,需要解析 ExcelTools excelReader = new ExcelTools(); Map<Integer, String> map = excelReader.readExcelContent(inputStream); //2.将读取的数据封装为User对象并形成列表 //2.1 获取Map中的每一个Entry List<User> users = new ArrayList<>(); Set<Entry<Integer, String>> entry = map.entrySet(); for (Entry<Integer, String> entryiter : entry) { //2.2 读取出Entry中的值,即用户信息字符串 String userdatastring = entryiter.getValue(); //2.3 通过分隔符"-"来解析数据,得到一个字符串数组,这个字符串数组代表一行数据 String[] dataarray = userdatastring.split("-"); //2.4 使用取出的字符串数组拼装出一个User对象 User user = new User(); String loginname = dataarray[0]; if (userMapper.loginnameValidate(null, loginname).size() > 0) { return false; } user.setLoginname(loginname); //对用户输入的密码进行加密 String password = dataarray[1].split("\\.")[0]; MD5Helper md5Helper = new MD5Helper(); String afterEncodepassword = md5Helper.getTwiceMD5ofString(password); user.setPassword(afterEncodepassword); user.setUsertruename(dataarray[2]); user.setJob(dataarray[3]); String phone = dataarray[4]; Double doublevalue = Double.parseDouble(phone); user.setPhone(Long.toString(doublevalue.longValue())); user.setEmail(dataarray[5]); Institution institution = new Institution(); institution.setInstname(dataarray[6]); institution = institutionService.findByKeyword(institution).get(0); user.setInstId(institution.getInstid()); Role role = new Role(); role.setRolename(dataarray[7]); role = roleService.getByKeyword(role).get(0); user.setRoleId(role.getRoleid()); user.setUserstate(1); //2.5 将拼装好的User对象加入到集合中 users.add(user); } //3.使用批量处理方式将数据加入数据库 //3.1 通过SessionFactory得到批量处理的SqlSession SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); //3.2 获得可以批量处理的UserMapper UserMapper userMapper = sqlSession.getMapper(UserMapper.class); //3.3 对每一个用户执行添加操作,通过“攒Sql”方式,全部编译完成后发给数据库,数据库一次性执行完成 try { for (User user : users) { if (userMapper.insertSelective(user) == 0) { //添加用户过程中出错 sqlSession.rollback(); sqlSession.close(); return false; } } //3.4 批量处理方式需要手动提交事务 sqlSession.commit(); return true; } catch (Exception e) { e.printStackTrace(); //3.5 出现异常要回滚事务 sqlSession.rollback(); return false; } finally { //3.6 无论是否出现异常,操作结束后都要关闭session sqlSession.close(); } } /** * 找出所有未被禁用的审核人员 * @return */ public List<User> findValidAuditor(Integer instid) { //设置查询的筛选信息 User user = new User(); user.setUserstate(1); //找出审核人员的id Role role = new Role(); role.setRolename("审核"); role = roleMapper.selectByKeyword(role).get(0); user.setRoleId(role.getRoleid()); //如果要限制企业 if (instid != null) { user.setInstId(instid); } return userMapper.selectByKeyWord(user); } /** * 找出所有未被禁用的审核人员 * @return */ public List<User> findValidAuditorRoleId(Integer instid, Integer roleId) { //设置查询的筛选信息 User user = new User(); user.setUserstate(1); //找出审核人员的id Role role = new Role(); role.setRolename("审核"); // role.setRoleid(roleId); role = roleMapper.selectByKeyword(role).get(0); user.setRoleId(role.getRoleid()); //如果要限制企业 if (instid != null) { user.setInstId(instid); } return userMapper.selectByKeyWord(user); } /** * 找出未被禁用的用户(作为备选项) * @return */ public List<User> findValidUser() { User user = new User(); user.setUserstate(1); return userMapper.selectByKeyWord(user); } /** * 检查登录名是否重复 * @param userid 用户id * @param loginname 登录名 * @return true 表示重复, false 表示不重复 */ public boolean hasSameName(Integer userid, String loginname) { return userMapper.loginnameValidate(userid, loginname).size() > 0; } /** * 登录检查 * @param loginname 登录名 * @param password 密码 * @return true 表示登录检查通过, false 表示不通过 */ public User loginValidate(String loginname, String password) { return userMapper.loginValidate(loginname, password); } /** * 模糊查询 * @return */ public List<User> findByKeyword(User user) { return userMapper.selectByKeyWord(user); } /** * 按用户id查询 * @param userid * @return */ public User findbyId(Integer userid) { return userMapper.selectByPrimaryKey(userid); } }
数据访问对象:UserMapper.java
package cn.edu.nuc.article.dao; import java.util.List; import org.apache.ibatis.annotations.Param; import cn.edu.nuc.article.entity.User; /** * 用户Mapper * @author 仰望星空 * */ public interface UserMapper { /** * 检查用户名是否重复 * @param userid 用户id * @param loginname 登录名 * @return */ List<User> loginnameValidate(@Param("userid") Integer userid, @Param("loginname") String loginname); /** * 登录检查 * @param loginname 登录名 * @param password 密码 * @return 符合用户名密码组合的用户记录 */ User loginValidate(@Param("loginname") String loginname, @Param("password") String password); /** * 按条件模糊查询 * @param user * @return */ List<User> selectByKeyWord(User user); /** * 按主键更新 * @param userid * @return */ User selectByPrimaryKey(Integer userid); /** * 动态插入记录 * @param record * @return */ int insertSelective(User record); /** * 动态更新记录 * @param record * @return 受影响行数 */ int updateByPrimaryKeySelective(User record); }
实体类:User.java
package cn.edu.nuc.article.entity; import java.io.Serializable; import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; import org.hibernate.validator.constraints.Email; import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.NotBlank; import cn.edu.nuc.article.validategroup.UserValidateGroupForInsert; import cn.edu.nuc.article.validategroup.UserValidateGroupForPasswordModify; import cn.edu.nuc.article.validategroup.UserValidateGroupForUpdate; import cn.edu.nuc.article.validategroup.UserValidateGroupForUserModify; /** * 用户实体类 * @author 仰望星空 * */ public class User implements Serializable{ /** * 序列化id */ private static final long serialVersionUID = 1L; /** * 用户id(主键) */ private Integer userid; /** * 登录名 */ @NotNull(message="登录名不可以为空!", groups={UserValidateGroupForInsert.class}) @NotBlank(message="登录名不可以填写空格!", groups={UserValidateGroupForInsert.class}) @Length(min = 4, max = 30, message="登录名输入长度不合法!", groups={UserValidateGroupForInsert.class}) @Pattern(message="登录名登录名只能由字母和数字组成!",regexp="[A-Za-z0-9]+", groups={UserValidateGroupForInsert.class}) private String loginname; /** * 密码 */ @NotNull(message="密码不可以为空!", //校验组指定校验规则什么时候生效 groups={UserValidateGroupForInsert.class, UserValidateGroupForPasswordModify.class}) @NotBlank(message="密码不可以填写空格!", //校验组指定校验规则什么时候生效 groups={UserValidateGroupForInsert.class, UserValidateGroupForPasswordModify.class}) @Length(max = 30, message="密码输入长度不合法!", //校验组指定校验规则什么时候生效 groups={UserValidateGroupForInsert.class, UserValidateGroupForPasswordModify.class}) private String password; /** * 旧密码(数据库没有对应列) */ @NotNull(message="旧密码不可以为空!", //校验组指定校验规则什么时候生效 groups={UserValidateGroupForPasswordModify.class}) @NotBlank(message="旧密码不可以填写空格!", //校验组指定校验规则什么时候生效 groups={UserValidateGroupForPasswordModify.class}) @Length(max = 30, message="旧密码输入长度不合法!", //校验组指定校验规则什么时候生效 groups={UserValidateGroupForPasswordModify.class}) private String oldPassword; /** * 用户真实姓名 */ @NotNull(message="用户真实姓名不可以为空!", groups={UserValidateGroupForInsert.class}) @NotBlank(message="用户真实姓名不可以填写空格!", groups={UserValidateGroupForInsert.class}) @Length(min = 2, max = 20, message="用户真实姓名输入长度不合法!", groups={UserValidateGroupForInsert.class}) @Pattern(regexp="[\\u4E00-\\u9FA5\\uF900-\\uFA2D]+", message="用户真实姓名只能输入中文汉字!", groups={UserValidateGroupForInsert.class}) private String usertruename; /** * 职称 */ @NotNull(message="职称不可以为空!") @NotBlank(message="职称不可以填写空格!") @Pattern(regexp="[\\u4E00-\\u9FA5\\uF900-\\uFA2D]+", message="职称只能输入中文汉字!", groups={UserValidateGroupForInsert.class, UserValidateGroupForUpdate.class, UserValidateGroupForUserModify.class}) private String job; /** * 手机号 */ @NotBlank(message="手机号不可以填写空格!", groups={UserValidateGroupForInsert.class, UserValidateGroupForUpdate.class, UserValidateGroupForUserModify.class}) @Pattern(regexp="1[3|5|7|8]\\d{9}", message="手机号格式不正确!", groups={UserValidateGroupForInsert.class, UserValidateGroupForUpdate.class, UserValidateGroupForUserModify.class}) private String phone; /** * 邮箱 */ @Email(message="您输入的邮箱格式不合法!", groups={UserValidateGroupForInsert.class, UserValidateGroupForUpdate.class, UserValidateGroupForUserModify.class}) @NotBlank(message="邮箱不可以填写空格!", groups={UserValidateGroupForInsert.class, UserValidateGroupForUpdate.class, UserValidateGroupForUserModify.class}) private String email; /** * 所属机构(外键) */ private Integer instId; /** * 所属机构信息 */ private Institution institution; /** * 角色id(外键) */ private Integer roleId; /** * 用户角色 */ private Role role; /** * 用户状态(1正常,0禁用) */ private Integer userstate; public Integer getUserid() { return userid; } public void setUserid(Integer userid) { this.userid = userid; } public String getLoginname() { return loginname; } public void setLoginname(String loginname) { this.loginname = loginname; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getOldPassword() { return oldPassword; } public void setOldPassword(String oldPassword) { this.oldPassword = oldPassword; } public String getUsertruename() { return usertruename; } public void setUsertruename(String usertruename) { this.usertruename = usertruename; } public String getJob() { return job; } public void setJob(String job) { this.job = job; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Integer getInstId() { return instId; } public void setInstId(Integer instId) { this.instId = instId; } public Institution getInstitution() { return institution; } public void setInstitution(Institution institution) { this.institution = institution; } public Integer getRoleId() { return roleId; } public void setRoleId(Integer roleId) { this.roleId = roleId; } public Role getRole() { return role; } public void setRole(Role role) { this.role = role; } public Integer getUserstate() { return userstate; } public void setUserstate(Integer userstate) { this.userstate = userstate; } @Override public String toString() { return "User [userid=" + userid + ", loginname=" + loginname + ", password=" + password + ", oldPassword=" + oldPassword + ", usertruename=" + usertruename + ", job=" + job + ", phone=" + phone + ", email=" + email + ", instId=" + instId + ", institution=" + institution + ", roleId=" + roleId + ", role=" + role + ", userstate=" + userstate + "]"; } /** * 用用户id作为唯一标识 */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((userid == null) ? 0 : userid.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; User other = (User) obj; if (userid == null) { if (other.userid != null) return false; } else if (!userid.equals(other.userid)) return false; return true; } }
Part2 各个成员遇到的问题
- 继续开发公文传输功能(20211302):编辑和查看功能复杂性: 实现公文的查看和编辑功能可能牵涉到富文本编辑、版本控制等复杂的需求。选择适当的富文本编辑库,确保编辑器的易用性和功能丰富性。使用版本控制系统,追踪和管理公文的修改历史。进行用户测试,确保用户能够轻松使用编辑和查看功能。
- 完善权限表,实现细粒度的权限控制(20211304):权限设计复杂性: 实现细粒度的权限控制可能需要考虑到各种操作和资源的权限设置。利用 RBAC 或 ABAC 模型,将权限分配与角色关联,以简化权限管理。进行系统内的模拟测试,验证各种场景下权限的正常工作。使用权限管理工具,简化权限设置和维护。
- 处理用户管理功能的反馈(20211308):稳定性问题: 用户管理功能的反馈可能包括系统崩溃、性能问题等方面的反馈。进行详细的日志记录,以便在出现问题时能够快速定位和解决。使用监控工具实时监测系统的性能。进行持续集成和自动化测试,确保每次代码变更都不会引入新的稳定性问题。
- 继续开发日志记录功能,记录更多的操作信息(20211317):日志记录性能和存储问题: 记录大量的操作信息可能导致性能问题和存储成本增加。选择适当的日志记录库,确保能够满足性能需求。进行日志的归档和定期清理,以控制存储成本。根据实际需求,采用异步方式记录日志,减轻对主业务逻辑的影响。
- 完成国密算法的集成和性能优化(20211318):性能优化困难: 集成国密算法后,可能需要优化算法以提高性能。进行性能分析,找到性能瓶颈。考虑使用硬件加速、并行计算等方式优化算法。使用缓存技术,避免重复计算。进行性能测试,确保优化效果符合预期。
Part3 明日各个成员的任务安排
- 20211302:进行公文传输功能的系统测试,确保完整的功能。
- 20211304:测试权限控制功能的性能,确保不会影响系统性能。
- 20211308:进行用户管理功能的最终测试,准备发布版本。
- 20211317:进行日志记录功能的系统测试,确保记录正常。
- 20211318:处理国密算法的评估结果,准备正式集成。
Part4 各个成员今日对项目的贡献量
Part5 燃尽图与站立式会议照片