jeecg-boot 2.0 模块开发版本发布

This commit is contained in:
zhangdaihao
2019-05-19 18:54:09 +08:00
parent 64fb100ea2
commit 4858af9f33
770 changed files with 85014 additions and 19508 deletions

View File

@ -0,0 +1,121 @@
server:
port: 8080
servlet:
context-path: /jeecg-boot
compression:
enabled: true
mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*
management:
endpoints:
web:
exposure:
include: metrics,httptrace
spring:
mail:
host: smtp.163.com
username: jeecgos@163.com
password: ??
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
## quartz定时任务,采用数据库方式
quartz:
job-store-type: jdbc
#json 时间戳统一转换
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
aop:
proxy-target-class: true
#配置freemarker
freemarker:
# 设置模板后缀名
suffix: .ftl
# 设置文档类型
content-type: text/html
# 设置页面编码格式
charset: UTF-8
# 设置页面缓存
cache: false
prefer-file-system-access: false
# 设置ftl文件路径
template-loader-path:
- classpath:/templates
# 设置静态文件路径js,css等
mvc:
static-path-pattern: /**
resource:
static-locations: classpath:/static/,classpath:/public/
autoconfigure:
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
datasource:
druid:
stat-view-servlet:
loginUsername: admin
loginPassword: 123456
dynamic:
druid: # 全局druid参数绝大部分值和默认保持一致。(现已支持的参数如下,不清楚含义不要乱设置)
# 连接池的配置信息
# 初始化大小,最小,最大
initial-size: 5
min-idle: 5
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 打开PSCache并且指定每个连接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
# 配置监控统计拦截的filters去掉后监控界面sql无法统计'wall'用于防火墙
filters: stat,wall,slf4j
# 通过connectProperties属性来打开mergeSql功能慢SQL记录
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
datasource:
master:
url: jdbc:mysql://127.0.0.1:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
# 多数据源配置
#multi-datasource1:
#url: jdbc:mysql://localhost:3306/jeecg-boot2?useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true
#username: root
#password: root
#driver-class-name: com.mysql.jdbc.Driver
#redis 配置
redis:
database: 0
host: 127.0.0.1
lettuce:
pool:
max-active: 8 #最大连接数据库连接数,设 0 为没有限制
max-idle: 8 #最大等待连接中的数量,设 0 为没有限制
max-wait: -1ms #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
min-idle: 0 #最小等待连接中的数量,设 0 为没有限制
shutdown-timeout: 100ms
password: ''
port: 6379
#mybatis plus 设置
mybatis-plus:
mapper-locations: classpath*:org/jeecg/modules/**/xml/*Mapper.xml
#jeecg专用配置
jeecg :
path :
#文件上传根目录 设置
upload: D://upFiles
#webapp文件路径
webapp: D://webapp

View File

@ -0,0 +1,121 @@
server:
port: 8080
servlet:
context-path: /jeecg-boot
compression:
enabled: true
mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*
management:
endpoints:
web:
exposure:
include: metrics,httptrace
spring:
mail:
host: smtp.163.com
username: jeecgos@163.com
password: ??
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
## quartz定时任务,采用数据库方式
quartz:
job-store-type: jdbc
#json 时间戳统一转换
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
aop:
proxy-target-class: true
#配置freemarker
freemarker:
# 设置模板后缀名
suffix: .ftl
# 设置文档类型
content-type: text/html
# 设置页面编码格式
charset: UTF-8
# 设置页面缓存
cache: false
prefer-file-system-access: false
# 设置ftl文件路径
template-loader-path:
- classpath:/templates
# 设置静态文件路径js,css等
mvc:
static-path-pattern: /**
resource:
static-locations: classpath:/static/,classpath:/public/
autoconfigure:
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
datasource:
druid:
stat-view-servlet:
loginUsername: admin
loginPassword: 123456
dynamic:
druid: # 全局druid参数绝大部分值和默认保持一致。(现已支持的参数如下,不清楚含义不要乱设置)
# 连接池的配置信息
# 初始化大小,最小,最大
initial-size: 5
min-idle: 5
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 打开PSCache并且指定每个连接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
# 配置监控统计拦截的filters去掉后监控界面sql无法统计'wall'用于防火墙
filters: stat,wall,slf4j
# 通过connectProperties属性来打开mergeSql功能慢SQL记录
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
datasource:
master:
url: jdbc:mysql://127.0.0.1:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
# 多数据源配置
#multi-datasource1:
#url: jdbc:mysql://localhost:3306/jeecg-boot2?useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true
#username: root
#password: root
#driver-class-name: com.mysql.jdbc.Driver
#redis 配置
redis:
database: 0
host: 118.89.223.144
lettuce:
pool:
max-active: 8 #最大连接数据库连接数,设 0 为没有限制
max-idle: 8 #最大等待连接中的数量,设 0 为没有限制
max-wait: -1ms #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
min-idle: 0 #最小等待连接中的数量,设 0 为没有限制
shutdown-timeout: 100ms
password: ''
port: 6379
#mybatis plus 设置
mybatis-plus:
mapper-locations: classpath*:org/jeecg/modules/**/xml/*Mapper.xml
#jeecg专用配置
jeecg :
path :
#文件上传根目录 设置
upload: /opt/jeecg-boot/upload
#webapp文件路径
webapp: /opt/jeecg-boot/webapp

View File

@ -0,0 +1,123 @@
server:
port: 8080
servlet:
context-path: /jeecg-boot
compression:
enabled: true
mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/*
management:
endpoints:
web:
exposure:
include: metrics,httptrace
spring:
mail:
host: smtp.163.com
username: jeecgos@163.com
password: ??
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
## quartz定时任务,采用数据库方式
quartz:
job-store-type: jdbc
#json 时间戳统一转换
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
aop:
proxy-target-class: true
#配置freemarker
freemarker:
# 设置模板后缀名
suffix: .ftl
# 设置文档类型
content-type: text/html
# 设置页面编码格式
charset: UTF-8
# 设置页面缓存
cache: false
prefer-file-system-access: false
# 设置ftl文件路径
template-loader-path:
- classpath:/templates
# 设置静态文件路径js,css等
mvc:
static-path-pattern: /**
resource:
static-locations: classpath:/static/,classpath:/public/
autoconfigure:
exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure
datasource:
druid:
stat-view-servlet:
loginUsername: admin
loginPassword: 123456
dynamic:
druid: # 全局druid参数绝大部分值和默认保持一致。(现已支持的参数如下,不清楚含义不要乱设置)
# 连接池的配置信息
# 初始化大小,最小,最大
initial-size: 5
min-idle: 5
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 打开PSCache并且指定每个连接上PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
# 配置监控统计拦截的filters去掉后监控界面sql无法统计'wall'用于防火墙
filters: stat,wall,slf4j
# 通过connectProperties属性来打开mergeSql功能慢SQL记录
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
datasource:
master:
url: jdbc:mysql://127.0.0.1:3306/jeecg-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
# 多数据源配置
#multi-datasource1:
#url: jdbc:mysql://localhost:3306/jeecg-boot2?useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true
#username: root
#password: root
#driver-class-name: com.mysql.jdbc.Driver
#redis 配置
redis:
database: 0
host: 192.168.1.199
lettuce:
pool:
max-active: 8 #最大连接数据库连接数,设 0 为没有限制
max-idle: 8 #最大等待连接中的数量,设 0 为没有限制
max-wait: -1ms #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
min-idle: 0 #最小等待连接中的数量,设 0 为没有限制
shutdown-timeout: 100ms
password: ''
port: 6379
#mybatis plus 设置
mybatis-plus:
mapper-locations: classpath*:org/jeecg/modules/**/xml/*Mapper.xml
#jeecg专用配置
jeecg :
path :
#文件上传根目录 设置
upload: D://upFiles
#webapp文件路径
webapp: D://webapp
logging:
level:
org.jeecg.modules.system.mapper : debug

View File

@ -0,0 +1,9 @@
spring:
profiles:
active: dev
swagger:
production: false
basic:
enable: true
username: jeecg
password: jeecg1314

View File

@ -0,0 +1,7 @@
(_) | | | |
_ ___ ___ ___ __ _ ______| |__ ___ ___ | |_
| |/ _ \/ _ \/ __/ _` |______| '_ \ / _ \ / _ \| __|
| | __/ __/ (_| (_| | | |_) | (_) | (_) | |_
| |\___|\___|\___\__, | |_.__/ \___/ \___/ \__|
_/ | __/ |
|__/ |___/

View File

@ -0,0 +1,8 @@
DELETE FROM demo;
INSERT INTO demo (id, name, age, email,sex,birthday,content) VALUES
(1, 'Jone', 18, 'test1@baomidou.com','1','2017-12-28','很好'),
(2, 'Jack', 20, 'test2@baomidou.com','2','2018-02-28','努力型'),
(3, 'Tom', 28, 'test3@baomidou.com','1','2018-11-28','吃苦'),
(4, 'Sandy', 21, 'test4@baomidou.com','1','2018-07-28','聪明'),
(5, 'Billie', 24, 'test5@baomidou.com','2','2018-12-11','出色');

View File

@ -0,0 +1,11 @@
DROP TABLE IF EXISTS demo;
CREATE TABLE demo (
id BIGINT(20) NOT NULL auto_increment COMMENT '主键ID',
name varchar(30) default NULL COMMENT '姓名',
sex varchar(2) default NULL,
age int(11) default NULL COMMENT '年龄',
birthday date default NULL COMMENT '生日',
email varchar(50) default NULL COMMENT '邮箱',
content varchar(1000) default NULL COMMENT '个人简介',
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

View File

@ -0,0 +1,251 @@
package ${bussiPackage}.${entityPackage}.controller;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.util.oConvertUtils;
import ${bussiPackage}.${entityPackage}.entity.${entityName};
import ${bussiPackage}.${entityPackage}.service.I${entityName}Service;
import java.util.Date;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
@Slf4j
@Api("${tableVo.ftlDescription}")
@RestController
@RequestMapping("/${entityPackage}/${entityName?uncap_first}")
public class ${entityName}Controller {
@Autowired
private I${entityName}Service ${entityName?uncap_first}Service;
/**
* 分页列表查询
* @param ${entityName?uncap_first}
* @param pageNo
* @param pageSize
* @param req
* @return
*/
@AutoLog(value = "${tableVo.ftlDescription}-分页列表查询")
@ApiOperation(value="${tableVo.ftlDescription}-分页列表查询", notes="${tableVo.ftlDescription}-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<${entityName}>> queryPageList(${entityName} ${entityName?uncap_first},
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
Result<IPage<${entityName}>> result = new Result<IPage<${entityName}>>();
QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap());
Page<${entityName}> page = new Page<${entityName}>(pageNo, pageSize);
IPage<${entityName}> pageList = ${entityName?uncap_first}Service.page(page, queryWrapper);
result.setSuccess(true);
result.setResult(pageList);
return result;
}
/**
* 添加
* @param ${entityName?uncap_first}
* @return
*/
@AutoLog(value = "${tableVo.ftlDescription}-添加")
@ApiOperation(value="${tableVo.ftlDescription}-添加", notes="${tableVo.ftlDescription}-添加")
@PostMapping(value = "/add")
public Result<${entityName}> add(@RequestBody ${entityName} ${entityName?uncap_first}) {
Result<${entityName}> result = new Result<${entityName}>();
try {
${entityName?uncap_first}Service.save(${entityName?uncap_first});
result.success("添加成功!");
} catch (Exception e) {
log.error(e.getMessage(),e);
result.error500("操作失败");
}
return result;
}
/**
* 编辑
* @param ${entityName?uncap_first}
* @return
*/
@AutoLog(value = "${tableVo.ftlDescription}-编辑")
@ApiOperation(value="${tableVo.ftlDescription}-编辑", notes="${tableVo.ftlDescription}-编辑")
@PutMapping(value = "/edit")
public Result<${entityName}> edit(@RequestBody ${entityName} ${entityName?uncap_first}) {
Result<${entityName}> result = new Result<${entityName}>();
${entityName} ${entityName?uncap_first}Entity = ${entityName?uncap_first}Service.getById(${entityName?uncap_first}.getId());
if(${entityName?uncap_first}Entity==null) {
result.error500("未找到对应实体");
}else {
boolean ok = ${entityName?uncap_first}Service.updateById(${entityName?uncap_first});
//TODO 返回false说明什么
if(ok) {
result.success("修改成功!");
}
}
return result;
}
/**
* 通过id删除
* @param id
* @return
*/
@AutoLog(value = "${tableVo.ftlDescription}-通过id删除")
@ApiOperation(value="${tableVo.ftlDescription}-通过id删除", notes="${tableVo.ftlDescription}-通过id删除")
@DeleteMapping(value = "/delete")
public Result<${entityName}> delete(@RequestParam(name="id",required=true) String id) {
Result<${entityName}> result = new Result<${entityName}>();
${entityName} ${entityName?uncap_first} = ${entityName?uncap_first}Service.getById(id);
if(${entityName?uncap_first}==null) {
result.error500("未找到对应实体");
}else {
boolean ok = ${entityName?uncap_first}Service.removeById(id);
if(ok) {
result.success("删除成功!");
}
}
return result;
}
/**
* 批量删除
* @param ids
* @return
*/
@AutoLog(value = "${tableVo.ftlDescription}-批量删除")
@ApiOperation(value="${tableVo.ftlDescription}-批量删除", notes="${tableVo.ftlDescription}-批量删除")
@DeleteMapping(value = "/deleteBatch")
public Result<${entityName}> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
Result<${entityName}> result = new Result<${entityName}>();
if(ids==null || "".equals(ids.trim())) {
result.error500("参数不识别!");
}else {
this.${entityName?uncap_first}Service.removeByIds(Arrays.asList(ids.split(",")));
result.success("删除成功!");
}
return result;
}
/**
* 通过id查询
* @param id
* @return
*/
@AutoLog(value = "${tableVo.ftlDescription}-通过id查询")
@ApiOperation(value="${tableVo.ftlDescription}-通过id查询", notes="${tableVo.ftlDescription}-通过id查询")
@GetMapping(value = "/queryById")
public Result<${entityName}> queryById(@RequestParam(name="id",required=true) String id) {
Result<${entityName}> result = new Result<${entityName}>();
${entityName} ${entityName?uncap_first} = ${entityName?uncap_first}Service.getById(id);
if(${entityName?uncap_first}==null) {
result.error500("未找到对应实体");
}else {
result.setResult(${entityName?uncap_first});
result.setSuccess(true);
}
return result;
}
/**
* 导出excel
*
* @param request
* @param response
*/
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
// Step.1 组装查询条件
QueryWrapper<${entityName}> queryWrapper = null;
try {
String paramsStr = request.getParameter("paramsStr");
if (oConvertUtils.isNotEmpty(paramsStr)) {
String deString = URLDecoder.decode(paramsStr, "UTF-8");
${entityName} ${entityName?uncap_first} = JSON.parseObject(deString, ${entityName}.class);
queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, request.getParameterMap());
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//Step.2 AutoPoi 导出Excel
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
List<${entityName}> pageList = ${entityName?uncap_first}Service.list(queryWrapper);
//导出文件名称
mv.addObject(NormalExcelConstants.FILE_NAME, "${tableVo.ftlDescription}列表");
mv.addObject(NormalExcelConstants.CLASS, ${entityName}.class);
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("${tableVo.ftlDescription}列表数据", "导出人:Jeecg", "导出信息"));
mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
return mv;
}
/**
* 通过excel导入数据
*
* @param request
* @param response
* @return
*/
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
MultipartFile file = entity.getValue();// 获取上传文件对象
ImportParams params = new ImportParams();
params.setTitleRows(2);
params.setHeadRows(1);
params.setNeedSave(true);
try {
List<${entityName}> list${entityName}s = ExcelImportUtil.importExcel(file.getInputStream(), ${entityName}.class, params);
for (${entityName} ${entityName?uncap_first}Excel : list${entityName}s) {
${entityName?uncap_first}Service.save(${entityName?uncap_first}Excel);
}
return Result.ok("文件导入成功!数据行数:" + list${entityName}s.size());
} catch (Exception e) {
log.error(e.getMessage(),e);
return Result.error("文件导入失败:"+e.getMessage());
} finally {
try {
file.getInputStream().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return Result.ok("文件导入失败!");
}
}

