1. 需求背景

  界面上可以显示公司数据库中的数据库、数据库下面对应的数据表和表的注释,没有表查看权限的员工只能看到界面上显示的信息,不能查看具体的表内容。现在没有表内容查看权限的员工想要查看具体表的信息,就需要在界面上选中想要查看的表名进行申请。员工在界面上选中想要查看的表,点击发送 "申请" 按钮后。后台需要做两件事情,一是把申请的信息存入到数据库中,二是发送一封邮件给管理员,由管理员进行申请审核。

2. 分析需求

  从需求描述中可以得知,需要把用户申请的信息存入数据库中,那么就需要根据要存入数据库中的信息(分析信息有哪些字段)创建表;在把用户申请的信息存入数据库之后需要发送邮件给管理员。(此处需要考虑的是要成功的把用户申请的信息存入到数据库中之后再发送邮件给管理员,如果第一次邮件发送失败,还需要考虑重新发送)。

3. 表设计

  通过分析申请的信息,可以设计如下两张表,一张是申请人信息表(apply_user),存放申请人相关信息,一张是申请信息表(apply_message),存放申请信息。具体表的定义如下:

  申请人信息表(apply_user)

CREATE TABLE `apply_user` (
   `id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
   `apply_user_name` VARCHAR(255) NOT NULL COMMENT '申请人姓名',
   `apply_user_um_account` VARCHAR(255) NOT NULL COMMENT '申请人UM账号',
   `apply_user_job` VARCHAR(255) DEFAULT NULL COMMENT '申请人岗位',
   `apply_user_department` VARCHAR(255) DEFAULT NULL COMMENT '申请人所属部门',
   PRIMARY KEY (`id`)
 ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='申请人信息表'

  申请信息表(apply_message)

CREATE TABLE `apply_message_new` (
   `id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
   `apply_user_id` INT(11) NOT NULL COMMENT '申请人ID',
   `event_name` VARCHAR(255) NOT NULL COMMENT '事件名称',
   `batch_apply_account` TEXT COMMENT '批量申请人集合',
   `apply_table` TEXT NOT NULL COMMENT '申请的表清单',
   `apply_reason` VARCHAR(255) NOT NULL COMMENT '申请原因',
   `apply_date` DATETIME NOT NULL COMMENT '申请时间',
   `apply_batch_num` INT(11) NOT NULL COMMENT '申请的批次号',
   PRIMARY KEY (`id`)
 ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

  

4. 概要设计

  前端传递的申请人信息存入到申请人信息表apply_user中。
  前端传递的申请信息存入到申请表apply_message_new中。

 

 

 

5. 详细设计

  1. 用户提交申请时,首先判断此次申请是否有批量申请用户,如果有,则判断批量申请用户是否为有效用户,如果存在任何一个用户不是有效用户,则结束程序,响应失败消息给前端;如果此次申请没有批量申请用户或者此次申请的批量申请用户都是有效用户,则执行步骤2;

  2. 到申请人信息表apply_person中查看是否存在此用户的账号,若不存在此用户的账号,则说明此用户是第一次申请,直接把申请内容信息插入到申请人信息表apply_person和申请表apply_message中(申请的批次号apply_batch_num为1),否则,说明此用户不是第一次主动申请(首先更新此申请人在申请人信息表中数据),再通过用户UM账号到申请人表apply_user中查找申请人id,通过此id到申请表apply_message表中查找此申请人最大的申请批次号,然后把申请的内容插入到申请表apply_message中(申请的批次号为最大申请批次号+1),转第3步;

  3. 判断此次申请是否有批量申请人,如果没有,则结束,否则,转第4步;

  4. 遍历每一个批量申请人,先到申请人表apply_user中查看是否已经存在此用户账号,若不存在此用户账号,则说明此用户是第一次被申请,直接把申请内容信息插入到申请人信息表apply_user和申请表apply_message中(申请的批次号apply_batch_num为1),否则,说明此用户不是第一次被申请(首先更新此申请人在申请人信息表中数据,通过遍历到的用户的UM账号到用户表中查询此用户信息,然后更新到申请人信息表apply_user中),再通过当前遍历到的UM账号到申请人表apply_user中查找被申请人id,然后通过id到申请表apply_message中查找当前被申请人最大的申请批次号,然后插入申请信息到申请表apply_message中国(申请批次号为最大申请批次号+1)。

6. 编码实现

 

package com.sun.springboot.controller;

import com.alibaba.fastjson.JSONObject;
import com.sun.springboot.bean.ApplyMessageNew;
import com.sun.springboot.bean.ApplyNew;
import com.sun.springboot.bean.ApplyNewVo;
import com.sun.springboot.bean.ApplyTableMessage;
import com.sun.springboot.bean.ApplyUser;
import com.sun.springboot.bean.User;
import com.sun.springboot.service.ApplyMessageService;
import com.sun.springboot.service.ApplyUserService;
import com.sun.springboot.service.UserService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.mail.internet.MimeMessage;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @author sunhongguang
 * @create 2020-11-19-23:34
 */
@RestController
@RequestMapping(path = "/new/apply")
public class ApplyController_new {

    private UserService userService;
    private ApplyUserService applyUserService;
    private ApplyMessageService applyMessageService;
    private JavaMailSenderImpl javaMailSender;

    public ApplyController_new(UserService userService, ApplyUserService applyUserService, ApplyMessageService applyMessageService, JavaMailSenderImpl javaMailSender) {
        this.userService = userService;
        this.applyUserService = applyUserService;
        this.applyMessageService = applyMessageService;
        this.javaMailSender = javaMailSender;
    }
    /**
     * 获取全部申请的信息
     *
     * @param userAccount um账号
     * @return 申请信息对象
     */
    @GetMapping(path = "/getAllApplyMessage")
    public ResponseEntity getAllApplyMessage(@RequestParam(value = "userAccount") String userAccount) {
        // 通过UM账号获取申请的用户信息
        ApplyUser applyUser = this.applyUserService.findApplyUser(userAccount);
        // 通过UM账号,获取用户最新申请的信息
        List<ApplyMessageNew> applyMessageNewList = this.applyMessageService.getAllApplyMessage(userAccount);
        for (ApplyMessageNew applyMessageNew1 : applyMessageNewList) {
            //获取批量申请的用户 字符串形式
            String batchApplyAccountString = applyMessageNew1.getBatchApplyAccountString();
            // 把JSON格式的字符串转换成集合
            List<String> listOfBatchApplyAccount = JSONObject.parseArray(batchApplyAccountString, String.class);
            // 获取申请的信息字符串
            String applyTableString = applyMessageNew1.getApplyTableString();
            // 把JSON格式的字符串转换成集合
            List<ApplyTableMessage> applyTableMessages = JSONObject.parseArray(applyTableString, ApplyTableMessage.class);

            applyMessageNew1.setBatchApplyAccount(listOfBatchApplyAccount);
            applyMessageNew1.setApplyTable(applyTableMessages);

            applyMessageNew1.setApplyTableString(null);
            applyMessageNew1.setBatchApplyAccountString(null);
        }
        ApplyNewVo applyNewVo = new ApplyNewVo();
        applyNewVo.setApplyUser(applyUser);
        applyNewVo.setApplyMessageNewList(applyMessageNewList);

        return ResponseEntity.ok(new HashMap<String, Object>() {{
            put("code", HttpStatus.OK);
            put("data", applyNewVo);
        }});
    }

    /**
     * 获取最新申请的信息
     *
     * @param userAccount um账号
     * @return 申请信息对象
     */
    @GetMapping(path = "/getApplyMessage")
    public ResponseEntity getApplyMessage(@RequestParam(value = "userAccount") String userAccount) {
        // 通过UM账号获取申请的用户信息
        ApplyUser applyUser = this.applyUserService.findApplyUser(userAccount);

        // 通过UM账号,获取用户最新申请的信息
        ApplyMessageNew applyMessageNew = this.applyMessageService.getApplyMessage(userAccount);
        //获取批量申请的用户 字符串形式
        String batchApplyAccountString = applyMessageNew.getBatchApplyAccountString();
        // 把JSON格式的字符串转换成集合
        List<String> listOfBatchApplyAccount = JSONObject.parseArray(batchApplyAccountString, String.class);
        // 获取申请的信息字符串
        String applyTableString = applyMessageNew.getApplyTableString();
        // 把JSON格式的字符串转换成集合
        List<ApplyTableMessage> applyTableMessages = JSONObject.parseArray(applyTableString, ApplyTableMessage.class);

        applyMessageNew.setBatchApplyAccount(listOfBatchApplyAccount);
        applyMessageNew.setApplyTable(applyTableMessages);

        applyMessageNew.setApplyTableString(null);
        applyMessageNew.setBatchApplyAccountString(null);

        ApplyNew applyNew = new ApplyNew();
        applyNew.setApplyUser(applyUser);
        applyNew.setApplyMessage(applyMessageNew);

        return ResponseEntity.ok(new HashMap<String, Object>() {{
            put("code", HttpStatus.OK);
            put("data", applyNew);
        }});
    }

    @PostMapping(path = "/table")
    public synchronized ResponseEntity applyTable(@RequestBody JSONObject jsonObject) {

        // 发送邮件
        try {
            sendComplexMail(jsonObject);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 获取申请人信息JSON对象
        JSONObject applyPersonJson = jsonObject.getJSONObject("applyUser");
        // 把申请人信息封装到ApplyUser对象中
        ApplyUser applyUser = JSONObject.toJavaObject(applyPersonJson, ApplyUser.class);

        // 获取申请的信息
        JSONObject applyMessageJson = jsonObject.getJSONObject("applyMessage");
        ApplyMessageNew applyMessage = JSONObject.toJavaObject(applyMessageJson, ApplyMessageNew.class);

        // 获取申请人信息里面的批量申请人集合
        List<String> batchApplyAccountList = applyMessage.getBatchApplyAccount();
        List<ApplyTableMessage> applyTable = applyMessage.getApplyTable();
        // 把List集合转换成JSON格式字符串
        String stringOfBatchAccount = JSONObject.toJSONString(batchApplyAccountList);
        String stringOfApplyTable = JSONObject.toJSONString(applyTable);

        String test = applyTable.toString();
        String test1 = batchApplyAccountList.toString();


        //判断批量申请列表中是否有不合法用户
        List<String> failList = judgeBatchApply(batchApplyAccountList);
        if (!CollectionUtils.isEmpty(failList)) {
            return ResponseEntity.ok(new HashMap<String, Object>() {{
                put("code", "-1");
                put("message", "申请失败!请检查批量申请的用户UM账号是否填写正确" + failList);
            }});
        }
        // 判断当前用户是否为第一次申请
        ApplyUser apply_user = this.applyUserService.findApplyUser(applyUser.getApplyUserAccount());
        if (apply_user == null) { // 如果apply_user为null,则说明这是用户第一次申请
            // 插入申请人信息到申请人信息表apply_user中
            this.applyUserService.saveApplyUser(applyUser);
            // 插入申请信息到申请表apply_message中
            int userId = this.applyUserService.findApplyUserId(applyUser.getApplyUserAccount());
            applyMessage.setApplyNum(1);
            applyMessage.setApplyUserId(userId);
            applyMessage.setApplyTableString(stringOfApplyTable);
            applyMessage.setBatchApplyAccountString(stringOfBatchAccount);
            this.applyMessageService.save(applyMessage);
        } else {
            // 如果此用户不是第一次申请,则先更新此用户(因为用户的用户名user_name,用户岗位user_job,用户部门user_department可能会变)
            applyUser.setId(apply_user.getId());
            this.applyUserService.updateApplyUser(applyUser);
            // 此用户不是第一次申请,则先去用户申请表中查找此申请用户的id
            int userId = this.applyUserService.findApplyUserId(apply_user.getApplyUserAccount());
            // 到申请信息表中查找最大的申请批次号
            int maxBatchApplyNum = this.applyUserService.findMaxBatchApplyNum_new(apply_user.getApplyUserAccount());
            applyMessage.setApplyNum(maxBatchApplyNum + 1);
            applyMessage.setApplyUserId(apply_user.getId());
            applyMessage.setApplyTableString(stringOfApplyTable);
            applyMessage.setBatchApplyAccountString(stringOfBatchAccount);
            this.applyMessageService.save(applyMessage);
        }
        return ResponseEntity.ok(new HashMap<String, Object>() {{
            put("code", 0);
            put("message", "申请成功,待申批。");
        }});
    }

    /**
     * 发送复杂邮件
     *
     * @param jsonObject
     * @throws Exception
     */
    private void sendComplexMail(JSONObject jsonObject) throws Exception {
        MimeMessage mimeMessage = this.javaMailSender.createMimeMessage();
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);

        // 发件人
        mimeMessageHelper.setFrom("2435049674@qq.com");
        // 收件人
        mimeMessageHelper.setTo("2954518534@qq.com");
        // 邮件主题
        mimeMessageHelper.setSubject("测试主题-复杂");
        // 正文
        // 1. 申请信息构造
        JSONObject applyUser = jsonObject.getJSONObject("applyUser");
        ApplyUser applyUser1 = JSONObject.toJavaObject(applyUser, ApplyUser.class);

        JSONObject applyMessage = jsonObject.getJSONObject("applyMessage");
        ApplyMessageNew applyMessageNew = JSONObject.toJavaObject(applyMessage, ApplyMessageNew.class);

        List<String> batchApplyAccountList = applyMessageNew.getBatchApplyAccount();
        List<ApplyTableMessage> applyTableList = applyMessageNew.getApplyTable();

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("<b style='color:red;'>申请人信息如下:").append("</b>").append("<br>");
        stringBuilder.append("<b>申请人姓名: </b>").append(applyUser1.getApplyUserName()).append("<br>");
        stringBuilder.append("<b>申请人UM账号:</b>").append(applyUser1.getApplyUserAccount()).append("<br>");
        stringBuilder.append("<b>申请人岗位:</b>").append(applyUser1.getApplyJob()).append("<br>");
        stringBuilder.append("<b>申请人部门:</b>").append(applyUser1.getApplyDepartment()).append("<br>").append("<br>");
        stringBuilder.append("<b style='color: red;'>申请信息如下:</b><br>");
        stringBuilder.append("<b>申请原因:</b>").append(applyMessageNew.getApplyReason()).append("<br>");
        stringBuilder.append("<b>申请时间:</b>").append(applyMessageNew.getFormatDate()).append("<br>");
        stringBuilder.append("<b>批量申请人:</b>").append(batchApplyAccountList).append("<br>");

        stringBuilder.append("<table border='1px' width='100%'>");
        stringBuilder.append("<tr height='50px'>");
        stringBuilder.append("<td>编号</td>");
        stringBuilder.append("<td>库名</td>");
        stringBuilder.append("<td>表名</td>");
        stringBuilder.append("<td>表注释</td>");
        stringBuilder.append("</tr>");
        for (ApplyTableMessage tableMessage : applyTableList) {
            stringBuilder.append("<tr>");
            stringBuilder.append("<td>").append(tableMessage.getId()).append("</td>");
            stringBuilder.append("<td>").append(tableMessage.getDatabaseName()).append("</td>");
            stringBuilder.append("<td>").append(tableMessage.getTableName()).append("</td>");
            stringBuilder.append("<td>").append(tableMessage.getTableComment()).append("</td>");
            stringBuilder.append("</tr>");
        }
        stringBuilder.append("</table>");
        mimeMessageHelper.setText(stringBuilder.toString(), true);
        // 附件
//        mimeMessageHelper.addAttachment("1.jpg", new File("C:\\Users\\Sun\\Desktop\\1.jpg"));
        javaMailSender.send(mimeMessage);
    }

    /**
     * 发送简单邮件
     *
     * @param jsonObject
     * @throws Exception
     */
    private void sendSimpleMail(JSONObject jsonObject) throws Exception {
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        simpleMailMessage.setFrom("2435049674@qq.com");
        simpleMailMessage.setTo("2954518534@qq.com");
        simpleMailMessage.setSubject("测试主题");
        simpleMailMessage.setText(jsonObject.toJSONString());
        this.javaMailSender.send(simpleMailMessage);
    }

    /**
     * 判断批量申请列表中是否有不合法用户
     *
     * @param batchApplyAccountList 批量申请的用户列表
     * @return 批量申请列表中是否有不合法的UM账号
     */
    private List<String> judgeBatchApply(List<String> batchApplyAccountList) {
        List<String> failList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(batchApplyAccountList)) {
            // 遍历批量申请人,到用户表中查找
            for (String account : batchApplyAccountList) {
                User user = this.userService.findUserByAccount(account);
                if (user == null) {
                    failList.add(account);
                }
            }
        } else { // 如果没有批量申请人,则直接返回true
            return failList;
        }
        return failList;
    }
}

 

  

 

