Jelajahi Sumber

first commit

fangq 4 tahun lalu
melakukan
00f9756b19

+ 62 - 0
.gitignore

@@ -0,0 +1,62 @@
+### gradle ###
+.gradle
+/build/
+!gradle/wrapper/gradle-wrapper.jar
+
+### STS ###
+.settings/
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+bin/
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+*.lock
+rebel.xml
+
+### NetBeans ###
+nbproject/private/
+build/
+nbbuild/
+dist/
+nbdist/
+.nb-gradle/
+
+### maven ###
+target/
+*.war
+*.ear
+*.zip
+*.tar
+*.tar.gz
+
+### logs ####
+/logs/
+*.log
+
+### temp ignore ###
+*.cache
+*.diff
+*.patch
+*.tmp
+*.java~
+*.properties~
+*.xml~
+
+### system ignore ###
+.DS_Store
+Thumbs.db
+Servers
+.metadata
+upload
+gen_code
+
+### node ###
+node_modules

+ 9 - 0
README.md

@@ -0,0 +1,9 @@
+# mall4g
+
+商城的代码生成器
+
+1. 修改数据库连接,修改 application.yml
+2. 代码生成器依赖生成模板,根据模板可以自己改造属于自己的代码生成器,模板位置 template文件夹
+3. 修改generator.properties 修改需要生成的模块
+4. 修改GenApplication里面的tables,更改需要生成的表,运行
+

+ 87 - 0
pom.xml

