瀏覽代碼

代码生成

fanxp 1 年之前
父節點
當前提交
1bb92f8b90

+ 1 - 0
.gitignore

@@ -2,6 +2,7 @@ HELP.md
 target/
 logs/
 generator/
+null/
 !.mvn/wrapper/maven-wrapper.jar
 !**/src/main/**/target/
 !**/src/test/**/target/

+ 1 - 1
Makefile

@@ -2,7 +2,7 @@ merge:
 	git checkout master;git merge dev;git push;git checkout dev;
 
 create-tag:
-	git checkout master;git tag v1.0.8;git push origin --tags;git checkout dev;
+	git checkout master;git tag v1.0.9;git push origin --tags;git checkout dev;
 
 remove-tag:
 	git tag -d v1.0.1;git push origin :refs/tags/v1.0.1;

+ 54 - 0
src/main/resources/apiTemplates/add.dto.java.ftl

@@ -0,0 +1,54 @@
+package ${package};
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.io.Serializable;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import java.util.List;
+<#--子表遍历-->
+<#if childTables?? >
+    <#list childTables as childTable>
+import com.xjrsoft.module.${outputArea}.entity.${childTable.tableName?cap_first};
+    </#list>
+</#if>
+
+
+
+/**
+* @title: ${tableComment}
+* @Author ${author}
+* @Date: ${date}
+* @Version 1.0
+*/
+@Data
+public class Add${entityClass}Dto implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+<#--属性遍历-->
+<#list fields as field>
+    /**
+    * ${field.fieldComment}
+    */
+    @ApiModelProperty("${field.fieldComment}")
+    <#if field.fieldType == "LocalDateTime" && field.pattern??>
+    @JsonFormat(pattern = "${field.pattern}")
+    </#if>
+    private ${field.fieldType} ${field.fieldName};
+</#list>
+
+<#--子表遍历-->
+<#if childTables?? >
+<#list childTables as childTable>
+    /**
+    * ${childTable.tableName}
+    */
+    @ApiModelProperty("${childTable.tableName}子表")
+    private List<Add${childTable.tableName?cap_first}Dto> ${childTable.tableName?uncap_first}List;
+</#list>
+</#if>
+}

+ 254 - 0
src/main/resources/apiTemplates/controller.java.ftl

