智销系统项目day4 - 代码生成器&权限的认识

1. 模板技术

1.1 简介

velocity-1.6.3.jar 默认模板的后缀vm
freemarker-2.2.19.jar 默认模板的后缀ftl

2.2 模板技术和jsp的异同

第一次jsp执行流程:jsp转译为java文件,编译为class文件
第2-n次jsp(没有修改)执行流程:直接访问class文件
apache-tomcat-8.x\work\Catalina\localhost_\org\apache\jsp\WEB_002dINF\views\employee

2.3 Struts2的主题样式使用freemarker完成的

jsp页面数据显示一般都是使用struts的标签库,标签库的内部的处理就是使用freemarker

struts2-core-2.x.jar\template\simple项目使用主题

<!-- struts.ui.theme=xhtml默认主题样式 -->
<constant name="struts.ui.theme" value="simple" />

2.4 模板技术怎样输出数据

数据(struts2的值栈)+模板(html文件,vm文件,ftl文件)=输出文本

pss05-代码生成器+角色权限管理\资料\velocity-1.7\docs\developer-guide.html开发指南,代码

2.5 Velocity模板技术可以实现的功能

动态页面静态化:xxx.html
在后台准备数据,在前台准备模板,通过IO把数据与模板合并,真正的生成一个html页面出来
用作发送邮件、短信模板
代码生成器(今天要完成的代码生成器)

2.6 pom.xml:添加jar文件

<!-- 代码生成器模版技术 -->
<dependency>
	<groupId>org.apache.velocity</groupId>
	<artifactId>velocity</artifactId>
	<version>1.6</version>
</dependency>

1.7 Hello Velocity

1.7.1 VelocityTest

package com.zpx.pss;

import java.io.StringWriter;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.junit.Test;
/**
 * 测试Velocity功能
 */
public class VelocityTest {
    @Test
    public void testVelocity01() throws Exception {
        //创建模板应用上下文
        VelocityContext context = new VelocityContext();
        context.put("msg", "小张是个好同志");
        //拿到相应的模板(需要设置好编码)
        Template template = Velocity.getTemplate("temptest/hello.html","UTF-8");
        //准备输出流
        StringWriter writer = new StringWriter();
        template.merge(context, writer);
        System.out.println(writer);
    }


    @Test
    public void testVelocity02() throws Exception {
        //创建模板应用上下文
        VelocityContext context = new VelocityContext();
        context.put("msg", "小张是个好同志");
        //拿到相应的模板(需要设置好编码)
        Template template = Velocity.getTemplate("temptest/hello.html","UTF-8");
        //准备输出流
        File file = new File("temptest/helloNew.html");
        FileWriter writer = new FileWriter(file);
        template.merge(context, writer);
        writer.close();
    }

}

1.7.2 temptest /hello.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
大伙都说:${msg}
</body>
</html>

其它的功能我们可以参见咱们的PDF文档进行学习

2. 代码生成器(自定义)

咱们在写代码的时候,应该已经发现了,如果你还要做另外一个模块,那么它们的基础代码都差不多,虽然我们直接拷备过来修改使用也是可以的。但还是会觉得有点浪费时间,所以我们可以做一个自己生成基础代码的功能,然后我们直接生成,再添加其它的功能即可!

没有代码生成器的时候,如果添加部门模型domain,复制IDepartmentService,修改类名,ctrl+f,进行人工替换
而使用了代码生成器就是先定义好模板,然后使用代码自动修改类名,有代码参照模板进行指定内容自动替换
先用一个临时模型Dept,进行测试
注:写代码生成器前,先把项目进行备份,以免写出问题无法挽回!

2.1 开发步骤

  1. 准备模板(把每个模块需要改的地方确定好)
  2. 确定所有模板的生成顺序
  3. 确定所有模板的生成位置
  4. 确定要生成的基本功能的domain(Dept)
  5. 根据Domain名称与模板结合,在相应位置生成文件
  6. 解决如果父文件夹不存在的问题
  7. 解决如果文件已经存在的问题
  8. 排错(有错先改模板)