@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <groupId>com.yami.shop</groupId>
+    <version>1.0.0</version>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>yami-shop-generator</artifactId>
+
+    <properties>
+        <yami.shop.version>0.0.1-SNAPSHOT</yami.shop.version>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <maven.compiler.plugin.version>3.7.0</maven.compiler.plugin.version>
+        <spring-boot.version>2.1.4.RELEASE</spring-boot.version>
+        <java.version>1.8</java.version>
+        <guava.version>20.0</guava.version>
+        <hutool.version>4.5.0</hutool.version>
+        <mybatis-plus.version>3.1.0</mybatis-plus.version>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>${spring-boot.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>${hutool.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+            <version>${mybatis-plus.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter</artifactId>
+        </dependency>
+        <!--代码生成模板引擎-->
+        <dependency>
+            <artifactId>velocity</artifactId>
+            <groupId>org.apache.velocity</groupId>
+            <version>1.7</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-configuration</groupId>
+            <artifactId>commons-configuration</artifactId>
+            <version>1.10</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>${maven.compiler.plugin.version}</version>
+                <configuration>
+                    <source>${java.version}</source>
+                    <target>${java.version}</target>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 42 - 0
src/main/java/com/yami/shop/generator/GenApplication.java

@@ -0,0 +1,42 @@
+package com.yami.shop.generator;
+
+import com.yami.shop.generator.service.SysGeneratorService;
+import lombok.AllArgsConstructor;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.BeansException;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.annotation.ComponentScan;
+
+/**
+ * @author LGH
+ */
+@SpringBootApplication
+@ComponentScan("com.yami.shop")
+@MapperScan({"com.yami.shop.generator.dao"})
+public class GenApplication implements ApplicationContextAware {
+
+    private static ApplicationContext applicationContext;
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext)
+            throws BeansException {
+        GenApplication.applicationContext = applicationContext;
+    }
+
+
+    public static void main(String[] args) {
+        SpringApplication.run(GenApplication.class, args);
+
+        SysGeneratorService sysGeneratorService = applicationContext.getBean(SysGeneratorService.class);
+
+        String[] tables = {"tz_seckill","tz_seckill_sku", "tz_seckill_order"};
+
+        for (String table : tables) {
+            sysGeneratorService.generatorCode(table);
+        }
+    }
+
+}

+ 39 - 0
src/main/java/com/yami/shop/generator/dao/SysGeneratorMapper.java

@@ -0,0 +1,39 @@
+package com.yami.shop.generator.dao;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 代码生成器
+ */
+public interface SysGeneratorMapper {
+
+    /**
+     * 分页查询表格
+     *
+     * @param page
+     * @param tableName
+     * @return
+     */
+    IPage<List<Map<String, Object>>> queryList(Page page, @Param("tableName") String tableName);
+
+    /**
+     * 查询表信息
+     *
+     * @param tableName 表名称
+     * @return
+     */
+    Map<String, String> queryTable(String tableName);
+
+    /**
+     * 查询表列信息
+     *
+     * @param tableName 表名称
+     * @return
+     */
+    List<Map<String, String>> queryColumns(String tableName);
+}

+ 39 - 0
src/main/java/com/yami/shop/generator/entity/ColumnEntity.java

@@ -0,0 +1,39 @@
+package com.yami.shop.generator.entity;
+
+import lombok.Data;
+
+/**
+ * 列属性: https://blog.csdn.net/lkforce/article/details/79557482
+ */
+@Data
+public class ColumnEntity {
+    /**
+     * 列表
+     */
+    private String columnName;
+    /**
+     * 数据类型
+     */
+    private String dataType;
+    /**
+     * 备注
+     */
+    private String comments;
+
+    /**
+     * 驼峰属性
+     */
+    private String caseAttrName;
+    /**
+     * 普通属性
+     */
+    private String lowerAttrName;
+    /**
+     * 属性类型
+     */
+    private String attrType;
+    /**
+     * 其他信息
+     */
+    private String extra;
+}

+ 22 - 0
src/main/java/com/yami/shop/generator/entity/CommonConstants.java

@@ -0,0 +1,22 @@
+package com.yami.shop.generator.entity;
+
+/**
+ */
+public interface CommonConstants {
+
+    /**
+     * 前端工程名
+     */
+    String FRONT_END_PROJECT = "yami-vue";
+
+    /**
+     * 后端工程名
+     */
+    String BACK_END_PROJECT = "yami-shop";
+
+    /**
+     * 后端工程名
+     */
+    String SQL_PROJECT = "yami-sql";
+
+}

+ 36 - 0
src/main/java/com/yami/shop/generator/entity/TableEntity.java

@@ -0,0 +1,36 @@
+package com.yami.shop.generator.entity;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 表属性: https://blog.csdn.net/lkforce/article/details/79557482
+ */
+@Data
+public class TableEntity {
+    /**
+     * 名称
+     */
+    private String tableName;
+    /**
+     * 备注
+     */
+    private String comments;
+    /**
+     * 主键
+     */
+    private ColumnEntity pk;
+    /**
+     * 列名
+     */
+    private List<ColumnEntity> columns;
+    /**
+     * 驼峰类型
+     */
+    private String caseClassName;
+    /**
+     * 普通类型
+     */
+    private String lowerClassName;
+}

+ 11 - 0
src/main/java/com/yami/shop/generator/service/SysGeneratorService.java

@@ -0,0 +1,11 @@
+package com.yami.shop.generator.service;
+
+
+public interface SysGeneratorService {
+    /**
+     * 生成代码
+     *
+     * @param tableName 表名称
+     */
+    void generatorCode(String tableName);
+}

+ 49 - 0
src/main/java/com/yami/shop/generator/service/impl/SysGeneratorServiceImpl.java

@@ -0,0 +1,49 @@
+package com.yami.shop.generator.service.impl;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+import com.yami.shop.generator.dao.SysGeneratorMapper;
+import com.yami.shop.generator.service.SysGeneratorService;
+import com.yami.shop.generator.util.GenUtils;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 代码生成器
+ */
+@Service
+@AllArgsConstructor
+public class SysGeneratorServiceImpl implements SysGeneratorService {
+    private final SysGeneratorMapper sysGeneratorMapper;
+
+    /**
+     * 生成代码
+     *
+     * @param tableName 表名称
+     */
+    @Override
+    public void generatorCode(String tableName) {
+
+        //查询表信息
+        Map<String, String> table = queryTable(tableName);
+        if (CollectionUtil.isEmpty(table)) {
+            throw new RuntimeException("在数据库中无法获取[" +tableName+"]表信息");
+        }
+        //查询列信息
+        List<Map<String, String>> columns = queryColumns(tableName);
+        //生成代码
+        GenUtils.generatorCode(table, columns);
+    }
+
+    private Map<String, String> queryTable(String tableName) {
+        return sysGeneratorMapper.queryTable(tableName);
+    }
+
+    private List<Map<String, String>> queryColumns(String tableName) {
+        return sysGeneratorMapper.queryColumns(tableName);
+    }
+}

+ 241 - 0
src/main/java/com/yami/shop/generator/util/GenUtils.java

@@ -0,0 +1,241 @@
+package com.yami.shop.generator.util;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.CharsetUtil;
+import com.yami.shop.generator.entity.ColumnEntity;
+import com.yami.shop.generator.entity.CommonConstants;
+import com.yami.shop.generator.entity.TableEntity;
+import lombok.experimental.UtilityClass;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.WordUtils;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.Velocity;
+
+import java.io.File;
+import java.io.StringWriter;
+import java.util.*;
+
+/**
+ * 代码生成器   工具类
+ */
+@Slf4j
+@UtilityClass
+public class GenUtils {
+
+    private final String ENTITY_JAVA_VM = "Model.java.vm";
+    private final String MAPPER_JAVA_VM = "Mapper.java.vm";
+    private final String SERVICE_JAVA_VM = "Service.java.vm";
+    private final String SERVICE_IMPL_JAVA_VM = "ServiceImpl.java.vm";
+    private final String CONTROLLER_JAVA_VM = "Controller.java.vm";
+    private final String MAPPER_XML_VM = "Mapper.xml.vm";
+    private final String MENU_SQL_VM = "menu.sql.vm";
+    private final String INDEX_VUE_VM = "index.vue.vm";
+    private final String ADD_OR_UPDATE_VUE_VM = "add-or-update.vue.vm";
+
+    private List<String> getTemplates() {
+        List<String> templates = new ArrayList<>();
+        templates.add("template/Model.java.vm");
+        templates.add("template/Mapper.java.vm");
+        templates.add("template/Mapper.xml.vm");
+        templates.add("template/Service.java.vm");
+        templates.add("template/ServiceImpl.java.vm");
+        templates.add("template/Controller.java.vm");
+        templates.add("template/menu.sql.vm");
+
+        templates.add("template/index.vue.vm");
+        templates.add("template/add-or-update.vue.vm");
+        return templates;
+    }
+
+    /**
+     * 生成代码
+     */
+    public void generatorCode(Map<String, String> table,
+                              List<Map<String, String>> columns) {
+        //配置信息
+        Configuration config = getConfig();
+        boolean hasBigDecimal = false;
+        //表信息
+        TableEntity tableEntity = new TableEntity();
+        tableEntity.setTableName(table.get("tableName"));
+
+
+        tableEntity.setComments(table.get("tableComment"));
+
+        String tablePrefix = config.getString("tablePrefix");
+
+        //表名转换成Java类名
+        String className = tableToJava(tableEntity.getTableName(), tablePrefix);
+        tableEntity.setCaseClassName(className);
+        tableEntity.setLowerClassName(StringUtils.uncapitalize(className));
+
+        //列信息
+        List<ColumnEntity> columnList = new ArrayList<>();
+        for (Map<String, String> column : columns) {
+            ColumnEntity columnEntity = new ColumnEntity();
+            columnEntity.setColumnName(column.get("columnName"));
+            columnEntity.setDataType(column.get("dataType"));
+            columnEntity.setComments(column.get("columnComment"));
+            columnEntity.setExtra(column.get("extra"));
+
+            //列名转换成Java属性名
+            String attrName = columnToJava(columnEntity.getColumnName());
+            columnEntity.setCaseAttrName(attrName);
+            columnEntity.setLowerAttrName(StringUtils.uncapitalize(attrName));
+
+            //列的数据类型,转换成Java类型
+            String attrType = config.getString(columnEntity.getDataType(), "unknowType");
+            columnEntity.setAttrType(attrType);
+            if (!hasBigDecimal && "BigDecimal".equals(attrType)) {
+                hasBigDecimal = true;
+            }
+            //是否主键
+            if ("PRI".equalsIgnoreCase(column.get("columnKey")) && tableEntity.getPk() == null) {
+                tableEntity.setPk(columnEntity);
+            }
+
+            columnList.add(columnEntity);
+        }
+        tableEntity.setColumns(columnList);
+
+        //没主键,则第一个字段为主键
+        if (tableEntity.getPk() == null) {
+            tableEntity.setPk(tableEntity.getColumns().get(0));
+        }
+
+        //设置velocity资源加载器
+        Properties prop = new Properties();
+        prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
+        Velocity.init(prop);
+        //封装模板数据
+        Map<String, Object> map = new HashMap<>(16);
+        map.put("tableName", tableEntity.getTableName());
+        map.put("pk", tableEntity.getPk());
+        map.put("className", tableEntity.getCaseClassName());
+        map.put("classname", tableEntity.getLowerClassName());
+        map.put("pathName", tableEntity.getLowerClassName().toLowerCase());
+        map.put("columns", tableEntity.getColumns());
+        map.put("hasBigDecimal", hasBigDecimal);
+        map.put("datetime", DateUtil.now());
+
+
+        map.put("comments", tableEntity.getComments());
+
+        map.put("author", config.getString("author"));
+
+
+        map.put("moduleName", config.getString("moduleName"));
+
+
+        map.put("package", config.getString("package"));
+        map.put("mainPath", config.getString("mainPath"));
+
+        VelocityContext context = new VelocityContext(map);
+
+        //获取模板列表
+        List<String> templates = getTemplates();
+        for (String template : templates) {
+            //渲染模板
+            StringWriter sw = new StringWriter();
+            Template tpl = Velocity.getTemplate(template, CharsetUtil.UTF_8);
+            tpl.merge(context, sw);
+
+            try {
+
+                File file = new File(config.getString("rootPath") + getFileName(template, tableEntity.getCaseClassName()
+                                                 , map.get("package").toString(), map.get("moduleName").toString()));
+                if (file.exists()) {
+                    file.delete();
+                }
+
+                FileUtil.writeString(sw.toString(),file,CharsetUtil.UTF_8);
+                System.out.println("成功创建文件:" + file.getPath());
+                IoUtil.close(sw);
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new RuntimeException("渲染模板失败,表名:" + tableEntity.getTableName());
+            }
+        }
+    }
+
+
+    /**
+     * 列名转换成Java属性名
+     */
+    private String columnToJava(String columnName) {
+        return WordUtils.capitalizeFully(columnName, new char[]{'_'}).replace("_", "");
+    }
+
+    /**
+     * 表名转换成Java类名
+     */
+    private String tableToJava(String tableName, String tablePrefix) {
+        if (StringUtils.isNotBlank(tablePrefix)) {
+            tableName = tableName.replaceFirst(tablePrefix, "");
+        }
+        return columnToJava(tableName);
+    }
+
+    /**
+     * 获取配置信息
+     */
+    private Configuration getConfig() {
+        try {
+            return new PropertiesConfiguration("generator.properties");
+        } catch (ConfigurationException e) {
+            throw new RuntimeException("获取配置文件失败,");
+        }
+    }
+
+    /**
+     * 获取文件名
+     */
+    private String getFileName(String template, String className, String packageName, String moduleName) {
+        String packagePath = CommonConstants.BACK_END_PROJECT + File.separator;
+
+        if (template.contains(ENTITY_JAVA_VM)) {
+            return packagePath + "model" + File.separator + className + ".java";
+        }
+
+        if (template.contains(MAPPER_JAVA_VM)) {
+            return packagePath + "dao" + File.separator + className + "Mapper.java";
+        }
+
+        if (template.contains(SERVICE_JAVA_VM)) {
+            return packagePath + "service" + File.separator + className + "Service.java";
+        }
+
+        if (template.contains(SERVICE_IMPL_JAVA_VM)) {
+            return packagePath + "service" + File.separator + "impl" + File.separator + className + "ServiceImpl.java";
+        }
+
+        if (template.contains(CONTROLLER_JAVA_VM)) {
+            return packagePath + "controller" + File.separator + className + "Controller.java";
+        }
+
+        if (template.contains(MAPPER_XML_VM)) {
+            return CommonConstants.BACK_END_PROJECT + File.separator + "xml" + File.separator + className + "Mapper.xml";
+        }
+
+        if (template.contains(MENU_SQL_VM)) {
+            return CommonConstants.SQL_PROJECT + File.separator + className.toLowerCase() + "_menu.sql";
+        }
+
+        if (template.contains(INDEX_VUE_VM)) {
+            return CommonConstants.FRONT_END_PROJECT + File.separator + "vue" + File.separator + StringUtils.uncapitalize(className) + ".vue";
+        }
+
+        if (template.contains(ADD_OR_UPDATE_VUE_VM)) {
+            return CommonConstants.FRONT_END_PROJECT + File.separator + "vue" + File.separator + StringUtils.uncapitalize(className) + "-add-or-update.vue";
+        }
+
+        return null;
+    }
+}

+ 28 - 0
src/main/resources/application.yml

@@ -0,0 +1,28 @@
+spring:
+  datasource:
+    url: jdbc:mysql://127.0.0.1:3306/yami_shops?allowMultiQueries=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true
+    username: root
+    password: root
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    type: com.zaxxer.hikari.HikariDataSource
+    hikari:
+      minimum-idle: 0
+      maximum-pool-size: 20
+      idle-timeout: 10000
+      auto-commit: true
+      connection-test-query: SELECT 1
+
+# mybaits-plus配置
+mybatis-plus:
+  # MyBatis Mapper所对应的XML文件位置
+  mapper-locations: classpath*:/mapper/*Mapper.xml
+  global-config:
+    # 关闭MP3.0自带的banner
+    banner: false
+    db-config:
+      # 主键类型 0:数据库ID自增 1.未定义 2.用户输入 3 id_worker 4.uuid 5.id_worker字符串表示
+      id-type: AUTO
+      #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
+      field-strategy: NOT_NULL
+      # 默认数据库表下划线命名
+      table-underline: true

+ 36 - 0
src/main/resources/generator.properties

@@ -0,0 +1,36 @@
+#\u4EE3\u7801\u751F\u6210\u5668\uFF0C\u914D\u7F6E\u4FE1\u606F
+rootPath=c:/generator/
+
+mainPath=com.yami.shop
+#\u5305\u540D
+package=com.yami.shop
+moduleName=seckill
+#\u4F5C\u8005
+author=LGH
+
+#\u8868\u524D\u7F00(\u7C7B\u540D\u4E0D\u4F1A\u5305\u542B\u8868\u524D\u7F00)
+tablePrefix=tz_
+
+#\u7C7B\u578B\u8F6C\u6362\uFF0C\u914D\u7F6E\u4FE1\u606F
+tinyint=Integer
+smallint=Integer
+mediumint=Integer
+int=Integer
+integer=Integer
+bigint=Long
+float=Float
+double=Double
+decimal=Double
+bit=Integer
+
+char=String
+varchar=String
+tinytext=String
+text=String
+mediumtext=String
+longtext=String
+json=String
+
+date=Date
+datetime=Date
+timestamp=Date

+ 23 - 0
src/main/resources/mapper/SysGeneratorMapper.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.yami.shop.generator.dao.SysGeneratorMapper">
+    <select id="queryList" resultType="map">
+        select table_name tableName, engine, table_comment tableComment, create_time createTime from information_schema.tables
+            where table_schema = (select database())
+        <if test="tableName != null and tableName.trim() != ''">
+            and table_name like concat('%', #{tableName}, '%')
+        </if>
+        order by create_time desc
+    </select>
+
+    <select id="queryTable" resultType="map">
+        select table_name tableName, engine, table_comment tableComment, create_time createTime from information_schema.tables
+            where table_schema = (select database()) and table_name = #{tableName}
+    </select>
+
+    <select id="queryColumns" resultType="map">
+        select column_name columnName, data_type dataType, column_comment columnComment, column_key columnKey, extra from information_schema.columns
+             where table_name = #{tableName} and table_schema = (select database()) order by ordinal_position
+    </select>
+</mapper>

+ 79 - 0
src/main/resources/template/Controller.java.vm

@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
+ *
+ * https://www.mall4j.com/
+ *
+ * 未经允许,不可做商业用途!
+ *
+ * 版权所有,侵权必究!
+ */
+package ${package}.${moduleName}.admin.controller;
+
+import ${package}.${moduleName}.common.model.${className};
+import ${package}.${moduleName}.common.service.${className}Service;
+
+import javax.validation.Valid;
+
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiModelProperty;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiImplicitParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.yami.shop.common.util.PageParam;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+
+
+/**
+ * ${comments}
+ *
+ * @author ${author}
+ * @date ${datetime}
+ */
+@RestController
+@RequestMapping("/${moduleName}/${classname}")
+@Api(tags = "${comments}")
+public class ${className}Controller {
+
+    @Autowired
+    private ${className}Service ${classname}Service;
+
+    @GetMapping("/page")
+    @ApiOperation(value = "获取${comments}列表", notes = "分页获取${comments}列表")
+    public ResponseEntity<IPage<${className}>> get${className}Page(PageParam<${className}> page, ${className} ${classname}) {
+        return ResponseEntity.ok(${classname}Service.page(page, new LambdaQueryWrapper<${className}>()));
+    }
+
+    @GetMapping("/info/{${pk.lowerAttrName}}")
+    @ApiOperation(value = "获取${comments}", notes = "根据${pk.lowerAttrName}获取${comments}")
+    @ApiImplicitParam(name = "${pk.lowerAttrName}", value = "${comments}", required = true, dataType = "${pk.attrType}")
+    public ResponseEntity<${className}> getById(@PathVariable("${pk.lowerAttrName}") ${pk.attrType} ${pk.lowerAttrName}) {
+        return ResponseEntity.ok(${classname}Service.getById(${pk.lowerAttrName}));
+    }
+
+    @PostMapping
+    @PreAuthorize("@pms.hasPermission('${moduleName}:${classname}:save')")
+    @ApiOperation(value = "保存${comments}", notes = "保存${comments}")
+    public ResponseEntity<Boolean> save(@RequestBody @Valid ${className} ${classname}) {
+        return ResponseEntity.ok(${classname}Service.save(${classname}));
+    }
+
+    @PutMapping
+    @PreAuthorize("@pms.hasPermission('${moduleName}:${classname}:update')")
+    @ApiOperation(value = "更新${comments}", notes = "更新${comments}")
+    public ResponseEntity<Boolean> updateById(@RequestBody @Valid ${className} ${classname}) {
+        return ResponseEntity.ok(${classname}Service.updateById(${classname}));
+    }
+
+    @DeleteMapping("/{${pk.lowerAttrName}}")
+    @PreAuthorize("@pms.hasPermission('${moduleName}:${classname}:delete')")
+    @ApiOperation(value = "删除${comments}", notes = "根据${comments}id删除${comments}")
+    @ApiImplicitParam(name = "${pk.lowerAttrName}", value = "${comments}", required = true, dataType = "${pk.attrType}")
+    public ResponseEntity<Boolean> removeById(@PathVariable ${pk.attrType} ${pk.lowerAttrName}) {
+        return ResponseEntity.ok(${classname}Service.removeById(${pk.lowerAttrName}));
+    }
+}

+ 23 - 0
src/main/resources/template/Mapper.java.vm

@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
+ *
+ * https://www.mall4j.com/
+ *
+ * 未经允许,不可做商业用途!
+ *
+ * 版权所有,侵权必究!
+ */
+package ${package}.${moduleName}.common.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import ${package}.${moduleName}.common.model.${className};
+
+/**
+ * ${comments}
+ *
+ * @author ${author}
+ * @date ${datetime}
+ */
+public interface ${className}Mapper extends BaseMapper<${className}> {
+
+}

+ 15 - 0
src/main/resources/template/Mapper.xml.vm

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="${package}.${moduleName}.common.dao.${className}Mapper">
+
+  <resultMap id="${classname}Map" type="${package}.${moduleName}.common.model.${className}">
+#foreach($column in $columns)
+#if($column.lowerAttrName==$pk.lowerAttrName)
+    <id column="${pk.columnName}" property="${pk.lowerAttrName}" />
+#else
+    <result column="${column.columnName}" property="${column.lowerAttrName}"/>
+#end
+#end
+  </resultMap>
+</mapper>

+ 43 - 0
src/main/resources/template/Model.java.vm

@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
+ *
+ * https://www.mall4j.com/
+ *
+ * 未经允许,不可做商业用途!
+ *
+ * 版权所有,侵权必究!
+ */
+package ${package}.${moduleName}.common.model;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+#if(${hasBigDecimal})
+import java.math.BigDecimal;
+#end
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * ${comments}
+ *
+ * @author ${author}
+ * @date ${datetime}
+ */
+@Data
+@TableName("${tableName}")
+@ApiModel("${comments}")
+public class ${className} implements Serializable{
+    private static final long serialVersionUID = 1L;
+
+#foreach ($column in $columns)
+#if($column.columnName == $pk.columnName)
+    @TableId
+#else
+    @ApiModelProperty(value = "$column.comments")
+#end
+    private $column.attrType $column.lowerAttrName;
+#end
+}

+ 23 - 0
src/main/resources/template/Service.java.vm

@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
+ *
+ * https://www.mall4j.com/
+ *
+ * 未经允许,不可做商业用途!
+ *
+ * 版权所有,侵权必究!
+ */
+package ${package}.${moduleName}.common.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import ${package}.${moduleName}.common.model.${className};
+
+/**
+ * ${comments}
+ *
+ * @author ${author}
+ * @date ${datetime}
+ */
+public interface ${className}Service extends IService<${className}> {
+
+}

+ 30 - 0
src/main/resources/template/ServiceImpl.java.vm

@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
+ *
+ * https://www.mall4j.com/
+ *
+ * 未经允许,不可做商业用途!
+ *
+ * 版权所有,侵权必究!
+ */
+package ${package}.${moduleName}.common.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import ${package}.${moduleName}.common.model.${className};
+import ${package}.${moduleName}.common.dao.${className}Mapper;
+import ${package}.${moduleName}.common.service.${className}Service;
+import org.springframework.stereotype.Service;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * ${comments}
+ *
+ * @author ${author}
+ * @date ${datetime}
+ */
+@Service
+public class ${className}ServiceImpl extends ServiceImpl<${className}Mapper, ${className}> implements ${className}Service {
+
+    @Autowired
+    private ${className}Mapper ${classname}Mapper;
+}

+ 76 - 0
src/main/resources/template/add-or-update.vue.vm

@@ -0,0 +1,76 @@
+<template>
+  <el-dialog
+    :title="!dataForm.${pk.lowerAttrName} ? this.$i18n.t('crud.addTitle') : this.$i18n.t('temp.modify')"
+    :close-on-click-modal="false"
+    :visible.sync="visible">
+    <el-form :model="dataForm" :rules="dataRule" ref="dataForm" @keyup.enter.native="dataFormSubmit()" label-width="80px">
+#foreach ($column in $columns)
+      <el-form-item label="$column.comments" prop="$column.lowerAttrName">
+        <el-input v-model="dataForm.$column.lowerAttrName"></el-input>
+      </el-form-item>
+#end
+    </el-form>
+    <span slot="footer" class="dialog-footer">
+      <el-button class="default-btn" @click="visible = false">{{$t("crud.filter.cancelBtn")}}</el-button>
+      <el-button class="default-btn primary-btn" type="primary" @click="dataFormSubmit()">{{$t("crud.filter.submitBtn")}}</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>#set($symbol="$")
+
+export default {
+  data () {
+    return {
+      visible: false,
+      dataForm: {
+#foreach ($column in $columns)
+        $column.lowerAttrName: null,
+#end
+      },
+      dataRule: {
+      }
+    }
+  },
+  methods: {
+    init (${pk.lowerAttrName}) {
+      this.dataForm.${pk.lowerAttrName} = ${pk.lowerAttrName} || 0
+      this.visible = true
+      this.$nextTick(() => {
+        this.$refs['dataForm'].resetFields()
+        if (this.dataForm.${pk.lowerAttrName}) {
+          this.$http({
+            url: this.${symbol}http.adornUrl('/${moduleName}/${classname}/info/' + this.dataForm.${pk.lowerAttrName}),
+            method: 'get',
+            params: this.$http.adornParams()
+          }).then(({data}) => {
+            this.dataForm = data
+          })
+        }
+      })
+    },
+    // 表单提交
+    dataFormSubmit () {
+      this.${symbol}refs['dataForm'].validate((valid) => {
+        if (valid) {
+          this.$http({
+            url: this.${symbol}http.adornUrl('/${moduleName}/${classname}'),
+            method: this.dataForm.${pk.lowerAttrName} ? 'put' : 'post',
+            data: this.${symbol}http.adornData(this.dataForm)
+          }).then(({data}) => {
+            this.$message({
+              message: this.$i18n.t('publics.operation'),
+              type: 'success',
+              duration: 1500,
+              onClose: () => {
+                this.visible = false
+                this.$emit('refreshDataList')
+              }
+            })
+          })
+        }
+      })
+    }
+  }
+}
+</script>

+ 151 - 0
src/main/resources/template/index.vue.vm

@@ -0,0 +1,151 @@
+<template>
+  <div class="mod-${moduleName}-${classname}">
+    <!-- 搜索相关区域 -->
+    <div class="search-bar">
+      <el-button class="default-btn primary-btn" @click="searchChange">{{$t('crud.searchBtn')}}</el-button>
+    </div>
+    <!-- 列表相关区域 -->
+    <div class="main-container">
+      <div class="operation-bar">
+        <div class="default-btn primary-btn" @click="addOrUpdateHandle()"
+             v-if="isAuth('${moduleName}:${classname}:save')">{{$t("crud.addTitle")}}</div>
+      </div>
+      <div class="table-con spec-table">
+        <el-table
+          ref="specListTable"
+          :data="dataList"
+          header-cell-class-name="table-header"
+          row-class-name="table-row"
+          style="width: 100%">
+#foreach($column in $columns)#if(${column.columnName} != "create_time" && ${column.columnName} != "update_time" && $column.lowerAttrName!=$pk.lowerAttrName)
+          <!-- $column.comments -->
+          <el-table-column :label="$t('${classname}.$column.lowerAttrName')" prop="$column.lowerAttrName" align="center">
+            <template slot-scope="scope">
+              <span>{{ scope.row.$column.lowerAttrName}}</span>
+            </template>
+          </el-table-column>
+#end#end
+          <el-table-column align="center" fixed="right" :label="$t('publics.operating')" width="auto">
+            <template slot-scope="scope">
+              <div class="text-btn-con">
+                <div class="default-btn text-btn" @click="addOrUpdateHandle(scope.row.${pk.lowerAttrName})"
+                     v-if="isAuth('${moduleName}:${classname}:update')">{{$t("crud.updateBtn")}}</div>
+                <div class="default-btn text-btn" @click.stop="deleteHandle(scope.row.${pk.lowerAttrName})"
+                     v-if="isAuth('${moduleName}:${classname}:delete')">{{$t("text.delBtn")}}</div>
+                </div>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+        <el-pagination
+          v-if="dataList.length"
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange"
+          :current-page="page.currentPage"
+          :page-sizes="[10, 20, 50, 100]"
+          :page-size="page.pageSize"
+          layout="total, sizes, prev, pager, next, jumper"
+          :total="page.total">
+        </el-pagination>
+      </div>
+    <add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="refreshChange"></add-or-update>
+  </div>
+</template>
+
+<script>#set($symbol="$")
+
+import AddOrUpdate from './${classname}-add-or-update'
+export default {
+  data () {
+    return {
+      dataList: [],
+      page: {
+        total: 0, // 总页数
+        currentPage: 1, // 当前页数
+        pageSize: 10 // 每页显示多少条
+      },
+      searchForm: {}, // 搜索
+      dataListLoading: false,
+      addOrUpdateVisible: false
+    }
+  },
+  components: {
+    AddOrUpdate
+  },
+  created () {
+  },
+  mounted () {
+  },
+  methods: {
+    getDataList (page) {
+      this.dataListLoading = true
+      this.$http({
+        url: this.${symbol}http.adornUrl('/${moduleName}/${classname}/page'),
+        method: 'get',
+        params: this.${symbol}http.adornParams(
+          Object.assign({
+            current: page == null ? this.page.currentPage : page.currentPage,
+            size: page == null ? this.page.pageSize : page.pageSize
+          },
+            this.searchForm
+          )
+        )
+      }).then(({data}) => {
+        this.dataList = data.records
+        this.page.total = data.total
+        this.dataListLoading = false
+      })
+    },
+    // 新增 / 修改
+    addOrUpdateHandle (id) {
+      this.addOrUpdateVisible = true
+      this.$nextTick(() => {
+        this.$refs.addOrUpdate.init(id)
+      })
+    },
+    deleteHandle (id) {
+      this.$confirm(this.$i18n.t('admin.isDeleOper') + '?', this.$i18n.t('text.tips'), {
+        confirmButtonText: this.$i18n.t('crud.filter.submitBtn'),
+        cancelButtonText: this.$i18n.t('crud.filter.cancelBtn'),
+        type: 'warning'
+      }).then(() => {
+        this.$http({
+          url: this.${symbol}http.adornUrl('/${moduleName}/${classname}/' + id),
+          method: 'delete',
+          data: this.$http.adornData({})
+        }).then(({ data }) => {
+          this.$message({
+            message: this.$i18n.t('publics.operation'),
+            type: 'success',
+            duration: 1500,
+            onClose: () => {
+              this.refreshChange()
+            }
+          })
+        })
+      }).catch(() => { })
+    },
+    // 刷新回调
+    refreshChange () {
+      this.page.currentPage = 1
+      this.getDataList(this.page)
+    },
+    searchChange (params) {
+      this.searchForm = params
+      this.getDataList(this.page)
+    },
+    handleSizeChange (val) {
+      this.page.pageSize = val
+      this.getDataList()
+    },
+    handleCurrentChange (val) {
+      this.page.currentPage = val
+      this.getDataList()
+    }
+  }
+}
+</script>
+<style lang="scss">
+.mod-${moduleName}-${classname} {
+}
+</style>

+ 20 - 0
src/main/resources/template/menu.sql.vm

@@ -0,0 +1,20 @@
+-- 该脚本不要执行,请完善 ID 对应关系,注意层级关系 !!!!
+
+-- 菜单SQL
+INSERT INTO `tz_sys_menu` (`parent_id`,`name`,`url`,`perms`,`type`,`icon`,`order_num`)
+    VALUES (0, '${comments}管理', '${moduleName}/${classname}', '', '1', '', '0');
+
+SET @yamiSysMenuLastInsertId = LAST_INSERT_ID();
+
+-- 菜单对应按钮SQL
+
+INSERT INTO `tz_sys_menu` (`parent_id`,`name`,`url`,`perms`,`type`,`icon`,`order_num`)
+    VALUES (@yamiSysMenuLastInsertId, '新增${comments}', '', '${moduleName}:${classname}:save', '2', '', '0');
+
+INSERT INTO `tz_sys_menu` (`parent_id`,`name`,`url`,`perms`,`type`,`icon`,`order_num`)
+    VALUES (@yamiSysMenuLastInsertId, '修改${comments}', '', '${moduleName}:${classname}:update', '2', '', '0');
+
+INSERT INTO `tz_sys_menu` (`parent_id`,`name`,`url`,`perms`,`type`,`icon`,`order_num`)
+    VALUES (@yamiSysMenuLastInsertId, '删除${comments}', '', '${moduleName}:${classname}:delete', '2', '', '0');
+
+SET @yamiSysMenuLastInsertId:=NULL;