View File

@ -0,0 +1,53 @@
package ${bussiPackage}.${entityPackage}.entity;
import java.io.Serializable;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
@Data
@TableName("${tableName}")
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="${tableName}对象", description="${tableVo.ftlDescription}")
public class ${entityName} {
<#list originalColumns as po>
/**${po.filedComment}*/
<#if po.fieldName == primaryKeyField>
@TableId(type = IdType.UUID)
<#else>
<#if po.fieldType =='java.util.Date'>
<#if po.fieldDbType =='date'>
@Excel(name = "${po.filedComment}", width = 15, format = "yyyy-MM-dd")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
<#elseif po.fieldDbType =='datetime'>
@Excel(name = "${po.filedComment}", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
</#if>
<#else>
@Excel(name = "${po.filedComment}", width = 15)
</#if>
</#if>
@ApiModelProperty(value = "${po.filedComment}")
private <#if po.fieldType=='java.sql.Blob'>byte[]<#else>${po.fieldType}</#if> ${po.fieldName};
</#list>
}

View File

@ -0,0 +1,17 @@
package ${bussiPackage}.${entityPackage}.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import ${bussiPackage}.${entityPackage}.entity.${entityName};
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
public interface ${entityName}Mapper extends BaseMapper<${entityName}> {
}

View File

@ -0,0 +1,5 @@
<?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="${bussiPackage}.${entityPackage}.mapper.${entityName}Mapper">
</mapper>

View File

@ -0,0 +1,14 @@
package ${bussiPackage}.${entityPackage}.service;
import ${bussiPackage}.${entityPackage}.entity.${entityName};
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
public interface I${entityName}Service extends IService<${entityName}> {
}

View File

@ -0,0 +1,19 @@
package ${bussiPackage}.${entityPackage}.service.impl;
import ${bussiPackage}.${entityPackage}.entity.${entityName};
import ${bussiPackage}.${entityPackage}.mapper.${entityName}Mapper;
import ${bussiPackage}.${entityPackage}.service.I${entityName}Service;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
@Service
public class ${entityName}ServiceImpl extends ServiceImpl<${entityName}Mapper, ${entityName}> implements I${entityName}Service {
}

View File

@ -0,0 +1,169 @@
<template>
<a-card :bordered="false">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-row :gutter="24">
<#list columns as po>
<#if po.fieldName !='id' && po_index<= tableVo.searchFieldNum>
<a-col :md="6" :sm="8">
<a-form-item label="${po.filedComment}">
<a-input placeholder="请输入${po.filedComment}" v-model="queryParam.${po.fieldName}"></a-input>
</a-form-item>
</a-col>
<#elseif po_index == 2>
<template v-if="toggleSearchStatus">
<a-col :md="6" :sm="8">
<a-form-item label="${po.filedComment}">
<a-input placeholder="请输入${po.filedComment}" v-model="queryParam.${po.fieldName}"></a-input>
</a-form-item>
</a-col>
<#elseif po.fieldName !='id' && po_index< 5>
<a-col :md="6" :sm="8">
<a-form-item label="${po.filedComment}">
<a-input placeholder="请输入${po.filedComment}" v-model="queryParam.${po.fieldName}"></a-input>
</a-form-item>
</a-col>
<#else>
</#if>
</#list>
</template>
<a-col :md="6" :sm="8" >
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
<a @click="handleToggleSearch" style="margin-left: 8px">
{{ toggleSearchStatus ? '收起' : '展开' }}
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
</a>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!-- 操作按钮区域 -->
<div class="table-operator">
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
<a-button type="primary" icon="download" @click="handleExportXls('${tableVo.ftlDescription}')">导出</a-button>
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
<a-button type="primary" icon="import">导入</a-button>
</a-upload>
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>
</a-dropdown>
</div>
<!-- table区域-begin -->
<div>
<div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
<i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
<a style="margin-left: 24px" @click="onClearSelected">清空</a>
</div>
<a-table
ref="table"
size="middle"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@change="handleTableChange">
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical" />
<a-dropdown>
<a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
<a-menu slot="overlay">
<a-menu-item>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
<a>删除</a>
</a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
</span>
</a-table>
</div>
<!-- table区域-end -->
<!-- 表单区域 -->
<${entityName?uncap_first}-modal ref="modalForm" @ok="modalFormOk"></${entityName?uncap_first}-modal>
</a-card>
</template>
<script>
import ${entityName}Modal from './modules/${entityName}Modal'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
export default {
name: "${entityName}List",
mixins:[JeecgListMixin],
components: {
${entityName}Modal
},
data () {
return {
description: '${tableVo.ftlDescription}管理页面',
// 表头
columns: [
{
title: '#',
dataIndex: '',
key:'rowIndex',
width:60,
align:"center",
customRender:function (t,r,index) {
return parseInt(index)+1;
}
},
<#list columns as po>
<#if po.fieldName !='id'>
{
title: '${po.filedComment}',
align:"center",
dataIndex: '${po.fieldName}'
},
</#if>
</#list>
{
title: '操作',
dataIndex: 'action',
align:"center",
scopedSlots: { customRender: 'action' },
}
],
url: {
list: "/${entityPackage}/${entityName?uncap_first}/list",
delete: "/${entityPackage}/${entityName?uncap_first}/delete",
deleteBatch: "/${entityPackage}/${entityName?uncap_first}/deleteBatch",
exportXlsUrl: "${entityPackage}/${entityName?uncap_first}/exportXls",
importExcelUrl: "${entityPackage}/${entityName?uncap_first}/importExcel",
},
}
},
computed: {
importExcelUrl: function(){
<#noparse>return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;</#noparse>
}
},
methods: {
}
}
</script>
<style scoped>
@import '~@assets/less/common.less'
</style>

View File

@ -0,0 +1,155 @@
<template>
<a-modal
:title="title"
:width="800"
:visible="visible"
:confirmLoading="confirmLoading"
@ok="handleOk"
@cancel="handleCancel"
cancelText="关闭">
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<#list columns as po><#rt/>
<#if po.fieldName !='id'><#rt/>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="${po.filedComment}">
<#if po.fieldType =='date'>
<a-date-picker v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<#elseif po.fieldType =='datetime'>
<a-date-picker showTime format='YYYY-MM-DD HH:mm:ss' v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<#elseif "int,decimal,double,"?contains(po.fieldType)>
<a-input-number v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<#else>
<a-input placeholder="请输入${po.filedComment}" v-decorator="['${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
</#if>
</a-form-item>
</#if>
</#list>
</a-form>
</a-spin>
</a-modal>
</template>
<script>
import { httpAction } from '@/api/manage'
import pick from 'lodash.pick'
import moment from "moment"
export default {
name: "${entityName}Modal",
data () {
return {
title:"操作",
visible: false,
model: {},
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
confirmLoading: false,
form: this.$form.createForm(this),
validatorRules:{
<#list columns as po>
<#if po.fieldName !='id'>
<#if po.nullable =='N'>
${po.fieldName}:{rules: [{ required: true, message: '请输入${po.filedComment}!' }]},
</#if>
</#if>
</#list>
},
url: {
add: "/${entityPackage}/${entityName?uncap_first}/add",
edit: "/${entityPackage}/${entityName?uncap_first}/edit",
},
}
},
created () {
},
methods: {
add () {
this.edit({});
},
edit (record) {
this.form.resetFields();
this.model = Object.assign({}, record);
this.visible = true;
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model<#list columns as po><#if po.fieldName !='id' && po.fieldType?index_of("date")==-1>,'${po.fieldName}'</#if></#list>))
//时间格式化
<#list columns as po>
<#if po.fieldName !='id' && po.fieldType?index_of("date")!=-1>
this.form.setFieldsValue({${po.fieldName}:this.model.${po.fieldName}?moment(this.model.${po.fieldName}):null})
</#if>
</#list>
});
},
close () {
this.$emit('close');
this.visible = false;
},
handleOk () {
const that = this;
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
that.confirmLoading = true;
let httpurl = '';
let method = '';
if(!this.model.id){
httpurl+=this.url.add;
method = 'post';
}else{
httpurl+=this.url.edit;
method = 'put';
}
let formData = Object.assign(this.model, values);
//时间格式化
<#list columns as po>
<#if po.fieldName !='id' && po.fieldType =='date'>
formData.${po.fieldName} = formData.${po.fieldName}?formData.${po.fieldName}.format():null;
<#elseif po.fieldName !='id' && po.fieldType =='datetime'>
formData.${po.fieldName} = formData.${po.fieldName}?formData.${po.fieldName}.format('YYYY-MM-DD HH:mm:ss'):null;
</#if>
</#list>
console.log(formData)
httpAction(httpurl,formData,method).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.$emit('ok');
}else{
that.$message.warning(res.message);
}
}).finally(() => {
that.confirmLoading = false;
that.close();
})
}
})
},
handleCancel () {
this.close()
},
}
}
</script>
<style lang="less" scoped>
</style>

View File

@ -0,0 +1,162 @@
<template>
<a-drawer
:title="title"
:width="800"
placement="right"
:closable="false"
@close="close"
:visible="visible"
>
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<#list columns as po><#rt/>
<#if po.fieldName !='id'><#rt/>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="${po.filedComment}">
<#if po.fieldType =='date'>
<a-date-picker v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<#elseif po.fieldType =='datetime'>
<a-date-picker showTime format='YYYY-MM-DD HH:mm:ss' v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<#elseif "int,decimal,double,"?contains(po.fieldType)>
<a-input-number v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<#else>
<a-input placeholder="请输入${po.filedComment}" v-decorator="['${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
</#if>
</a-form-item>
</#if>
</#list>
</a-form>
</a-spin>
<a-button type="primary" @click="handleOk">确定</a-button>
<a-button type="primary" @click="handleCancel">取消</a-button>
</a-drawer>
</template>
<script>
import { httpAction } from '@/api/manage'
import pick from 'lodash.pick'
import moment from "moment"
export default {
name: "${entityName}Modal",
data () {
return {
title:"操作",
visible: false,
model: {},
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
confirmLoading: false,
form: this.$form.createForm(this),
validatorRules:{
<#list columns as po>
<#if po.fieldName !='id'>
<#if po.nullable =='N'>
${po.fieldName}:{rules: [{ required: true, message: '请输入${po.filedComment}!' }]},
</#if>
</#if>
</#list>
},
url: {
add: "/${entityPackage}/${entityName?uncap_first}/add",
edit: "/${entityPackage}/${entityName?uncap_first}/edit",
},
}
},
created () {
},
methods: {
add () {
this.edit({});
},
edit (record) {
this.form.resetFields();
this.model = Object.assign({}, record);
this.visible = true;
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model<#list columns as po><#if po.fieldName !='id' && po.fieldType?index_of("date")==-1>,'${po.fieldName}'</#if></#list>))
//时间格式化
<#list columns as po>
<#if po.fieldName !='id' && po.fieldType?index_of("date")!=-1>
this.form.setFieldsValue({${po.fieldName}:this.model.${po.fieldName}?moment(this.model.${po.fieldName}):null})
</#if>
</#list>
});
},
close () {
this.$emit('close');
this.visible = false;
},
handleOk () {
const that = this;
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
that.confirmLoading = true;
let httpurl = '';
let method = '';
if(!this.model.id){
httpurl+=this.url.add;
method = 'post';
}else{
httpurl+=this.url.edit;
method = 'put';
}
let formData = Object.assign(this.model, values);
//时间格式化
<#list columns as po>
<#if po.fieldName !='id' && po.fieldType =='date'>
formData.${po.fieldName} = formData.${po.fieldName}?formData.${po.fieldName}.format():null;
<#elseif po.fieldName !='id' && po.fieldType =='datetime'>
formData.${po.fieldName} = formData.${po.fieldName}?formData.${po.fieldName}.format('YYYY-MM-DD HH:mm:ss'):null;
</#if>
</#list>
console.log(formData)
httpAction(httpurl,formData,method).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.$emit('ok');
}else{
that.$message.warning(res.message);
}
}).finally(() => {
that.confirmLoading = false;
that.close();
})
}
})
},
handleCancel () {
this.close()
},
}
}
</script>
<style lang="less" scoped>
/** Button按钮间距 */
.ant-btn {
margin-left: 30px;
margin-bottom: 30px;
float: right;
}
</style>

View File