2.2 准备模板

我需要生成多少个文件,我就得准备多少个模板
把所有Employee对应的文件都拷备一份到相应的位置(并改名为Domain):
(注意:大写与小写的替换)

把模板中的文件进行修改
提示(大家要操作的时候小心小心再小心)
所有的(大写)Employee换成 D o m a i n 所 有 的 ( 小 写 ) e m p l o y e e 换 成 {Domain} 所有的(小写)employee换成 Domain()employee{domain}
只留下一个最基础的name字段,其它的多余功能全部去掉
注意(Employee中关于部门的操作都需要去掉)
替换的位置$不要值不要出现前后空格

2.3 确定顺序

/ /**

  • 确定修改的顺序(这个顺序你根据自己的习惯决定即可)
  • 1.src/main/java/cn/itsource/pss/query/DomainQuery.java
  • 2.src/main/java/cn/itsource/pss/repository/DomainRepository.java
  • 3.src/main/java/cn/itsource/pss/service/IDomainService.java
  • 4.src/main/java/cn/itsource/pss/service/impl/DomainServiceImpl.java
  • 5.src/main/java/cn/itsource/pss/web/controller/DomainController.java
  • 6.src/main/test/cn/itsource/pss/service/DomainServiceTest.java
  • 7.src/main/webapp/js/model/domain.js
  • 8.src/main/webapp/WEB-INF/views/domain/domain.jsp
    */

2.4 准备路径等

//准备拼接路径的常量,如果有更多文件有利于重复利用
private static final String SRC = "src/main/java/";
private static final String PACKAGE = "cn/itsource/pss/";
private static final String TEST = "src/test/java /";
private static final String WEBAPP = "src/main/webapp/";

//准备路径的拼接
private String[] paths ={
        SRC+PACKAGE+"query/", SRC+PACKAGE+"repository/", SRC+PACKAGE+"service/",
        SRC+PACKAGE+"service/impl/", SRC+PACKAGE+"web/controller/", TEST+PACKAGE+"service/",
        WEBAPP+"js/model/",WEBAPP+"WEB-INF/views/domain/"
};

//准备所有模板名称(和路径顺序一致)
private String[] tempNames = {
        "DomainQuery.java","DomainRepository.java","IDomainService.java",
        "DomainServiceImpl.java","DomainController.java","DomainServiceTest.java",
        "domain.js","domain.jsp"
};

//准备要生成的Domain(有可能同时生成多个)
private String[] domains = {"Dept"};

2.5 完成创建代码

//生成相应的文件
@Test
public void testCreate() throws Exception{
    //创建模板应用上下文
    VelocityContext context = new VelocityContext();
    //一.遍历所有的Domain
    for (int i = 0; i < domains.length; i++) {
        //1.1拿到大写的domain
        String domainBig = domains[i];
        //1.2拿到小写的domain
        String domainSmall = domainBig.substring(0,1).toLowerCase() + domainBig.substring(1);
        //System.out.println(domainBig);
        //System.out.println(domainSmall);
        //1.3设置上下文的替换名称
        context.put("Domain",domainBig);
        context.put("domain",domainSmall);
        //二.遍历所有的路径
        for (int j = 0; j < paths.length; j++) {
            //2.1拿到相应的路径
            String path =paths[j];
            //2.2拿到相应的模板名称
            String tempName = tempNames[j];
            //2.3拼接回我们需要的位置文件
            String realPath = (path + tempName).replaceAll("Domain",domainBig).replaceAll("domain",domainSmall);

            //三.准备相应文件与模板进行组合
            //3.1准备相应的文件(要生成的文件)
            File file = new File(realPath);
            //  如果父文件不存在,我们创建一个
            File parentFile = file.getParentFile();
            if(!parentFile.exists()){
                parentFile.mkdirs();
            }
            //3.2拿到相应的模板(需要设置好编码)
            Template template = Velocity.getTemplate("template/"+tempName,"UTF-8");
            FileWriter writer = new FileWriter(file);
            template.merge(context, writer);
            writer.close();
        }
    }
}

