仰望星空——冲刺日志Day5
Part1 各个成员今日完成的任务
- 20211302:继续开发公文传输功能,实现公文的查看和编辑。
- 20211304:完善权限表,实现细粒度的权限控制。
- 20211308:继续处理用户管理功能的反馈,确保稳定性。
- 20211317:继续开发日志记录功能,记录更多的操作信息。
- 20211318:完成国密算法的集成和性能优化。
公文的查看和编辑功能:
控制器:ArticleController.java
package cn.edu.nuc.article.controller; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.activiti.engine.RuntimeService; import org.activiti.engine.TaskService; import org.activiti.engine.runtime.ProcessInstance; import org.activiti.engine.task.Task; 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.transaction.annotation.Transactional; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import cn.edu.nuc.article.dto.TreeDto; import cn.edu.nuc.article.entity.Article; import cn.edu.nuc.article.entity.Attachment; import cn.edu.nuc.article.entity.AuditMessage; import cn.edu.nuc.article.entity.Log; import cn.edu.nuc.article.entity.User; import cn.edu.nuc.article.service.ArticleService; import cn.edu.nuc.article.service.AttachmentService; import cn.edu.nuc.article.service.AuditMessageService; import cn.edu.nuc.article.service.FileService; import cn.edu.nuc.article.service.LogService; import cn.edu.nuc.article.service.ReceiveService; import cn.edu.nuc.article.service.UserService; import cn.edu.nuc.article.util.IpUtil; /** * 公文Controller * @author 仰望星空 * */ @Controller @RequestMapping("/article") public class ArticleController { /** * 公文Service */ @Autowired private ArticleService articleService; /** * 用户Service */ @Autowired private UserService userService; /** * 文件服务 */ @Autowired private FileService fileService; /** * 公文接收Service */ @Autowired private ReceiveService receiveService; /** * 附件Service */ @Autowired private AttachmentService attachmentService; /** * 公文审核信息Service */ @Autowired private AuditMessageService auditMessageService; /** * 日志Service */ @Autowired private LogService logService; /** * Activiti运行时Service,用于启动流程 */ @Autowired private RuntimeService runtimeService; /** * Activiti任务Service,查询待办任务和完成任务 */ @Autowired private TaskService taskService; /** * 公文修改(撰稿) * @return */ @RequestMapping("/modifyArticle") @Transactional public String modifyArticle(Map<String, Object> map, HttpSession session , String title, Integer articleId, Integer[] received, Integer auditor, String taskId, @RequestParam(name= "doc", required = false) MultipartFile doc, @RequestParam(name= "attachment", required = false) MultipartFile[] attachment) { try { //1.首先检查必填项是否都填写正确 if (validateForm(map, articleId, title, received, auditor, doc) == false) { return "forward:/article/toModify"; } //2.设置公文相关参数并新增公文 Article article = new Article(); article.setArticleid(articleId); article.setArticlestate(0); //0表示审核中 article.setTitle(title); //撰稿人、审稿人、发布时间在公文撰稿时已经设置过,不需要也不能改 //判断操作结果是否成功 if (!articleService.modifyArticle(article)) { map.put("msg", "系统出现错误,在修改公文信息时操作失败!"); map.put("result", false); return "forward:/article/toModify"; } //拿到修改后的公文信息 User user = (User) session.getAttribute("user"); article = articleService.getArticleById(articleId, user.getUserid()); //3 删除旧的接收关系,再添加信息 //3.1 删除旧的接收关系 if (receiveService.deleteReceive(articleId)) { //3.2 添加新的接收人信息 for (Integer receiverId : received) { if (!receiveService.addReceive(articleId, receiverId)) { map.put("msg", "系统出现错误,在修改公文接收人信息时操作失败!"); map.put("result", false); return "forward:/article/toModify"; } } } else { map.put("msg", "系统出现错误,在修改公文接收人信息时操作失败!"); map.put("result", false); return "forward:/article/toModify"; } //4. 看一下公文原文是否需要更新,如果需要则更新之 if (doc != null && doc.getSize() != 0) { //4.1 删掉旧的公文原文信息 Attachment target = null; for (Attachment attachment2 : article.getAttachments()) { if (attachment2.getAttachtype() == 0) { //正文 target = attachment2; } } boolean result = attachmentService.deleteAttachment(target.getAttachmentid()); if (result == true) { //4.2 调用FileService,使用JackRabbit保存新的公文电子文档 String fileId = fileService.save(doc.getInputStream()); //4.3 拼装出公文原文的附件信息 Attachment articleDocument = new Attachment(); articleDocument.setArticleId(article.getArticleid()); articleDocument.setAttachtype(0); //0表示正文 articleDocument.setFilename(doc.getOriginalFilename()); articleDocument.setMimetype(doc.getContentType()); articleDocument.setUploadtime(new Date()); articleDocument.setFilesize(doc.getSize()); articleDocument.setFileid(fileId); //JackRabbit返回的FileId //4.4 添加信息到附件表 if (!attachmentService.addAttachment(articleDocument)) { map.put("msg", "系统出现错误,在添加公文附件时操作失败!"); map.put("result", false); return "forward:/article/toModify"; } } else { map.put("msg", "系统出现错误,在删除公文旧附件时操作失败!"); map.put("result", false); return "forward:/article/toModify"; } } //5.如果用户上传了附件,就要做对应更新 if (attachment != null && attachment.length != 0 && attachment[0].getSize() != 0) { //5.1 删掉公文旧附件 for (Attachment attachment2 : article.getAttachments()) { if (attachment2.getAttachtype() != 0) { //附件 attachmentService.deleteAttachment(attachment2.getAttachmentid()); } } //5.2 上传新附件 for (MultipartFile attachFile : attachment) { //5.2.1 调用FileService,使用JackRabbit保存公文附件 String attfileId = fileService.save(attachFile.getInputStream()); //5.2.2 拼装附件信息 Attachment attch = new Attachment(); attch.setArticleId(article.getArticleid()); attch.setAttachtype(1); //1表示附件 attch.setFileid(attfileId); attch.setFilename(attachFile.getOriginalFilename()); attch.setFilesize(attachFile.getSize()); attch.setMimetype(attachFile.getContentType()); attch.setUploadtime(new Date()); //5.2.3 添加信息到附件表 if (!attachmentService.addAttachment(attch)) { map.put("msg", "系统出现错误,在修改公文附件时操作失败!"); map.put("result", false); return "forward:/article/toModify"; } } } //6.完成公文修改的待办任务,使其转向公文审核任务 //6.1 完成选择,使其转向修改公文任务 Map<String, Object> variables = new HashMap<>(); variables.put("decision", true); taskService.complete(taskId, variables); //6.2 根据流程实例和办理人查询待办,得到修改公文任务的TaskId,然后完成该任务 Task task = taskService.createTaskQuery() .taskAssignee(user.getUserid().toString()) .processInstanceId(article.getProcessinstanceId()) .singleResult(); taskService.complete(task.getId()); //7.如果以上操作都没有问题,那就是成功了 map.put("msg", "公文[" + article.getTitle() + "]上传成功,请耐心等待审核!"); map.put("result", true); //返回等待审核结果界面 return "forward:/article/toAduitResult"; } catch (Exception e) { System.out.println("公文修改出错!"); e.printStackTrace(); map.put("msg", "系统出现严重错误,公文修改操作失败!"); map.put("result", false); return "forward:/article/toModfiy"; } } /** * 进入公文修改界面 * @return * @throws Exception */ @RequestMapping("/toModfiy") public String toModify(HttpSession session, Map<String, Object> map, Integer articleId, String taskId) throws Exception { //加载出该用户所在机构所有审稿人姓名 //1 从Session中取出User User user = (User) session.getAttribute("user"); //2 通过用户得到其所在机构的id Integer instid = user.getInstId(); //3 得到该机构所有未被禁用的审核人员的信息 List<User> auditors = userService.findValidAuditor(instid); //4 得到公文信息 Article article = articleService.getArticleById(articleId, user.getUserid()); //5 保存为备选项 map.put("auditors", auditors); map.put("article", article); map.put("taskId", taskId); return "article/articlemodify"; } /** * 通过Ajax方式获得联系人树(修改) * @return * @throws Exception */ @ResponseBody @RequestMapping("/getTreeModify") public List<TreeDto> getTreeModify(HttpSession session, Integer articleId) throws Exception { User user = (User) session.getAttribute("user"); List<TreeDto> dtos = new ArrayList<>(); dtos.add(articleService.getTreeDTOJSON(articleId, user.getUserid())); return dtos; } /** * 用户选择删除公文 * @param map * @return */ @RequestMapping("/deleteArticle") public String deleteArticle(Map<String, Object> map, Integer articleId, String taskId) { //设置公文状态为被删除 Article article = new Article(); article.setArticleid(articleId); article.setArticlestate(4); if (articleService.modifyArticle(article)) { Map<String, Object> variables = new HashMap<>(); variables.put("decision", false); taskService.complete(taskId, variables); map.put("msg", "删除公文成功"); map.put("result", true); } else { map.put("msg", "删除公文失败"); map.put("result", false); } return "forward:/article/toAduitResult"; } /** * 按id加载公文接收信息 * @return */ @RequestMapping("/findByIdHistory") public String findByIdHistory(Map<String, Object> map, HttpSession session, HttpServletRequest request, Integer articleId) { //1.从Session中获得User,取得其UserId User user = (User) session.getAttribute("user"); Integer userId = user.getUserid(); //2.向日志表插入一条日志记录 Log log = new Log(); log.setBussinessId(articleId); log.setIpaddress(IpUtil.getRequestRealIp(request)); //获取ip地址 log.setOperatorId(userId); log.setOptname("查看公文"); log.setOpttime(new Date()); logService.addLog(log); //3.检查访问权限 if (articleService.isArticleAvaliable(articleId, userId) == true) { Article article = articleService.getArticleById(articleId, userId); //4.保存查询结果 map.put("article", article); return "article/articleDetail"; } else { map.put("msg", "您没有查看公文的权限!"); map.put("result", false); return "forward:/article/getMyHistoryList"; } } /** * 查询接收公文信息 * @param map * @param session * @param keyword * @return */ @RequestMapping("/getMyHistoryList") public String getMyHistoryList(Map<String, Object> map, HttpSession session, @RequestParam(value="keyword", required=false) String keyword) { //找出当前登录用户 User user = (User) session.getAttribute("user"); //设置查询条件 Article article = new Article(); article.setUserId(user.getUserid()); if (StringUtils.hasText(keyword)) { //用户指定了查询关键字 article.setTitle(keyword); } List<Article> articles = articleService.getMyArticleList(article); //保存结果集带到页面显示 map.put("articles", articles); //保存模糊查询条件以便回显 map.put("keyword", keyword); return "article/articleHistoryManage"; } /** * 按id加载公文接收信息 * @return */ @RequestMapping("/findByIdReceive") public String findByIdReceive(Map<String, Object> map, HttpSession session, HttpServletRequest request, Integer articleId) { //1.从Session中获得User,取得其UserId User user = (User) session.getAttribute("user"); Integer userId = user.getUserid(); //2.向日志表插入一条日志记录 Log log = new Log(); log.setBussinessId(articleId); log.setIpaddress(IpUtil.getRequestRealIp(request)); //获取ip地址 log.setOperatorId(userId); log.setOptname("查看公文"); log.setOpttime(new Date()); logService.addLog(log); //3.检查访问权限 if (articleService.isArticleAvaliable(articleId, userId) == true) { Article article = articleService.getArticleById(articleId, userId); //4.保存查询结果 map.put("article", article); return "article/articleDetail"; } else { map.put("msg", "您没有查看公文的权限!"); map.put("result", false); return "forward:/article/getMyReceiveList"; } } /** * 查询接收公文信息 * @param map * @param session * @param keyword * @return */ @RequestMapping("/getMyReceiveList") public String getMyReceiveList(Map<String, Object> map, HttpSession session, @RequestParam(value="keyword", required=false) String keyword) { //找出当前登录用户 User user = (User) session.getAttribute("user"); //设置查询条件 Article article = new Article(); article.setArticlestate(3); article.setUserId(user.getUserid()); if (StringUtils.hasText(keyword)) { //用户指定了查询关键字 article.setTitle(keyword); } List<Article> articles = articleService.getMyArticles(article); //保存结果集带到页面显示 map.put("articles", articles); //保存模糊查询条件以便回显 map.put("keyword", keyword); return "article/articleReceiveManage"; } /** * 提交公文审核结果 * @param map * @param taskId * @param result * @param articleId * @param auditmessage * @return */ @RequestMapping("/submitAuditResult") public String submitAuditResult(Map<String, Object> map, String taskId, Integer result, Integer articleId, String auditmessage){ AuditMessage auditMessage = new AuditMessage(); auditMessage.setAuditdate(new Date()); auditMessage.setAuditmessage(auditmessage); auditMessage.setAuditresult(result); auditMessage.setArticleId(articleId); //先添加审核信息 if (auditMessageService.addAuditMessage(auditMessage)) { Map<String, Object> variables = new HashMap<>(); if (result == 1) { //审核通过 variables.put("auditresult", true); Article article = new Article(); article.setArticleid(articleId); article.setArticlestate(3); //3表示审核通过且发布 articleService.modifyArticle(article); //更新数据库字段 } else { variables.put("auditresult", false); Article article = new Article(); article.setArticleid(articleId); article.setArticlestate(2); //2表示审核驳回 articleService.modifyArticle(article); //更新数据库字段 } //使用流程变量完成待办任务 taskService.complete(taskId, variables); map.put("msg", "提交审核结果成功!"); map.put("result", true); } else { map.put("msg", "提交审核结果失败!"); map.put("result", false); } return "redirect:/article/toAduit"; } /** * 下载公文或附件 * @param session * @param filename * @param fileId * @return * @throws Exception */ @RequestMapping("/download") public ResponseEntity<byte[]> downloadArticle(HttpSession session, HttpServletRequest request, HttpServletResponse httpServletResponse, Integer attachmentid, String fileId) throws Exception { byte [] body = null; Attachment attachment = new Attachment(); attachment.setAttachmentid(attachmentid); attachment = attachmentService.findByKeyword(attachment).get(0); User user = (User) session.getAttribute("user"); boolean result = articleService.isArticleAvaliable( attachment.getArticleId(), user.getUserid()); if (result == true) { //如果下载的是公文原文而不是附件,则向日志表插入一条日志记录 if (attachment.getAttachtype() == 0) { Log log = new Log(); log.setBussinessId(attachment.getArticleId()); log.setIpaddress(IpUtil.getRequestRealIp(request)); //获取ip地址 log.setOperatorId(user.getUserid()); log.setOptname("下载公文"); log.setOpttime(new Date()); logService.addLog(log); } //通过JackRabbit找到文件,获得输入流 InputStream in = fileService.getByFileId(fileId); body = new byte[in.available()]; in.read(body); HttpHeaders headers = new HttpHeaders(); headers.add("Content-Disposition", "attachment;filename=" + new String(attachment.getFilename().getBytes(), "ISO-8859-1")); HttpStatus statusCode = HttpStatus.OK; ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(body, headers, statusCode); return response; } return null; } /** * 按id加载公文信息 * @return */ @RequestMapping("/toAuditPage") public String toAuditPage(Map<String, Object> map, HttpSession session, Integer articleId) { //1.从Session中获得User,取得其UserId User user = (User) session.getAttribute("user"); Integer userId = user.getUserid(); //2. 读取当前用户的待办任务,包括直接分配给当前人或已经签收的任务 List<Task> doingTask = taskService.createTaskQuery() .taskAssignee(user.getUserid().toString()).list(); //2.检查访问权限 if (articleService.isArticleAvaliable(articleId, userId) == true) { //3.查询公文信息 Article article = articleService.getArticleById(articleId, userId); //4.根据公文的流程实例id找到当前任务 Task task = null; for (Task task1 : doingTask) { if (article.getProcessinstanceId().equals(task1.getProcessInstanceId())) { task = task1; } } //3.保存查询结果 map.put("article", article); map.put("task", task); return "article/articleAuditDetail"; } else { map.put("msg", "您没有查看公文的权限!"); map.put("result", false); return "forward:/article/toAduit"; } } /** * 按id加载公文审核结果信息 * @return */ @RequestMapping("/findById") public String findById(Map<String, Object> map, HttpSession session, HttpServletRequest request, Integer articleId) { //1.从Session中获得User,取得其UserId User user = (User) session.getAttribute("user"); Integer userId = user.getUserid(); //2.检查访问权限 if (articleService.isArticleAvaliable(articleId, userId) == true) { //3.向日志表插入一条日志记录 Log log = new Log(); log.setBussinessId(articleId); log.setIpaddress(IpUtil.getRequestRealIp(request)); //获取ip地址 log.setOperatorId(userId); log.setOptname("查看公文"); log.setOpttime(new Date()); logService.addLog(log); Article article = articleService.getArticleById(articleId, userId); //4.保存查询结果 map.put("article", article); return "article/articleDetail"; } else { map.put("msg", "您没有查看公文的权限!"); map.put("result", false); return "forward:/article/toAduitResult"; } } /** * 进入审核界面 * @param map * @param pageNo * @param pageCount * @param keyword * @return */ @RequestMapping("/toAduit") public String toAduit(Map<String, Object> map, HttpSession session, @RequestParam(value="keyword", required=false) String keyword) { // 查询得到结果集 List<Article> articles; User user = (User) session.getAttribute("user"); //读取当前用户的待办任务,包括直接分配给当前人或已经签收的任务 List<Task> doingTask = taskService.createTaskQuery() .taskAssignee(user.getUserid().toString()).list(); if (doingTask != null && doingTask.size() != 0) { //有该用户的待办任务 if (StringUtils.hasText(keyword)) { //用户指定了查询关键字 articles = articleService.getByProcessInstances(doingTask, keyword, Arrays.asList(0)); } else { //用户没指定查询关键字 articles = articleService.getByProcessInstances(doingTask, null, Arrays.asList(0)); } } else { //没有待办任务 articles = new ArrayList<>(); } //保存结果集带到页面显示 map.put("articles", articles); map.put("tasks", doingTask); //保存模糊查询条件以便回显 map.put("keyword", keyword); return "article/articleAuditManage"; } /** * 进入审核结果 * @param map * @param pageNo * @param pageCount * @param keyword * @return */ @RequestMapping("/toAduitResult") public String toAduitResult(Map<String, Object> map, HttpSession session, @RequestParam(value="keyword", required=false) String keyword) { // 查询得到结果集 List<Article> articles; User user = (User) session.getAttribute("user"); //读取当前用户的待办任务,包括直接分配给当前人或已经签收的任务 List<Task> doingTask = taskService.createTaskQuery() .taskAssignee(user.getUserid().toString()).list(); if (doingTask != null && doingTask.size() != 0) { //有该用户的待办任务 if (StringUtils.hasText(keyword)) { //用户指定了查询关键字 articles = articleService.getByProcessInstances(doingTask, keyword, Arrays.asList(1, 2)); } else { //用户没指定查询关键字 articles = articleService.getByProcessInstances(doingTask, null, Arrays.asList(1, 2)); } } else { //没有待办任务 articles = new ArrayList<>(); } //为每一篇公文加入对应的Task for (Task task : doingTask) { for (Article article : articles) { if (task.getProcessInstanceId().equals(article.getProcessinstanceId())) { article.setTask(task); } } } //查询出正在审核中的公文 Article article = new Article(); article.setTitle(keyword); article.setUserId(user.getUserid()); List<Article> auditing = articleService.getMyAuditList(article); articles.addAll(auditing); //合并两个集合 //保存结果集带到页面显示 map.put("articles", articles); map.put("tasks", doingTask); //保存模糊查询条件以便回显 map.put("keyword", keyword); return "article/articleAuditResultManage"; } /** * 公文上传(撰稿) * @return */ @RequestMapping("/addArticle") @Transactional public String addArticle(Map<String, Object> map, HttpSession session , String title, Integer[] received, Integer auditor, MultipartFile doc, @RequestParam(name= "attachment", required = false) MultipartFile[] attachment) { try { //1.首先检查必填项是否都填写正确 if (validateForm(map, null, title, received, auditor, doc) == false) { return "forward:/article/toAdd"; } //2.设置公文相关参数并新增公文 Article article = new Article(); article.setArticlestate(0); //0表示审核中 article.setTitle(title); //撰稿人就是当前用户 User user = (User)session.getAttribute("user"); article.setCopywriterId(user.getUserid()); article.setInstId(user.getInstId()); article.setAuditorId(auditor); article.setPublishtime(new Date()); //判断操作结果是否成功 if (!articleService.addArticle(article)) { map.put("msg", "系统出现错误,在添加公文信息时操作失败!"); map.put("result", false); return "forward:/article/toAdd"; } //3.启动Activiti工作流流程,拿到流程实例id //3.1 设置流程变量,指定审核人(为防止用户姓名重复,使用用户id) Map<String, Object> variables = new HashMap<String, Object>(); variables.put("auditorId", auditor); //指定公文审核的办理人Id variables.put("copywriterId", user.getUserid()); //指定撰稿人Id //3.2 按流程实例id启动流程 ProcessInstance processInstance = runtimeService.startProcessInstanceByKey( "articleProcess", article.getArticleid().toString() , variables); //3.3 得到流程实例id String procInstanceKey = processInstance.getId(); //3.4 更新公文信息,设置流程id article.setProcessinstanceId(procInstanceKey); if (!articleService.modifyArticle(article)) { map.put("msg", "系统出现错误,在添加公文信息时操作失败!"); map.put("result", false); return "forward:/article/toAdd"; } //4 利用公文id继续去添加其他信息 //4.1 添加接收关系 for (Integer receiverId : received) { if (!receiveService.addReceive(article.getArticleid(), receiverId)) { map.put("msg", "系统出现错误,在添加公文接收信息时操作失败!"); map.put("result", false); return "forward:/article/toAdd"; } } //4.2 调用FileService,使用JackRabbit保存公文电子文档 String fileId = fileService.save(doc.getInputStream()); //4.3 拼装出公文原文的附件信息 Attachment articleDocument = new Attachment(); articleDocument.setArticleId(article.getArticleid()); articleDocument.setAttachtype(0); //0表示正文 articleDocument.setFilename(doc.getOriginalFilename()); articleDocument.setMimetype(doc.getContentType()); articleDocument.setUploadtime(new Date()); articleDocument.setFilesize(doc.getSize()); articleDocument.setFileid(fileId); //JackRabbit返回的FileId //4.4 添加信息到附件表 if (!attachmentService.addAttachment(articleDocument)) { map.put("msg", "系统出现错误,在添加公文附件时操作失败!"); map.put("result", false); return "forward:/article/toAdd"; } //5.如果用户上传了附件,就要把附件也保存下来 for (MultipartFile attachFile : attachment) { //5.1 调用FileService,使用JackRabbit保存公文附件 String attfileId = fileService.save(attachFile.getInputStream()); //5.2 拼装附件信息 Attachment attch = new Attachment(); attch.setArticleId(article.getArticleid()); attch.setAttachtype(1); //1表示附件 attch.setFileid(attfileId); attch.setFilename(attachFile.getOriginalFilename()); attch.setFilesize(attachFile.getSize()); attch.setMimetype(attachFile.getContentType()); attch.setUploadtime(new Date()); //5.3 添加信息到附件表 if (!attachmentService.addAttachment(attch)) { map.put("msg", "系统出现错误,在添加公文附件时操作失败!"); map.put("result", false); return "forward:/article/toAdd"; } } //6.如果以上操作都没有问题,那就是成功了 map.put("msg", "公文[" + article.getTitle() + "]上传成功,请耐心等待审核!"); map.put("result", true); //返回等待审核结果界面 return "forward:/article/toAduitResult"; } catch (Exception e) { System.out.println("公文撰稿出错!"); e.printStackTrace(); map.put("msg", "系统出现严重错误,公文撰稿操作失败!"); map.put("result", false); return "forward:/article/toAdd"; } } /** * 检查公文撰稿表单是否填写正确 * @param map * @param title * @param received * @param auditor * @param doc * @return */ private boolean validateForm(Map<String, Object> map, Integer articleid, String title, Integer[] received, Integer auditor, MultipartFile doc) { //1.1检查公文标题是否符合规定格式 if (StringUtils.hasText(title) == false || Pattern.matches("^\\S{2,150}$", title) == false) { map.put("msg", "您填写的公文标题不合法,上传失败!公文标题不能为空,并且长度为2~150。"); map.put("result", false); return false; } //1.2 检查接收人id是否填写 if (received == null || received.length == 0) { map.put("msg", "您还没有选择接收人,上传失败!"); map.put("result", false); return false; } //1.3 检查审核人是否填写 if (articleid == null && auditor == null) { map.put("msg", "您还没有选择审核人,上传失败!"); map.put("result", false); return false; } //1.4 检查公文电子文档是否上传 if (articleid == null && doc == null) { map.put("msg", "您还没有上传公文电子文档,上传失败!"); map.put("result", false); return false; } //1.5 检查公文名称是否重复,如果重复则不允许其通过 if (articleService.validateTitle(title, articleid) == false) { map.put("msg", "您填写的公文标题与已有标题重复,上传失败!"); map.put("result", false); return false; } return true; } /** * 进入公文撰稿界面 * @return * @throws Exception */ @RequestMapping("/toAdd") public String toAdd(HttpSession session, Map<String, Object> map) throws Exception { //加载出该用户所在机构所有审稿人姓名 //1 从Session中取出User User user = (User) session.getAttribute("user"); //2 通过用户得到其所在机构的id Integer instid = user.getInstId(); //3 得到该机构所有未被禁用的审核人员的信息 // List<User> auditors = userService.findValidAuditor(instid); List<User> auditors = userService.findValidAuditorRoleId(instid, user.getRoleId()); //4 保存为备选项 map.put("auditors", auditors); return "article/articleupload"; } /** * 通过Ajax方式获得联系人树 * @return * @throws Exception */ @ResponseBody @RequestMapping("/getTree") public List<TreeDto> getTree() throws Exception { List<TreeDto> dtos = new ArrayList<>(); dtos.add(articleService.getTreeDTOJSON(null, null)); return dtos; } }
服务层:ArticleService.java
package cn.edu.nuc.article.service; import java.util.List; import org.activiti.engine.task.Task; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import cn.edu.nuc.article.dao.ArticleMapper; import cn.edu.nuc.article.dto.State; import cn.edu.nuc.article.dto.TreeDto; import cn.edu.nuc.article.entity.Article; import cn.edu.nuc.article.entity.Institution; import cn.edu.nuc.article.entity.User; /** * 公文Service * @author 仰望星空 * */ @Service public class ArticleService { /** * 公文Mapper */ @Autowired private ArticleMapper articleMapper; /** * 用户Service */ @Autowired private UserService userService; /** * 机构Service */ @Autowired private InstitutionService institutionService; /** * 得到被驳回公文的数量 * @param userId 用户id * @return */ public Long getWaitCount(Integer userId){ return articleMapper.selectMyWaitingCount(userId); } /** * 得到被驳回公文的数量 * @param userId 用户id * @return */ public Long getFailCount(Integer userId){ return articleMapper.selectMyFailCount(userId); } /** * 得到待处理公文数量 * @param userId 用户id * @return */ public Long getDealCount(Integer userId) { return articleMapper.selectMyDealCount(userId); } /** * 得到待接收公文数量 * @param userId 用户ID * @return */ public Long getReceivedCount(Integer userId) { return articleMapper.selectMyCountReceiver(userId); } /** * 检查公文是否可以被访问 * @param articleId * @param userId * @return */ public boolean isArticleAvaliable(Integer articleId, Integer userId) { return articleMapper.validateAccess(userId, articleId) > 0; } /** * 通过流程实例id加载功能信息 * @param ids * @return */ public List<Article> getByProcessInstances(List<Task> tasks, String title, List<Integer> articlestates) { return articleMapper.selectByProcessInstances(tasks, title, articlestates); } /** * 按id加载公文记录 * @param articleId 公文Id * @return */ public Article getArticleById(Integer articleId, Integer userId) { return articleMapper.selectOne(articleId, userId); } /** * 查询出与我相关的公文 * @param article * @return */ public List<Article> getMyArticles(Article article) { return articleMapper.selectMyReceiveList(article); } /** * 找出与我相关的公文 * @param article * @return */ public List<Article> getMyAuditList(Article article) { return articleMapper.selectMyAuditList(article); } /** * 找出与我相关的公文 * @param article * @return */ public List<Article> getMyArticleList(Article article) { return articleMapper.selectMyList(article); } /** * 测试公文标题是否重复 * @param title * @return true 不重复。 false 重复 */ public boolean validateTitle(String title, Integer articleid) { return articleMapper.validateTitle(title, articleid) == 0; } /** * 更新公文信息 * @param article * @return */ public boolean modifyArticle(Article article) { return articleMapper.updateByPrimaryKeySelective(article) > 0; } /** * 添加公文 * @return */ public boolean addArticle(Article article) { return articleMapper.insertSelective(article) > 0; } /** * 获得树的DTO对象的JSON字符串 * @return * @throws Exception */ public TreeDto getTreeDTOJSON(Integer articleId, Integer userId) throws Exception { //1.加载出所有的未被禁用的机构 //1.1 设置查询条件,要求机构的状态必须是正常,即不可以是禁用或者被合并 Institution institution1 = new Institution(); institution1.setInststate(1); //1代表正常 //1.2 使用查询条件拿到结果集 List<Institution> institutions = institutionService.findByKeyword(institution1); //2.加载出未被禁用的用户 List<User> users = userService.findValidUser(); //3.如果有公文id,还要查询出公文信息(修改公文时用) Article article = null; if (articleId != null) { article = articleMapper.selectOne(articleId, userId); } return getTree(institutions, users, article); } /** * 根据机构和用户信息装出联系人树对象 * @param institutions 机构信息 * @param users 用户信息 * @return 联系人树 */ private TreeDto getTree(List<Institution> institutions, List<User> users, Article article) { //标志位 boolean isFirstLevelSelected = false; //1 先构造出树的根 TreeDto root = new TreeDto(); root.setText("所有联系人"); //2 遍历每一个机构 for (Institution institution : institutions) { //3.2 为当前机构构建出一个一级子节点 TreeDto firstLevel = new TreeDto(); firstLevel.setText(institution.getInstname()); //节点名称就是机构名称 boolean isSecondLevelSelected = false; //3.3 遍历每一个用户 for (User user : users) { //3.4 如果这个用户属于当前机构 if (user.getInstId() == institution.getInstid()) { //3.5 为当前用户创建子节点 TreeDto secondLevel = new TreeDto(); secondLevel.setText(user.getUsertruename()); //节点名称是用户真实姓名 secondLevel.setId(user.getUserid()); //用户节点的id就是用户id,只有用户节点才有id //判断是否需要设置选中 if (article != null) { List<User> receivers = article.getReceivers(); for (User receiver : receivers) { if (user.getUserid() == receiver.getUserid()) { State state = new State(); state.setChecked(true); secondLevel.setState(state); isSecondLevelSelected = true; } } } //3.6把用户节点加到机构节点下面 firstLevel.addNode(secondLevel); }//if }//for user //3.7判断是否勾选 if (isSecondLevelSelected == true) { isFirstLevelSelected = true; State state = new State(); state.setChecked(true); firstLevel.setState(state); } //3.8 把机构节点加入到根节点下面 root.addNode(firstLevel); } if (isFirstLevelSelected == true) { State state = new State(); state.setChecked(true); root.setState(state); } return root; } }
数据访问对象:ArticleMapper.java
package cn.edu.nuc.article.dao; import java.util.List; import org.activiti.engine.task.Task; import org.apache.ibatis.annotations.Param; import cn.edu.nuc.article.entity.Article; /** * 公文Mapper * @author 仰望星空 * */ public interface ArticleMapper { /** * 插入一条公文信息(公文撰稿时调用) * @param record * @return */ int insertSelective(Article record); /** * 修改一条公文信息 * @param record * @return */ int updateByPrimaryKeySelective(Article record); /** * 模糊查询全部 * @param article * @return */ List<Article> selectListAll(Article article); /** * 查与我有关的信息 * @param article * @return */ List<Article> selectMyReceiveList(Article article); /** * 查询审核结果中正在审核的公文 * @param article * @return */ List<Article> selectMyAuditList(Article article); /** * 查与我有关的信息 * @param article * @return */ List<Article> selectMyList(Article article); /** * 按照流程实例id加载公文信息 * @param ids * @return */ List<Article> selectByProcessInstances( @Param("tasks") List<Task> tasks, @Param("title") String title, @Param("articlestates") List<Integer> articlestates); /** * 按id查询公文详细信息 * @param articleid * @return */ Article selectOne(@Param("articleid") Integer articleid, @Param("userId") Integer userId); /** * 检查公文是否可以被下载和查看 * @param userId * @param articleid * @return */ Long validateAccess(@Param("userId") Integer userId, @Param("articleid") Integer articleid); /** * 查询等待审核通过公文的数量 * @param userId 用户id * @return */ Long selectMyWaitingCount(Integer userId); /** * 查询被驳回的公文数量 * @param userId 用户id * @return */ Long selectMyFailCount(Integer userId); /** * 查询需要我审核的公文数量 * @param userId 用户id * @return */ Long selectMyDealCount(Integer userId); /** * 查询待收取公文数量 * @param userId 用户id * @return */ Long selectMyCountReceiver(Integer userId); /** * 撰稿人删除公文 * @param articleid * @return */ Integer deleteById(Integer articleid); /** * 检查公文标题是否重复 * @param title * @return */ Long validateTitle(@Param("title") String title, @Param("articleid") Integer articleid); }
实体类:Article.java
package cn.edu.nuc.article.entity; import java.io.Serializable; import java.util.Date; import java.util.List; import org.activiti.engine.task.Task; /** * 公文 * @author 仰望星空 * */ public class Article implements Serializable { /** * 序列化id */ private static final long serialVersionUID = 1L; /** * 公文id */ private Integer articleid; /** * 公文标题 */ private String title; /** * 发布时间 */ private Date publishtime; /** * 撰稿人id */ private Integer copywriterId; /** * 存放级联查询出来的撰稿人信息(数据库没字段对应) */ private User copywriter; /** * 审稿人id */ private Integer auditorId; /** * 存放级联查询出来的审稿人信息(数据库没字段对应) */ private User auditor; /** * 发布机构id */ private Integer instId; /** * 存放级联查询出来的发布机构信息(数据库没字段对应) */ private Institution institution; /** * 公文状态: * 0 审核中 * 1 审核通过 * 2 审核驳回 * 3 公文发布 * 4 公文删除 */ private Integer articlestate; /** * 流程实例Id */ private String processinstanceId; /** * 点击量 */ private Long clickcount; /** * 下载量 */ private Long downloadcount; /** * 附件 */ private List<Attachment> attachments; /** * 校验信息 */ private List<AuditMessage> auditMessages; /** * 接收人 */ private List<User> receivers; /** * 加载和自己有关的列表时使用 */ private Integer userId; /** * 任务 */ private Task task; public Integer getArticleid() { return articleid; } public void setArticleid(Integer articleid) { this.articleid = articleid; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public Date getPublishtime() { return publishtime; } public void setPublishtime(Date publishtime) { this.publishtime = publishtime; } public Integer getCopywriterId() { return copywriterId; } public void setCopywriterId(Integer copywriterId) { this.copywriterId = copywriterId; } public User getCopywriter() { return copywriter; } public void setCopywriter(User copywriter) { this.copywriter = copywriter; } public Integer getAuditorId() { return auditorId; } public void setAuditorId(Integer auditorId) { this.auditorId = auditorId; } public User getAuditor() { return auditor; } public void setAuditor(User auditor) { this.auditor = auditor; } 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 getArticlestate() { return articlestate; } public void setArticlestate(Integer articlestate) { this.articlestate = articlestate; } public String getProcessinstanceId() { return processinstanceId; } public void setProcessinstanceId(String processinstanceId) { this.processinstanceId = processinstanceId; } public Long getClickcount() { return clickcount; } public void setClickcount(Long clickcount) { this.clickcount = clickcount; } public Long getDownloadcount() { return downloadcount; } public void setDownloadcount(Long downloadcount) { this.downloadcount = downloadcount; } public List<Attachment> getAttachments() { return attachments; } public void setAttachments(List<Attachment> attachments) { this.attachments = attachments; } public List<AuditMessage> getAuditMessages() { return auditMessages; } public void setAuditMessages(List<AuditMessage> auditMessages) { this.auditMessages = auditMessages; } public List<User> getReceivers() { return receivers; } public void setReceivers(List<User> receivers) { this.receivers = receivers; } public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public Task getTask() { return task; } public void setTask(Task task) { this.task = task; } @Override public String toString() { return "\n----------------\n" + "Article [articleid=" + articleid + ", \ntitle=" + title + ", \npublishtime=" + publishtime + ", \ncopywriterId=" + copywriterId + ", \ncopywriter=" + copywriter + ", \nauditorId=" + auditorId + ", \nauditor=" + auditor + ", \ninstId=" + instId + ", \ninstitution=" + institution + ", \narticlestate=" + articlestate + ", \nprocessinstanceId=" + processinstanceId + ", \nclickcount=" + clickcount + ", \ndownloadcount=" + downloadcount + ", \nattachments=" + attachments + ", \nauditMessages=" + auditMessages + ", \nreceivers=" + receivers + ", \nuserId=" + userId + "]\n--------------\n"; } /** * 以公文id为唯一标示 */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((articleid == null) ? 0 : articleid.hashCode()); return result; } /** * 以公文id为唯一标示 */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Article other = (Article) obj; if (articleid == null) { if (other.articleid != null) return false; } else if (!articleid.equals(other.articleid)) return false; return true; } }
国密算法:
Part2 各个成员遇到的问题
- 继续开发公文传输功能(20211302):编辑和查看功能复杂性: 实现公文的查看和编辑功能可能牵涉到富文本编辑、版本控制等复杂的需求。选择适当的富文本编辑库,确保编辑器的易用性和功能丰富性。使用版本控制系统,追踪和管理公文的修改历史。进行用户测试,确保用户能够轻松使用编辑和查看功能。
- 完善权限表,实现细粒度的权限控制(20211304):权限设计复杂性: 实现细粒度的权限控制可能需要考虑到各种操作和资源的权限设置。利用 RBAC 或 ABAC 模型,将权限分配与角色关联,以简化权限管理。进行系统内的模拟测试,验证各种场景下权限的正常工作。使用权限管理工具,简化权限设置和维护。
- 处理用户管理功能的反馈(20211308):稳定性问题: 用户管理功能的反馈可能包括系统崩溃、性能问题等方面的反馈。进行详细的日志记录,以便在出现问题时能够快速定位和解决。使用监控工具实时监测系统的性能。进行持续集成和自动化测试,确保每次代码变更都不会引入新的稳定性问题。
- 继续开发日志记录功能,记录更多的操作信息(20211317):日志记录性能和存储问题: 记录大量的操作信息可能导致性能问题和存储成本增加。选择适当的日志记录库,确保能够满足性能需求。进行日志的归档和定期清理,以控制存储成本。根据实际需求,采用异步方式记录日志,减轻对主业务逻辑的影响。
- 完成国密算法的集成和性能优化(20211318):性能优化困难: 集成国密算法后,可能需要优化算法以提高性能。进行性能分析,找到性能瓶颈。考虑使用硬件加速、并行计算等方式优化算法。使用缓存技术,避免重复计算。进行性能测试,确保优化效果符合预期。
Part3 明日各个成员的任务安排
- 20211302:继续开发公文传输功能,实现公文的审批和流转。
- 20211304:测试权限控制功能,确保权限生效。
- 20211308:进行用户管理功能的系统测试,修复可能存在的漏洞。
- 20211317:继续完善日志记录功能,确保记录的完整性。
- 20211318:进行国密算法的性能测试和安全性评估。
Part4 各个成员今日对项目的贡献量
Part5 燃尽图与站立式会议照片