@ -0,0 +1,239 @@
package ${bussiPackage}.controller.${entityPackage};
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.oConvertUtils;
import ${bussiPackage}.entity.${entityPackage}.${entityName};
import ${bussiPackage}.service.${entityPackage}.I${entityName}Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import com.alibaba.fastjson.JSON;
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
@RestController
@RequestMapping("/${entityPackage}/${entityName?uncap_first}")
@Slf4j
public class ${entityName}Controller {
@Autowired
private I${entityName}Service ${entityName?uncap_first}Service;
/**
* 分页列表查询
* @param ${entityName?uncap_first}
* @param pageNo
* @param pageSize
* @param req
* @return
*/
@GetMapping(value = "/list")
public Result<IPage<${entityName}>> queryPageList(${entityName} ${entityName?uncap_first},
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
Result<IPage<${entityName}>> result = new Result<IPage<${entityName}>>();
QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap());
Page<${entityName}> page = new Page<${entityName}>(pageNo, pageSize);
IPage<${entityName}> pageList = ${entityName?uncap_first}Service.page(page, queryWrapper);
result.setSuccess(true);
result.setResult(pageList);
return result;
}
/**
* 添加
* @param ${entityName?uncap_first}
* @return
*/
@PostMapping(value = "/add")
public Result<${entityName}> add(@RequestBody ${entityName} ${entityName?uncap_first}) {
Result<${entityName}> result = new Result<${entityName}>();
try {
${entityName?uncap_first}Service.save(${entityName?uncap_first});
result.success("添加成功!");
} catch (Exception e) {
log.error(e.getMessage(),e);
result.error500("操作失败");
}
return result;
}
/**
* 编辑
* @param ${entityName?uncap_first}
* @return
*/
@PutMapping(value = "/edit")
public Result<${entityName}> edit(@RequestBody ${entityName} ${entityName?uncap_first}) {
Result<${entityName}> result = new Result<${entityName}>();
${entityName} ${entityName?uncap_first}Entity = ${entityName?uncap_first}Service.getById(${entityName?uncap_first}.getId());
if(${entityName?uncap_first}Entity==null) {
result.error500("未找到对应实体");
}else {
boolean ok = ${entityName?uncap_first}Service.updateById(${entityName?uncap_first});
//TODO 返回false说明什么
if(ok) {
result.success("修改成功!");
}
}
return result;
}
/**
* 通过id删除
* @param id
* @return
*/
@DeleteMapping(value = "/delete")
public Result<${entityName}> delete(@RequestParam(name="id",required=true) String id) {
Result<${entityName}> result = new Result<${entityName}>();
${entityName} ${entityName?uncap_first} = ${entityName?uncap_first}Service.getById(id);
if(${entityName?uncap_first}==null) {
result.error500("未找到对应实体");
}else {
boolean ok = ${entityName?uncap_first}Service.removeById(id);
if(ok) {
result.success("删除成功!");
}
}
return result;
}
/**
* 批量删除
* @param ids
* @return
*/
@DeleteMapping(value = "/deleteBatch")
public Result<${entityName}> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
Result<${entityName}> result = new Result<${entityName}>();
if(ids==null || "".equals(ids.trim())) {
result.error500("参数不识别!");
}else {
this.${entityName?uncap_first}Service.removeByIds(Arrays.asList(ids.split(",")));
result.success("删除成功!");
}
return result;
}
/**
* 通过id查询
* @param id
* @return
*/
@GetMapping(value = "/queryById")
public Result<${entityName}> queryById(@RequestParam(name="id",required=true) String id) {
Result<${entityName}> result = new Result<${entityName}>();
${entityName} ${entityName?uncap_first} = ${entityName?uncap_first}Service.getById(id);
if(${entityName?uncap_first}==null) {
result.error500("未找到对应实体");
}else {
result.setResult(${entityName?uncap_first});
result.setSuccess(true);
}
return result;
}
/**
* 导出excel
*
* @param request
* @param response
*/
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
// Step.1 组装查询条件
QueryWrapper<${entityName}> queryWrapper = null;
try {
String paramsStr = request.getParameter("paramsStr");
if (oConvertUtils.isNotEmpty(paramsStr)) {
String deString = URLDecoder.decode(paramsStr, "UTF-8");
${entityName} ${entityName?uncap_first} = JSON.parseObject(deString, ${entityName}.class);
queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, request.getParameterMap());
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//Step.2 AutoPoi 导出Excel
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
List<${entityName}> pageList = ${entityName?uncap_first}Service.list(queryWrapper);
//导出文件名称
mv.addObject(NormalExcelConstants.FILE_NAME, "${tableVo.ftlDescription}列表");
mv.addObject(NormalExcelConstants.CLASS, ${entityName}.class);
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("${tableVo.ftlDescription}列表数据", "导出人:Jeecg", "导出信息"));
mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
return mv;
}
/**
* 通过excel导入数据
*
* @param request
* @param response
* @return
*/
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
MultipartFile file = entity.getValue();// 获取上传文件对象
ImportParams params = new ImportParams();
params.setTitleRows(2);
params.setHeadRows(1);
params.setNeedSave(true);
try {
List<${entityName}> list${entityName}s = ExcelImportUtil.importExcel(file.getInputStream(), ${entityName}.class, params);
for (${entityName} ${entityName?uncap_first}Excel : list${entityName}s) {
${entityName?uncap_first}Service.save(${entityName?uncap_first}Excel);
}
return Result.ok("文件导入成功!数据行数:" + list${entityName}s.size());
} catch (Exception e) {
log.error(e.getMessage(),e);
return Result.error("文件导入失败:"+e.getMessage());
} finally {
try {
file.getInputStream().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return Result.ok("文件导入失败!");
}
}

View File

@ -0,0 +1,45 @@
package ${bussiPackage}.entity.${entityPackage};
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
@Data
@TableName("${tableName}")
public class ${entityName} implements Serializable {
private static final long serialVersionUID = 1L;
<#list originalColumns as po>
/**${po.filedComment}*/
<#if po.fieldName == primaryKeyField>
@TableId(type = IdType.UUID)
<#else>
<#if po.fieldType =='java.util.Date'>
<#if po.fieldDbType =='date'>
@Excel(name = "${po.filedComment}", width = 15, format = "yyyy-MM-dd")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
<#elseif po.fieldDbType =='datetime'>
@Excel(name = "${po.filedComment}", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
</#if>
<#else>
@Excel(name = "${po.filedComment}", width = 15)
</#if>
</#if>
private <#if po.fieldType=='java.sql.Blob'>byte[]<#else>${po.fieldType}</#if> ${po.fieldName};
</#list>
}

View File

@ -0,0 +1,17 @@
package ${bussiPackage}.mapper.${entityPackage};
import java.util.List;
import org.apache.ibatis.annotations.Param;
import ${bussiPackage}.entity.${entityPackage}.${entityName};
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
public interface ${entityName}Mapper extends BaseMapper<${entityName}> {
}

View File

@ -0,0 +1,5 @@
<?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="${bussiPackage}.mapper.${entityPackage}.${entityName}Mapper">
</mapper>

View File

@ -0,0 +1,14 @@
package ${bussiPackage}.service.${entityPackage};
import ${bussiPackage}.entity.${entityPackage}.${entityName};
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
public interface I${entityName}Service extends IService<${entityName}> {
}

View File

@ -0,0 +1,19 @@
package ${bussiPackage}.service.${entityPackage}.impl;
import ${bussiPackage}.entity.${entityPackage}.${entityName};
import ${bussiPackage}.mapper.${entityPackage}.${entityName}Mapper;
import ${bussiPackage}.service.${entityPackage}.I${entityName}Service;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
@Service
public class ${entityName}ServiceImpl extends ServiceImpl<${entityName}Mapper, ${entityName}> implements I${entityName}Service {
}

View File

@ -0,0 +1,169 @@
<template>
<a-card :bordered="false">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-row :gutter="24">
<#list columns as po>
<#if po.fieldName !='id' && po_index<= tableVo.searchFieldNum>
<a-col :md="6" :sm="8">
<a-form-item label="${po.filedComment}">
<a-input placeholder="请输入${po.filedComment}" v-model="queryParam.${po.fieldName}"></a-input>
</a-form-item>
</a-col>
<#elseif po_index == 2>
<template v-if="toggleSearchStatus">
<a-col :md="6" :sm="8">
<a-form-item label="${po.filedComment}">
<a-input placeholder="请输入${po.filedComment}" v-model="queryParam.${po.fieldName}"></a-input>
</a-form-item>
</a-col>
<#elseif po.fieldName !='id' && po_index< 5>
<a-col :md="6" :sm="8">
<a-form-item label="${po.filedComment}">
<a-input placeholder="请输入${po.filedComment}" v-model="queryParam.${po.fieldName}"></a-input>
</a-form-item>
</a-col>
<#else>
</#if>
</#list>
</template>
<a-col :md="6" :sm="8" >
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
<a @click="handleToggleSearch" style="margin-left: 8px">
{{ toggleSearchStatus ? '收起' : '展开' }}
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
</a>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!-- 操作按钮区域 -->
<div class="table-operator">
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
<a-button type="primary" icon="download" @click="handleExportXls('${tableVo.ftlDescription}')">导出</a-button>
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
<a-button type="primary" icon="import">导入</a-button>
</a-upload>
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>
</a-dropdown>
</div>
<!-- table区域-begin -->
<div>
<div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
<i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
<a style="margin-left: 24px" @click="onClearSelected">清空</a>
</div>
<a-table
ref="table"
size="middle"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@change="handleTableChange">
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical" />
<a-dropdown>
<a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
<a-menu slot="overlay">
<a-menu-item>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
<a>删除</a>
</a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
</span>
</a-table>
</div>
<!-- table区域-end -->
<!-- 表单区域 -->
<${entityName?uncap_first}-modal ref="modalForm" @ok="modalFormOk"></${entityName?uncap_first}-modal>
</a-card>
</template>
<script>
import ${entityName}Modal from './modules/${entityName}Modal'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
export default {
name: "${entityName}List",
mixins:[JeecgListMixin],
components: {
${entityName}Modal
},
data () {
return {
description: '${tableVo.ftlDescription}管理页面',
// 表头
columns: [
{
title: '#',
dataIndex: '',
key:'rowIndex',
width:60,
align:"center",
customRender:function (t,r,index) {
return parseInt(index)+1;
}
},
<#list columns as po>
<#if po.fieldName !='id'>
{
title: '${po.filedComment}',
align:"center",
dataIndex: '${po.fieldName}'
},
</#if>
</#list>
{
title: '操作',
dataIndex: 'action',
align:"center",
scopedSlots: { customRender: 'action' },
}
],
url: {
list: "/${entityPackage}/${entityName?uncap_first}/list",
delete: "/${entityPackage}/${entityName?uncap_first}/delete",
deleteBatch: "/${entityPackage}/${entityName?uncap_first}/deleteBatch",
exportXlsUrl: "${entityPackage}/${entityName?uncap_first}/exportXls",
importExcelUrl: "${entityPackage}/${entityName?uncap_first}/importExcel",
},
}
},
computed: {
importExcelUrl: function(){
<#noparse>return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;</#noparse>
}
},
methods: {
}
}
</script>
<style scoped>
@import '~@assets/less/common.less'
</style>

View File

@ -0,0 +1,155 @@
<template>
<a-modal
:title="title"
:width="800"
:visible="visible"
:confirmLoading="confirmLoading"
@ok="handleOk"
@cancel="handleCancel"
cancelText="关闭">
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<#list columns as po><#rt/>
<#if po.fieldName !='id'><#rt/>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="${po.filedComment}">
<#if po.fieldType =='date'>
<a-date-picker v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<#elseif po.fieldType =='datetime'>
<a-date-picker showTime format='YYYY-MM-DD HH:mm:ss' v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<#elseif "int,decimal,double,"?contains(po.fieldType)>
<a-input-number v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<#else>
<a-input placeholder="请输入${po.filedComment}" v-decorator="['${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
</#if>
</a-form-item>
</#if>
</#list>
</a-form>
</a-spin>
</a-modal>
</template>
<script>
import { httpAction } from '@/api/manage'
import pick from 'lodash.pick'
import moment from "moment"
export default {
name: "${entityName}Modal",
data () {
return {
title:"操作",
visible: false,
model: {},
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
confirmLoading: false,
form: this.$form.createForm(this),
validatorRules:{
<#list columns as po>
<#if po.fieldName !='id'>
<#if po.nullable =='N'>
${po.fieldName}:{rules: [{ required: true, message: '请输入${po.filedComment}!' }]},
</#if>
</#if>
</#list>
},
url: {
add: "/${entityPackage}/${entityName?uncap_first}/add",
edit: "/${entityPackage}/${entityName?uncap_first}/edit",
},
}
},
created () {
},
methods: {
add () {
this.edit({});
},
edit (record) {
this.form.resetFields();
this.model = Object.assign({}, record);
this.visible = true;
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model<#list columns as po><#if po.fieldName !='id' && po.fieldType?index_of("date")==-1>,'${po.fieldName}'</#if></#list>))
//时间格式化
<#list columns as po>
<#if po.fieldName !='id' && po.fieldType?index_of("date")!=-1>
this.form.setFieldsValue({${po.fieldName}:this.model.${po.fieldName}?moment(this.model.${po.fieldName}):null})
</#if>
</#list>
});
},
close () {
this.$emit('close');
this.visible = false;
},
handleOk () {
const that = this;
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
that.confirmLoading = true;
let httpurl = '';
let method = '';
if(!this.model.id){
httpurl+=this.url.add;
method = 'post';
}else{
httpurl+=this.url.edit;
method = 'put';
}
let formData = Object.assign(this.model, values);
//时间格式化
<#list columns as po>
<#if po.fieldName !='id' && po.fieldType =='date'>
formData.${po.fieldName} = formData.${po.fieldName}?formData.${po.fieldName}.format():null;
<#elseif po.fieldName !='id' && po.fieldType =='datetime'>
formData.${po.fieldName} = formData.${po.fieldName}?formData.${po.fieldName}.format('YYYY-MM-DD HH:mm:ss'):null;
</#if>
</#list>
console.log(formData)
httpAction(httpurl,formData,method).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.$emit('ok');
}else{
that.$message.warning(res.message);
}
}).finally(() => {
that.confirmLoading = false;
that.close();
})
}
})
},
handleCancel () {
this.close()
},
}
}
</script>
<style lang="less" scoped>
</style>

View File