2.6 解决$冲突问题

创建出来后我们运行,会发现domain.js会报错。原因是js中有很多 , 而 这 些 ,而这些 ,和Velocity中的$形成了冲突,我们可以使用以下这种办法来进行解决:
domain.js修改
顶部加上:#set( D = ′ D = &#x27; D=’ ) -> 为$显示设置一个变量
进行替换
$( -> ${D}(
$. -> ${D}.

2.7 其它细节处理

先运行看效果,如果有问题,请先进行模板文件的修改,再重新生成。直到最后功能可以成功!(记住:有错先改模板)

完整代码如下(还解决了如果文件存在我们就不再覆盖的问题):

package cn.itsource.pss.common;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.junit.Test;

import java.io.File;
import java.io.FileWriter;

public class CreateCodeTest {

    /**
     * 确定修改的顺序(这个顺序你根据自己的习惯决定即可)
     * 1.src/main/java/cn/itsource/pss/query/DomainQuery.java
     * 2.src/main/java/cn/itsource/pss/repository/DomainRepository.java
     * 3.src/main/java/cn/itsource/pss/service/IDomainService.java
     * 4.src/main/java/cn/itsource/pss/service/impl/DomainServiceImpl.java
     * 5.src/main/java/cn/itsource/pss/web/controller/DomainController.java
     * 6.src/main/test/cn/itsource/pss/service/DomainServiceTest.java
     * 7.src/main/webapp/js/model/domain.js
     * 8.src/main/webapp/WEB-INF/views/domain/domain.jsp
     */

    //准备拼接路径的常量,如果有更多文件有利于重复利用
    private static final String SRC = "src/main/java/";
    private static final String PACKAGE = "cn/itsource/pss/";
    private static final String TEST = "src/main/test/";
    private static final String WEBAPP = "src/main/webapp/";

    //准备路径(拼接)
    private String[] paths ={
            SRC+PACKAGE+"query/", SRC+PACKAGE+"repository/", SRC+PACKAGE+"service/",
            SRC+PACKAGE+"service/impl/", SRC+PACKAGE+"web/controller/", TEST+PACKAGE+"service/",
            WEBAPP+"js/model/",WEBAPP+"WEB-INF/views/domain/"
    };

    //准备所有模板名称(和路径顺序一致)
    private String[] tempNames = {
            "DomainQuery.java","DomainRepository.java","IDomainService.java",
            "DomainServiceImpl.java","DomainController.java","DomainServiceTest.java",
            "domain.js","domain.jsp"
    };

    //准备要生成的Domain(有可能同时生成多个)
    private String[] domains = {"Dept"};

    //是否需要覆盖已经存在的文件 false代表不覆盖,一般就用这个
    //true代表覆盖,危险操作
    private static final  boolean FLAG = false;

    //生成相应的文件
    @Test
    public void testCreate() throws Exception{
        //创建模板应用上下文
        VelocityContext context = new VelocityContext();
        //一.遍历所有的Domain
        for (int i = 0; i < domains.length; i++) {
            //1.1拿到大写的domain
            String domainBig = domains[i];
            //1.2拿到小写的domain
            String domainSmall = domainBig.substring(0,1).toLowerCase() + domainBig.substring(1);
            //System.out.println(domainBig);
            //System.out.println(domainSmall);
            //1.3设置上下文的替换名称
            context.put("Domain",domainBig);
            context.put("domain",domainSmall);
            //二.遍历所有的路径
            for (int j = 0; j < paths.length; j++) {
                //2.1拿到相应的路径
                String path =paths[j];
                //2.2拿到相应的模板名称
                String tempName = tempNames[j];
                //2.3拼接回我们需要的位置文件
                String realPath = (path + tempName).replaceAll("Domain",domainBig).replaceAll("domain",domainSmall);

                //三.准备相应文件与模板进行组合
                //3.1准备相应的文件(要生成的文件)
                File file = new File(realPath);
                // 如果文件存在,我们根据情况看是否需要覆盖
                if (file.exists() && !FLAG){
                    return;
                }
                //  如果父文件不存在,我们创建一个
                File parentFile = file.getParentFile();
                if(!parentFile.exists()){
                    parentFile.mkdirs();
                }
                System.out.println(file.getAbsoluteFile()); //查看生成路径
                //3.2拿到相应的模板(需要设置好编码)
                Template template = Velocity.getTemplate("template/"+tempName,"UTF-8");
                FileWriter writer = new FileWriter(file);
                template.merge(context, writer);
                writer.close();
            }
        }
    }
}

如果代码生成器生成的文件有问题(错误),找到错误,修改模板,重新生成 -> 一直到生成没有问题为止(慢慢调)

上面是咱们以前代码生成器的开发方案,现在咱们使用一个idea的插件(EasyCode)来完成相应的代码生成功能(前提是需要会Velocity的技术)。
对于EasyCode也是有相应文档可以查询(需要联网)!

3. EasyCode

它就是一个idea的插件

3.1 官方说明

EasyCode是基于IntelliJ IDEA开发的代码生成插件,支持自定义任意模板(Java,html,js,xml)。只要是与数据库相关的代码都可以通过自定义模板来生成。支持数据库类型与java类型映射关系配置。支持同时生成生成多张表的代码。每张表有独立的配置信息。完全的个性化定义,规则由你设置。
前提:你要会Velocity!!

3.1.1 EasyCode能做什么?

EasyCode是基于IntelliJ IDEA Ultimate版开发的一个代码生成插件,主要通过自定义模板(基于velocity)来生成各种你想要的代码。通常用于生成Entity(domain)、Dao、Service、Controller。如果你动手能力强还可以用于生成HTML、JS、PHP等代码。理论上来说只要是与数据有关的代码都是可以生成的。

3.1.2 使用环境

IntelliJ IDEA Ultimate版(172+)

3.1.3 支持的数据库类型

因为是基于Database Tool开发,所有Database Tool支持的数据库都是支持的。
包括如下数据库:

  1. MySQL
  2. SQL Server
  3. Oracle
  4. PostgreSQL
  5. Sqlite
  6. Sybase
  7. Derby
  8. DB2
  9. HSQLDB
  10. H2
    当然支持的数据库类型也会随着Database Tool插件的更新同步更新。

3.1.4 功能说明:

• 支持多表同时操作
• 支持同时生成多个模板
• 支持自定义模板
• 支持自定义类型映射(支持正则)
• 支持自定义附加列
• 支持列附加属性
• 所有配置项目支持分组模式,在不同项目(或选择不同数据库时),只需要切换对应的分组,所有配置统一变化。

3.1.5 功能对比:

功能Easy Code其他工具
自定义模板支持支持
多表生成支持支持
生成方式无缝集成在项目中部分工具需要复制粘贴
附加列支持不支持
附加列属性支持不支持
动态调试模板支持不支持
图形化界面支持部分支持
使用环境仅限IDEA支持各种形式
在线支持后期扩展不支持
自定义类型映射支持部分支持
全局变量支持不支持

3.2 使用手册

我们这只作一些简单的讲解,手册具体的部分可以参见给的 makejava-EasyCode 文档
https://gitee.com/makejava/EasyCode/wikis/pages

3.2.1 安装

在线安装,直接打开
在这里插入图片描述
离线安装(先下载相应的zip包)
在这里插入图片描述

3.2.2 添加数据源(已经学过,不做详细讲解)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

最主要的就是控制它的位置与内容

3.2.3 生成一个基本代码

使用dept为例:这个是最简单的测试!!
在这里插入图片描述
我们这里只是生成一个最简单的实体类(当然,这个是使用它的自己原来的一个代码生成器模板,和我们最后想要的效果还有很大的差别!)

3.3 自定义模板生成

3.3.1 新建一个分组

咱们的代码生成器
在这里插入图片描述

3.3.2 模板的创建与位置问题

在这里插入图片描述
我们直接从原来模板中的entity中拷备过来,然后改成我们需要的代码即可!
注意:解决文件生成的位置问题:
模板代码的位置:
在这里插入图片描述
生成时的路径位置:
在这里插入图片描述
注:两个位置结合起来,最后才能把文件放到自己想要的地方

4. 代码生成器模板

4.1 Domain实体对象

##导入宏定义
$!define

##保存文件(宏定义)
#save("/main/java/com/zpx/domain", ".java")

##包路径(宏定义)
#setPackageSuffix("domain")

##自动导入包(全局变量)
$!autoImport
import javax.persistence.*;

##表注释(宏定义)
@Entity
@Table(name = "${tableInfo.obj.name}")
public class $!{tableInfo.name} extends BaseDomain {

#foreach($column in $tableInfo.otherColumn)
    #if(${column.comment})//${column.comment}#end

    private $!{tool.getClsNameByFullName($column.type)} $!{column.name};
#end

#foreach($column in $tableInfo.otherColumn)
    #getSetMethod($column)
#end

}

完成后可以查询生成代码,没有问题继续!

4.2 Query查询对象

这个我们可以参考默认代码中的service等地方

##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "Query"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/main/java/com/zpx/query"))


#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}query;

$!autoImport
import com.zpx.domain.$!{tableInfo.name};
import com.github.wenhao.jpa.Specifications;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.jpa.domain.Specification;

public class $!{tableName} extends BaseQuery {

    private String name;


    @Override
    public Specification createSpec(){
        
        Specification<$!{tableInfo.name}> spec = Specifications.<$!{tableInfo.name}>and()
                .like(StringUtils.isNotBlank(name),"name", "%"+name+"%")
                .build();
        return spec;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

4.3 Repository数据层

其实代码都差不多,只需要把相应位置的名称替换了即可

##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "Repository"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/main/java/com/zpx/repository"))


#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}repository;

$!autoImport
import com.zpx.domain.$!{tableInfo.name};

public interface $!{tableName} extends BaseRepository<$tableInfo.name,Long> {

}

4.4 IXxxService业务层接口

##定义初始变量
#set($tableName = $tool.append("I",$tableInfo.name, "Service"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/main/java/com/zpx/service"))


#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service;

$!autoImport
import com.zpx.domain.$!{tableInfo.name};

public interface $!{tableName} extends IBaseService<$tableInfo.name,Long> {

}

4.5 XxxServiceImpl

##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "ServiceImpl"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/main/java/com/zpx/service/impl"))


#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service.impl;

$!autoImport
import com.zpx.domain.$!{tableInfo.name};
import com.zpx.repository.$!{tableInfo.name}Repository;
import com.zpx.service.I$!{tableInfo.name}Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class $!{tableName} extends BaseServiceImpl<$!{tableInfo.name},Long> implements I$!{tableInfo.name}Service {
    @Autowired
    private $!{tableInfo.name}Repository $!{tableInfo.obj.name}Repository;
}

4.6 Test基本测试生成

##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "ServiceTest"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/test/java/com/zpx/service"))


#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service;

import com.zpx.BaseSpringTest;
import com.zpx.domain.$!{tableInfo.name};
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

public class $!{tableInfo.name}ServiceTest extends BaseSpringTest {
    @Autowired
    private I$!{tableInfo.name}Service $!{tableInfo.obj.name}Service;

    @Test
    public void testFindAll()throws Exception{
        $!{tableInfo.obj.name}Service.findAll().forEach(e-> System.out.println(e));
    }

}

4.7 XxxController:控制层

需要替换的太多,大家可以选拷备出去替换了后再重新进行操作
去掉多余的东西(如department相关与用户名验证功能)

##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "Controller"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/main/java/com/zpx/web/controller"))


#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}web.controller;

$!autoImport
import com.zpx.common.JsonResult;
import com.zpx.common.UIPage;
import com.zpx.domain.$!{tableInfo.name};
import com.zpx.query.$!{tableInfo.name}Query;
import com.zpx.service.I$!{tableInfo.name}Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
@RequestMapping("/$!{tableInfo.obj.name}")
public class $!{tableInfo.name}Controller extends BaseController {
    @Autowired
    private I$!{tableInfo.name}Service $!{tableInfo.obj.name}Service;
    @RequestMapping("/index")
    public String index(){
        //根据配置,这里会跳到/WEB-INF/views/$!{tableInfo.obj.name}/$!{tableInfo.obj.name}.jsp页面
        return "$!{tableInfo.obj.name}/$!{tableInfo.obj.name}";
    }
    /*@RequestMapping("/list")
    @ResponseBody
    public List<$!{tableInfo.name}> list(){
        return $!{tableInfo.obj.name}Service.findAll();
    }*/
    @RequestMapping("/page")
    @ResponseBody
    public UIPage<$!{tableInfo.name}> page($!{tableInfo.name}Query query){
        Page page = $!{tableInfo.obj.name}Service.findPageByQuery(query);
        //返回一个封装的对象
        return new UIPage(page);
    }
    //解决数据丢失
    /**
     *ModelAttribute:路径访问Controller的每个方法,都会先执行它里面的代码
     */
    @ModelAttribute("edit$!{tableInfo.name}")
    public $!{tableInfo.name} beforeEdit(Long id,String cmd){
        if (id!=null && "_update".equals(cmd)){
            //修改才走这个代码
            $!{tableInfo.name} db$!{tableInfo.name} = $!{tableInfo.obj.name}Service.findOne(id);
            //解决n-to-n的问题,把关联对象设置为空
            //employee.setDepartment(null);
            return db$!{tableInfo.name};
        }
        return null;
    }
    //删除功能
    @RequestMapping("/delete")
    @ResponseBody
    public JsonResult delete(Long id){
        try {
            $!{tableInfo.obj.name}Service.delete(id);
            return new JsonResult();
        } catch (Exception e) {
            e.printStackTrace();
            return new JsonResult(false,e.getMessage());
        }
    }
    //保存功能
    @RequestMapping("/save")
    @ResponseBody
    public JsonResult save($!{tableInfo.name} $!{tableInfo.obj.name}){
        try {
            $!{tableInfo.obj.name}Service.save($!{tableInfo.obj.name});
            return new JsonResult();
        } catch (Exception e) {
            e.printStackTrace();
            return new JsonResult(false,e.getMessage());
        }
    }
    //修改功能
    @RequestMapping("/update")
    @ResponseBody
    public JsonResult update(@ModelAttribute("edit$!{tableInfo.name}")$!{tableInfo.name} $!{tableInfo.obj.name}){
        try {
            $!{tableInfo.obj.name}Service.save($!{tableInfo.obj.name});
            return new JsonResult();
        } catch (Exception e) {
            e.printStackTrace();
            return new JsonResult(false,e.getMessage());
        }
    }
   
}

4.8 xxx.jsp 页面展示

##设置回调
$!callback.setFileName($tool.append($tableInfo.obj.name, ".jsp"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/main/webapp/WEB-INF/views/${tableInfo.obj.name}"))
<%--
  这是一个处理数据与查询的页面
  Created by IntelliJ IDEA.
  User: 86147
  Date: 2019/7/5
  Time: 11:03
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>智销系统</title>
    <%--页面引入--%>
    <%@include file="/WEB-INF/views/head.jsp" %>
    <%--引入js--%>
    <script src="/js/model/$!{tableInfo.obj.name}.js"></script>
</head>
<body>
<%--enableHeaderClickMenu=true列数据隐藏--%>
<%--onRowContextMenu:showMenu右键增删改--%>
<%--pagination:true分页条--%>
<%--数据表格--%>
    <table id="$!{tableInfo.obj.name}Grid" class="easyui-datagrid"
           data-options="url:'/$!{tableInfo.obj.name}/page',fitColumns:true
           ,singleSelect:true,fit:true
           ,pagination:true,toolbar:'#gridTools',onRowContextMenu:showMenu
">
        <thead>
        <%--sortable="true"自动排序--%>
        <tr>
            #foreach($column in $tableInfo.otherColumn)
            <th data-options="field:'$!{column.name}',width:100">$!{column.name}</th>
            #end
        </tr>
        </thead>
    </table>

    <%--grid顶部工具栏--%>
    <div id="gridTools" style="padding:5px;height:auto">
        <%--功能条--%>
        <div id="gridMenu" style="margin-bottom:5px">
            <a href="#" data-method="add" class="easyui-linkbutton" iconCls="icon-add" plain="true">添加</a>
            <a href="#" data-method="update" class="easyui-linkbutton" iconCls="icon-edit" plain="true">修改</a>
            <a href="#" data-method="del" class="easyui-linkbutton" iconCls="icon-remove" plain="true">删除</a>
        </div>
            <%--查询条--%>
        <form id="searchForm">
            名称: <input name="name" class="easyui-textbox" style="width:80px">
            <a href="#" data-method="search" class="easyui-linkbutton" iconCls="icon-search">搜索</a>
        </form>
    </div>

    <%--添加与修改的表单对话框--%>
    <div id="editDialog" class="easyui-dialog" title="功能编辑" style="width:400px;"
         data-options="iconCls:'icon-save',resizable:true,modal:true,closed:true">
        <form id="editForm" method="post">
            <input id="$!{tableInfo.obj.name}Id" type="hidden" name="id" />
            <table cellpadding="5">
                #foreach($column in $tableInfo.otherColumn)
                <tr>
                    <td>$!{column.name}:</td>
                    <td><input class="easyui-validatebox" type="text" name="$!{column.name}"
                               data-options="required:true"></input></td>
                </tr>
                #end
            </table>
        </form>
        <div style="text-align:center;padding:5px">
            <a href="javascript:void(0)" class="easyui-linkbutton" data-method="save">提交</a>
            <a href="javascript:void(0)" class="easyui-linkbutton" data-method="closeDialog">关闭</a>
        </div>
    </div>
</body>
</html>

4.9 Xxx.js

注意:拷备Employee实现后删除多余的内容(如department与一些format代码)

##设置回调
$!callback.setFileName($tool.append($tableInfo.obj.name, ".js"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/main/webapp/js/model"))
$(function () {
    //1.获取常用的一些组件
    //数据表格
    var $!{tableInfo.obj.name}Grid = $("#$!{tableInfo.obj.name}Grid");
    //查询条
    var searchForm = $("#searchForm");
    //添加修改功能框
    var editDialog = $("#editDialog");
    //功能框表单
    var editForm = $("#editForm");

    //2.绑定相应事件
    $("*[data-method]").on("click",function () {
        var methodName = $(this).data("method");
        window.itsource[methodName]();
    })

    itsource={
        search(){
            //拿到from表单里的所有值,封装为一个对象(需要用到jqery扩展功能)
            //serializeObject:拿到一个form中的所有数据,封装成json对象
            var params = searchForm.serializeObject();
            $!{tableInfo.obj.name}Grid.datagrid("load",params);
        },
        add(){
            $("*[data-edit] input").validatebox("enable");
            $("*[data-edit]").show();
            //0.每次打开时,清空from表单里的数据
            editForm.form("clear");
            //1.打开弹出框(每次打开时绝对居中)
            editDialog.dialog("center").dialog("open");
        },
        update(){
            //1.获取需要修改的那行数据
            let row = $!{tableInfo.obj.name}Grid.datagrid("getSelected");
            //2.如果没有选中,给出提示,后面的代码就不再执行了
            if (!row){
                $.messager.alert('警告','请选中后再操作!',"warning");
                return ;
            }
            //清空form数据
            editForm.form("clear");
            //让密码框失效且隐藏起来
            $("*[data-edit] input").validatebox("disable");
            $("*[data-edit]").hide();
            /*
            //把结果进行回显
            if (row.department){
                row["department.id"] = row.department.id;
            }
            */
            //清空后回显选中行数据
            editForm.form("load",row);
            //3.打开弹出框
            editDialog.dialog("center").dialog("open");
        },
        //保存功能
        save(){
            var url ="/$!{tableInfo.obj.name}/save";
            //获取id的值
            var $!{tableInfo.obj.name}Id = $("#$!{tableInfo.obj.name}Id").val();
            if ($!{tableInfo.obj.name}Id){
                url = "/$!{tableInfo.obj.name}/update?cmd=_update";
            }
            editForm.form('submit',{
                //提交的路径
                url:"/$!{tableInfo.obj.name}/save",
                //提交之前的操作
                onSubmit:function () {
                    //做一些检查,表单若有违规字段,则不予提交
                    //返回false可以组织提交
                    return $(this).form('validate');
                },
                //data : {success:true/false,msg:xxx} -> 字符串
                success:function (data) {
                    //需要将字符串的data数据转化为json类型
                    var result = JSON.parse(data);
                    if (result.success){
                        $!{tableInfo.obj.name}Grid.datagrid("reload");
                    }else {
                        $.messager.alert('错误',`保存失败! 原因是:${result.msg}`,"error");
                    }
                    //关闭弹出框
                    itsource.closeDialog();
                }
            });
        },
        del(){
            //1.拿到选中数据
            let row = $!{tableInfo.obj.name}Grid.datagrid("getSelected");
            //2.如果没有选中,给出提示,后面的代码就不再执行了
            if (!row){
                $.messager.alert('警告','请选中后再操作!',"warning");
                return ;
            }
            //3.选中后,弹出确认删除窗口
            $.messager.confirm('确认','您确认想要删除记录吗?',function(r){
                if (r){
                    //4.如果确认,则把id传到后台,后台删除数据
                    $.get("/$!{tableInfo.obj.name}/delete",{id:row.id},function (result) {
                        if (result.success){
                            //删除成功则重载行
                            $!{tableInfo.obj.name}Grid.datagrid("reload");
                        }else{
                            $.messager.alert('错误',`删除失败! 原因是:${result.msg}`,"error");
                        }
                    })
                }
            });

        },
        //关闭窗口
        closeDialog(){
            editDialog.dialog("close");
        }

    }
    
})

//右键增删改扩展
function showMenu(e, rowIndex, rowData) {

    //选中这个行
    $("#$!{tableInfo.obj.name}Grid").datagrid("selectRow",rowIndex);
    //第0个位置的面板不支持相应功能
    e.preventDefault();
    $('#gridMenu').menu('show', {
        left: e.pageX,
        top: e.pageY
    });
}


5. 权限设计

  • 权限是什么
    简单的说:就是说你能不能对系统做某一种操作!
    一般我们分两种:登录认证 + 权限认证
    以前咱们登录:成功后所有内容都可以访问!
    权限认证:你登录成功后,是否有操作某一个功能的权限
  • 登录的逻辑
    没有登录的人,我们称它为游客
    游客要有票(令牌:token【username,password】)才可以进入

  • 我们进入相应的验证:
  1. 判断用户名是否存在
  2. 判断密码是否正确
  3. 判断用户是否已经过期
  4. 其它错误(解释权归我们自己)
  • 两个问题:session不通过(SE系统)/密码不安全

  • 密码加密问题
    把密码进行散列加密(Sha,MD5)
    加密次数,加盐 以及我们如何判断登录

  • 角色资源的认识

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值