@@ -0,0 +1,254 @@
+package ${package};
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.xjrsoft.common.constant.GlobalConstant;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.xjrsoft.common.page.ConventPage;
+import com.xjrsoft.common.page.PageOutput;
+import com.xjrsoft.common.model.result.R;
+import com.xjrsoft.common.utils.VoToColumnUtil;
+import com.xjrsoft.module.${outputArea}.dto.Add${entityClass}Dto;
+import com.xjrsoft.module.${outputArea}.dto.Update${entityClass}Dto;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+<#if codeRules != "">
+    import com.xjrsoft.module.system.service.ICodeRuleService;
+</#if>
+<#if isImport || isExport>
+import com.alibaba.excel.EasyExcel;
+</#if>
+<#if isImport>
+import org.springframework.web.multipart.MultipartFile;
+import java.io.IOException;
+</#if>
+<#if isExport>
+import com.alibaba.excel.support.ExcelTypeEnum;
+import org.springframework.http.ResponseEntity;
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+</#if>
+
+<#if !isPage>
+import com.xjrsoft.module.${outputArea}.dto.${entityClass}ListDto;
+<#else>
+import com.xjrsoft.module.${outputArea}.dto.${entityClass}PageDto;
+</#if>
+import com.xjrsoft.module.${outputArea}.entity.${entityClass};
+import com.xjrsoft.module.${outputArea}.service.I${className}Service;
+<#if !isPage>
+import com.xjrsoft.module.${outputArea}.vo.${entityClass}ListVo;
+<#else>
+import com.xjrsoft.module.${outputArea}.vo.${entityClass}PageVo;
+</#if>
+<#if isDataAuth>
+import com.xjrsoft.module.authority.dto.BatchSetDataAuthDto;
+import java.util.stream.Collectors;
+import java.util.ArrayList;
+</#if>
+
+import com.xjrsoft.module.${outputArea}.vo.${entityClass}Vo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+* @title: ${tableComment}
+* @Author ${author}
+* @Date: ${date}
+* @Version 1.0
+*/
+@RestController
+@RequestMapping("/${outputArea}" + "/${className?lower_case}")
+@Api(value = "/${outputArea}"  + "/${className?lower_case}",tags = "${tableComment}代码")
+@AllArgsConstructor
+public class ${className}Controller {
+
+
+    private final I${className}Service ${className?uncap_first}Service;
+<#if codeRules != "">
+    private final ICodeRuleService codeRuleService;
+</#if>
+
+<#if !isPage>
+    @GetMapping(value = "/list")
+    @ApiOperation(value="${entityClass}列表(不分页)")
+    @SaCheckPermission("${className?lower_case}:detail")
+    public R list(@Valid ${entityClass}ListDto dto){
+
+        LambdaQueryWrapper<${entityClass}> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper
+            <#--属性遍历-->
+            <#list fields as field>
+                <#if field.fieldType == "String">
+                    .like(StrUtil.isNotBlank(dto.get${field.fieldName?cap_first}()),${entityClass}::get${field.fieldName?cap_first},dto.get${field.fieldName?cap_first}())
+                <#elseif field.fieldType == "Integer" || field.fieldType == "Long"|| field.fieldType == "Double"|| field.fieldType == "Float"|| field.fieldType == "Boolean"|| field.fieldType == "BigDecimal" >
+                    .eq(ObjectUtil.isNotNull(dto.get${field.fieldName?cap_first}()),${entityClass}::get${field.fieldName?cap_first},dto.get${field.fieldName?cap_first}())
+                <#elseif field.fieldType == "LocalDateTime" || field.fieldType == "LocalTime">
+                    .between(ObjectUtil.isNotNull(dto.get${field.fieldName?cap_first}Start()) && ObjectUtil.isNotNull(dto.get${field.fieldName?cap_first}End()),${entityClass}::get${field.fieldName?cap_first},dto.get${field.fieldName?cap_first}Start(),dto.get${field.fieldName?cap_first}End())
+                <#else>
+                    .like(StrUtil.isNotBlank(dto.get${field.fieldName?cap_first}()),${entityClass}::get${field.fieldName?cap_first},dto.get${field.fieldName?cap_first}())
+                </#if>
+            </#list>
+                <#--默认排序-->
+                <#if orderField?? && orderField != "">
+                    <#if orderType>
+                    .orderByDesc(${entityClass}::get${orderField?cap_first})
+                    <#else>
+                    .orderByAsc(${entityClass}::get${orderField?cap_first})
+                    </#if>
+<#--                    如果需要根据前端所传字段排序 屏蔽上面  放开下面-->
+<#--                    .orderBy(StrUtil.isBlank(dto.getOrderField()),${orderType?string("false","true")},${entityClass}::get${orderField?cap_first})-->
+<#--                    .last(StrUtil.isNotBlank(dto.getOrderField()) && StrUtil.isNotBlank(dto.getOrder()),"order by " + dto.getOrderField() + StringPool.SPACE + dto.getOrder())-->
+                </#if>
+                    .select(${entityClass}.class,x -> VoToColumnUtil.fieldsToColumns(${entityClass}ListVo.class).contains(x.getProperty()));
+
+        List<${entityClass}> list = ${className?uncap_first}Service.list(queryWrapper);
+        List<${entityClass}ListVo> listVos = BeanUtil.copyToList(list, ${entityClass}ListVo.class);
+        return R.ok(listVos);
+    }
+<#else>
+    @GetMapping(value = "/page")
+    @ApiOperation(value="${entityClass}列表(分页)")
+    @SaCheckPermission("${className?lower_case}:detail")
+    public R page(@Valid ${entityClass}PageDto dto){
+
+        LambdaQueryWrapper<${entityClass}> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper
+        <#--属性遍历-->
+        <#list fields as field>
+            <#if field.fieldType == "String">
+                .like(StrUtil.isNotBlank(dto.get${field.fieldName?cap_first}()),${entityClass}::get${field.fieldName?cap_first},dto.get${field.fieldName?cap_first}())
+            <#elseif field.fieldType == "Integer" || field.fieldType == "Long"|| field.fieldType == "Double"|| field.fieldType == "Float"|| field.fieldType == "Boolean" || field.fieldType == "BigDecimal" >
+                .eq(ObjectUtil.isNotNull(dto.get${field.fieldName?cap_first}()),${entityClass}::get${field.fieldName?cap_first},dto.get${field.fieldName?cap_first}())
+            <#elseif field.fieldType == "LocalDateTime" || field.fieldType == "LocalTime">
+                .between(ObjectUtil.isNotNull(dto.get${field.fieldName?cap_first}Start()) && ObjectUtil.isNotNull(dto.get${field.fieldName?cap_first}End()),${entityClass}::get${field.fieldName?cap_first},dto.get${field.fieldName?cap_first}Start(),dto.get${field.fieldName?cap_first}End())
+            <#else>
+                .like(StrUtil.isNotBlank(dto.get${field.fieldName?cap_first}()),${entityClass}::get${field.fieldName?cap_first},dto.get${field.fieldName?cap_first}())
+            </#if>
+        </#list>
+            <#--默认排序-->
+            <#if orderField?? && orderField != "">
+                <#if orderType>
+                    .orderByDesc(${entityClass}::get${orderField?cap_first})
+                <#else>
+                    .orderByAsc(${entityClass}::get${orderField?cap_first})
+                </#if>
+<#--                .orderBy(StrUtil.isBlank(dto.getOrderField()),${orderType?string("false","true")},${entityClass}::get${orderField?cap_first})-->
+            </#if>
+                .select(${entityClass}.class,x -> VoToColumnUtil.fieldsToColumns(${entityClass}PageVo.class).contains(x.getProperty()));
+        IPage<${entityClass}> page = ${className?uncap_first}Service.page(ConventPage.getPage(dto), queryWrapper);
+        PageOutput<${entityClass}PageVo> pageOutput = ConventPage.getPageOutput(page, ${entityClass}PageVo.class);
+        return R.ok(pageOutput);
+    }
+</#if>
+
+    @GetMapping(value = "/info")
+    @ApiOperation(value="根据id查询${entityClass}信息")
+    @SaCheckPermission("${className?lower_case}:detail")
+    public R info(@RequestParam Long id){
+        ${entityClass} ${entityClass?uncap_first} = ${className?uncap_first}Service.${isMulti?string("getByIdDeep","getById")}(id);
+        if (${entityClass?uncap_first} == null) {
+           return R.error("找不到此数据!");
+        }
+        return R.ok(BeanUtil.toBean(${entityClass?uncap_first}, ${entityClass}Vo.class));
+    }
+
+
+    @PostMapping
+    @ApiOperation(value = "新增${entityClass}")
+    @SaCheckPermission("${className?lower_case}:add")
+    public R add(@Valid @RequestBody Add${entityClass}Dto dto){
+    <#if isMulti>
+        ${entityClass} ${entityClass?uncap_first} = BeanUtil.toBean(dto, ${entityClass}.class);
+        boolean isSuccess = ${className?uncap_first}Service.add(${entityClass?uncap_first});
+    <#else >
+        ${entityClass} ${entityClass?uncap_first} = BeanUtil.toBean(dto, ${entityClass}.class);
+        boolean isSuccess = ${className?uncap_first}Service.save(${entityClass?uncap_first});
+    </#if>
+    <#if codeRules != "">
+        codeRuleService.useEncode("${codeRules}");
+    </#if>
+    return R.ok(isSuccess);
+    }
+
+    @PutMapping
+    @ApiOperation(value = "修改${entityClass}")
+    @SaCheckPermission("${className?lower_case}:edit")
+    public R update(@Valid @RequestBody Update${entityClass}Dto dto){
+
+    <#if isMulti>
+        ${entityClass} ${entityClass?uncap_first} = BeanUtil.toBean(dto, ${entityClass}.class);
+        return R.ok(${className?uncap_first}Service.update(${entityClass?uncap_first}));
+    <#else >
+        ${entityClass} ${entityClass?uncap_first} = BeanUtil.toBean(dto, ${entityClass}.class);
+        return R.ok(${className?uncap_first}Service.updateById(${entityClass?uncap_first}));
+    </#if>
+
+    }
+
+    @DeleteMapping
+    @ApiOperation(value = "删除")
+    @SaCheckPermission("${className?lower_case}:delete")
+    public R delete(@Valid @RequestBody List<Long> ids){
+    <#if isMulti>
+        return R.ok(${className?uncap_first}Service.delete(ids));
+    <#else >
+        return R.ok(${className?uncap_first}Service.removeBatchByIds(ids));
+    </#if>
+
+    }
+<#if isPage>
+<#assign importClass = "${entityClass}Page">
+<#else>
+<#assign importClass = "${entityClass}List">
+</#if>
+<#if isImport>
+    @PostMapping("/import")
+    @ApiOperation(value = "导入")
+    public R importData(@RequestParam MultipartFile file) throws IOException {
+        List<${importClass}Vo> savedDataList = EasyExcel.read(file.getInputStream()).head(${importClass}Vo.class).sheet().doReadSync();
+        ${className?uncap_first}Service.saveBatch(BeanUtil.copyToList(savedDataList, ${entityClass}.class));
+        return R.ok();
+    }
+</#if>
+
+<#if isExport>
+    @GetMapping("/export")
+    @ApiOperation(value = "导出")
+    public ResponseEntity<byte[]> exportData(@Valid ${importClass}Dto dto, @RequestParam(defaultValue = "false") Boolean isTemplate) {
+<#if isPage>
+        List<${importClass}Vo> customerList = isTemplate != null && isTemplate ? new ArrayList<>() : ((PageOutput<${importClass}Vo>) page(dto).getData()).getList();
+<#else>
+        List<${importClass}Vo> customerList = (List<${importClass}Vo>) list(dto).getData();
+</#if>
+        ByteArrayOutputStream bot = new ByteArrayOutputStream();
+        EasyExcel.write(bot, ${importClass}Vo.class).automaticMergeHead(false).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(customerList);
+
+        return R.fileStream(bot.toByteArray(), "${className}" + ExcelTypeEnum.XLSX.getValue());
+    }
+</#if>
+<#if isDataAuth>
+    @PutMapping("/data-auth")
+    @ApiOperation(value = "批量设置权限所属人")
+    public R setDataAUth(@RequestBody BatchSetDataAuthDto dto){
+        List<${entityClass}> toUpdateList = new ArrayList<>();
+<#--        String userIdStr = dto.getUserIdList().stream().collect(Collectors.joining(StringPool.COMMA));-->
+        for (Long dataId : dto.getDataIdList()) {
+            ${entityClass} ${entityClass?uncap_first} = new ${entityClass}();
+            ${entityClass?uncap_first}.set${pkField?cap_first}(dataId);
+            ${entityClass?uncap_first}.setRuleUserId(dto.getUserIdList().get(0));
+            toUpdateList.add(${entityClass?uncap_first});
+        }
+        return R.ok(${className?uncap_first}Service.updateBatchById(toUpdateList));
+    }
+</#if>
+}