7. 测试
    /**
     * 发送复杂邮件
     *
     * @param jsonObject
     * @throws Exception
     */
    private void sendComplexMail(JSONObject jsonObject) throws Exception {
        MimeMessage mimeMessage = this.javaMailSender.createMimeMessage();
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);

        // 发件人
        mimeMessageHelper.setFrom("2435049674@qq.com");
        // 收件人
        mimeMessageHelper.setTo("2954518534@qq.com");
        // 邮件主题
        mimeMessageHelper.setSubject("测试主题-复杂");
        // 正文
        // 1. 申请信息构造
        JSONObject applyUser = jsonObject.getJSONObject("applyUser");
        ApplyUser applyUser1 = JSONObject.toJavaObject(applyUser, ApplyUser.class);

        JSONObject applyMessage = jsonObject.getJSONObject("applyMessage");
        ApplyMessageNew applyMessageNew = JSONObject.toJavaObject(applyMessage, ApplyMessageNew.class);

        List<String> batchApplyAccountList = applyMessageNew.getBatchApplyAccount();
        List<ApplyTableMessage> applyTableList = applyMessageNew.getApplyTable();

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("<b style='color:red;'>申请人信息如下:").append("</b>").append("<br>");
        stringBuilder.append("<b>申请人姓名: </b>").append(applyUser1.getApplyUserName()).append("<br>");
        stringBuilder.append("<b>申请人UM账号:</b>").append(applyUser1.getApplyUserAccount()).append("<br>");
        stringBuilder.append("<b>申请人岗位:</b>").append(applyUser1.getApplyJob()).append("<br>");
        stringBuilder.append("<b>申请人部门:</b>").append(applyUser1.getApplyDepartment()).append("<br>").append("<br>");
        stringBuilder.append("<b style='color: red;'>申请信息如下:</b><br>");
        stringBuilder.append("<b>申请原因:</b>").append(applyMessageNew.getApplyReason()).append("<br>");
        stringBuilder.append("<b>申请时间:</b>").append(applyMessageNew.getFormatDate()).append("<br>");
        stringBuilder.append("<b>批量申请人:</b>").append(batchApplyAccountList).append("<br>");

        stringBuilder.append("<table border='1px' width='100%'>");
        stringBuilder.append("<tr height='50px'>");
        stringBuilder.append("<td>编号</td>");
        stringBuilder.append("<td>库名</td>");
        stringBuilder.append("<td>表名</td>");
        stringBuilder.append("<td>表注释</td>");
        stringBuilder.append("</tr>");
        for (ApplyTableMessage tableMessage : applyTableList) {
            stringBuilder.append("<tr>");
            stringBuilder.append("<td>").append(tableMessage.getId()).append("</td>");
            stringBuilder.append("<td>").append(tableMessage.getDatabaseName()).append("</td>");
            stringBuilder.append("<td>").append(tableMessage.getTableName()).append("</td>");
            stringBuilder.append("<td>").append(tableMessage.getTableComment()).append("</td>");
            stringBuilder.append("</tr>");
        }
        stringBuilder.append("</table>");
        mimeMessageHelper.setText(stringBuilder.toString(), true);
        // 附件
//        mimeMessageHelper.addAttachment("1.jpg", new File("C:\\Users\\Sun\\Desktop\\1.jpg"));
        javaMailSender.send(mimeMessage);
    }