@ -0,0 +1,162 @@
<template>
<a-drawer
:title="title"
:width="800"
placement="right"
:closable="false"
@close="close"
:visible="visible"
>
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<#list columns as po><#rt/>
<#if po.fieldName !='id'><#rt/>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="${po.filedComment}">
<#if po.fieldType =='date'>
<a-date-picker v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<#elseif po.fieldType =='datetime'>
<a-date-picker showTime format='YYYY-MM-DD HH:mm:ss' v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<#elseif "int,decimal,double,"?contains(po.fieldType)>
<a-input-number v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<#else>
<a-input placeholder="请输入${po.filedComment}" v-decorator="['${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
</#if>
</a-form-item>
</#if>
</#list>
</a-form>
</a-spin>
<a-button type="primary" @click="handleOk">确定</a-button>
<a-button type="primary" @click="handleCancel">取消</a-button>
</a-drawer>
</template>
<script>
import { httpAction } from '@/api/manage'
import pick from 'lodash.pick'
import moment from "moment"
export default {
name: "${entityName}Modal",
data () {
return {
title:"操作",
visible: false,
model: {},
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
confirmLoading: false,
form: this.$form.createForm(this),
validatorRules:{
<#list columns as po>
<#if po.fieldName !='id'>
<#if po.nullable =='N'>
${po.fieldName}:{rules: [{ required: true, message: '请输入${po.filedComment}!' }]},
</#if>
</#if>
</#list>
},
url: {
add: "/${entityPackage}/${entityName?uncap_first}/add",
edit: "/${entityPackage}/${entityName?uncap_first}/edit",
},
}
},
created () {
},
methods: {
add () {
this.edit({});
},
edit (record) {
this.form.resetFields();
this.model = Object.assign({}, record);
this.visible = true;
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model<#list columns as po><#if po.fieldName !='id' && po.fieldType?index_of("date")==-1>,'${po.fieldName}'</#if></#list>))
//时间格式化
<#list columns as po>
<#if po.fieldName !='id' && po.fieldType?index_of("date")!=-1>
this.form.setFieldsValue({${po.fieldName}:this.model.${po.fieldName}?moment(this.model.${po.fieldName}):null})
</#if>
</#list>
});
},
close () {
this.$emit('close');
this.visible = false;
},
handleOk () {
const that = this;
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
that.confirmLoading = true;
let httpurl = '';
let method = '';
if(!this.model.id){
httpurl+=this.url.add;
method = 'post';
}else{
httpurl+=this.url.edit;
method = 'put';
}
let formData = Object.assign(this.model, values);
//时间格式化
<#list columns as po>
<#if po.fieldName !='id' && po.fieldType =='date'>
formData.${po.fieldName} = formData.${po.fieldName}?formData.${po.fieldName}.format():null;
<#elseif po.fieldName !='id' && po.fieldType =='datetime'>
formData.${po.fieldName} = formData.${po.fieldName}?formData.${po.fieldName}.format('YYYY-MM-DD HH:mm:ss'):null;
</#if>
</#list>
console.log(formData)
httpAction(httpurl,formData,method).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.$emit('ok');
}else{
that.$message.warning(res.message);
}
}).finally(() => {
that.confirmLoading = false;
that.close();
})
}
})
},
handleCancel () {
this.close()
},
}
}
</script>
<style lang="less" scoped>
/** Button按钮间距 */
.ant-btn {
margin-left: 30px;
margin-bottom: 30px;
float: right;
}
</style>

View File