+ 17 - 0
src/main/resources/apiTemplates/mapper.java.ftl

@@ -0,0 +1,17 @@
+package ${package};
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.github.yulichang.base.MPJBaseMapper;
+import com.xjrsoft.module.${outputArea}.entity.${entityClass};
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @title: ${tableComment}
+* @Author ${author}
+* @Date: ${date}
+* @Version 1.0
+*/
+@Mapper
+public interface ${entityClass}Mapper extends ${isMulti?string("MPJBaseMapper","BaseMapper")}<${entityClass}> {
+
+}

+ 36 - 0
src/main/resources/apiTemplates/page.list.dto.java.ftl

@@ -0,0 +1,36 @@
+package ${package};
+
+${isPage?string("import com.xjrsoft.common.page.PageInput;","import com.xjrsoft.common.page.ListInput;")}
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+
+
+/**
+* @title: ${tableComment}
+* @Author ${author}
+* @Date: ${date}
+* @Version 1.0
+*/
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class ${entityClass}${isPage?string("Page","List")}Dto ${isPage?string("extends PageInput","extends ListInput")} {
+
+<#--属性遍历-->
+<#list fields as field>
+    /**
+    * ${field.fieldComment}
+    */
+    @ApiModelProperty("${field.fieldComment}")
+    <#if field.fieldType == "LocalDateTime" >
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    </#if>
+    private ${field.fieldType} ${field.fieldName};
+</#list>
+
+}

+ 74 - 0
src/main/resources/apiTemplates/page.list.vo.java.ftl

@@ -0,0 +1,74 @@
+package ${package};
+
+<#if isImport || isExport>
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.write.style.ContentStyle;
+</#if>
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import com.xjrsoft.common.annotation.Trans;
+import com.xjrsoft.common.enums.TransType;
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+
+/**
+* @title: ${tableComment}
+* @Author ${author}
+* @Date: ${date}
+* @Version 1.0
+*/
+@Data
+public class ${entityClass}${isPage?string("Page","List")}Vo {
+
+<#--属性遍历-->
+<#list fields as field>
+    /**
+    * ${field.fieldComment}
+    */
+    <#if !(field.pk || field.fieldName == "ruleUserId")>
+    <#if isImport || isExport>
+<#--    所有单元格设置成文本格式-->
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("${field.label}")
+    </#if>
+    <#else>
+    <#if isImport || isExport>
+    @ExcelIgnore
+    </#if>
+    </#if>
+    @ApiModelProperty("${field.fieldComment}")
+    <#if field.fieldType == "LocalDateTime"  && field.pattern??>
+    @JsonFormat(pattern = "${field.pattern}")
+    </#if>
+    <#if field.datasourceType??>
+        <#assign multi = "">
+        <#if field.multi><#assign multi = ", isMulti = true"></#if>
+        <#if field.datasourceType = "dic">
+    @Trans(type = TransType.DIC, id = "${field.datasourceId}"${multi})
+        </#if>
+        <#if field.datasourceType = "api">
+    @Trans(type = TransType.API, id = "${field.datasourceId}"${multi})
+        </#if>
+    </#if>
+    <#if field.componentType??>
+        <#if field.componentType = "user">
+    @Trans(type = TransType.USER)
+        </#if>
+        <#if field.componentType = "organization">
+    @Trans(type = TransType.DEPT)
+        </#if>
+        <#if field.componentType = "area">
+    @Trans(type = TransType.AREA)
+        </#if>
+        <#if field.componentType = "cascader">
+    @Trans(type = TransType.CASCADE, id = "${field.datasourceId}", separator = "${field.separator}", showFormat = "${field.showFormat}")
+        </#if>
+    </#if>
+    private ${field.fieldType} ${field.fieldName};
+</#list>
+
+}