@ -0,0 +1,277 @@
package ${bussiPackage}.${entityPackage}.controller;
import java.io.UnsupportedEncodingException;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.oConvertUtils;
<#list subTables as sub>
import ${bussiPackage}.${entityPackage}.entity.${sub.entityName};
</#list>
import ${bussiPackage}.${entityPackage}.entity.${entityName};
import ${bussiPackage}.${entityPackage}.vo.${entityName}Page;
import ${bussiPackage}.${entityPackage}.service.I${entityName}Service;
<#list subTables as sub>
import ${bussiPackage}.${entityPackage}.service.I${sub.entityName}Service;
</#list>
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import com.alibaba.fastjson.JSON;
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
@RestController
@RequestMapping("/${entityPackage}/${entityName?uncap_first}")
@Slf4j
public class ${entityName}Controller {
@Autowired
private I${entityName}Service ${entityName?uncap_first}Service;
<#list subTables as sub>
@Autowired
private I${sub.entityName}Service ${sub.entityName?uncap_first}Service;
</#list>
/**
* 分页列表查询
* @param ${entityName?uncap_first}
* @param pageNo
* @param pageSize
* @param req
* @return
*/
@GetMapping(value = "/list")
public Result<IPage<${entityName}>> queryPageList(${entityName} ${entityName?uncap_first},
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
Result<IPage<${entityName}>> result = new Result<IPage<${entityName}>>();
QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap());
Page<${entityName}> page = new Page<${entityName}>(pageNo, pageSize);
IPage<${entityName}> pageList = ${entityName?uncap_first}Service.page(page, queryWrapper);
result.setSuccess(true);
result.setResult(pageList);
return result;
}
/**
* 添加
* @param ${entityName?uncap_first}Page
* @return
*/
@PostMapping(value = "/add")
public Result<${entityName}> add(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) {
Result<${entityName}> result = new Result<${entityName}>();
try {
${entityName} ${entityName?uncap_first} = new ${entityName}();
BeanUtils.copyProperties(${entityName?uncap_first}Page, ${entityName?uncap_first});
${entityName?uncap_first}Service.saveMain(${entityName?uncap_first}, <#list subTables as sub>${entityName?uncap_first}Page.get${sub.entityName}List()<#if sub_has_next>,</#if></#list>);
result.success("添加成功!");
} catch (Exception e) {
log.error(e.getMessage(),e);
result.error500("操作失败");
}
return result;
}
/**
* 编辑
* @param ${entityName?uncap_first}Page
* @return
*/
@PutMapping(value = "/edit")
public Result<${entityName}> edit(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) {
Result<${entityName}> result = new Result<${entityName}>();
${entityName} ${entityName?uncap_first} = new ${entityName}();
BeanUtils.copyProperties(${entityName?uncap_first}Page, ${entityName?uncap_first});
${entityName} ${entityName?uncap_first}Entity = ${entityName?uncap_first}Service.getById(${entityName?uncap_first}.getId());
if(${entityName?uncap_first}Entity==null) {
result.error500("未找到对应实体");
}else {
boolean ok = ${entityName?uncap_first}Service.updateById(${entityName?uncap_first});
${entityName?uncap_first}Service.updateMain(${entityName?uncap_first}, <#list subTables as sub>${entityName?uncap_first}Page.get${sub.entityName}List()<#if sub_has_next>,</#if></#list>);
result.success("修改成功!");
}
return result;
}
/**
* 通过id删除
* @param id
* @return
*/
@DeleteMapping(value = "/delete")
public Result<${entityName}> delete(@RequestParam(name="id",required=true) String id) {
Result<${entityName}> result = new Result<${entityName}>();
${entityName} ${entityName?uncap_first} = ${entityName?uncap_first}Service.getById(id);
if(${entityName?uncap_first}==null) {
result.error500("未找到对应实体");
}else {
${entityName?uncap_first}Service.delMain(id);
result.success("删除成功!");
}
return result;
}
/**
* 批量删除
* @param ids
* @return
*/
@DeleteMapping(value = "/deleteBatch")
public Result<${entityName}> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
Result<${entityName}> result = new Result<${entityName}>();
if(ids==null || "".equals(ids.trim())) {
result.error500("参数不识别!");
}else {
this.${entityName?uncap_first}Service.delBatchMain(Arrays.asList(ids.split(",")));
result.success("删除成功!");
}
return result;
}
/**
* 通过id查询
* @param id
* @return
*/
@GetMapping(value = "/queryById")
public Result<${entityName}> queryById(@RequestParam(name="id",required=true) String id) {
Result<${entityName}> result = new Result<${entityName}>();
${entityName} ${entityName?uncap_first} = ${entityName?uncap_first}Service.getById(id);
if(${entityName?uncap_first}==null) {
result.error500("未找到对应实体");
}else {
result.setResult(${entityName?uncap_first});
result.setSuccess(true);
}
return result;
}
<#list subTables as sub>
/**
* 通过id查询
* @param id
* @return
*/
@GetMapping(value = "/query${sub.entityName}ByMainId")
public Result<List<${sub.entityName}>> query${sub.entityName}ListByMainId(@RequestParam(name="id",required=true) String id) {
Result<List<${sub.entityName}>> result = new Result<List<${sub.entityName}>>();
List<${sub.entityName}> ${sub.entityName?uncap_first}List = ${sub.entityName?uncap_first}Service.selectByMainId(id);
result.setResult(${sub.entityName?uncap_first}List);
result.setSuccess(true);
return result;
}
</#list>
/**
* 导出excel
*
* @param request
* @param response
*/
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
// Step.1 组装查询条件
QueryWrapper<${entityName}> queryWrapper = null;
try {
String paramsStr = request.getParameter("paramsStr");
if (oConvertUtils.isNotEmpty(paramsStr)) {
String deString = URLDecoder.decode(paramsStr, "UTF-8");
${entityName} ${entityName?uncap_first} = JSON.parseObject(deString, ${entityName}.class);
queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, request.getParameterMap());
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//Step.2 AutoPoi 导出Excel
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
List<${entityName}Page> pageList = new ArrayList<${entityName}Page>();
List<${entityName}> ${entityName?uncap_first}List = ${entityName?uncap_first}Service.list(queryWrapper);
for (${entityName} ${entityName?uncap_first} : ${entityName?uncap_first}List) {
${entityName}Page vo = new ${entityName}Page();
BeanUtils.copyProperties(${entityName?uncap_first}, vo);
<#list subTables as sub>
List<${sub.entityName}> ${sub.entityName?uncap_first}List = ${sub.entityName?uncap_first}Service.selectByMainId(${entityName?uncap_first}.getId());
vo.set${sub.entityName}List(${sub.entityName?uncap_first}List);
</#list>
pageList.add(vo);
}
//导出文件名称
mv.addObject(NormalExcelConstants.FILE_NAME, "${tableVo.ftlDescription}列表");
mv.addObject(NormalExcelConstants.CLASS, ${entityName}Page.class);
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("${tableVo.ftlDescription}列表数据", "导出人:Jeecg", "导出信息"));
mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
return mv;
}
/**
* 通过excel导入数据
*
* @param request
* @param response
* @return
*/
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
MultipartFile file = entity.getValue();// 获取上传文件对象
ImportParams params = new ImportParams();
params.setTitleRows(2);
params.setHeadRows(1);
params.setNeedSave(true);
try {
List<${entityName}Page> list = ExcelImportUtil.importExcel(file.getInputStream(), ${entityName}Page.class, params);
for (${entityName}Page page : list) {
${entityName} po = new ${entityName}();
BeanUtils.copyProperties(page, po);
${entityName?uncap_first}Service.saveMain(po, <#list subTables as sub>page.get${sub.entityName}List()<#if sub_has_next>,</#if></#list>);
}
return Result.ok("文件导入成功!数据行数:" + list.size());
} catch (Exception e) {
log.error(e.getMessage(),e);
return Result.error("文件导入失败:"+e.getMessage());
} finally {
try {
file.getInputStream().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return Result.ok("文件导入失败!");
}
}

View File

@ -0,0 +1,39 @@
package ${bussiPackage}.${entityPackage}.entity;
import java.io.Serializable;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
@Data
@TableName("${tableName}")
public class ${entityName} implements Serializable {
private static final long serialVersionUID = 1L;
<#list originalColumns as po>
/**${po.filedComment}*/
<#if po.fieldName == primaryKeyField>
@TableId(type = IdType.UUID)
</#if>
<#if po.fieldType =='java.util.Date'>
<#if po.fieldDbType =='date'>
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
<#elseif po.fieldDbType =='datetime'>
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
</#if>
</#if>
private <#if po.fieldType=='java.sql.Blob'>byte[]<#else>${po.fieldType}</#if> ${po.fieldName};
</#list>
}

View File

@ -0,0 +1,50 @@
<#list subTables as subTab>
#segment#${subTab.entityName}.java
package ${bussiPackage}.${entityPackage}.entity;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
import java.util.Date;
/**
* @Description: ${subTab.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
@Data
@TableName("${subTab.tableName}")
public class ${subTab.entityName} implements Serializable {
private static final long serialVersionUID = 1L;
<#list subTab.originalColumns as po>
/**${po.filedComment}*/
<#if po.fieldName == primaryKeyField>
@TableId(type = IdType.UUID)
<#else>
<#if po.fieldType =='java.util.Date'>
<#if po.fieldDbType =='date'>
@Excel(name = "${po.filedComment}", width = 15, format = "yyyy-MM-dd")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
<#elseif po.fieldDbType =='datetime'>
@Excel(name = "${po.filedComment}", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
</#if>
<#else>
<#if !subTab.foreignKeys?seq_contains(po.fieldName?cap_first)>
@Excel(name = "${po.filedComment}", width = 15)
</#if>
</#if>
</#if>
private <#if po.fieldType=='java.sql.Blob'>byte[]<#else>${po.fieldType}</#if> ${po.fieldName};
</#list>
}
</#list>

View File

@ -0,0 +1,17 @@
package ${bussiPackage}.${entityPackage}.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import ${bussiPackage}.${entityPackage}.entity.${entityName};
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
public interface ${entityName}Mapper extends BaseMapper<${entityName}> {
}

View File

@ -0,0 +1,21 @@
<#list subTables as subTab>
#segment#${subTab.entityName}Mapper.java
package ${bussiPackage}.${entityPackage}.mapper;
import java.util.List;
import ${bussiPackage}.${entityPackage}.entity.${subTab.entityName};
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: ${subTab.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
public interface ${subTab.entityName}Mapper extends BaseMapper<${subTab.entityName}> {
public boolean deleteByMainId(String mainId);
public List<${subTab.entityName}> selectByMainId(String mainId);
}
</#list>

View File

@ -0,0 +1,5 @@
<?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="${bussiPackage}.${entityPackage}.mapper.${entityName}Mapper">
</mapper>

View File

@ -0,0 +1,36 @@
<#list subTables as subTab>
<#assign originalForeignKeys = subTab.originalForeignKeys>
#segment#${subTab.entityName}Mapper.xml
<?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="${bussiPackage}.${entityPackage}.mapper.${subTab.entityName}Mapper">
<delete id="deleteByMainId" parameterType="java.lang.String">
DELETE
FROM ${subTab.tableName}
WHERE
<#list originalForeignKeys as key>
<#if key?lower_case?index_of("${primaryKeyField}")!=-1>
${key} = ${r'#'}{${primaryKeyField}} <#rt/>
<#else>
${key} = ${r'#'}{${key}} <#rt/>
</#if>
<#if key_has_next>AND</#if>
</#list>
</delete>
<select id="selectByMainId" parameterType="java.lang.String" resultType="${bussiPackage}.${entityPackage}.entity.${subTab.entityName}">
SELECT *
FROM ${subTab.tableName}
WHERE
<#list originalForeignKeys as key>
<#if key?lower_case?index_of("${primaryKeyField}")!=-1>
${key} = ${r'#'}{${primaryKeyField}} <#rt/>
<#else>
${key} = ${r'#'}{${key}} <#rt/>
</#if>
<#if key_has_next>AND</#if>
</#list>
</select>
</mapper>
</#list>

View File

@ -0,0 +1,42 @@
package ${bussiPackage}.${entityPackage}.service;
<#list subTables as sub>
import ${bussiPackage}.${entityPackage}.entity.${sub.entityName};
</#list>
import ${bussiPackage}.${entityPackage}.entity.${entityName};
import com.baomidou.mybatisplus.extension.service.IService;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
public interface I${entityName}Service extends IService<${entityName}> {
/**
* 添加一对多
*
*/
public void saveMain(${entityName} ${entityName?uncap_first},<#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,</#if></#list>) ;
/**
* 修改一对多
*
*/
public void updateMain(${entityName} ${entityName?uncap_first},<#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,</#if></#list>);
/**
* 删除一对多
*/
public void delMain (String id);
/**
* 批量删除一对多
*/
public void delBatchMain (Collection<? extends Serializable> idList);
}

View File

@ -0,0 +1,19 @@
<#list subTables as subTab>
#segment#I${subTab.entityName}Service.java
package ${bussiPackage}.${entityPackage}.service;
import ${bussiPackage}.${entityPackage}.entity.${subTab.entityName};
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* @Description: ${subTab.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
public interface I${subTab.entityName}Service extends IService<${subTab.entityName}> {
public List<${subTab.entityName}> selectByMainId(String mainId);
}
</#list>

View File

@ -0,0 +1,101 @@
package ${bussiPackage}.${entityPackage}.service.impl;
import ${bussiPackage}.${entityPackage}.entity.${entityName};
<#list subTables as sub>
import ${bussiPackage}.${entityPackage}.entity.${sub.entityName};
</#list>
<#list subTables as sub>
import ${bussiPackage}.${entityPackage}.mapper.${sub.entityName}Mapper;
</#list>
import ${bussiPackage}.${entityPackage}.mapper.${entityName}Mapper;
import ${bussiPackage}.${entityPackage}.service.I${entityName}Service;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.util.List;
import java.util.Collection;
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
@Service
public class ${entityName}ServiceImpl extends ServiceImpl<${entityName}Mapper, ${entityName}> implements I${entityName}Service {
@Autowired
private ${entityName}Mapper ${entityName?uncap_first}Mapper;
<#list subTables as sub>
@Autowired
private ${sub.entityName}Mapper ${sub.entityName?uncap_first}Mapper;
</#list>
@Override
@Transactional
public void saveMain(${entityName} ${entityName?uncap_first}, <#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,</#if></#list>) {
${entityName?uncap_first}Mapper.insert(${entityName?uncap_first});
<#list subTables as sub>
for(${sub.entityName} entity:${sub.entityName?uncap_first}List) {
<#list sub.foreignKeys as key>
//外键设置
<#if key?lower_case?index_of("${primaryKeyField}")!=-1>
entity.set${key?cap_first}(${entityName?uncap_first}.get${primaryKeyField?cap_first}());
<#else>
entity.set${key?cap_first}(${entityName?uncap_first}.get${key}());
</#if>
</#list>
${sub.entityName?uncap_first}Mapper.insert(entity);
}
</#list>
}
@Override
@Transactional
public void updateMain(${entityName} ${entityName?uncap_first},<#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,</#if></#list>) {
${entityName?uncap_first}Mapper.updateById(${entityName?uncap_first});
//1.先删除子表数据
<#list subTables as sub>
${sub.entityName?uncap_first}Mapper.deleteByMainId(${entityName?uncap_first}.getId());
</#list>
//2.子表数据重新插入
<#list subTables as sub>
for(${sub.entityName} entity:${sub.entityName?uncap_first}List) {
<#list sub.foreignKeys as key>
//外键设置
<#if key?lower_case?index_of("${primaryKeyField}")!=-1>
entity.set${key?cap_first}(${entityName?uncap_first}.get${primaryKeyField?cap_first}());
<#else>
entity.set${key?cap_first}(${entityName?uncap_first}.get${key}());
</#if>
</#list>
${sub.entityName?uncap_first}Mapper.insert(entity);
}
</#list>
}
@Override
@Transactional
public void delMain(String id) {
<#list subTables as sub>
${sub.entityName?uncap_first}Mapper.deleteByMainId(id);
</#list>
${entityName?uncap_first}Mapper.deleteById(id);
}
@Override
@Transactional
public void delBatchMain(Collection<? extends Serializable> idList) {
for(Serializable id:idList) {
<#list subTables as sub>
${sub.entityName?uncap_first}Mapper.deleteByMainId(id.toString());
</#list>
${entityName?uncap_first}Mapper.deleteById(id);
}
}
}

View File

@ -0,0 +1,30 @@
<#list subTables as subTab>
#segment#${subTab.entityName}ServiceImpl.java
package ${bussiPackage}.${entityPackage}.service.impl;
import ${bussiPackage}.${entityPackage}.entity.${subTab.entityName};
import ${bussiPackage}.${entityPackage}.mapper.${subTab.entityName}Mapper;
import ${bussiPackage}.${entityPackage}.service.I${subTab.entityName}Service;
import org.springframework.stereotype.Service;
import java.util.List;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @Description: ${subTab.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
@Service
public class ${subTab.entityName}ServiceImpl extends ServiceImpl<${subTab.entityName}Mapper, ${subTab.entityName}> implements I${subTab.entityName}Service {
@Autowired
private ${subTab.entityName}Mapper ${subTab.entityName?uncap_first}Mapper;
@Override
public List<${subTab.entityName}> selectByMainId(String mainId) {
return ${subTab.entityName?uncap_first}Mapper.selectByMainId(mainId);
}
}
</#list>

View File

@ -0,0 +1,50 @@
package ${bussiPackage}.${entityPackage}.vo;
import java.util.List;
import ${bussiPackage}.${entityPackage}.entity.${entityName};
<#list subTables as sub>
import ${bussiPackage}.${entityPackage}.entity.${sub.entityName};
</#list>
import lombok.Data;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.jeecgframework.poi.excel.annotation.ExcelCollection;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
@Data
public class ${entityName}Page {
<#list originalColumns as po>
/**${po.filedComment}*/
<#if po.fieldName == primaryKeyField>
<#else>
<#if po.fieldType =='java.util.Date'>
<#if po.fieldDbType =='date'>
@Excel(name = "${po.filedComment}", width = 15, format = "yyyy-MM-dd")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
<#elseif po.fieldDbType =='datetime'>
@Excel(name = "${po.filedComment}", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
</#if>
<#else>
@Excel(name = "${po.filedComment}", width = 15)
</#if>
</#if>
private <#if po.fieldType=='java.sql.Blob'>byte[]<#else>${po.fieldType}</#if> ${po.fieldName};
</#list>
<#list subTables as sub>
@ExcelCollection(name="${sub.ftlDescription}")
private List<${sub.entityName}> ${sub.entityName?uncap_first}List;
</#list>
}

View File

@ -0,0 +1,162 @@
<template>
<a-card :bordered="false">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-row :gutter="24">
<#list columns as po><#rt/>
<#if po.fieldName !='id' && po_index<= tableVo.searchFieldNum>
<a-col :span="6">
<a-form-item label="${po.filedComment}">
<a-input placeholder="请输入${po.filedComment}" v-model="queryParam.${po.fieldName}"></a-input>
</a-form-item>
</a-col>
</#if>
</#list>
<a-col :span="8" >
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!-- 操作按钮区域 -->
<div class="table-operator">
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
<a-button type="primary" icon="download" @click="handleExportXls('${tableVo.ftlDescription}')">导出</a-button>
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
<a-button type="primary" icon="import">导入</a-button>
</a-upload>
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>
</a-dropdown>
</div>
<!-- table区域-begin -->
<div>
<div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
<i class="anticon anticon-info-circle ant-alert-icon"></i>
<span>已选择</span>
<a style="font-weight: 600">
{{ selectedRowKeys.length }}
</a>
<span>项</span>
<a style="margin-left: 24px" @click="onClearSelected">清空</a>
</div>
<a-table
ref="table"
size="middle"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@change="handleTableChange">
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical" />
<a-dropdown>
<a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
<a-menu slot="overlay">
<a-menu-item>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
<a>删除</a>
</a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
</span>
</a-table>
</div>
<!-- table区域-end -->
<!-- 表单区域 -->
<${entityName?uncap_first}-modal ref="modalForm" @ok="modalFormOk"/>
</a-card>
</template>
<script>
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import ${entityName}Modal from './modules/${entityName}Modal'
export default {
name: "${entityName}List",
mixins: [JeecgListMixin],
components: {
${entityName}Modal
},
data () {
return {
description: '${tableVo.ftlDescription}管理页面',
// 表头
columns: [
{
title: '#',
dataIndex: '',
key: 'rowIndex',
width: 60,
align: "center",
customRender:function (t, r, index) {
return parseInt(index)+1;
}
},
<#list columns as po><#rt/>
<#if po.fieldName !='id'>
{
title: '${po.filedComment}',
align:"center",
dataIndex: '${po.fieldName}'
},
</#if>
</#list>
{
title: '操作',
dataIndex: 'action',
align:"center",
scopedSlots: { customRender: 'action' },
}
],
// 请求参数
url: {
list: "/${entityPackage}/${entityName?uncap_first}/list",
delete: "/${entityPackage}/${entityName?uncap_first}/delete",
deleteBatch: "/${entityPackage}/${entityName?uncap_first}/deleteBatch",
exportXlsUrl: "${entityPackage}/${entityName?uncap_first}/exportXls",
importExcelUrl: "${entityPackage}/${entityName?uncap_first}/importExcel",
},
}
},
computed: {
importExcelUrl: function(){
<#noparse>return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;</#noparse>
}
},
methods: {
initDictConfig() {
}
}
}
</script>
<style scoped>
@import '~@assets/less/common.less'
</style>

View File

@ -0,0 +1,184 @@
<template>
<a-modal
:title="title"
:width="1200"
:visible="visible"
:maskClosable="false"
:confirmLoading="confirmLoading"
@ok="handleOk"
@cancel="handleCancel">
<a-spin :spinning="confirmLoading">
<!-- 主表单区域 -->
<a-form :form="form">
<#list columns as po><#rt/>
<#if po_index % 2 == 0 ><#rt/>
<a-row>
<#if po.fieldName !='id'>
<#list [po_index, po_index+1] as idx><#rt/>
<#if idx lt columns?size>
<a-col :span="12" :gutter="8">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="${columns[idx].filedComment}">
<#if columns[idx].fieldType =='date'>
<a-date-picker
placeholder="请输入${columns[idx].filedComment}"
style="width:100%"
v-decorator="[ '${columns[idx].fieldName}', <#if columns[idx].nullable =='N'>validatorRules.${columns[idx].fieldName} <#else>{}</#if>]"/>
<#elseif columns[idx].fieldType =='datetime'>
<a-date-picker
placeholder="请输入${columns[idx].filedComment}"
style="width:100%"
:showTime="true"
format="YYYY-MM-DD HH:mm:ss"
v-decorator="[ '${columns[idx].fieldName}', <#if columns[idx].nullable =='N'>validatorRules.${columns[idx].fieldName} <#else>{}</#if>]"/>
<#elseif "int,decimal,double,"?contains(columns[idx].fieldType)>
<a-input-number placeholder="请输入${columns[idx].filedComment}" style="width:100%" v-decorator="[ '${columns[idx].fieldName}', <#if columns[idx].nullable =='N'>validatorRules.${columns[idx].fieldName} <#else>{}</#if>]"/>
<#else>
<a-input placeholder="请输入${columns[idx].filedComment}" v-decorator="['${columns[idx].fieldName}', <#if columns[idx].nullable =='N'>validatorRules.${columns[idx].fieldName} <#else>{}</#if>]"/>
</#if>
</a-form-item>
</a-col>
</#if>
</#list><#rt/>
</#if><#rt/>
</a-row>
</#if><#rt/>
</#list>
</a-form>
<!-- 子表单区域 -->
<a-tabs v-model="activeKey" @change="handleChangeTabs">
<#list subTables as sub><#rt/>
<a-tab-pane tab="${sub.ftlDescription}" :key="refKeys[${sub_index}]" :forceRender="true">
<j-editable-table
:ref="refKeys[${sub_index}]"
:loading="${sub.entityName?uncap_first}Table.loading"
:columns="${sub.entityName?uncap_first}Table.columns"
:dataSource="${sub.entityName?uncap_first}Table.dataSource"
:maxHeight="300"
:rowNumber="true"
:rowSelection="true"
:actionButton="true"/>
</a-tab-pane>
</#list>
</a-tabs>
</a-spin>
</a-modal>
</template>
<script>
import moment from 'moment'
import pick from 'lodash.pick'
import { FormTypes } from '@/utils/JEditableTableUtil'
import { JEditableTableMixin } from '@/mixins/JEditableTableMixin'
export default {
name: '${entityName}Modal',
mixins: [JEditableTableMixin],
data() {
return {
// 新增时子表默认添加几行空数据
addDefaultRowNum: 1,
validatorRules: {
<#list columns as po>
<#if po.fieldName !='id'>
<#if po.nullable =='N'>
${po.fieldName}: { rules: [{ required: true, message: '请输入${po.filedComment}!' }] },
</#if>
</#if>
</#list>
},
refKeys: [<#list subTables as sub>'${sub.entityName?uncap_first}', </#list>],
activeKey: '${subTables[0].entityName?uncap_first}',
<#list subTables as sub><#rt/>
// ${sub.ftlDescription}
${sub.entityName?uncap_first}Table: {
loading: false,
dataSource: [],
columns: [
<#list sub.colums as col><#rt/>
<#if col.filedComment !='外键'>
{
title: '${col.filedComment}',
key: '${col.fieldName}',
<#if col.fieldType =='date'>
type: FormTypes.date,
<#elseif col.fieldType =='datetime'>
type: FormTypes.datetime,
<#elseif "int,decimal,double,"?contains(col.fieldType)>
type: FormTypes.inputNumber,
<#else>
type: FormTypes.input,
</#if>
defaultValue: '',
placeholder: '请输入${'$'}{title}',
<#if col.nullable =='N'>
validateRules: [{ required: true, message: '${'$'}{title}不能为空' }],
</#if>
},
</#if>
</#list>
]
},
</#list>
url: {
add: "/${entityPackage}/${entityName?uncap_first}/add",
edit: "/${entityPackage}/${entityName?uncap_first}/edit",
<#list subTables as sub><#rt/>
${sub.entityName?uncap_first}: {
list: '/${entityPackage}/${entityName?uncap_first}/query${sub.entityName}ByMainId'
},
</#list>
}
}
},
methods: {
/** 调用完edit()方法之后会自动调用此方法 */
editAfter() {
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model, <#list columns as col>'${col.fieldName}', </#list>))
// 时间格式化
<#list columns as col><#rt/>
<#if col.fieldName !='id' && (col.fieldType =='date' || col.fieldType =='datetime')>
this.form.setFieldsValue({ ${col.fieldName}: this.model.${col.fieldName} ? moment(this.model.${col.fieldName}) : null })
</#if>
</#list>
})
// 加载子表数据
if (this.model.id) {
let params = { id: this.model.id }
<#list subTables as sub><#rt/>
this.requestSubTableData(this.url.${sub.entityName?uncap_first}.list, params, this.${sub.entityName?uncap_first}Table)
</#list>
}
},
/** 整理成formData */
classifyIntoFormData(allValues) {
let main = Object.assign(this.model, allValues.formValue)
//时间格式化
<#list columns as col><#rt/>
<#if col.fieldName !='id' && col.fieldType =='date'>
main.${col.fieldName} = main.${col.fieldName} ? main.${col.fieldName}.format() : null;
<#elseif col.fieldName !='id' && col.fieldType =='datetime'>
main.${col.fieldName} = main.${col.fieldName} ? main.${col.fieldName}.format('YYYY-MM-DD HH:mm:ss') : null;
</#if>
</#list>
return {
...main, // 展开
<#list subTables as sub><#rt/>
${sub.entityName?uncap_first}List: allValues.tablesValue[${sub_index}].values,
</#list>
}
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,377 @@
package ${bussiPackage}.${entityPackage}.controller;
import java.io.UnsupportedEncodingException;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.oConvertUtils;
<#list subTables as sub>
import ${bussiPackage}.${entityPackage}.entity.${sub.entityName};
</#list>
import ${bussiPackage}.${entityPackage}.entity.${entityName};
import ${bussiPackage}.${entityPackage}.vo.${entityName}Page;
import ${bussiPackage}.${entityPackage}.service.I${entityName}Service;
<#list subTables as sub>
import ${bussiPackage}.${entityPackage}.service.I${sub.entityName}Service;
</#list>
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import com.alibaba.fastjson.JSON;
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
@RestController
@RequestMapping("/${entityPackage}/${entityName?uncap_first}")
@Slf4j
public class ${entityName}Controller {
@Autowired
private I${entityName}Service ${entityName?uncap_first}Service;
<#list subTables as sub>
@Autowired
private I${sub.entityName}Service ${sub.entityName?uncap_first}Service;
</#list>
/**
* 分页列表查询
* @param ${entityName?uncap_first}
* @param pageNo
* @param pageSize
* @param req
* @return
*/
@GetMapping(value = "/list")
public Result<IPage<${entityName}>> queryPageList(${entityName} ${entityName?uncap_first},
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
Result<IPage<${entityName}>> result = new Result<IPage<${entityName}>>();
QueryWrapper<${entityName}> queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, req.getParameterMap());
Page<${entityName}> page = new Page<${entityName}>(pageNo, pageSize);
IPage<${entityName}> pageList = ${entityName?uncap_first}Service.page(page, queryWrapper);
result.setSuccess(true);
result.setResult(pageList);
return result;
}
/**
* 添加
* @param ${entityName?uncap_first}Page
* @return
*/
@PostMapping(value = "/add")
public Result<${entityName}> add(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) {
Result<${entityName}> result = new Result<${entityName}>();
try {
${entityName} ${entityName?uncap_first} = new ${entityName}();
BeanUtils.copyProperties(${entityName?uncap_first}Page, ${entityName?uncap_first});
${entityName?uncap_first}Service.save(${entityName?uncap_first});
result.success("添加成功!");
} catch (Exception e) {
log.error(e.getMessage(),e);
result.error500("操作失败");
}
return result;
}
/**
* 编辑
* @param ${entityName?uncap_first}Page
* @return
*/
@PutMapping(value = "/edit")
public Result<${entityName}> edit(@RequestBody ${entityName}Page ${entityName?uncap_first}Page) {
Result<${entityName}> result = new Result<${entityName}>();
${entityName} ${entityName?uncap_first} = new ${entityName}();
BeanUtils.copyProperties(${entityName?uncap_first}Page, ${entityName?uncap_first});
${entityName} ${entityName?uncap_first}Entity = ${entityName?uncap_first}Service.getById(${entityName?uncap_first}.getId());
if(${entityName?uncap_first}Entity==null) {
result.error500("未找到对应实体");
}else {
${entityName?uncap_first}Service.updateById(${entityName?uncap_first});
result.success("修改成功!");
}
return result;
}
/**
* 通过id删除
* @param id
* @return
*/
@DeleteMapping(value = "/delete")
public Result<${entityName}> delete(@RequestParam(name="id",required=true) String id) {
Result<${entityName}> result = new Result<${entityName}>();
${entityName} ${entityName?uncap_first} = ${entityName?uncap_first}Service.getById(id);
if(${entityName?uncap_first}==null) {
result.error500("未找到对应实体");
}else {
${entityName?uncap_first}Service.delMain(id);
result.success("删除成功!");
}
return result;
}
/**
* 批量删除
* @param ids
* @return
*/
@DeleteMapping(value = "/deleteBatch")
public Result<${entityName}> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
Result<${entityName}> result = new Result<${entityName}>();
if(ids==null || "".equals(ids.trim())) {
result.error500("参数不识别!");
}else {
this.${entityName?uncap_first}Service.removeByIds(Arrays.asList(ids.split(",")));
result.success("删除成功!");
}
return result;
}
/**
* 通过id查询
* @param id
* @return
*/
@GetMapping(value = "/queryById")
public Result<${entityName}> queryById(@RequestParam(name="id",required=true) String id) {
Result<${entityName}> result = new Result<${entityName}>();
${entityName} ${entityName?uncap_first} = ${entityName?uncap_first}Service.getById(id);
if(${entityName?uncap_first}==null) {
result.error500("未找到对应实体");
}else {
result.setResult(${entityName?uncap_first});
result.setSuccess(true);
}
return result;
}
//===========================以下是子表信息操作相关API====================================
<#list subTables as sub>
/**
* 通过主表id查询${sub.ftlDescription}
* @param mainId
* @return
*/
@GetMapping(value = "/list${sub.entityName}ByMainId")
public Result<List<${sub.entityName}>> query${sub.entityName}ListByMainId(@RequestParam(name="mainId",required=false) String mainId) {
Result<List<${sub.entityName}>> result = new Result<List<${sub.entityName}>>();
List<${sub.entityName}> ${sub.entityName?uncap_first}List = null;
if (mainId != null) {
${sub.entityName?uncap_first}List = ${sub.entityName?uncap_first}Service.selectByMainId(mainId);
result.setResult(${sub.entityName?uncap_first}List);
result.setSuccess(true);
return result;
}else return null;
}
/**
* 添加${sub.ftlDescription}
*
* @param ${sub.entityName?uncap_first}
* @return
*/
@PostMapping(value = "/add${sub.entityName}")
public Result<${sub.entityName}> add${sub.entityName}(@RequestBody ${sub.entityName} ${sub.entityName?uncap_first}) {
Result<${sub.entityName}> result = new Result<>();
try {
boolean ok = ${sub.entityName?uncap_first}Service.save(${sub.entityName?uncap_first});
if (ok) {
result.setSuccess(true);
result.setMessage("添加${sub.ftlDescription}成功.");
} else {
result.setSuccess(false);
result.setMessage("添加${sub.ftlDescription}失败!");
}
return result;
} catch (Exception e) {
e.fillInStackTrace();
result.setSuccess(false);
result.setMessage("添加${sub.ftlDescription}过程中出现了异常: " + e.getMessage());
return result;
}
}
/**
* 编辑${sub.ftlDescription}
*
* @param ${sub.entityName?uncap_first}
* @return
*/
@PutMapping("/edit${sub.entityName}")
public Result<${sub.entityName}> edit${sub.entityName}(@RequestBody ${sub.entityName} ${sub.entityName?uncap_first}) {
Result<${sub.entityName}> result = new Result<>();
try {
boolean ok = ${sub.entityName?uncap_first}Service.updateById(${sub.entityName?uncap_first});
if (ok) {
result.setSuccess(true);
result.setMessage("更新${sub.ftlDescription}成功.");
} else {
result.setSuccess(false);
result.setMessage("更新${sub.ftlDescription}失败!");
}
return result;
} catch (Exception e) {
result.setSuccess(false);
result.setMessage("更新数据过程中出现异常啦: " + e.getMessage());
return result;
}
}
/**
* 通过id删除${sub.ftlDescription}
*
* @param id
* @return
*/
@DeleteMapping(value = "/delete${sub.entityName}")
public Result<${sub.entityName}> delete${sub.entityName}(@RequestParam(name = "id", required = true) String id) {
Result<${sub.entityName}> result = new Result<>();
try {
boolean ok = ${sub.entityName?uncap_first}Service.removeById(id);
if (ok) {
result.setSuccess(true);
result.setMessage("删除${sub.ftlDescription}成功.");
} else {
result.setSuccess(false);
result.setMessage("删除${sub.ftlDescription}失败!");
}
return result;
} catch (Exception e) {
result.setSuccess(false);
result.setMessage("删除${sub.ftlDescription}过程中出现异常啦: " + e.getMessage());
return result;
}
}
/**
* 批量删除${sub.ftlDescription}
*
* @param ids
* @return
*/
@DeleteMapping(value = "/deleteBatch${sub.entityName}")
public Result<${sub.entityName}> deleteBatch${sub.entityName}(@RequestParam(name = "ids", required = true) String ids) {
Result<${sub.entityName}> result = new Result<${sub.entityName}>();
if (ids == null || "".equals(ids.trim())) {
result.error500("参数不识别!");
} else {
this.${sub.entityName?uncap_first}Service.removeByIds(Arrays.asList(ids.split(",")));
result.success("删除成功!");
}
return result;
}
</#list>
/**
* 导出excel
*
* @param request
* @param response
*/
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) {
// Step.1 组装查询条件
QueryWrapper<${entityName}> queryWrapper = null;
try {
String paramsStr = request.getParameter("paramsStr");
if (oConvertUtils.isNotEmpty(paramsStr)) {
String deString = URLDecoder.decode(paramsStr, "UTF-8");
${entityName} ${entityName?uncap_first} = JSON.parseObject(deString, ${entityName}.class);
queryWrapper = QueryGenerator.initQueryWrapper(${entityName?uncap_first}, request.getParameterMap());
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//Step.2 AutoPoi 导出Excel
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
List<${entityName}Page> pageList = new ArrayList<${entityName}Page>();
List<${entityName}> ${entityName?uncap_first}List = ${entityName?uncap_first}Service.list(queryWrapper);
for (${entityName} ${entityName?uncap_first} : ${entityName?uncap_first}List) {
${entityName}Page vo = new ${entityName}Page();
BeanUtils.copyProperties(${entityName?uncap_first}, vo);
<#list subTables as sub>
List<${sub.entityName}> ${sub.entityName?uncap_first}List = ${sub.entityName?uncap_first}Service.selectByMainId(${entityName?uncap_first}.getId());
vo.set${sub.entityName}List(${sub.entityName?uncap_first}List);
</#list>
pageList.add(vo);
}
//导出文件名称
mv.addObject(NormalExcelConstants.FILE_NAME, "${tableVo.ftlDescription}列表");
mv.addObject(NormalExcelConstants.CLASS, ${entityName}Page.class);
mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("${tableVo.ftlDescription}列表数据", "导出人:Jeecg", "导出信息"));
mv.addObject(NormalExcelConstants.DATA_LIST, pageList);
return mv;
}
/**
* 通过excel导入数据
*
* @param request
* @param response
* @return
*/
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
MultipartFile file = entity.getValue();// 获取上传文件对象
ImportParams params = new ImportParams();
params.setTitleRows(2);
params.setHeadRows(1);
params.setNeedSave(true);
try {
List<${entityName}Page> list = ExcelImportUtil.importExcel(file.getInputStream(), ${entityName}Page.class, params);
for (${entityName}Page page : list) {
${entityName} po = new ${entityName}();
BeanUtils.copyProperties(page, po);
${entityName?uncap_first}Service.saveMain(po, <#list subTables as sub>page.get${sub.entityName}List()<#if sub_has_next>,</#if></#list>);
}
return Result.ok("文件导入成功!数据行数:" + list.size());
} catch (Exception e) {
log.error(e.getMessage(),e);
return Result.error("文件导入失败:"+e.getMessage());
} finally {
try {
file.getInputStream().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return Result.ok("文件导入失败!");
}
}

View File

@ -0,0 +1,39 @@
package ${bussiPackage}.${entityPackage}.entity;
import java.io.Serializable;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
@Data
@TableName("${tableName}")
public class ${entityName} implements Serializable {
private static final long serialVersionUID = 1L;
<#list originalColumns as po>
/**${po.filedComment}*/
<#if po.fieldName == primaryKeyField>
@TableId(type = IdType.UUID)
</#if>
<#if po.fieldType =='java.util.Date'>
<#if po.fieldDbType =='date'>
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
<#elseif po.fieldDbType =='datetime'>
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
</#if>
</#if>
private <#if po.fieldType=='java.sql.Blob'>byte[]<#else>${po.fieldType}</#if> ${po.fieldName};
</#list>
}

View File

@ -0,0 +1,49 @@
<#list subTables as subTab>
#segment#${subTab.entityName}.java
package ${bussiPackage}.${entityPackage}.entity;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
import org.jeecgframework.poi.excel.annotation.Excel;
/**
* @Description: ${subTab.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
@Data
@TableName("${subTab.tableName}")
public class ${subTab.entityName} implements Serializable {
private static final long serialVersionUID = 1L;
<#list subTab.originalColumns as po>
/**${po.filedComment}*/
<#if po.fieldName == primaryKeyField>
@TableId(type = IdType.UUID)
<#else>
<#if po.fieldType =='java.util.Date'>
<#if po.fieldDbType =='date'>
@Excel(name = "${po.filedComment}", width = 15, format = "yyyy-MM-dd")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
<#elseif po.fieldDbType =='datetime'>
@Excel(name = "${po.filedComment}", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
</#if>
<#else>
<#if !subTab.foreignKeys?seq_contains(po.fieldName?cap_first)>
@Excel(name = "${po.filedComment}", width = 15)
</#if>
</#if>
</#if>
private <#if po.fieldType=='java.sql.Blob'>byte[]<#else>${po.fieldType}</#if> ${po.fieldName};
</#list>
}
</#list>

View File

@ -0,0 +1,17 @@
package ${bussiPackage}.${entityPackage}.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import ${bussiPackage}.${entityPackage}.entity.${entityName};
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
public interface ${entityName}Mapper extends BaseMapper<${entityName}> {
}

View File

@ -0,0 +1,21 @@
<#list subTables as subTab>
#segment#${subTab.entityName}Mapper.java
package ${bussiPackage}.${entityPackage}.mapper;
import java.util.List;
import ${bussiPackage}.${entityPackage}.entity.${subTab.entityName};
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @Description: ${subTab.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
public interface ${subTab.entityName}Mapper extends BaseMapper<${subTab.entityName}> {
public boolean deleteByMainId(String mainId);
public List<${subTab.entityName}> selectByMainId(String mainId);
}
</#list>

View File

@ -0,0 +1,5 @@
<?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="${bussiPackage}.${entityPackage}.mapper.${entityName}Mapper">
</mapper>

View File

@ -0,0 +1,36 @@
<#list subTables as subTab>
<#assign originalForeignKeys = subTab.originalForeignKeys>
#segment#${subTab.entityName}Mapper.xml
<?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="${bussiPackage}.${entityPackage}.mapper.${subTab.entityName}Mapper">
<delete id="deleteByMainId" parameterType="java.lang.String">
DELETE
FROM ${subTab.tableName}
WHERE
<#list originalForeignKeys as key>
<#if key?lower_case?index_of("${primaryKeyField}")!=-1>
${key} = ${r'#'}{${primaryKeyField}} <#rt/>
<#else>
${key} = ${r'#'}{${key}} <#rt/>
</#if>
<#if key_has_next>AND</#if>
</#list>
</delete>
<select id="selectByMainId" parameterType="java.lang.String" resultType="${bussiPackage}.${entityPackage}.entity.${subTab.entityName}">
SELECT *
FROM ${subTab.tableName}
WHERE
<#list originalForeignKeys as key>
<#if key?lower_case?index_of("${primaryKeyField}")!=-1>
${key} = ${r'#'}{${primaryKeyField}} <#rt/>
<#else>
${key} = ${r'#'}{${key}} <#rt/>
</#if>
<#if key_has_next>AND</#if>
</#list>
</select>
</mapper>
</#list>

View File

@ -0,0 +1,42 @@
package ${bussiPackage}.${entityPackage}.service;
<#list subTables as sub>
import ${bussiPackage}.${entityPackage}.entity.${sub.entityName};
</#list>
import ${bussiPackage}.${entityPackage}.entity.${entityName};
import com.baomidou.mybatisplus.extension.service.IService;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
public interface I${entityName}Service extends IService<${entityName}> {
/**
* 添加一对多
*
*/
public void saveMain(${entityName} ${entityName?uncap_first},<#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,</#if></#list>) ;
/**
* 修改一对多
*
*/
public void updateMain(${entityName} ${entityName?uncap_first},<#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,</#if></#list>);
/**
* 删除一对多
*/
public void delMain (String id);
/**
* 批量删除一对多
*/
public void delBatchMain (Collection<? extends Serializable> idList);
}

View File

@ -0,0 +1,19 @@
<#list subTables as subTab>
#segment#I${subTab.entityName}Service.java
package ${bussiPackage}.${entityPackage}.service;
import ${bussiPackage}.${entityPackage}.entity.${subTab.entityName};
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* @Description: ${subTab.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
public interface I${subTab.entityName}Service extends IService<${subTab.entityName}> {
public List<${subTab.entityName}> selectByMainId(String mainId);
}
</#list>

View File

@ -0,0 +1,101 @@
package ${bussiPackage}.${entityPackage}.service.impl;
import ${bussiPackage}.${entityPackage}.entity.${entityName};
<#list subTables as sub>
import ${bussiPackage}.${entityPackage}.entity.${sub.entityName};
</#list>
<#list subTables as sub>
import ${bussiPackage}.${entityPackage}.mapper.${sub.entityName}Mapper;
</#list>
import ${bussiPackage}.${entityPackage}.mapper.${entityName}Mapper;
import ${bussiPackage}.${entityPackage}.service.I${entityName}Service;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.util.List;
import java.util.Collection;
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
@Service
public class ${entityName}ServiceImpl extends ServiceImpl<${entityName}Mapper, ${entityName}> implements I${entityName}Service {
@Autowired
private ${entityName}Mapper ${entityName?uncap_first}Mapper;
<#list subTables as sub>
@Autowired
private ${sub.entityName}Mapper ${sub.entityName?uncap_first}Mapper;
</#list>
@Override
@Transactional
public void saveMain(${entityName} ${entityName?uncap_first}, <#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,</#if></#list>) {
${entityName?uncap_first}Mapper.insert(${entityName?uncap_first});
<#list subTables as sub>
for(${sub.entityName} entity:${sub.entityName?uncap_first}List) {
<#list sub.foreignKeys as key>
//外键设置
<#if key?lower_case?index_of("${primaryKeyField}")!=-1>
entity.set${key?cap_first}(${entityName?uncap_first}.get${primaryKeyField?cap_first}());
<#else>
entity.set${key?cap_first}(${entityName?uncap_first}.get${key}());
</#if>
</#list>
${sub.entityName?uncap_first}Mapper.insert(entity);
}
</#list>
}
@Override
@Transactional
public void updateMain(${entityName} ${entityName?uncap_first},<#list subTables as sub>List<${sub.entityName}> ${sub.entityName?uncap_first}List<#if sub_has_next>,</#if></#list>) {
${entityName?uncap_first}Mapper.updateById(${entityName?uncap_first});
//1.先删除子表数据
<#list subTables as sub>
${sub.entityName?uncap_first}Mapper.deleteByMainId(${entityName?uncap_first}.getId());
</#list>
//2.子表数据重新插入
<#list subTables as sub>
for(${sub.entityName} entity:${sub.entityName?uncap_first}List) {
<#list sub.foreignKeys as key>
//外键设置
<#if key?lower_case?index_of("${primaryKeyField}")!=-1>
entity.set${key?cap_first}(${entityName?uncap_first}.get${primaryKeyField?cap_first}());
<#else>
entity.set${key?cap_first}(${entityName?uncap_first}.get${key}());
</#if>
</#list>
${sub.entityName?uncap_first}Mapper.insert(entity);
}
</#list>
}
@Override
@Transactional
public void delMain(String id) {
<#list subTables as sub>
${sub.entityName?uncap_first}Mapper.deleteByMainId(id);
</#list>
${entityName?uncap_first}Mapper.deleteById(id);
}
@Override
@Transactional
public void delBatchMain(Collection<? extends Serializable> idList) {
for(Serializable id:idList) {
<#list subTables as sub>
${sub.entityName?uncap_first}Mapper.deleteByMainId(id.toString());
</#list>
${entityName?uncap_first}Mapper.deleteById(id);
}
}
}

View File

@ -0,0 +1,30 @@
<#list subTables as subTab>
#segment#${subTab.entityName}ServiceImpl.java
package ${bussiPackage}.${entityPackage}.service.impl;
import ${bussiPackage}.${entityPackage}.entity.${subTab.entityName};
import ${bussiPackage}.${entityPackage}.mapper.${subTab.entityName}Mapper;
import ${bussiPackage}.${entityPackage}.service.I${subTab.entityName}Service;
import org.springframework.stereotype.Service;
import java.util.List;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @Description: ${subTab.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
@Service
public class ${subTab.entityName}ServiceImpl extends ServiceImpl<${subTab.entityName}Mapper, ${subTab.entityName}> implements I${subTab.entityName}Service {
@Autowired
private ${subTab.entityName}Mapper ${subTab.entityName?uncap_first}Mapper;
@Override
public List<${subTab.entityName}> selectByMainId(String mainId) {
return ${subTab.entityName?uncap_first}Mapper.selectByMainId(mainId);
}
}
</#list>

View File

@ -0,0 +1,49 @@
package ${bussiPackage}.${entityPackage}.vo;
import java.util.List;
import ${bussiPackage}.${entityPackage}.entity.${entityName};
<#list subTables as sub>
import ${bussiPackage}.${entityPackage}.entity.${sub.entityName};
</#list>
import lombok.Data;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.jeecgframework.poi.excel.annotation.ExcelCollection;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
/**
* @Description: ${tableVo.ftlDescription}
* @Author: jeecg-boot
* @Date: ${.now?string["yyyy-MM-dd"]}
* @Version: V1.0
*/
@Data
public class ${entityName}Page {
<#list originalColumns as po>
/**${po.filedComment}*/
<#if po.fieldName == primaryKeyField>
<#else>
<#if po.fieldType =='java.util.Date'>
<#if po.fieldDbType =='date'>
@Excel(name = "${po.filedComment}", width = 15, format = "yyyy-MM-dd")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern="yyyy-MM-dd")
<#elseif po.fieldDbType =='datetime'>
@Excel(name = "${po.filedComment}", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
</#if>
<#else>
@Excel(name = "${po.filedComment}", width = 15)
</#if>
</#if>
private <#if po.fieldType=='java.sql.Blob'>byte[]<#else>${po.fieldType}</#if> ${po.fieldName};
</#list>
<#list subTables as sub>
@ExcelCollection(name="${sub.ftlDescription}")
private List<${sub.entityName}> ${sub.entityName?uncap_first}List;
</#list>
}

View File

@ -0,0 +1,225 @@
<template>
<a-card :bordered="false">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-row :gutter="24">
<#list columns as po><#rt/>
<#if po.fieldName !='id' && po_index<= tableVo.searchFieldNum>
<a-col :md="6" :sm="24">
<a-form-item label="${po.filedComment}">
<a-input placeholder="请输入${po.filedComment}" v-model="queryParam.${po.fieldName}"></a-input>
</a-form-item>
</a-col>
</#if>
</#list>
<a-col :md="6" :sm="24">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!-- 操作按钮区域 -->
<div class="table-operator">
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
<a-button type="primary" icon="download" @click="handleExportXls('${tableVo.ftlDescription}')">导出</a-button>
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
<a-button type="primary" icon="import">导入</a-button>
</a-upload>
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel">
<a-icon type="delete"/>删除
</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px"> 批量操作
<a-icon type="down" />
</a-button>
</a-dropdown>
</div>
<!-- table区域-begin -->
<div>
<div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
<i class="anticon anticon-info-circle ant-alert-icon"></i>
<span>已选择</span>
<a style="font-weight: 600">
{{ selectedRowKeys.length }}
</a>
<span>项</span>
<a style="margin-left: 24px" @click="onClearSelected">清空</a>
</div>
<a-table
ref="table"
size="middle"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange,type:type}"
@change="handleTableChange"
:customRow="clickThenCheck">
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical" />
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
<a>删除</a>
</a-popconfirm>
</span>
</a-table>
</div>
<!-- table区域-end -->
<a-tabs defaultActiveKey="1">
<#list subTables as sub><#rt/>
<a-tab-pane tab="${sub.ftlDescription}" :key="refKeys[${sub_index}]" :forceRender="true">
<${sub.entityName?uncap_first}-List ref="${sub.entityName}List"></${sub.entityName?uncap_first}-List>
</a-tab-pane>
</#list>
</a-tabs>
<!-- 表单区域 -->
<${entityName?uncap_first}-modal ref="modalForm" @ok="modalFormOk"/>
</a-card>
</template>
<script>
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import ${entityName}Modal from './modules/${entityName}Modal'
import {deleteAction} from '@/api/manage'
<#list subTables as sub><#rt/>
import ${sub.entityName}List from './${sub.entityName}List'
import ${sub.entityName}Modal from './modules/${sub.entityName}Modal'
</#list>
export default {
name: "${entityName}List",
mixins: [JeecgListMixin],
components: {
${entityName}Modal,
<#list subTables as sub><#rt/>
${sub.entityName}Modal,
${sub.entityName}List,
</#list>
},
data () {
return {
refKeys: [<#list subTables as sub>'${sub.entityName?uncap_first}', </#list>],
description: '${tableVo.ftlDescription}管理页面',
// 表头
columns: [
{
title: '#',
dataIndex: '',
key: 'rowIndex',
width: 60,
align: "center",
customRender:function (t, r, index) {
return parseInt(index)+1;
}
},
<#list columns as po><#rt/>
<#if po.fieldName !='id'>
{
title: '${po.filedComment}',
align:"center",
dataIndex: '${po.fieldName}'
},
</#if>
</#list>
{
title: '操作',
dataIndex: 'action',
align:"center",
scopedSlots: { customRender: 'action' },
}
],
//操作url
type: "radio",
url: {
list: "/${entityPackage}/${entityName?uncap_first}/list",
delete: "/${entityPackage}/${entityName?uncap_first}/delete",
deleteBatch: "/${entityPackage}/${entityName?uncap_first}/deleteBatch",
exportXlsUrl: "${entityPackage}/${entityName?uncap_first}/exportXls",
importExcelUrl: "${entityPackage}/${entityName?uncap_first}/importExcel",
},
}
},
computed: {
importExcelUrl: function(){
<#noparse>return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;</#noparse>
}
},
methods: {
clickThenCheck(record) {
return {
on: {
click: () => {
this.onSelectChange(record.id.split(","), [record]);
}
}
};
},
onSelectChange(selectedRowKeys, selectionRows) {
this.selectedRowKeys = selectedRowKeys;
this.selectionRows = selectionRows;
<#list subTables as sub><#rt/>
this.$refs.${sub.entityName}List.getMain(this.selectedRowKeys[0]);
</#list>
},
onClearSelected() {
this.selectedRowKeys = [];
this.selectionRows = [];
<#list subTables as sub><#rt/>
this.$refs.${sub.entityName}List.queryParam.mainId = null;
this.$refs.${sub.entityName}List.loadData();
this.$refs.${sub.entityName}List.selectedRowKeys = [];
this.$refs.${sub.entityName}List.selectionRows = [];
</#list>
},
handleDelete: function (id) {
var that = this;
deleteAction(that.url.delete, {id: id}).then((res) => {
if (res.success) {
that.$message.success(res.message);
that.loadData();
<#list subTables as sub><#rt/>
this.$refs.${sub.entityName}List.loadData();
</#list>
} else {
that.$message.warning(res.message);
}
});
},
searchQuery:function(){
this.selectedRowKeys = [];
this.selectionRows = [];
<#list subTables as sub><#rt/>
this.$refs.${sub.entityName}List.queryParam.mainId = null;
this.$refs.${sub.entityName}List.loadData();
this.$refs.${sub.entityName}List.selectedRowKeys = [];
this.$refs.${sub.entityName}List.selectionRows = [];
</#list>
this.loadData();
}
}
}
</script>
<style scoped>
@import '~@assets/less/common.less'
</style>

View File

@ -0,0 +1,140 @@
<#list subTables as subTab>
#segment#${subTab.entityName}List.vue
<template>
<a-card :bordered="false">
<!-- 操作按钮区域 -->
<div class="table-operator" :md="24" :sm="24" style="margin: 0px 0px 20px 0px">
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel">
<a-icon type="delete"/>删除
</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px"> 批量操作
<a-icon type="down"/>
</a-button>
</a-dropdown>
</div>
<!-- table区域-begin -->
<div>
<div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
<i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
<a style="margin-left: 24px" @click="onClearSelected">清空</a>
</div>
<a-table
ref="table"
size="middle"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@change="handleTableChange">
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical"/>
<a-dropdown>
<a class="ant-dropdown-link">
更多 <a-icon type="down"/>
</a>
<a-menu slot="overlay">
<a-menu-item>
<a href="javascript:;" @click="handleDetail(record)">详情</a>
</a-menu-item>
<a-menu-item>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
<a>删除</a>
</a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
</span>
</a-table>
</div>
<!-- table区域-end -->
<!-- 表单区域 -->
<${subTab.entityName}-modal ref="modalForm" @ok="modalFormOk"/>
</a-card>
</template>
<script>
import ${subTab.entityName}Modal from './modules/${subTab.entityName}Modal'
import {JeecgListMixin} from '@/mixins/JeecgListMixin'
import {getAction} from '@/api/manage'
export default {
name: "${subTab.entityName}List",
mixins: [JeecgListMixin],
components: {
${subTab.entityName}Modal,
},
data() {
return {
description: '信息',
// 表头
columns: [
<#list subTab.colums as po><#rt/>
<#if po.fieldName !='id' && subTab.foreignKeys[0]?uncap_first != po.fieldName>
{
title: '${po.filedComment}',
align:"center",
dataIndex: '${po.fieldName}'
},
</#if>
</#list>
{
title: '操作',
key: 'operation',
align: "center",
width: 130,
scopedSlots: {customRender: 'action'},
}],
url: {
list: "/${entityPackage}/${entityName?uncap_first}/list${subTab.entityName}ByMainId",
delete: "/${entityPackage}/${entityName?uncap_first}/delete${subTab.entityName}",
deleteBatch: "/${entityPackage}/${entityName?uncap_first}/deleteBatch${subTab.entityName}",
}
}
},
methods: {
loadData(arg) {
if (arg === 1) {
this.ipagination.current = 1;
}
var params = this.getQueryParams();
getAction(this.url.list, {mainId: params.mainId}).then((res) => {
if (res.success) {
this.dataSource = res.result;
} else {
this.dataSource = null;
}
})
},
getMain(mainId) {
this.queryParam.mainId = mainId;
this.loadData(1);
},
handleAdd: function () {
this.$refs.modalForm.add(this.queryParam.mainId);
this.$refs.modalForm.title = "添加${subTab.ftlDescription}";
},
}
}
</script>
<style scoped>
.ant-card {
margin-left: -30px;
margin-right: -30px;
}
</style>
</#list>

View File

@ -0,0 +1,167 @@
<template>
<a-modal
:title="title"
:width="1000"
:visible="visible"
:confirmLoading="confirmLoading"
@ok="handleOk"
@cancel="handleCancel">
<a-spin :spinning="confirmLoading">
<!-- 主表单区域 -->
<a-form :form="form">
<#list columns as po><#rt/>
<#if po.fieldName !='id'><#rt/>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="${po.filedComment}">
<#if po.fieldType =='date'>
<a-date-picker v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<#elseif po.fieldType =='datetime'>
<a-date-picker showTime format="YYYY-MM-DD HH:mm:ss" v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<#elseif "int,decimal,double,"?contains(po.fieldType)>
<a-input-number v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<#else>
<a-input placeholder="请输入${po.filedComment}" v-decorator="['${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
</#if>
</a-form-item>
</#if>
</#list>
</a-form>
</a-spin>
</a-modal>
</template>
<script>
import {httpAction} from '@/api/manage'
import JDate from '@/components/jeecg/JDate'
import pick from 'lodash.pick'
import moment from "moment"
export default {
name: '${entityName}Modal',
components: {
JDate
},
data() {
return {
title: "操作",
visible: false,
model: {},
labelCol: {
xs: {span: 24},
sm: {span: 5},
},
wrapperCol: {
xs: {span: 24},
sm: {span: 16},
},
confirmLoading: false,
form: this.$form.createForm(this),
validatorRules: {
<#list columns as po>
<#if po.fieldName !='id'>
<#if po.nullable =='N'>
${po.fieldName}: { rules: [{ required: true, message: '请输入${po.filedComment}!' }] },
</#if>
</#if>
</#list>
},
url: {
add: "/${entityPackage}/${entityName?uncap_first}/add",
edit: "/${entityPackage}/${entityName?uncap_first}/edit",
<#list subTables as sub><#rt/>
${sub.entityName?uncap_first}List: '/${entityPackage}/${entityName?uncap_first}/query${sub.entityName}ByMainId',
</#list>
}
}
},
methods: {
add() {
this.edit({});
},
edit(record) {
this.form.resetFields();
this.model = Object.assign({}, record);
//初始化明细表数据
console.log(this.model.id)
this.visible = true;
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model, <#list columns as col>'${col.fieldName}', </#list>))
// 时间格式化
<#list columns as col><#rt/>
<#if col.fieldName !='id' && (col.fieldType =='date' || col.fieldType =='datetime')>
this.form.setFieldsValue({ ${col.fieldName}: this.model.${col.fieldName} ? moment(this.model.${col.fieldName}) : null })
</#if>
</#list>
});
},
close() {
this.$emit('close');
this.visible = false;
},
handleOk() {
const that = this;
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
that.confirmLoading = true;
let httpurl = '';
let method = '';
if (!this.model.id) {
httpurl += this.url.add;
method = 'post';
} else {
httpurl += this.url.edit;
method = 'put';
}
let formData = Object.assign(this.model, values);
//时间格式化
<#list columns as po>
<#if po.fieldName !='id' && po.fieldType =='date'>
formData.${po.fieldName} = formData.${po.fieldName}?formData.${po.fieldName}.format():null;
<#elseif po.fieldName !='id' && po.fieldType =='datetime'>
formData.${po.fieldName} = formData.${po.fieldName}?formData.${po.fieldName}.format('YYYY-MM-DD HH:mm:ss'):null;
</#if>
</#list>
httpAction(httpurl, formData, method).then((res) => {
if (res.success) {
that.$message.success(res.message);
that.$emit('ok');
} else {
that.$message.warning(res.message);
}
}).finally(() => {
that.confirmLoading = false;
that.close();
})
}
})
},
handleCancel() {
this.close()
}
}
}
</script>
<style scoped>
.ant-btn {
padding: 0 10px;
margin-left: 3px;
}
.ant-form-item-control {
line-height: 0px;
}
/** 主表单行间距 */
.ant-form .ant-form-item {
margin-bottom: 10px;
}
/** Tab页面行间距 */
.ant-tabs-content .ant-form-item {
margin-bottom: 0px;
}
</style>

View File

@ -0,0 +1,183 @@
<#list subTables as subTab>
#segment#${subTab.entityName}Modal.vue
<template>
<a-modal
:title="title"
:width="800"
:visible="visible"
:okButtonProps="{ props: {disabled: disableSubmit} }"
:confirmLoading="confirmLoading"
@ok="handleOk"
@cancel="handleCancel"
cancelText="关闭">
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<#list subTab.colums as po><#rt/>
<#if po.fieldName !='id'><#rt/>
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="${po.filedComment}"
<#if subTab.foreignKeys[0]?uncap_first == po.fieldName>
:hidden="hiding"
</#if>
hasFeedback>
<#if po.fieldType =='date'>
<a-date-picker v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<#elseif po.fieldType =='datetime'>
<a-date-picker showTime format="YYYY-MM-DD HH:mm:ss" v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<#elseif "int,decimal,double,"?contains(po.fieldType)>
<a-input-number v-decorator="[ '${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
<#else>
<#if subTab.foreignKeys[0]?uncap_first == po.fieldName>
<a-input placeholder="请输入${po.filedComment}" v-decorator="['${po.fieldName}', {'initialValue':this.mainId}]" />
<#else>
<a-input placeholder="请输入${po.filedComment}" v-decorator="['${po.fieldName}', <#if po.nullable =='N'>validatorRules.${po.fieldName} <#else>{}</#if>]" />
</#if>
</#if>
</a-form-item>
</#if>
</#list>
</a-form>
</a-spin>
</a-modal>
</template>
<script>
import {httpAction} from '@/api/manage'
import pick from 'lodash.pick'
import moment from 'moment'
import JDate from '@/components/jeecg/JDate'
export default {
components: {
JDate
},
name: '${subTab.entityName}Modal',
data() {
return {
title: '操作',
visible: false,
model: {},
labelCol: {
xs: {span: 24},
sm: {span: 5}
},
wrapperCol: {
xs: {span: 24},
sm: {span: 16}
},
moment,
format: 'YYYY-MM-DD HH:mm:ss',
disableSubmit: false,
mainId: '',
hiding: false,
confirmLoading: false,
form: this.$form.createForm(this),
validatorRules: {
<#list subTab.colums as po>
<#if po.fieldName !='id' && subTab.foreignKeys[0]?uncap_first != po.fieldName>
<#if po.nullable =='N'>
${po.fieldName}: { rules: [{ required: true, message: '请输入${po.filedComment}!' }] },
</#if>
</#if>
</#list>
},
url: {
add: '/${entityPackage}/${entityName?uncap_first}/add${subTab.entityName}',
edit: '/${entityPackage}/${entityName?uncap_first}/edit${subTab.entityName}'
}
}
},
created() {
},
methods: {
add(mainId) {
if (mainId) {
this.edit({mainId}, '')
} else {
this.$message.warning('请选择一条数据')
}
},
detail(record) {
this.edit(record, 'd')
},
edit(record, v) {
if (v == 'e') {
this.hiding = false;
this.disableSubmit = false;
} else if (v == 'd') {
this.hiding = false;
this.disableSubmit = true;
} else {
this.hiding = true;
this.disableSubmit = false;
}
this.form.resetFields();
this.mainId = record.mainId;
this.model = Object.assign({}, record);
this.visible = true;
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model, <#list subTab.colums as col>'${col.fieldName}', </#list>))
// 时间格式化
<#list subTab.colums as col><#rt/>
<#if col.fieldName !='id' && (col.fieldType =='date' || col.fieldType =='datetime')>
this.form.setFieldsValue({ ${col.fieldName}: this.model.${col.fieldName} ? moment(this.model.${col.fieldName}) : null })
</#if>
</#list>
})
},
close() {
this.$emit('close');
this.visible = false;
},
handleOk() {
const that = this;
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
that.confirmLoading = true;
let httpurl = '';
let method = '';
if (!this.model.id) {
httpurl += this.url.add;
method = 'post';
} else {
httpurl += this.url.edit;
method = 'put';
}
let formData = Object.assign(this.model, values);
//时间格式化
<#list subTab.colums as po>
<#if po.fieldName !='id' && po.fieldType =='date'>
formData.${po.fieldName} = formData.${po.fieldName}?formData.${po.fieldName}.format():null;
<#elseif po.fieldName !='id' && po.fieldType =='datetime'>
formData.${po.fieldName} = formData.${po.fieldName}?formData.${po.fieldName}.format('YYYY-MM-DD HH:mm:ss'):null;
</#if>
</#list>
httpAction(httpurl, formData, method).then((res) => {
if (res.success) {
that.$message.success(res.message);
that.$emit('ok');
} else {
that.$message.warning(res.message);
}
}).finally(() => {
that.confirmLoading = false;
that.close();
})
}
})
},
handleCancel() {
this.close();
}
}
}
</script>
<style scoped>
</style>
</#list>

View File

@ -0,0 +1,30 @@
#code_generate_project_path
project_path=E:\\eclipse2018-workspace\\jeecg-boot
#bussi_package[User defined]
bussi_package=org.jeecg.modules.demo
#default code path
#source_root_package=src
#webroot_package=WebRoot
#maven code path
source_root_package=src.main.java
webroot_package=src.main.webapp
#ftl resource url
templatepath=/jeecg/code-template
system_encoding=utf-8
#db Table id [User defined]
db_table_id=id
#db convert flag[true/false]
db_filed_convert=true
#page Search Field num [User defined]
page_search_filed_num=1
#page_filter_fields
page_filter_fields=create_time,create_by,update_time,update_by

View File

@ -0,0 +1,27 @@
#mysql
diver_name=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jeecg-boot?useUnicode=true&characterEncoding=UTF-8
username=root
password=root
database_name=jeecg-boot
#oracle
#diver_name=oracle.jdbc.driver.OracleDriver
#url=jdbc:oracle:thin:@192.168.1.200:1521:ORCL
#username=scott
#password=tiger
#database_name=ORCL
#postgre
#diver_name=org.postgresql.Driver
#url=jdbc:postgresql://localhost:5432/jeecg
#username=postgres
#password=postgres
#database_name=jeecg
#SQLServer2005\u4ee5\u4e0a
#diver_name=org.hibernate.dialect.SQLServerDialect
#url=jdbc:sqlserver://192.168.1.200:1433;DatabaseName=jeecg
#username=sa
#password=SA
#database_name=jeecg

View File

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!--定义日志文件的存储地址 -->
<property name="LOG_HOME" value="../logs" />
<property name="COLOR_PATTERN" value="%black(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta( %replace(%caller{1}){'\t|Caller.{1}0|\r\n', ''})- %gray(%msg%xEx%n)" />
<!-- 控制台输出 -->
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
<encoder
class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期%thread表示线程名%-5level级别从左显示5个字符宽度%msg日志消息%n是换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern>
</encoder>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名 -->
<FileNamePattern>${LOG_HOME}/jeecgboot.%d{yyyy-MM-dd}.log
</FileNamePattern>
<!--日志文件保留天数 -->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder
class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期%thread表示线程名%-5level级别从左显示5个字符宽度%msg日志消息%n是换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern>
</encoder>
<!--日志文件最大的大小 -->
<triggeringPolicy
class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- 生成html格式日志开始 -->
<appender name="HTML" class="ch.qos.logback.core.FileAppender">
<!-- 过滤器只记录WARN级别的日志 -->
<!-- <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>info</level>
<onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> -->
<encoder
class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="ch.qos.logback.classic.html.HTMLLayout">
<pattern>%p%d%msg%M%F{32}%L</pattern>
</layout>
</encoder>
<file>${LOG_HOME}/error-log.html</file>
</appender>
<!-- 生成html格式日志结束 -->
<!-- 每天生成一个html格式的日志开始 -->
<appender name="FILE_HTML"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名 -->
<FileNamePattern>${LOG_HOME}/jeecgboot.%d{yyyy-MM-dd}.html
</FileNamePattern>
<!--日志文件保留天数 -->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder
class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="ch.qos.logback.classic.html.HTMLLayout">
<pattern>%p%d%msg%M%F{32}%L</pattern>
</layout>
</encoder>
<!--日志文件最大的大小 -->
<triggeringPolicy
class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- 每天生成一个html格式的日志结束 -->
<!--myibatis log configure -->
<logger name="com.apache.ibatis" level="TRACE" />
<logger name="java.sql.Connection" level="DEBUG" />
<logger name="java.sql.Statement" level="DEBUG" />
<logger name="java.sql.PreparedStatement" level="DEBUG" />
<!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
<appender-ref ref="HTML" />
<appender-ref ref="FILE_HTML" />
</root>
</configuration>

View File

@ -0,0 +1,177 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More