+ 113 - 0
src/main/resources/apiTemplates/service.impl.java.ftl

@@ -0,0 +1,113 @@
+package ${package};
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.github.yulichang.base.MPJBaseServiceImpl;
+<#if isMulti>
+        <#--子表遍历-->
+    <#list childTables as childTable>
+import com.xjrsoft.module.${outputArea}.entity.${childTable.tableName?cap_first};
+import com.xjrsoft.module.${outputArea}.mapper.${childTable.tableName?cap_first}Mapper;
+    </#list>
+</#if>
+import com.xjrsoft.module.${outputArea}.entity.${entityClass};
+import com.xjrsoft.module.${outputArea}.mapper.${entityClass}Mapper;
+import com.xjrsoft.module.${outputArea}.service.I${className}Service;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+<#if databaseId?? && databaseId != "master">
+import com.baomidou.dynamic.datasource.annotation.DS;
+</#if>
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+
+/**
+* @title: ${tableComment}
+* @Author ${author}
+* @Date: ${date}
+* @Version 1.0
+*/
+@Service
+@AllArgsConstructor
+<#if databaseId?? && databaseId != "master">
+@DS("${databaseId}")
+</#if>
+public class ${className}ServiceImpl extends ${isMulti?string("MPJBaseService","Service")}Impl<${entityClass}Mapper, ${entityClass}> implements I${className}Service {
+<#if isMulti>
+    private final ${entityClass}Mapper ${className?uncap_first}${entityClass}Mapper;
+
+    <#--子表遍历-->
+    <#list childTables as childTable>
+    private final ${childTable.tableName?cap_first}Mapper ${className?uncap_first}${childTable.tableName?cap_first}Mapper;
+    </#list>
+
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean add(${entityClass} ${entityClass?uncap_first}) {
+        ${className?uncap_first}${entityClass}Mapper.insert(${entityClass?uncap_first});
+    <#--子表遍历-->
+    <#list childTables as childTable>
+        for (${childTable.tableName?cap_first} ${childTable.tableName} : ${entityClass?uncap_first}.get${childTable.tableName?cap_first}List()) {
+            ${childTable.tableName}.set${childTable.relationField?cap_first}(${entityClass?uncap_first}.get${childTable.relationTableField?cap_first}());
+            ${className?uncap_first}${childTable.tableName?cap_first}Mapper.insert(${childTable.tableName});
+        }
+    </#list>
+
+        return true;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean update(${entityClass} ${entityClass?uncap_first}) {
+        ${className?uncap_first}${entityClass}Mapper.updateById(${entityClass?uncap_first});
+    <#--子表遍历-->
+    <#list childTables as childTable>
+        //********************************* ${childTable.tableName?cap_first}  增删改  开始 *******************************************/
+        {
+            // 查出所有子级的id
+            List<${childTable.tableName?cap_first}> ${childTable.tableName}List = ${className?uncap_first}${childTable.tableName?cap_first}Mapper.selectList(Wrappers.lambdaQuery(${childTable.tableName?cap_first}.class).eq(${childTable.tableName?cap_first}::get${childTable.relationField?cap_first}, ${entityClass?uncap_first}.get${childTable.relationTableField?cap_first}()).select(${childTable.tableName?cap_first}::get${childTable.pkField?cap_first}));
+            List<${childTable.pkType}> ${childTable.tableName}Ids = ${childTable.tableName}List.stream().map(${childTable.tableName?cap_first}::get${childTable.pkField?cap_first}).collect(Collectors.toList());
+            //原有子表单 没有被删除的主键
+            List<${childTable.pkType}> ${childTable.tableName}OldIds = ${entityClass?uncap_first}.get${childTable.tableName?cap_first}List().stream().map(${childTable.tableName?cap_first}::get${childTable.pkField?cap_first}).filter(Objects::nonNull).collect(Collectors.toList());
+            //找到需要删除的id
+            List<${childTable.pkType}> ${childTable.tableName}RemoveIds = ${childTable.tableName}Ids.stream().filter(item -> !${childTable.tableName}OldIds.contains(item)).collect(Collectors.toList());
+
+            for (${childTable.tableName?cap_first} ${childTable.tableName} : ${entityClass?uncap_first}.get${childTable.tableName?cap_first}List()) {
+                //如果不等于空则修改
+                if (${childTable.tableName}.get${childTable.pkField?cap_first}() != null) {
+                    ${className?uncap_first}${childTable.tableName?cap_first}Mapper.updateById(${childTable.tableName});
+                }
+                //如果等于空 则新增
+                else {
+                    //已经不存在的id 删除
+                    ${childTable.tableName}.set${childTable.relationField?cap_first}(${entityClass?uncap_first}.get${childTable.relationTableField?cap_first}());
+                    ${className?uncap_first}${childTable.tableName?cap_first}Mapper.insert(${childTable.tableName});
+                }
+            }
+            //已经不存在的id 删除
+            if(${childTable.tableName}RemoveIds.size() > 0){
+                ${className?uncap_first}${childTable.tableName?cap_first}Mapper.deleteBatchIds(${childTable.tableName}RemoveIds);
+            }
+        }
+        //********************************* ${childTable.tableName?cap_first}  增删改  结束 *******************************************/
+
+    </#list>
+        return true;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean delete(List<Long> ids) {
+        ${className?uncap_first}${entityClass}Mapper.deleteBatchIds(ids);
+    <#--子表遍历-->
+    <#list childTables as childTable>
+        ${className?uncap_first}${childTable.tableName?cap_first}Mapper.delete(Wrappers.lambdaQuery(${childTable.tableName?cap_first}.class).in(${childTable.tableName?cap_first}::get${childTable.relationField?cap_first}, ids));
+    </#list>
+
+        return true;
+    }
+</#if>
+}

+ 42 - 0
src/main/resources/apiTemplates/service.java.ftl

@@ -0,0 +1,42 @@
+package ${package};
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.github.yulichang.base.MPJBaseService;
+import com.xjrsoft.module.${outputArea}.entity.${entityClass};
+import lombok.Data;
+import java.util.List;
+
+/**
+* @title: ${tableComment}
+* @Author ${author}
+* @Date: ${date}
+* @Version 1.0
+*/
+
+public interface I${className}Service extends ${isMulti?string("MPJBaseService","IService")}<${entityClass}> {
+<#if isMulti>
+    /**
+    * 新增
+    *
+    * @param ${entityClass?uncap_first}
+    * @return
+    */
+    Boolean add(${entityClass} ${entityClass?uncap_first});
+
+    /**
+    * 更新
+    *
+    * @param ${entityClass?uncap_first}
+    * @return
+    */
+    Boolean update(${entityClass} ${entityClass?uncap_first});
+
+    /**
+    * 删除
+    *
+    * @param ids
+    * @return
+    */
+    Boolean delete(List<Long> ids);
+</#if>
+}

+ 43 - 0
src/main/resources/apiTemplates/update.dto.java.ftl

@@ -0,0 +1,43 @@
+package ${package};
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.io.Serializable;
+
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import java.util.List;
+<#--子表遍历-->
+<#if childTables?? >
+    <#list childTables as childTable>
+import com.xjrsoft.module.${outputArea}.entity.${childTable.tableName?cap_first};
+    </#list>
+</#if>
+
+
+
+/**
+* @title: ${tableComment}
+* @Author ${author}
+* @Date: ${date}
+* @Version 1.0
+*/
+@Data
+public class Update${entityClass}Dto extends Add${entityClass}Dto {
+
+    private static final long serialVersionUID = 1L;
+
+<#--属性遍历-->
+<#list fields as field>
+    /**
+    * ${field.fieldComment}
+    */
+    @ApiModelProperty("${field.fieldComment}")
+    <#if field.fieldType == "LocalDateTime" && field.pattern??>
+    @JsonFormat(pattern = "${field.pattern}")
+    </#if>
+    private ${field.fieldType} ${field.fieldName};
+</#list>
+}

+ 47 - 0
src/main/resources/apiTemplates/vo.java.ftl

@@ -0,0 +1,47 @@
+package ${package};
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import java.util.List;
+<#--子表遍历-->
+<#if childTables?? >
+    <#list childTables as childTable>
+import com.xjrsoft.module.${outputArea}.entity.${childTable.tableName?cap_first};
+    </#list>
+</#if>
+
+/**
+* @title: ${tableComment}
+* @Author ${author}
+* @Date: ${date}
+* @Version 1.0
+*/
+@Data
+public class ${entityClass}Vo {
+
+<#--属性遍历-->
+<#list fields as field>
+    /**
+    * ${field.fieldComment}
+    */
+    @ApiModelProperty("${field.fieldComment}")
+    private ${field.fieldType} ${field.fieldName};
+</#list>
+
+
+<#--子表遍历-->
+<#if childTables?? >
+<#list childTables as childTable>
+    /**
+    * ${childTable.tableName}
+    */
+    @ApiModelProperty("${childTable.tableName}子表")
+    private List<${childTable.tableName?cap_first}Vo> ${childTable.tableName}List;
+</#list>
+</#if>
+
+}

+ 13 - 139
src/test/java/com/xjrsoft/xjrsoftboot/FreeMarkerGeneratorTest.java

@@ -3,6 +3,7 @@ package com.xjrsoft.xjrsoftboot;
 import cn.dev33.satoken.secure.SaSecureUtil;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.db.ds.simple.SimpleDataSource;
 import cn.hutool.db.meta.Column;
 import cn.hutool.db.meta.MetaUtil;
 import cn.hutool.db.meta.Table;
@@ -18,6 +19,7 @@ import com.xjrsoft.module.generator.entity.FieldConfig;
 import com.xjrsoft.module.generator.entity.GeneratorConfig;
 import com.xjrsoft.module.generator.entity.TableConfig;
 import com.xjrsoft.module.generator.service.IApiGeneratorService;
+import com.xjrsoft.module.generator.service.impl.ApiGeneratorServiceImpl;
 import freemarker.template.Template;
 import freemarker.template.TemplateException;
 import lombok.AllArgsConstructor;
@@ -29,25 +31,21 @@ import org.springframework.test.context.junit4.SpringRunner;
 import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
 import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
 
+import javax.sql.DataSource;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.stream.Collectors;
 
-@SpringBootTest(classes = XjrSoftApplication.class)
 public class FreeMarkerGeneratorTest {
 
-    private static final String ENTITY_TEMPLATE_NAME = "entity.java.ftl";
-
-    @Autowired
-    private FreeMarkerConfigurer freeMarkerConfigurer;
-
-    @Autowired
-    private IApiGeneratorService apiGeneratorService;
+    private static final DataSource ds = new SimpleDataSource("jdbc:mysql://8.142.26.206:3306/tl?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true",
+            "root" , "Zwr~-f6H,u6QE^]C-AD_" );
 
     @Test
-    public void generateCodesTest(){
+    public void generateCodesTest() throws IOException {
         List<TableConfig> tableConfigs = new ArrayList<>();
         TableConfig mainTable = new TableConfig();
         mainTable.setTableName("xjr_oa_news");
@@ -73,143 +71,19 @@ public class FreeMarkerGeneratorTest {
         childTable2.setRelationTableField(GlobalConstant.DEFAULT_PK);
 
         tableConfigs.add(mainTable);
-        tableConfigs.add(childTable1);
-        tableConfigs.add(childTable2);
+//        tableConfigs.add(childTable1);
+//        tableConfigs.add(childTable2);
 
         ApiGenerateCodesDto params = new ApiGenerateCodesDto();
         params.setAuthor("fanxp");
         params.setPackageName("test");
         params.setTableConfigs(tableConfigs);
+        params.setPage(true);
+        params.setDs(ds);
 
-        apiGeneratorService.generateCodes(params);
-    }
-
-    @Test
-    public void freeMarkerTest() throws IOException, TemplateException {
-
-        List<TableConfig> tableConfigs = new ArrayList<>();
-        TableConfig mainTable = new TableConfig();
-        mainTable.setTableName("xjr_oa_news");
-        mainTable.setIsMain(true);
-        mainTable.setPkField(GlobalConstant.DEFAULT_PK);
-        mainTable.setPkType(GlobalConstant.DEFAULT_PK_TYPE);
-
-        TableConfig childTable1 = new TableConfig();
-        childTable1.setTableName("xjr_oa_news_relation");
-        childTable1.setIsMain(false);
-        childTable1.setPkField(GlobalConstant.DEFAULT_PK);
-        childTable1.setPkType(GlobalConstant.DEFAULT_PK_TYPE);
-        childTable1.setRelationField("news_id");
-        childTable1.setRelationTableField(GlobalConstant.DEFAULT_PK);
 
+        IApiGeneratorService apiGeneratorService = new ApiGeneratorServiceImpl();
 
-        TableConfig childTable2 = new TableConfig();
-        childTable2.setTableName("xjr_oa_news_relation_config");
-        childTable2.setIsMain(false);
-        childTable2.setPkField(GlobalConstant.DEFAULT_PK);
-        childTable2.setPkType(GlobalConstant.DEFAULT_PK_TYPE);
-        childTable2.setRelationField("news_id");
-        childTable2.setRelationTableField(GlobalConstant.DEFAULT_PK);
-
-        tableConfigs.add(mainTable);
-        tableConfigs.add(childTable1);
-        tableConfigs.add(childTable2);
-
-        GeneratorConfig generatorConfig = new GeneratorConfig();
-        generatorConfig.setTableConfigs(tableConfigs);
-
-
-
-        List<Table> tableInfos = new ArrayList<>();
-        for (TableConfig tableConfig : generatorConfig.getTableConfigs()) {
-            //判断是否为默认数据源
-            if (StrUtil.equalsIgnoreCase(generatorConfig.getDatabaseId(), GlobalConstant.DEFAULT_DATASOURCE_KEY)) {
-                tableInfos.add(MetaUtil.getTableMeta(DatasourceUtil.getDatasourceMaster(), tableConfig.getTableName()));
-            } else {
-                tableInfos.add(MetaUtil.getTableMeta(DatasourceUtil.getDataSource(generatorConfig.getDatabaseId()), tableConfig.getTableName()));
-            }
-        }
-
-        System.out.println(tableInfos);
-
-        Map<String, String> entityCodeMap = new HashMap<>(tableInfos.size());
-        // 遍历数据表配置 根据表明搜索表信息  然后生成代码
-        for (Table tableInfo : tableInfos) {
-            //获取表的所有字段
-            Collection<Column> columns = tableInfo.getColumns();
-            List<FieldConfig> fieldConfigList = new ArrayList<>();
-
-            for (Column column : columns) {
-                FieldConfig fieldConfig = new FieldConfig();
-
-                if (GlobalConstant.AUTO_INSERT.contains(column.getName())) {
-                    fieldConfig.setAutoInsert(true);
-                }
-
-                if (GlobalConstant.AUTO_UPDATE.contains(column.getName())) {
-                    fieldConfig.setAutoUpdate(true);
-                }
-
-                if (StrUtil.equalsIgnoreCase(column.getName(), GlobalConstant.DELETE_MARK)) {
-                    fieldConfig.setDeleteMark(true);
-                }
-                fieldConfig.setFieldComment(column.getComment());
-                fieldConfig.setPk(column.isPk());
-                fieldConfig.setFieldType(JdbcToJavaUtil.getClassName(column.getTypeEnum()));
-                fieldConfig.setFieldName(StrUtil.toCamelCase(column.getName()));
-
-                fieldConfigList.add(fieldConfig);
-
-            }
-
-
-            //如果有子表  每多一个子表  多加1个长度
-            Map<String, Object> entityMap = new HashMap<>(8);
-            entityMap.put(EntityConstant.PACKAGE, GlobalConstant.GENERATOR_DEFAULT_PATH + StringPool.DOT + "test" + StringPool.DOT + "entity");
-            entityMap.put(EntityConstant.AUTH_NAME, "fanxp");
-            entityMap.put(EntityConstant.DATE, LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
-            entityMap.put(EntityConstant.TABLE_NAME, tableInfo.getTableName());
-            entityMap.put(EntityConstant.TABLE_COMMENT, tableInfo.getComment());
-            //先将表明转换为驼峰命名 然后在转换为首字母大写
-            entityMap.put(EntityConstant.ENTITY_CLASS_NAME, StrUtil.upperFirst(StrUtil.toCamelCase(tableInfo.getTableName())));
-            entityMap.put(EntityConstant.TABLE_FIELDS, fieldConfigList);
-
-            //如果是多表关联 则需要添加关联表的信息  判断数据表配置是否大于1  并且  是主表
-            boolean isMainTable = generatorConfig.getTableConfigs().stream().anyMatch(x -> StrUtil.equals(x.getTableName(), tableInfo.getTableName()) && x.getIsMain());
-            if (tableInfos.size() > 1 && isMainTable) {
-                List<TableConfig> childTables = generatorConfig.getTableConfigs().stream()
-                        .filter(x -> !x.getIsMain())
-                        .collect(Collectors.toList());
-
-                List<TableConfig> newChildTables = new ArrayList<>();
-                for (TableConfig childTable : childTables) {
-                    TableConfig newTableConfig = BeanUtil.toBean(childTable, TableConfig.class);
-
-                    newTableConfig.setRelationField(StrUtil.toCamelCase(childTable.getRelationField()));
-                    newTableConfig.setRelationTableField(StrUtil.toCamelCase(childTable.getRelationTableField()));
-                    newTableConfig.setTableName(StrUtil.toCamelCase(childTable.getTableName()));
-
-                    newChildTables.add(newTableConfig);
-                }
-//                Optional<TableConfig> parentTable = generatorConfig.getTableConfigs().stream().filter(TableConfig::getIsMain).findFirst();
-                entityMap.put(EntityConstant.CHILD_TABLES, newChildTables);
-//                parentTable.ifPresent(x -> entityMap.put(EntityConstant.PARENT_RELATION_FIELD_KEY, x.getRelationTableField()));
-            }
-
-
-            //生产目标代码
-//            Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
-//            configuration.setDefaultEncoding(StandardCharsets.UTF_8.name());
-//            configuration.setDirectoryForTemplateLoading(new File(TEMPLATE_PATH));
-//            Template template = configuration.getTemplate(ENTITY_TEMPLATE_NAME);
-
-            Template template = freeMarkerConfigurer.getConfiguration().getTemplate(ENTITY_TEMPLATE_NAME);
-            String entityContent = FreeMarkerTemplateUtils.processTemplateIntoString(template, entityMap);
-
-            entityCodeMap.put(StrUtil.upperFirst(StrUtil.toCamelCase(tableInfo.getTableName())), entityContent);
-        }
-
-        System.out.println(entityCodeMap);
-
+        apiGeneratorService.generateCodes(params);
     }
 }