refactor(codegen): 重构codegen 使用anyline 实现数据库创表抽象

This commit is contained in:
冷冷 committed 2024-08-22 09:42:38 +08:00
1 parent 9540050f63
commit 4e8fff59ab
61 files changed
+1696 -1689

No files matched your search

+27 -1
View File
@@ -52,7 +52,7 @@
<cloud.plugin.version>1.0.0</cloud.plugin.version>
<sentinel.version>1.8.4</sentinel.version>
<sensitive.word.version>0.17.0</sensitive.word.version>
<anyline.version>8.7.2-jdk17-20240808</anyline.version>
<anyline.version>8.7.2-20240808</anyline.version>
<sms4j.version>3.2.1</sms4j.version>
<javax.mail.version>1.6.2</javax.mail.version>
<velocity.version>2.3</velocity.version>
@@ -288,6 +288,32 @@
<artifactId>HgdbJdbc</artifactId>
<version>${highgo.version}</version>
</dependency>
<!--anyline-->
<dependency>
<groupId>org.anyline</groupId>
<artifactId>anyline-environment-spring-data-jdbc</artifactId>
<version>${anyline.version}</version>
</dependency>
<dependency>
<groupId>org.anyline</groupId>
<artifactId>anyline-data-jdbc-mysql</artifactId>
<version>${anyline.version}</version>
</dependency>
<dependency>
<groupId>org.anyline</groupId>
<artifactId>anyline-data-jdbc-oracle</artifactId>
<version>${anyline.version}</version>
</dependency>
<dependency>
<groupId>org.anyline</groupId>
<artifactId>anyline-data-jdbc-postgresql</artifactId>
<version>${anyline.version}</version>
</dependency>
<dependency>
<groupId>org.anyline</groupId>
<artifactId>anyline-data-jdbc-dm</artifactId>
<version>${anyline.version}</version>
</dependency>
<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
+1
View File
@@ -55,5 +55,6 @@
<module>pigx-common-swagger</module>
<module>pigx-common-websocket</module>
<module>pigx-common-xss</module>
<module>pigx-common-sse</module>
</modules>
</project>
@@ -3,7 +3,7 @@ package com.pig4cloud.pigx.flow.task.config;
import cn.hutool.core.date.DateUtil;
import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder;
import com.pig4cloud.pigx.common.sequence.builder.DbSeqBuilder;
import com.pig4cloud.pigx.common.sequence.properties.SequenceDbProperties;
import com.pig4cloud.pigx.common.sequence.properties.BaseSequenceProperties;
import com.pig4cloud.pigx.common.sequence.sequence.Sequence;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -26,11 +26,13 @@ public class SequenceConfiguration {
* @return
*/
@Bean
public Sequence flowSequence(DataSource dataSource, SequenceDbProperties properties) {
public Sequence flowSequence(DataSource dataSource, BaseSequenceProperties properties) {
return DbSeqBuilder.create()
.bizName(() -> String.format("flow_%s_%s", TenantContextHolder.getTenantId(), DateUtil.today()))
.dataSource(dataSource).step(properties.getStep()).retryTimes(properties.getRetryTimes())
.tableName(properties.getTableName()).build();
.dataSource(dataSource)
.step(properties.getStep())
.retryTimes(properties.getDb().getRetryTimes())
.tableName(properties.getDb().getTableName())
.build();
}
}
@@ -0,0 +1,61 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.api.feign;
import com.pig4cloud.pigx.admin.api.entity.SysMenu;
import com.pig4cloud.pigx.common.core.constant.ServiceNameConstants;
import com.pig4cloud.pigx.common.core.util.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
/**
* 远程菜单服务
*
* @author lengleng
* @date 2024/07/16
*/
@FeignClient(contextId = "remoteMenuService", value = ServiceNameConstants.UPMS_SERVICE)
public interface RemoteMenuService {
/**
* 获取菜单详细信息
*
* @param sysMenu SYS菜单
* @return {@link R }<{@link List }<{@link SysMenu }>>
*/
@GetMapping("/menu/details")
R<List<SysMenu>> getMenuDetails(@SpringQueryMap SysMenu sysMenu);
/**
* 保存菜单
*
* @param sysMenu SYS菜单
* @return {@link R }<{@link Boolean }>
*/
@PostMapping("/menu")
R<SysMenu> saveMenu(@RequestBody SysMenu sysMenu);
}
@@ -0,0 +1,59 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.admin.api.feign;
import com.pig4cloud.pigx.admin.api.entity.SysRouteConf;
import com.pig4cloud.pigx.common.core.constant.ServiceNameConstants;
import com.pig4cloud.pigx.common.core.util.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
/**
* 远程路由 CONF 服务
*
* @author lengleng
* @date 2024/07/16
*/
@FeignClient(contextId = "remoteRouteConfService", value = ServiceNameConstants.UPMS_SERVICE)
public interface RemoteRouteConfService {
/**
* 获取路由详细信息
*
* @return {@link R }<{@link List }<{@link SysRouteConf }>>
*/
@GetMapping("/route")
R<List<SysRouteConf>> getRouteDetails();
/**
* 保存 sys route conf
*
* @param SysRouteConf sys 路由配置
* @return {@link R }<{@link Boolean }>
*/
@PostMapping("/route/save")
R<SysRouteConf> saveSysRouteConf(@RequestBody SysRouteConf SysRouteConf);
}
@@ -28,6 +28,7 @@ import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
/**
@@ -43,33 +44,43 @@ import org.springframework.web.bind.annotation.*;
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysRouteConfController {
private final SysRouteConfService sysRouteConfService;
private final SysRouteConfService sysRouteConfService;
/**
* 获取当前定义的路由信息
* @return
*/
@GetMapping
public R listRoutes(@RequestParam(required = false) String routeId) {
return R.ok(sysRouteConfService.list(Wrappers.<SysRouteConf>lambdaQuery().eq(StrUtil.isNotBlank(routeId),
SysRouteConf::getRouteId, routeId)));
}
/**
* 获取当前定义的路由信息
*
* @return
*/
@GetMapping
public R listRoutes(@RequestParam(required = false) String routeId) {
return R.ok(sysRouteConfService.list(Wrappers.<SysRouteConf>lambdaQuery()
.eq(StrUtil.isNotBlank(routeId), SysRouteConf::getRouteId, routeId)));
}
@DeleteMapping("/{routeId}")
public R deleteRoute(@PathVariable String routeId) {
return R.ok(
sysRouteConfService.remove(Wrappers.<SysRouteConf>lambdaQuery().eq(SysRouteConf::getRouteId, routeId)));
}
@DeleteMapping("/{routeId}")
@PreAuthorize("@pms.hasPermission('sys_route_manage')")
public R deleteRoute(@PathVariable String routeId) {
return R
.ok(sysRouteConfService.remove(Wrappers.<SysRouteConf>lambdaQuery().eq(SysRouteConf::getRouteId, routeId)));
}
/**
* 新增修改路由
* @param route 路由定义
* @return success
*/
@SysLog("新增修改路由")
@PostMapping
public R addOrUpdateRoute(@RequestBody JSONObject route) {
return R.ok(sysRouteConfService.addOrUpdateRoute(route));
}
/**
* 新增修改路由
*
* @param route 路由定义
* @return success
*/
@SysLog("新增修改路由")
@PostMapping
@PreAuthorize("@pms.hasPermission('sys_route_manage')")
public R addOrUpdateRoute(@RequestBody JSONObject route) {
return R.ok(sysRouteConfService.addOrUpdateRoute(route));
}
@SysLog("新增路由")
@PostMapping("/save")
@PreAuthorize("@pms.hasPermission('sys_route_manage')")
public R saveRoute(@RequestBody SysRouteConf routeConf) {
return R.ok(sysRouteConfService.saveRoute(routeConf));
}
}
@@ -37,4 +37,11 @@ public interface SysRouteConfService extends IService<SysRouteConf> {
*/
Mono<Void> addOrUpdateRoute(JSONObject route);
/**
* 保存路由
*
* @param routeConf 路由配置
* @return {@link SysRouteConf }
*/
SysRouteConf saveRoute(SysRouteConf routeConf);
}
@@ -57,6 +57,7 @@ public class SysRouteConfServiceImpl extends ServiceImpl<SysRouteConfMapper, Sys
/**
* 更新路由信息
*
* @param route 路由信息
* @return
*/
@@ -118,16 +119,29 @@ public class SysRouteConfServiceImpl extends ServiceImpl<SysRouteConfMapper, Sys
routeConf.setMetadata(JSONUtil.toJsonStr(vo.getMetadata()));
this.save(routeConf);
log.debug("更新网关路由结束 ");
}
catch (Exception e) {
} catch (Exception e) {
log.error("路由配置解析失败", e);
// 抛出异常
throw new RuntimeException(e);
}
finally {
} finally {
this.applicationEventPublisher.publishEvent(new DynamicRouteInitEvent(this));
}
return Mono.empty();
}
/**
* 保存路由
*
* @param routeConf 路由配置
* @return {@link SysRouteConf }
*/
@Override
@Transactional(rollbackFor = Exception.class)
public SysRouteConf saveRoute(SysRouteConf routeConf) {
baseMapper.insert(routeConf);
this.applicationEventPublisher.publishEvent(new DynamicRouteInitEvent(this));
return routeConf;
}
}
+1
View File
@@ -3,6 +3,7 @@ FROM registry.cn-hangzhou.aliyuncs.com/dockerhub_mirror/java:1.8-full
MAINTAINER wangiegie@gmail.com
ENV TZ=Asia/Shanghai
ENV LANG C.UTF-8
ENV JAVA_OPTS="-Xms128m -Xmx256m -Djava.security.egd=file:/dev/./urandom"
RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
+28 -8
View File
@@ -16,9 +16,8 @@
<properties>
<magic.version>2.0.2</magic.version>
<screw.version>0.0.1</screw.version>
<screw.version>0.0.6</screw.version>
<db2.version>11.5.0.0</db2.version>
<anyline.version>8.7.1-20240223</anyline.version>
<configuration.version>1.10</configuration.version>
</properties>
@@ -89,26 +88,36 @@
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<!--anyline-->
<dependency>
<groupId>org.anyline</groupId>
<artifactId>anyline-environment-spring-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.anyline</groupId>
<artifactId>anyline-data-jdbc-mysql</artifactId>
<version>${anyline.version}</version>
</dependency>
<dependency>
<groupId>org.anyline</groupId>
<artifactId>anyline-data-jdbc-postgresql</artifactId>
<version>${anyline.version}</version>
</dependency>
<dependency>
<groupId>org.anyline</groupId>
<artifactId>anyline-data-jdbc-oracle</artifactId>
</dependency>
<dependency>
<groupId>org.anyline</groupId>
<artifactId>anyline-data-jdbc-dm</artifactId>
<version>${anyline.version}</version>
</dependency>
<!--common-->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-core</artifactId>
</dependency>
<!-- 幂等插件使用 -->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-idempotent</artifactId>
</dependency>
<dependency>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
@@ -150,16 +159,14 @@
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity.version}</version>
</dependency>
<dependency>
<groupId>org.apache.velocity.tools</groupId>
<artifactId>velocity-tools-generic</artifactId>
<version>${velocity.tool.version}</version>
</dependency>
<!--生成文档-->
<dependency>
<groupId>io.springboot.plugin</groupId>
<groupId>group.springframework.plugin</groupId>
<artifactId>screw-spring-boot-starter</artifactId>
<version>${screw.version}</version>
</dependency>
@@ -178,11 +185,24 @@
<profiles>
<profile>
<id>cloud</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<loaderImplementation>CLASSIC</loaderImplementation>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
@@ -30,8 +30,8 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
* @date 2018/07/29 代码生成模块
*/
@EnableDynamicDataSource
@EnableOpenApi("gen")
@EnablePigxFeignClients
@EnableOpenApi("gen")
@EnableDiscoveryClient
@EnablePigxResourceServer
@SpringBootApplication
@@ -0,0 +1,92 @@
package com.pig4cloud.pigx.codegen.config;
import cn.smallbun.screw.core.constant.DefaultConstants;
import lombok.Data;
import org.anyline.util.ConfigTable;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* 代码生成默认配置类
*
* @author lengleng
* @date 2024/7/15
*/
@Data
@Configuration(proxyBeanMethods = false)
@ConfigurationProperties(prefix = PigxCodeGenDefaultProperties.PREFIX)
public class PigxCodeGenDefaultProperties implements InitializingBean {
public static final String PREFIX = "codegen";
/**
* 是否开启在线更新
*/
private boolean autoCheckVersion = true;
/**
* 模板项目地址
*/
private String onlineUrl = DefaultConstants.CGTM_URL;
/**
* 生成代码的包名
*/
private String packageName = "com.pig4cloud.pigx";
/**
* 生成代码的版本
*/
private String version = "1.0.0";
/**
* 生成代码的模块名
*/
private String moduleName = "admin";
/**
* 生成代码的后端路径
*/
private String backendPath = "pigx";
/**
* 生成代码的前端路径
*/
private String frontendPath = "pigx-ui";
/**
* 生成代码的作者
*/
private String author = "pigx";
/**
* 生成代码的邮箱
*/
private String email = "sw@pigx.vip";
/**
* 表单布局(一列、两列)
*/
private Integer formLayout = 2;
/**
* 下载方式 (0 文件下载、1写入目录)
*/
private String generatorType = "0";
/**
* 是否同步路由
*/
private String syncRoute = "1";
/**
* <a href="http://doc.anyline.org/aa/3c_14011">集成mybatis动态数据源</a>
*
* @throws Exception 例外
*/
@Override
public void afterPropertiesSet() throws Exception {
ConfigTable.KEEP_ADAPTER = 0;
}
}
@@ -18,7 +18,6 @@ package com.pig4cloud.pigx.codegen.controller;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.ContentType;
import cn.smallbun.screw.boot.config.Screw;
import cn.smallbun.screw.boot.properties.ScrewProperties;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
@@ -63,8 +62,9 @@ public class GenDsConfController {
@GetMapping("/page")
public R getSysDatasourceConfPage(Page page, GenDatasourceConf datasourceConf) {
return R.ok(datasourceConfService.page(page,
Wrappers.<GenDatasourceConf>lambdaQuery().like(StrUtil.isNotBlank(datasourceConf.getDsName()),
GenDatasourceConf::getDsName, datasourceConf.getDsName())));
Wrappers.<GenDatasourceConf>lambdaQuery()
.like(StrUtil.isNotBlank(datasourceConf.getDsName()), GenDatasourceConf::getDsName,
datasourceConf.getDsName())));
}
/**
@@ -135,11 +135,11 @@ public class GenDsConfController {
ScrewProperties screwProperties = SpringContextHolder.getBean(ScrewProperties.class);
// 生成
byte[] data = screw.documentGeneration(dataSource, screwProperties).toByteArray();
byte[] data = screw.documentGeneration(dsName, dataSource, screwProperties).toByteArray();
response.reset();
response.addHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(data.length));
response.setContentType(ContentType.OCTET_STREAM.getValue());
IoUtil.write(response.getOutputStream(), Boolean.TRUE, data);
response.setContentType("application/octet-stream");
IoUtil.write(response.getOutputStream(), Boolean.FALSE, data);
}
}
@@ -60,8 +60,9 @@ public class GenFieldTypeController {
@GetMapping("/page")
public R getFieldTypePage(Page page, GenFieldType fieldType) {
return R.ok(fieldTypeService.page(page,
Wrappers.<GenFieldType>lambdaQuery().like(StrUtil.isNotBlank(fieldType.getColumnType()),
GenFieldType::getColumnType, fieldType.getColumnType())));
Wrappers.<GenFieldType>lambdaQuery()
.like(StrUtil.isNotBlank(fieldType.getColumnType()), GenFieldType::getColumnType,
fieldType.getColumnType())));
}
@Operation(summary = "查询列表", description = "查询列表")
@@ -23,7 +23,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pigx.codegen.entity.GenGroupEntity;
import com.pig4cloud.pigx.codegen.service.GenGroupService;
import com.pig4cloud.pigx.codegen.util.vo.GroupVo;
import com.pig4cloud.pigx.codegen.util.vo.GroupVO;
import com.pig4cloud.pigx.codegen.util.vo.TemplateGroupDTO;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
@@ -51,96 +51,106 @@ import java.util.List;
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class GenGroupController {
private final GenGroupService genGroupService;
private final GenGroupService genGroupService;
/**
* 分页查询
* @param page 分页对象
* @param genGroup 模板分组
* @return
*/
@Operation(summary = "分页查询", description = "分页查询")
@GetMapping("/page")
@PreAuthorize("@pms.hasPermission('codegen_group_view')")
public R getgenGroupPage(Page page, GenGroupEntity genGroup) {
LambdaQueryWrapper<GenGroupEntity> wrapper = Wrappers.<GenGroupEntity>lambdaQuery()
.like(genGroup.getId() != null, GenGroupEntity::getId, genGroup.getId())
.like(StrUtil.isNotEmpty(genGroup.getGroupName()), GenGroupEntity::getGroupName,
genGroup.getGroupName());
return R.ok(genGroupService.page(page, wrapper));
}
/**
* 分页查询
*
* @param page 分页对象
* @param genGroup 模板分组
* @return
*/
@Operation(summary = "分页查询", description = "分页查询")
@GetMapping("/page")
@PreAuthorize("@pms.hasPermission('codegen_group_view')")
public R getgenGroupPage(Page page, GenGroupEntity genGroup) {
LambdaQueryWrapper<GenGroupEntity> wrapper = Wrappers.<GenGroupEntity>lambdaQuery()
.like(genGroup.getId() != null, GenGroupEntity::getId, genGroup.getId())
.like(StrUtil.isNotEmpty(genGroup.getGroupName()), GenGroupEntity::getGroupName, genGroup.getGroupName());
return R.ok(genGroupService.page(page, wrapper));
}
/**
* 通过id查询模板分组
* @param id id
* @return R
*/
@Operation(summary = "通过id查询", description = "通过id查询")
@GetMapping("/{id}")
@PreAuthorize("@pms.hasPermission('codegen_group_view')")
public R getById(@PathVariable("id") Long id) {
return R.ok(genGroupService.getGroupVoById(id));
}
/**
* 通过id查询模板分组
*
* @param id id
* @return R
*/
@Operation(summary = "通过id查询", description = "通过id查询")
@GetMapping("/{id}")
@PreAuthorize("@pms.hasPermission('codegen_group_view')")
public R getById(@PathVariable("id") Long id) {
return R.ok(genGroupService.getGroupVoById(id));
}
/**
* 新增模板分组
* @param genTemplateGroup 模板分组
* @return R
*/
@Operation(summary = "新增模板分组", description = "新增模板分组")
@SysLog("新增模板分组")
@PostMapping
@PreAuthorize("@pms.hasPermission('codegen_group_add')")
public R save(@RequestBody TemplateGroupDTO genTemplateGroup) {
genGroupService.saveGenGroup(genTemplateGroup);
return R.ok();
}
/**
* 新增模板分组
*
* @param genTemplateGroup 模板分组
* @return R
*/
@Operation(summary = "新增模板分组", description = "新增模板分组")
@SysLog("新增模板分组")
@PostMapping
@PreAuthorize("@pms.hasPermission('codegen_group_add')")
public R save(@RequestBody TemplateGroupDTO genTemplateGroup) {
genGroupService.saveGenGroup(genTemplateGroup);
return R.ok();
}
/**
* 修改模板分组
* @param groupVo 模板分组
* @return R
*/
@Operation(summary = "修改模板分组", description = "修改模板分组")
@SysLog("修改模板分组")
@PutMapping
@PreAuthorize("@pms.hasPermission('codegen_group_edit')")
public R updateById(@RequestBody GroupVo groupVo) {
genGroupService.updateGroupAndTemplateById(groupVo);
return R.ok();
}
/**
* 修改模板分组
*
* @param groupVo 模板分组
* @return R
*/
@Operation(summary = "修改模板分组", description = "修改模板分组")
@SysLog("修改模板分组")
@PutMapping
@PreAuthorize("@pms.hasPermission('codegen_group_edit')")
public R updateById(@RequestBody GroupVO groupVo) {
genGroupService.updateGroupAndTemplateById(groupVo);
return R.ok();
}
/**
* 通过id删除模板分组
* @param ids id列表
* @return R
*/
@Operation(summary = "通过id删除模板分组", description = "通过id删除模板分组")
@SysLog("通过id删除模板分组")
@DeleteMapping
@PreAuthorize("@pms.hasPermission('codegen_group_del')")
public R removeById(@RequestBody Long[] ids) {
genGroupService.delGroupAndTemplate(ids);
return R.ok();
}
/**
* 通过id删除模板分组
*
* @param ids id列表
* @return R
*/
@Operation(summary = "通过id删除模板分组", description = "通过id删除模板分组")
@SysLog("通过id删除模板分组")
@DeleteMapping
@PreAuthorize("@pms.hasPermission('codegen_group_del')")
public R removeById(@RequestBody Long[] ids) {
genGroupService.delGroupAndTemplate(ids);
return R.ok();
}
/**
* 导出excel 表格
* @param genGroup 查询条件
* @return excel 文件流
*/
@ResponseExcel
@GetMapping("/export")
@PreAuthorize("@pms.hasPermission('codegen_group_export')")
public List<GenGroupEntity> export(GenGroupEntity genGroup) {
return genGroupService.list(Wrappers.query(genGroup));
}
/**
* 导出excel 表格
*
* @param genGroup 查询条件
* @return excel 文件流
*/
@ResponseExcel
@GetMapping("/export")
@PreAuthorize("@pms.hasPermission('codegen_group_export')")
public List<GenGroupEntity> export(GenGroupEntity genGroup) {
return genGroupService.list(Wrappers.query(genGroup));
}
@GetMapping("/list")
@Operation(summary = "查询列表", description = "查询列表")
public R list() {
List<GenGroupEntity> list = genGroupService.list();
return R.ok(list);
}
/**
* @return 响应信息主体
*/
@GetMapping("/list")
@Operation(summary = "查询列表", description = "查询列表")
public R list() {
List<GenGroupEntity> list = genGroupService.list(Wrappers.<GenGroupEntity>lambdaQuery()
.orderByDesc(GenGroupEntity::getCreateTime));
return R.ok(list);
}
}
@@ -61,31 +61,74 @@ public class GenTableController {
@Operation(summary = "分页查询", description = "分页查询")
@GetMapping("/page")
public R getTablePage(Page page, GenTable table) {
return R.ok(tableService.list(page, table));
return R.ok(tableService.queryTablePage(page, table));
}
/**
* 通过id查询列属性
* 通过id查询表信息(代码生成设置 + 表 + 字段设置)
* @param id id
* @return R
*/
@Operation(summary = "通过id查询", description = "通过id查询")
@GetMapping("/{id}")
public R getById(@PathVariable("id") Long id) {
public R getTable(@PathVariable("id") Long id) {
return R.ok(tableService.getById(id));
}
/**
* 新增列属性
* @param table 列属性
* @return R
* 查询数据源所有表
* @param dsName 数据源
*/
@Operation(summary = "新增列属性", description = "新增列属性")
@SysLog("新增列属性")
@PostMapping
public R save(@RequestBody GenTable table) {
return R.ok(tableService.save(table));
@GetMapping("/list/{dsName}")
public R listTable(@PathVariable("dsName") String dsName) {
return R.ok(tableService.queryTableList(dsName));
}
/**
* 获取表信息
* @param dsName 数据源
* @param tableName 表名称
*/
@GetMapping("/{dsName}/{tableName}")
public R<GenTable> getTable(@PathVariable("dsName") String dsName, @PathVariable String tableName) {
return R.ok(tableService.queryOrBuildTable(dsName, tableName));
}
/**
* 查询表DDL语句
* @param dsName 数据源
* @param tableName 表名称
*/
@GetMapping("/column/{dsName}/{tableName}")
public R getColumn(@PathVariable("dsName") String dsName, @PathVariable String tableName) throws Exception {
return R.ok(tableService.queryTableColumn(dsName, tableName));
}
/**
* 查询表DDL语句
* @param dsName 数据源
* @param tableName 表名称
*/
@GetMapping("/ddl/{dsName}/{tableName}")
public R getDdl(@PathVariable("dsName") String dsName, @PathVariable String tableName) throws Exception {
return R.ok(tableService.queryTableDdl(dsName, tableName));
}
/**
* 同步表信息
* @param dsName 数据源
* @param tableName 表名称
*/
@GetMapping("/sync/{dsName}/{tableName}")
public R<GenTable> syncTable(@PathVariable("dsName") String dsName, @PathVariable String tableName) {
// 表配置删除
tableService.remove(
Wrappers.<GenTable>lambdaQuery().eq(GenTable::getDsName, dsName).eq(GenTable::getTableName, tableName));
// 字段配置删除
tableColumnService.remove(Wrappers.<GenTableColumnEntity>lambdaQuery()
.eq(GenTableColumnEntity::getDsName, dsName)
.eq(GenTableColumnEntity::getTableName, tableName));
return R.ok(tableService.queryOrBuildTable(dsName, tableName));
}
/**
@@ -101,15 +144,16 @@ public class GenTableController {
}
/**
* 通过id删除列属性
* @param id id
* @return R
* 修改表字段数据
* @param dsName 数据源
* @param tableName 表名称
* @param tableFieldList 字段列表
*/
@Operation(summary = "通过id删除列属性", description = "通过id删除列属性")
@SysLog("通过id删除列属性")
@DeleteMapping("/{id}")
public R removeById(@PathVariable Long id) {
return R.ok(tableService.removeById(id));
@PutMapping("/field/{dsName}/{tableName}")
public R<String> updateTableField(@PathVariable("dsName") String dsName, @PathVariable String tableName,
@RequestBody List<GenTableColumnEntity> tableFieldList) {
tableColumnService.updateTableField(dsName, tableName, tableFieldList);
return R.ok();
}
/**
@@ -123,53 +167,4 @@ public class GenTableController {
return tableService.list(Wrappers.query(table));
}
@GetMapping("/list/{dsName}")
public R listTable(@PathVariable("dsName") String dsName) {
return R.ok(tableService.queryDsAllTable(dsName));
}
@GetMapping("/column/{dsName}/{tableName}")
public R column(@PathVariable("dsName") String dsName, @PathVariable String tableName) {
return R.ok(tableService.queryColumn(dsName, tableName));
}
/**
* 获取表信息
* @param dsName 数据源
* @param tableName 表名称
*/
@GetMapping("/{dsName}/{tableName}")
public R<GenTable> info(@PathVariable("dsName") String dsName, @PathVariable String tableName) {
return R.ok(tableService.queryOrBuildTable(dsName, tableName));
}
/**
* 同步表信息
* @param dsName 数据源
* @param tableName 表名称
*/
@GetMapping("/sync/{dsName}/{tableName}")
public R<GenTable> sync(@PathVariable("dsName") String dsName, @PathVariable String tableName) {
// 表配置删除
tableService.remove(
Wrappers.<GenTable>lambdaQuery().eq(GenTable::getDsName, dsName).eq(GenTable::getTableName, tableName));
// 字段配置删除
tableColumnService.remove(Wrappers.<GenTableColumnEntity>lambdaQuery()
.eq(GenTableColumnEntity::getDsName, dsName).eq(GenTableColumnEntity::getTableName, tableName));
return R.ok(tableService.queryOrBuildTable(dsName, tableName));
}
/**
* 修改表字段数据
* @param dsName 数据源
* @param tableName 表名称
* @param tableFieldList 字段列表
*/
@PutMapping("/field/{dsName}/{tableName}")
public R<String> updateTableField(@PathVariable("dsName") String dsName, @PathVariable String tableName,
@RequestBody List<GenTableColumnEntity> tableFieldList) {
tableColumnService.updateTableField(dsName, tableName, tableFieldList);
return R.ok();
}
}
@@ -51,99 +51,131 @@ import java.util.List;
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class GenTemplateController {
private final GenTemplateService genTemplateService;
private final GenTemplateService genTemplateService;
/**
* 分页查询
* @param page 分页对象
* @param genTemplate 模板
* @return
*/
@Operation(summary = "分页查询", description = "分页查询")
@GetMapping("/page")
@PreAuthorize("@pms.hasPermission('codegen_template_view')")
public R getgenTemplatePage(Page page, GenTemplateEntity genTemplate) {
LambdaQueryWrapper<GenTemplateEntity> wrapper = Wrappers.<GenTemplateEntity>lambdaQuery()
.like(genTemplate.getId() != null, GenTemplateEntity::getId, genTemplate.getId())
.like(StrUtil.isNotEmpty(genTemplate.getTemplateName()), GenTemplateEntity::getTemplateName,
genTemplate.getTemplateName());
return R.ok(genTemplateService.page(page, wrapper));
}
/**
* 分页查询
*
* @param page 分页对象
* @param genTemplate 模板
* @return
*/
@Operation(summary = "分页查询", description = "分页查询")
@GetMapping("/page")
@PreAuthorize("@pms.hasPermission('codegen_template_view')")
public R getGenTemplatePage(Page page, GenTemplateEntity genTemplate) {
LambdaQueryWrapper<GenTemplateEntity> wrapper = Wrappers.<GenTemplateEntity>lambdaQuery()
.like(genTemplate.getId() != null, GenTemplateEntity::getId, genTemplate.getId())
.like(StrUtil.isNotEmpty(genTemplate.getTemplateName()), GenTemplateEntity::getTemplateName,
genTemplate.getTemplateName());
return R.ok(genTemplateService.page(page, wrapper));
}
/**
* 查询全部模板
* @return
*/
@Operation(summary = "查询全部", description = "查询全部")
@GetMapping("/list")
@PreAuthorize("@pms.hasPermission('codegen_template_view')")
public R list() {
return R.ok(genTemplateService.list(Wrappers.emptyWrapper()));
}
/**
* 查询全部模板
*
* @return
*/
@Operation(summary = "查询全部", description = "查询全部")
@GetMapping("/list")
@PreAuthorize("@pms.hasPermission('codegen_template_view')")
public R list() {
return R.ok(genTemplateService.list(Wrappers.<GenTemplateEntity>lambdaQuery()
.orderByDesc(GenTemplateEntity::getCreateTime)));
}
/**
* 通过id查询模板
* @param id id
* @return R
*/
@Operation(summary = "通过id查询", description = "通过id查询")
@GetMapping("/{id}")
@PreAuthorize("@pms.hasPermission('codegen_template_view')")
public R getById(@PathVariable("id") Long id) {
return R.ok(genTemplateService.getById(id));
}
/**
* 通过id查询模板
*
* @param id id
* @return R
*/
@Operation(summary = "通过id查询", description = "通过id查询")
@GetMapping("/{id}")
@PreAuthorize("@pms.hasPermission('codegen_template_view')")
public R getById(@PathVariable("id") Long id) {
return R.ok(genTemplateService.getById(id));
}
/**
* 新增模板
* @param genTemplate 模板
* @return R
*/
@XssCleanIgnore
@Operation(summary = "新增模板", description = "新增模板")
@SysLog("新增模板")
@PostMapping
@PreAuthorize("@pms.hasPermission('codegen_template_add')")
public R save(@RequestBody GenTemplateEntity genTemplate) {
return R.ok(genTemplateService.save(genTemplate));
}
/**
* 新增模板
*
* @param genTemplate 模板
* @return R
*/
@XssCleanIgnore
@Operation(summary = "新增模板", description = "新增模板")
@SysLog("新增模板")
@PostMapping
@PreAuthorize("@pms.hasPermission('codegen_template_add')")
public R save(@RequestBody GenTemplateEntity genTemplate) {
return R.ok(genTemplateService.save(genTemplate));
}
/**
* 修改模板
* @param genTemplate 模板
* @return R
*/
@XssCleanIgnore
@Operation(summary = "修改模板", description = "修改模板")
@SysLog("修改模板")
@PutMapping
@PreAuthorize("@pms.hasPermission('codegen_template_edit')")
public R updateById(@RequestBody GenTemplateEntity genTemplate) {
return R.ok(genTemplateService.updateById(genTemplate));
}
/**
* 修改模板
*
* @param genTemplate 模板
* @return R
*/
@XssCleanIgnore
@Operation(summary = "修改模板", description = "修改模板")
@SysLog("修改模板")
@PutMapping
@PreAuthorize("@pms.hasPermission('codegen_template_edit')")
public R updateById(@RequestBody GenTemplateEntity genTemplate) {
return R.ok(genTemplateService.updateById(genTemplate));
}
/**
* 通过id删除模板
* @param ids id列表
* @return R
*/
@Operation(summary = "通过id删除模板", description = "通过id删除模板")
@SysLog("通过id删除模板")
@DeleteMapping
@PreAuthorize("@pms.hasPermission('codegen_template_del')")
public R removeById(@RequestBody Long[] ids) {
return R.ok(genTemplateService.removeBatchByIds(CollUtil.toList(ids)));
}
/**
* 通过id删除模板
*
* @param ids id列表
* @return R
*/
@Operation(summary = "通过id删除模板", description = "通过id删除模板")
@SysLog("通过id删除模板")
@DeleteMapping
@PreAuthorize("@pms.hasPermission('codegen_template_del')")
public R removeById(@RequestBody Long[] ids) {
return R.ok(genTemplateService.removeBatchByIds(CollUtil.toList(ids)));
}
/**
* 导出excel 表格
* @param genTemplate 查询条件
* @return excel 文件流
*/
@ResponseExcel
@GetMapping("/export")
@PreAuthorize("@pms.hasPermission('codegen_template_export')")
public List<GenTemplateEntity> export(GenTemplateEntity genTemplate) {
return genTemplateService.list(Wrappers.query(genTemplate));
}
/**
* 导出excel 表格
*
* @param genTemplate 查询条件
* @return excel 文件流
*/
@ResponseExcel
@GetMapping("/export")
@PreAuthorize("@pms.hasPermission('codegen_template_export')")
public List<GenTemplateEntity> export(GenTemplateEntity genTemplate) {
return genTemplateService.list(Wrappers.query(genTemplate));
}
/**
* 在线更新模板
*
* @return R
*/
@Operation(summary = "在线更新模板", description = "在线更新模板")
@GetMapping("/online")
@PreAuthorize("@pms.hasPermission('codegen_template_view')")
public R online() {
return genTemplateService.onlineUpdate();
}
/**
* 检查版本
* @return {@link R }
*/
@Operation(summary = "在线检查模板", description = "在线检查模板")
@GetMapping("/checkVersion")
@PreAuthorize("@pms.hasPermission('codegen_template_view')")
public R checkVersion() {
return genTemplateService.checkVersion();
}
}
@@ -21,6 +21,7 @@ import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import com.pig4cloud.pigx.codegen.service.GeneratorService;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.idempotent.annotation.Idempotent;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.http.HttpHeaders;
@@ -56,6 +57,7 @@ public class GeneratorController {
*/
@SneakyThrows
@GetMapping("/download")
@Idempotent(key = "#tableIds", expireTime = 10, info = "正在生成代码,请勿重复操作")
public void download(String tableIds, HttpServletResponse response) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ZipOutputStream zip = new ZipOutputStream(outputStream);
@@ -82,6 +84,7 @@ public class GeneratorController {
*/
@ResponseBody
@GetMapping("/code")
@Idempotent(key = "#tableIds", expireTime = 10, info = "正在生成代码,请勿重复操作")
public R<String> code(String tableIds) throws Exception {
// 生成代码
for (String tableId : tableIds.split(StrUtil.COMMA)) {
@@ -38,73 +38,73 @@ import java.time.LocalDateTime;
@Schema(description = "自动创建表管理")
public class GenCreateTable extends Model<GenCreateTable> {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "主键ID")
private Long id;
/**
* 主键ID
*/
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "主键ID")
private Long id;
/**
* 数据源名称
*/
@Schema(description = "数据源名称")
private String dsName;
/**
* 数据源名称
*/
@Schema(description = "数据源名称")
private String dsName;
/**
* 表名称
*/
@Schema(description = "表名称")
private String tableName;
/**
* 表名称
*/
@Schema(description = "表名称")
private String tableName;
/**
* 表注释
*/
@Schema(description = "表注释")
private String comments;
/**
* 表注释
*/
@Schema(description = "表注释")
private String comments;
/**
* 字段信息
*/
@Schema(description = "字段信息")
private String columnInfo;
/**
* 字段信息
*/
@Schema(description = "字段信息")
private String columnInfo;
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
@Schema(description = "创建人")
private String createBy;
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
@Schema(description = "创建人")
private String createBy;
/**
* 修改人
*/
@TableField(fill = FieldFill.UPDATE)
@Schema(description = "修改人")
private String updateBy;
/**
* 修改人
*/
@TableField(fill = FieldFill.UPDATE)
@Schema(description = "修改人")
private String updateBy;
/**
* 创建时间
*/
@Schema(description = "创建时间")
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 创建时间
*/
@Schema(description = "创建时间")
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 修改时间
*/
@Schema(description = "修改时间")
@TableField(fill = FieldFill.UPDATE)
private LocalDateTime updateTime;
/**
* 修改时间
*/
@Schema(description = "修改时间")
@TableField(fill = FieldFill.UPDATE)
private LocalDateTime updateTime;
/**
* 删除标识(0-正常,1-删除)
*/
@TableLogic
@TableField(fill = FieldFill.INSERT)
@Schema(description = "删除标记,1:已删除,0:正常")
private String delFlag;
/**
* 删除标识(0-正常,1-删除)
*/
@TableLogic
@TableField(fill = FieldFill.INSERT)
@Schema(description = "删除标记,1:已删除,0:正常")
private String delFlag;
}
@@ -19,6 +19,7 @@ package com.pig4cloud.pigx.codegen.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.pig4cloud.pigx.common.core.util.TenantTable;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -32,6 +33,7 @@ import java.time.LocalDateTime;
* @date 2023-02-21 20:01:53
*/
@Data
@TenantTable
@TableName("gen_group")
@EqualsAndHashCode(callSuper = true)
@Schema(description = "模板分组")
@@ -25,6 +25,7 @@ import com.baomidou.mybatisplus.extension.activerecord.Model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.FieldNameConstants;
import java.time.LocalDateTime;
import java.util.List;
@@ -37,157 +38,170 @@ import java.util.List;
*/
@Data
@TableName("gen_table")
@FieldNameConstants
@EqualsAndHashCode(callSuper = true)
@Schema(description = "列属性")
public class GenTable extends Model<GenTable> {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "id")
private Long id;
/**
* id
*/
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "id")
private Long id;
/**
* 数据源名称
*/
@Schema(description = "数据源名称")
private String dsName;
/**
* 数据源名称
*/
@Schema(description = "数据源名称")
private String dsName;
/**
* 数据源类型
*/
@Schema(description = "数据源类型")
private String dbType;
/**
* 数据源类型
*/
@Schema(description = "数据源类型")
private String dbType;
/**
* 表名
*/
@Schema(description = "表名")
private String tableName;
/**
* 表名
*/
@Schema(description = "表名")
private String tableName;
/**
* 类名
*/
@Schema(description = "类名")
private String className;
/**
* 类名
*/
@Schema(description = "类名")
private String className;
/**
* 说明
*/
@Schema(description = "说明")
private String tableComment;
/**
* 说明
*/
@Schema(description = "说明")
private String tableComment;
/**
* 作者
*/
@Schema(description = "作者")
private String author;
/**
* 作者
*/
@Schema(description = "作者")
private String author;
/**
* 邮箱
*/
@Schema(description = "邮箱")
private String email;
/**
* 邮箱
*/
@Schema(description = "邮箱")
private String email;
/**
* 项目包名
*/
@Schema(description = "项目包名")
private String packageName;
/**
* 项目包名
*/
@Schema(description = "项目包名")
private String packageName;
/**
* 项目版本号
*/
@Schema(description = "项目版本号")
private String version;
/**
* 项目版本号
*/
@Schema(description = "项目版本号")
private String version;
/**
* 生成方式 0:zip压缩包 1:自定义目录
*/
@Schema(description = "生成方式 0:zip压缩包 1:自定义目录")
private String generatorType;
/**
* 生成方式 0:zip压缩包 1:自定义目录
*/
@Schema(description = "生成方式 0:zip压缩包 1:自定义目录")
private String generatorType;
/**
* 后端生成路径
*/
@Schema(description = "后端生成路径")
private String backendPath;
/**
* 后端生成路径
*/
@Schema(description = "后端生成路径")
private String backendPath;
/**
* 前端生成路径
*/
@Schema(description = "前端生成路径")
private String frontendPath;
/**
* 前端生成路径
*/
@Schema(description = "前端生成路径")
private String frontendPath;
/**
* 模块名
*/
@Schema(description = "模块名")
private String moduleName;
/**
* 模块名
*/
@Schema(description = "模块名")
private String moduleName;
/**
* 功能名
*/
@Schema(description = "功能名")
private String functionName;
/**
* 功能名
*/
@Schema(description = "功能名")
private String functionName;
/**
* 表单布局 1:一列 2:两列
*/
@Schema(description = "表单布局 1:一列 2:两列")
private Integer formLayout;
/**
* 表单布局 1:一列 2:两列
*/
@Schema(description = "表单布局 1:一列 2:两列")
private Integer formLayout;
/**
* 基类ID
*/
@Schema(description = "基类ID")
private Long baseclassId;
/**
* 所属菜单ID
*/
@Schema(description = "所属菜单ID")
private Long syncMenuId;
/**
* 创建时间
*/
@Schema(description = "创建时间")
private LocalDateTime createTime;
/**
* 是否同步路由
*/
@Schema
private String syncRoute;
/**
* 代码生成风格
*/
private Long style;
/**
* 基类ID
*/
@Schema(description = "基类ID")
private Long baseclassId;
/**
* 子表名称
*/
private String childTableName;
/**
* 创建时间
*/
@Schema(description = "创建时间")
private LocalDateTime createTime;
/**
* 主表关联键
*/
private String mainField;
/**
* 代码生成风格
*/
private Long style;
/**
* 子表关联键
*/
private String childField;
/**
* 子表名称
*/
private String childTableName;
/**
* 字段列表
*/
@TableField(exist = false)
private List<GenTableColumnEntity> fieldList;
/**
* 主表关联键
*/
private String mainField;
/**
* 子表字段列表
*/
@TableField(exist = false)
private List<GenTableColumnEntity> childFieldList;
/**
* 子表关联键
*/
private String childField;
/**
* 代码风格(模版分组信息)
*/
@TableField(exist = false)
private List<GenGroupEntity> groupList;
/**
* 字段列表
*/
@TableField(exist = false)
private List<GenTableColumnEntity> fieldList;
/**
* 子表字段列表
*/
@TableField(exist = false)
private List<GenTableColumnEntity> childFieldList;
/**
* 代码风格(模版分组信息)
*/
@TableField(exist = false)
private List<GenGroupEntity> groupList;
}
@@ -39,73 +39,73 @@ import java.time.LocalDateTime;
@Schema(description = "模板")
public class GenTemplateEntity extends Model<GenTemplateEntity> {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "主键")
private Long id;
/**
* 主键
*/
@TableId(type = IdType.ASSIGN_ID)
@Schema(description = "主键")
private Long id;
/**
* 模板名称
*/
@Schema(description = "模板名称")
private String templateName;
/**
* 模板名称
*/
@Schema(description = "模板名称")
private String templateName;
/**
* 模板路径
*/
@Schema(description = "模板路径")
private String generatorPath;
/**
* 模板路径
*/
@Schema(description = "模板路径")
private String generatorPath;
/**
* 模板描述
*/
@Schema(description = "模板描述")
private String templateDesc;
/**
* 模板描述
*/
@Schema(description = "模板描述")
private String templateDesc;
/**
* 模板代码
*/
@Schema(description = "模板代码")
private String templateCode;
/**
* 模板代码
*/
@Schema(description = "模板代码")
private String templateCode;
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
@Schema(description = "创建人")
private String createBy;
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
@Schema(description = "创建人")
private String createBy;
/**
* 修改人
*/
@TableField(fill = FieldFill.UPDATE)
@Schema(description = "修改人")
private String updateBy;
/**
* 修改人
*/
@TableField(fill = FieldFill.UPDATE)
@Schema(description = "修改人")
private String updateBy;
/**
* 创建时间
*/
@Schema(description = "创建时间")
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 创建时间
*/
@Schema(description = "创建时间")
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 修改时间
*/
@Schema(description = "修改时间")
@TableField(fill = FieldFill.UPDATE)
private LocalDateTime updateTime;
/**
* 修改时间
*/
@Schema(description = "修改时间")
@TableField(fill = FieldFill.UPDATE)
private LocalDateTime updateTime;
/**
* 删除标识(0-正常,1-删除)
*/
@TableLogic
@TableField(fill = FieldFill.INSERT)
@Schema(description = "删除标记,1:已删除,0:正常")
private String delFlag;
/**
* 删除标识(0-正常,1-删除)
*/
@TableLogic
@TableField(fill = FieldFill.INSERT)
@Schema(description = "删除标记,1:已删除,0:正常")
private String delFlag;
}
@@ -18,7 +18,7 @@
package com.pig4cloud.pigx.codegen.mapper;
import com.pig4cloud.pigx.codegen.entity.GenGroupEntity;
import com.pig4cloud.pigx.codegen.util.vo.GroupVo;
import com.pig4cloud.pigx.codegen.util.vo.GroupVO;
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@@ -32,6 +32,6 @@ import org.apache.ibatis.annotations.Param;
@Mapper
public interface GenGroupMapper extends PigxBaseMapper<GenGroupEntity> {
GroupVo getGroupVoById(@Param("id") Long id);
GroupVO getGroupVoById(@Param("id") Long id);
}
@@ -1,31 +0,0 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.codegen.mapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 支持 db2 代码生成器
*
* @author lengleng
* @date 2020-12-11
*/
@Mapper
public interface GeneratorDB2Mapper extends GeneratorMapper {
}
@@ -1,31 +0,0 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.codegen.mapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 支持 达梦 代码生成器
*
* @author lengleng
* @date 2022-03-24
*/
@Mapper
public interface GeneratorDmMapper extends GeneratorMapper {
}
@@ -1,31 +0,0 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.codegen.mapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 支持 瀚高数据库 代码生成器
*
* @author lengleng
* @date 2023-04-26
*/
@Mapper
public interface GeneratorHighGoMapper extends GeneratorMapper {
}
@@ -1,97 +0,0 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.codegen.mapper;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pigx.codegen.entity.ColumnEntity;
import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* 代码生成器
*
* @author lengleng
* @date 2018-07-30
*/
public interface GeneratorMapper extends PigxBaseMapper<ColumnEntity> {
/**
* 查询全部的表
* @return
*/
@InterceptorIgnore(tenantLine = "true")
List<Map<String, Object>> queryTable();
/**
* 分页查询表格
* @param page 分页信息
* @param tableName 表名称
* @return
*/
@InterceptorIgnore(tenantLine = "true")
IPage<Map<String, Object>> queryTable(Page page, @Param("tableName") String tableName);
/**
* 查询表信息
* @param tableName 表名称
* @param dsName 数据源名称
* @return
*/
@DS("#last")
@InterceptorIgnore(tenantLine = "true")
Map<String, String> queryTable(@Param("tableName") String tableName, String dsName);
/**
* 分页查询表分页信息
* @param page
* @param tableName
* @param dsName
* @return
*/
@DS("#last")
@InterceptorIgnore(tenantLine = "true")
IPage<ColumnEntity> selectTableColumn(Page page, @Param("tableName") String tableName,
@Param("dsName") String dsName);
/**
* 查询表全部列信息
* @param tableName
* @param dsName
* @return
*/
@DS("#last")
@InterceptorIgnore(tenantLine = "true")
List<ColumnEntity> selectTableColumn(@Param("tableName") String tableName, @Param("dsName") String dsName);
/**
* 查询表全部列信息
* @param tableName 表名称
* @param dsName 数据源名称
* @return
*/
@DS("#last")
@InterceptorIgnore(tenantLine = "true")
List<Map<String, String>> selectMapTableColumn(@Param("tableName") String tableName, String dsName);
}
@@ -1,31 +0,0 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.codegen.mapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 支持 SQL SERVER 代码生成器
*
* @author lengleng
* @date 2020-12-11
*/
@Mapper
public interface GeneratorMssqlMapper extends GeneratorMapper {
}
@@ -1,31 +0,0 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.codegen.mapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 支持 mysql 代码生成器
*
* @author lengleng
* @date 2020-12-11
*/
@Mapper
public interface GeneratorMysqlMapper extends GeneratorMapper {
}
@@ -1,31 +0,0 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.codegen.mapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 支持 Oracle 代码生成器
*
* @author lengleng
* @date 2020-12-11
*/
@Mapper
public interface GeneratorOracleMapper extends GeneratorMapper {
}
@@ -1,31 +0,0 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.codegen.mapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 支持 PostgreSQL 代码生成器
*
* @author lengleng
* @date 2020-12-11
*/
@Mapper()
public interface GeneratorPostgresqlMapper extends GeneratorMapper {
}
@@ -19,7 +19,7 @@ package com.pig4cloud.pigx.codegen.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.codegen.entity.GenGroupEntity;
import com.pig4cloud.pigx.codegen.util.vo.GroupVo;
import com.pig4cloud.pigx.codegen.util.vo.GroupVO;
import com.pig4cloud.pigx.codegen.util.vo.TemplateGroupDTO;
/**
@@ -42,12 +42,12 @@ public interface GenGroupService extends IService<GenGroupEntity> {
* 查询group数据
* @param id
*/
GroupVo getGroupVoById(Long id);
GroupVO getGroupVoById(Long id);
/**
* 更新group数据
* @param groupVo
* @param GroupVo
*/
void updateGroupAndTemplateById(GroupVo groupVo);
void updateGroupAndTemplateById(GroupVO GroupVo);
}
@@ -21,9 +21,9 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.codegen.entity.GenTable;
import org.anyline.metadata.Table;
import java.util.List;
import java.util.Map;
/**
* 列属性
@@ -33,19 +33,50 @@ import java.util.Map;
*/
public interface GenTableService extends IService<GenTable> {
/**
* 获取默认配置信息
* @param path 配置文件路径
* @return
*/
Map<String, Object> getGeneratorConfig();
IPage list(Page<GenTable> page, GenTable table);
/**
* 查询对应数据源的表
*
* @param page 分页信息
* @param table 查询条件
* @return 表
*/
IPage queryTablePage(Page<Table> page, GenTable table);
GenTable queryOrBuildTable(String dsName, String tableName);
/**
* 查询表信息(列),然后插入到中间表中
*
* @param dsName 数据源
* @param tableName 表名
* @return GenTable
*/
GenTable queryOrBuildTable(String dsName, String tableName);
List<Map<String, Object>> queryDsAllTable(String dsName);
/**
* 查询表ddl 语句
*
* @param dsName 数据源名称
* @param tableName 表名称
* @return ddl 语句
* @throws Exception
*/
String queryTableDdl(String dsName, String tableName) throws Exception;
List<Map<String, String>> queryColumn(String dsName, String tableName);
/**
* 查询数据源里面的全部表
*
* @param dsName 数据源名称
* @return table
*/
List<String> queryTableList(String dsName);
/**
* 查询表的全部字段
*
* @param dsName 数据源
* @param tableName 表名称
* @return column
*/
List<String> queryTableColumn(String dsName, String tableName);
}
@@ -19,6 +19,7 @@ package com.pig4cloud.pigx.codegen.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.pig4cloud.pigx.codegen.entity.GenTemplateEntity;
import com.pig4cloud.pigx.common.core.util.R;
/**
* 模板
@@ -28,4 +29,17 @@ import com.pig4cloud.pigx.codegen.entity.GenTemplateEntity;
*/
public interface GenTemplateService extends IService<GenTemplateEntity> {
/**
* 检查版本
* @return {@link R }
*/
R checkVersion();
/**
* 在线更新
*
* @return {@link R }
*/
R onlineUpdate();
}
@@ -27,39 +27,50 @@ import java.util.zip.ZipOutputStream;
*/
public interface GeneratorService {
/**
* 生成代码zip写出
* @param tableId 表
* @param zip 输出流
*/
void downloadCode(Long tableId, ZipOutputStream zip);
/**
* 生成代码zip写出
*
* @param tableId 表
* @param zip 输出流
*/
void downloadCode(Long tableId, ZipOutputStream zip);
/**
* 预览代码
* @param tableId 表
* @return [{模板名称:渲染结果}]
*/
List<Map<String, String>> preview(Long tableId);
/**
* 预览代码
*
* @param tableId 表
* @return [{模板名称:渲染结果}]
*/
List<Map<String, String>> preview(Long tableId);
/**
* 目标目录写入渲染结果
* @param tableId 表
*/
void generatorCode(Long tableId);
/**
* 目标目录写入渲染结果
*
* @param tableId 表
*/
void generatorCode(Long tableId);
/**
* 获取表单设计器需要的 JSON
* @param dsName 数据源名称
* @param tableName 表名称
* @return json string
*/
String vform(String dsName, String tableName);
/**
* 获取表单设计器需要的 JSON
*
* @param dsName 数据源名称
* @param tableName 表名称
* @return json string
*/
String vform(String dsName, String tableName);
/**
* 获取表单设计器需要的 JSON
* @param formId 数据源名称
* @return json string
*/
String vformSfc(Long formId);
/**
* 获取表单设计器需要的 JSON
*
* @param formId 数据源名称
* @return json string
*/
String vformSfc(Long formId);
/**
* 同步路由和菜单
*
* @param tableId 表ID
*/
void syncRouteAndMenu(Long tableId);
}
@@ -110,7 +110,7 @@ public class GenDatasourceConfServiceImpl extends ServiceImpl<GenDatasourceConfM
public Boolean removeByDsId(Long[] dsIds) {
DynamicRoutingDataSource dynamicRoutingDataSource = SpringContextHolder.getBean(DynamicRoutingDataSource.class);
this.baseMapper.selectBatchIds(CollUtil.toList(dsIds))
.forEach(ds -> dynamicRoutingDataSource.removeDataSource(ds.getName()));
.forEach(ds -> dynamicRoutingDataSource.removeDataSource(ds.getName()));
this.baseMapper.deleteBatchIds(CollUtil.toList(dsIds));
return Boolean.TRUE;
}
@@ -70,7 +70,8 @@ public class GenFormConfServiceImpl extends ServiceImpl<GenFormConfMapper, GenFo
}
else {
int span = Optional.ofNullable(json.getJSONObject(VFormConfigConsts.options))
.map(options -> options.getInt(VFormConfigConsts.span, 24)).orElse(24);
.map(options -> options.getInt(VFormConfigConsts.span, 24))
.orElse(24);
jsonObject.set(VFormConfigConsts.span, span);
@@ -25,7 +25,7 @@ import com.pig4cloud.pigx.codegen.entity.GenTemplateGroupEntity;
import com.pig4cloud.pigx.codegen.mapper.GenGroupMapper;
import com.pig4cloud.pigx.codegen.service.GenGroupService;
import com.pig4cloud.pigx.codegen.service.GenTemplateGroupService;
import com.pig4cloud.pigx.codegen.util.vo.GroupVo;
import com.pig4cloud.pigx.codegen.util.vo.GroupVO;
import com.pig4cloud.pigx.codegen.util.vo.TemplateGroupDTO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -78,7 +78,7 @@ public class GenGroupServiceImpl extends ServiceImpl<GenGroupMapper, GenGroupEnt
this.removeBatchByIds(CollUtil.toList(ids));
// 删除关系
genTemplateGroupService
.remove(Wrappers.<GenTemplateGroupEntity>lambdaQuery().in(GenTemplateGroupEntity::getGroupId, ids));
.remove(Wrappers.<GenTemplateGroupEntity>lambdaQuery().in(GenTemplateGroupEntity::getGroupId, ids));
}
/**
@@ -87,7 +87,7 @@ public class GenGroupServiceImpl extends ServiceImpl<GenGroupMapper, GenGroupEnt
* @return
*/
@Override
public GroupVo getGroupVoById(Long id) {
public GroupVO getGroupVoById(Long id) {
return baseMapper.getGroupVoById(id);
}
@@ -96,7 +96,7 @@ public class GenGroupServiceImpl extends ServiceImpl<GenGroupMapper, GenGroupEnt
* @param groupVo
*/
@Override
public void updateGroupAndTemplateById(GroupVo groupVo) {
public void updateGroupAndTemplateById(GroupVO groupVo) {
// 1.更新自身
GenGroupEntity groupEntity = new GenGroupEntity();
BeanUtil.copyProperties(groupVo, groupEntity);
@@ -81,8 +81,9 @@ public class GenTableColumnServiceImpl extends ServiceImpl<GenTableColumnMapper,
public void updateTableField(String dsName, String tableName, List<GenTableColumnEntity> tableFieldList) {
AtomicInteger sort = new AtomicInteger();
this.updateBatchById(tableFieldList.stream().peek(field -> field.setSort(sort.getAndIncrement()))
.collect(Collectors.toList()));
this.updateBatchById(tableFieldList.stream()
.peek(field -> field.setSort(sort.getAndIncrement()))
.collect(Collectors.toList()));
}
}
@@ -16,37 +16,44 @@
*/
package com.pig4cloud.pigx.codegen.service.impl;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.NamingCase;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.codegen.config.PigxCodeGenDefaultProperties;
import com.pig4cloud.pigx.codegen.entity.GenGroupEntity;
import com.pig4cloud.pigx.codegen.entity.GenTable;
import com.pig4cloud.pigx.codegen.entity.GenTableColumnEntity;
import com.pig4cloud.pigx.codegen.mapper.GenTableMapper;
import com.pig4cloud.pigx.codegen.mapper.GeneratorMapper;
import com.pig4cloud.pigx.codegen.service.GenGroupService;
import com.pig4cloud.pigx.codegen.service.GenTableColumnService;
import com.pig4cloud.pigx.codegen.service.GenTableService;
import com.pig4cloud.pigx.codegen.util.*;
import com.pig4cloud.pigx.codegen.util.AutoFillEnum;
import com.pig4cloud.pigx.codegen.util.BoolFillEnum;
import com.pig4cloud.pigx.codegen.util.CommonColumnFiledEnum;
import com.pig4cloud.pigx.codegen.util.GenKit;
import lombok.RequiredArgsConstructor;
import org.anyline.metadata.Column;
import org.anyline.metadata.Database;
import org.anyline.metadata.Table;
import org.anyline.proxy.ServiceProxy;
import org.anyline.service.AnylineService;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* 列属性
@@ -58,147 +65,208 @@ import java.util.Objects;
@RequiredArgsConstructor
public class GenTableServiceImpl extends ServiceImpl<GenTableMapper, GenTable> implements GenTableService {
/**
* 默认配置信息
*/
private static final String CONFIG_PATH = "template/config.json";
private final PigxCodeGenDefaultProperties defaultProperties;
private final GenTableColumnService columnService;
private final GenTableColumnService columnService;
private final GenGroupService genGroupService;
private final GenGroupService genGroupService;
/**
* 获取配置信息
* @param path 配置文件路径
* @return
*/
@Override
public Map<String, Object> getGeneratorConfig() {
ClassPathResource classPathResource = new ClassPathResource(CONFIG_PATH);
JSONObject jsonObject = JSONUtil.parseObj(IoUtil.readUtf8(classPathResource.getStream()));
return jsonObject.getRaw();
}
@Override
public List<Map<String, Object>> queryDsAllTable(String dsName) {
GeneratorMapper mapper = GenKit.getMapper(dsName);
// 手动切换数据源
DynamicDataSourceContextHolder.push(dsName);
return mapper.queryTable();
}
/**
* 查询表ddl 语句
*
* @param dsName 数据源名称
* @param tableName 表名称
* @return ddl 语句
* @throws Exception
*/
@Override
public String queryTableDdl(String dsName, String tableName) throws Exception {
// 手动切换数据源
DynamicDataSourceContextHolder.push(dsName);
Table table = ServiceProxy.metadata().table(tableName); // 获取表结构
table.execute(false);// 不执行SQL
ServiceProxy.ddl().create(table);
return table.getDdl();// 返回创建表的DDL
}
@Override
public List<Map<String, String>> queryColumn(String dsName, String tableName) {
GeneratorMapper mapper = GenKit.getMapper(dsName);
return mapper.selectMapTableColumn(tableName, dsName);
}
/**
* 查询表的全部字段
*
* @param dsName 数据源
* @param tableName 表名称
* @return column
*/
@Override
public List<String> queryTableColumn(String dsName, String tableName) {
// 手动切换数据源
DynamicDataSourceContextHolder.push(dsName);
return ServiceProxy.metadata().columns(tableName).values().stream().map(Column::getName).collect(Collectors.toList());
}
@Override
public IPage list(Page<GenTable> page, GenTable table) {
GeneratorMapper mapper = GenKit.getMapper(table.getDsName());
// 手动切换数据源
DynamicDataSourceContextHolder.push(table.getDsName());
return mapper.queryTable(page, table.getTableName());
}
/**
* 查询对应数据源的表
*
* @param page 分页信息
* @param table 查询条件
* @return 表
*/
@Override
public IPage queryTablePage(Page<Table> page, GenTable table) {
// 手动切换数据源
DynamicDataSourceContextHolder.push(table.getDsName());
List<Table> tableList = ServiceProxy.metadata().tables()
.values().stream().filter(t -> {
if (StrUtil.isBlank(table.getTableName())) {
return true;
}
/**
* 获取表信息
* @param dsName
* @param tableName
* @return
*/
@Override
public GenTable queryOrBuildTable(String dsName, String tableName) {
GenTable genTable = baseMapper.selectOne(
Wrappers.<GenTable>lambdaQuery().eq(GenTable::getTableName, tableName).eq(GenTable::getDsName, dsName));
// 如果 genTable 为空, 执行导入
if (Objects.isNull(genTable)) {
genTable = this.tableImport(dsName, tableName);
}
// 通过表名和表注释进行模糊查询
return StrUtil.containsIgnoreCase(t.getName(false), table.getTableName())
|| StrUtil.containsIgnoreCase(t.getComment(), table.getTableName());
})
// 根据 createTime 、updateTime 倒序排序
.sorted((o1, o2) -> {
long time1 = (o1.getUpdateTime() != null ? o1.getUpdateTime().getTime() :
(o1.getCreateTime() != null ? o1.getCreateTime().getTime() : 0));
long time2 = (o2.getUpdateTime() != null ? o2.getUpdateTime().getTime() :
(o2.getCreateTime() != null ? o2.getCreateTime().getTime() : 0));
return NumberUtil.compare(time2, time1);
}).collect(Collectors.toList());
List<GenTableColumnEntity> fieldList = columnService
.list(Wrappers.<GenTableColumnEntity>lambdaQuery().eq(GenTableColumnEntity::getDsName, dsName)
.eq(GenTableColumnEntity::getTableName, tableName).orderByAsc(GenTableColumnEntity::getSort));
genTable.setFieldList(fieldList);
// 根据 page 进行分页
List<Table> records = CollUtil.page((int) page.getCurrent() - 1, (int) page.getSize(), tableList);
page.setTotal(tableList.size());
page.setRecords(records);
return page;
}
// 查询模板分组信息
List<GenGroupEntity> groupEntities = genGroupService.list();
genTable.setGroupList(groupEntities);
return genTable;
}
/**
* 查询数据源里面的全部表
*
* @param dsName 数据源名称
* @return table
*/
@Override
public List<String> queryTableList(String dsName) {
// 手动切换数据源
DynamicDataSourceContextHolder.push(dsName);
return ServiceProxy.metadata().tables().values().stream().map(Table::getName).collect(Collectors.toList());
}
@Transactional(rollbackFor = Exception.class)
public GenTable tableImport(String dsName, String tableName) {
GeneratorMapper mapper = GenKit.getMapper(dsName);
// 手动切换数据源
DynamicDataSourceContextHolder.push(dsName);
/**
* 查询表信息(列),然后插入到中间表中
*
* @param dsName 数据源
* @param tableName 表名
* @return GenTable
*/
@Override
public GenTable queryOrBuildTable(String dsName, String tableName) {
GenTable genTable = baseMapper.selectOne(
Wrappers.<GenTable>lambdaQuery().eq(GenTable::getTableName, tableName).eq(GenTable::getDsName, dsName));
// 如果 genTable 为空, 执行导入
if (Objects.isNull(genTable)) {
genTable = this.tableImport(dsName, tableName);
}
// 查询表是否存在
GenTable table = new GenTable();
List<GenTableColumnEntity> fieldList = columnService.list(Wrappers.<GenTableColumnEntity>lambdaQuery()
.eq(GenTableColumnEntity::getDsName, dsName)
.eq(GenTableColumnEntity::getTableName, tableName)
.orderByAsc(GenTableColumnEntity::getSort));
genTable.setFieldList(fieldList);
// 从数据库获取表信息
Map<String, String> queryTable = mapper.queryTable(tableName, dsName);
// 查询模板分组信息
List<GenGroupEntity> groupEntities = genGroupService.list();
genTable.setGroupList(groupEntities);
return genTable;
}
// 获取默认表配置信息 ()
Map<String, Object> generatorConfig = getGeneratorConfig();
@Transactional(rollbackFor = Exception.class)
public GenTable tableImport(String dsName, String tableName) {
// 手动切换数据源
DynamicDataSourceContextHolder.push(dsName);
JSONObject project = (JSONObject) generatorConfig.get("project");
JSONObject developer = (JSONObject) generatorConfig.get("developer");
// 查询表是否存在
GenTable table = new GenTable();
// 从数据库获取表信息
AnylineService service = ServiceProxy.service();
Table tableMetadata = service.metadata().table(tableName);
Database database = service.metadata().database();
// 获取默认表配置信息 ()
table.setPackageName(project.getStr("packageName"));
table.setVersion(project.getStr("version"));
table.setBackendPath(project.getStr("backendPath"));
table.setFrontendPath(project.getStr("frontendPath"));
table.setAuthor(developer.getStr("author"));
table.setEmail(developer.getStr("email"));
table.setTableName(tableName);
table.setDsName(dsName);
table.setTableComment(MapUtil.getStr(queryTable, "tableComment"));
table.setDbType(MapUtil.getStr(queryTable, "dbType"));
table.setFormLayout(FormLayoutEnum.TWO.getValue());
table.setGeneratorType(GeneratorTypeEnum.ZIP_DOWNLOAD.getValue());
table.setClassName(NamingCase.toPascalCase(tableName));
table.setModuleName(GenKit.getModuleName(table.getPackageName()));
table.setFunctionName(GenKit.getFunctionName(tableName));
table.setCreateTime(LocalDateTime.now());
this.save(table);
table.setPackageName(defaultProperties.getPackageName());
table.setVersion(defaultProperties.getVersion());
table.setBackendPath(defaultProperties.getBackendPath());
table.setFrontendPath(defaultProperties.getFrontendPath());
table.setAuthor(defaultProperties.getAuthor());
table.setEmail(defaultProperties.getEmail());
table.setTableName(tableName);
table.setDsName(dsName);
table.setTableComment(tableMetadata.getComment());
// 获取原生字段数据
List<Map<String, String>> queryColumnList = mapper.selectMapTableColumn(tableName, dsName);
List<GenTableColumnEntity> tableFieldList = new ArrayList<>();
table.setDbType(database.getDatabase().title());
table.setFormLayout(defaultProperties.getFormLayout());
table.setSyncRoute(defaultProperties.getSyncRoute());
table.setGeneratorType(defaultProperties.getGeneratorType());
table.setClassName(NamingCase.toPascalCase(tableName));
// 模块名称默认为 admin
table.setModuleName(defaultProperties.getModuleName());
table.setFunctionName(GenKit.getFunctionName(tableName));
table.setCreateTime(LocalDateTime.now());
for (Map<String, String> columnMap : queryColumnList) {
String columnName = MapUtil.getStr(columnMap, "columnName");
GenTableColumnEntity genTableColumnEntity = new GenTableColumnEntity();
genTableColumnEntity.setTableName(tableName);
genTableColumnEntity.setDsName(dsName);
genTableColumnEntity.setFieldName(MapUtil.getStr(columnMap, "columnName"));
genTableColumnEntity.setFieldComment(MapUtil.getStr(columnMap, "comments"));
genTableColumnEntity.setFieldType(MapUtil.getStr(columnMap, "dataType"));
String columnKey = MapUtil.getStr(columnMap, "columnKey");
genTableColumnEntity.setPrimaryPk((StringUtils.isNotBlank(columnKey) && "PRI".equalsIgnoreCase(columnKey))
? BoolFillEnum.TRUE.getValue() : BoolFillEnum.FALSE.getValue());
genTableColumnEntity.setAutoFill(AutoFillEnum.DEFAULT.name());
genTableColumnEntity.setFormItem(BoolFillEnum.TRUE.getValue());
genTableColumnEntity.setGridItem(BoolFillEnum.TRUE.getValue());
// 使用默认数据源
DynamicDataSourceContextHolder.clear();
this.save(table);
// 审计字段处理
if (EnumUtil.contains(CommonColumnFiledEnum.class, columnName)) {
CommonColumnFiledEnum commonColumnFiledEnum = CommonColumnFiledEnum.valueOf(columnName);
genTableColumnEntity.setFormItem(commonColumnFiledEnum.getFormItem());
genTableColumnEntity.setGridItem(commonColumnFiledEnum.getGridItem());
genTableColumnEntity.setAutoFill(commonColumnFiledEnum.getAutoFill());
genTableColumnEntity.setSort(commonColumnFiledEnum.getSort());
}
tableFieldList.add(genTableColumnEntity);
}
// 初始化字段数据
columnService.initFieldList(tableFieldList);
// 保存列数据
columnService.saveOrUpdateBatch(tableFieldList);
// 获取原生字段数据
List<GenTableColumnEntity> tableFieldList = getGenTableColumnEntities(dsName, tableName, tableMetadata);
table.setFieldList(tableFieldList);
return table;
}
// 初始化字段数据
columnService.initFieldList(tableFieldList);
// 保存列数据
columnService.saveOrUpdateBatch(tableFieldList);
table.setFieldList(tableFieldList);
return table;
}
/**
* 获取表字段信息
*
* @param dsName 数据源信息
* @param tableName 表名称
* @param tableMetadata 表的元数据
* @return list
*/
private static @NotNull List<GenTableColumnEntity> getGenTableColumnEntities(String dsName, String tableName,
Table tableMetadata) {
List<GenTableColumnEntity> tableFieldList = new ArrayList<>();
LinkedHashMap<String, Column> columns = tableMetadata.getColumns();
columns.forEach((columnName, column) -> {
GenTableColumnEntity genTableColumnEntity = new GenTableColumnEntity();
genTableColumnEntity.setTableName(tableName);
genTableColumnEntity.setDsName(dsName);
genTableColumnEntity.setFieldName(column.getName());
genTableColumnEntity.setFieldComment(column.getComment());
genTableColumnEntity.setFieldType(column.getTypeName());
genTableColumnEntity.setPrimaryPk(
column.isPrimaryKey() == 1 ? BoolFillEnum.TRUE.getValue() : BoolFillEnum.FALSE.getValue());
genTableColumnEntity.setAutoFill(AutoFillEnum.DEFAULT.name());
genTableColumnEntity.setFormItem(BoolFillEnum.TRUE.getValue());
genTableColumnEntity.setGridItem(BoolFillEnum.TRUE.getValue());
// 审计字段处理
if (EnumUtil.contains(CommonColumnFiledEnum.class, column.getName())) {
CommonColumnFiledEnum commonColumnFiledEnum = CommonColumnFiledEnum.valueOf(column.getName());
genTableColumnEntity.setFormItem(commonColumnFiledEnum.getFormItem());
genTableColumnEntity.setGridItem(commonColumnFiledEnum.getGridItem());
genTableColumnEntity.setAutoFill(commonColumnFiledEnum.getAutoFill());
genTableColumnEntity.setSort(commonColumnFiledEnum.getSort());
}
tableFieldList.add(genTableColumnEntity);
});
return tableFieldList;
}
}
@@ -16,11 +16,35 @@
*/
package com.pig4cloud.pigx.codegen.service.impl;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.smallbun.screw.core.constant.DefaultConstants;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.codegen.config.PigxCodeGenDefaultProperties;
import com.pig4cloud.pigx.codegen.entity.GenGroupEntity;
import com.pig4cloud.pigx.codegen.entity.GenTemplateEntity;
import com.pig4cloud.pigx.codegen.entity.GenTemplateGroupEntity;
import com.pig4cloud.pigx.codegen.mapper.GenGroupMapper;
import com.pig4cloud.pigx.codegen.mapper.GenTemplateGroupMapper;
import com.pig4cloud.pigx.codegen.mapper.GenTemplateMapper;
import com.pig4cloud.pigx.codegen.service.GenTemplateService;
import com.pig4cloud.pigx.codegen.util.vo.GenTemplateFileVO;
import com.pig4cloud.pigx.common.core.exception.CheckedException;
import com.pig4cloud.pigx.common.core.util.R;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 模板
@@ -28,8 +52,150 @@ import org.springframework.stereotype.Service;
* @author PIG
* @date 2023-02-21 11:08:43
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class GenTemplateServiceImpl extends ServiceImpl<GenTemplateMapper, GenTemplateEntity>
implements GenTemplateService {
implements GenTemplateService {
private final PigxCodeGenDefaultProperties defaultProperties;
private final GenTemplateGroupMapper genTemplateGroupMapper;
private final GenGroupMapper genGroupMapper;
/**
* 在线更新
*
* @return {@link R }
*/
@Override
@Transactional(rollbackFor = Exception.class)
public R onlineUpdate() {
// 获取 config.json 和 version 文件
Map<String, Object> configAndVersion = getConfigAndVersion();
JSONObject configJsonObj = (JSONObject) configAndVersion.get("configJsonObj");
String versionFile = (String) configAndVersion.get("versionFile");
// 查询出全部的模板组名称
Set<String> cgtmConfigGroupNames = configJsonObj.keySet();
// 根据模板组名称+version 查询是否存在,不存在则新增,存在跳过
for (String cgtmConfigGroupName : cgtmConfigGroupNames) {
boolean exists = genGroupMapper.exists(Wrappers.<GenGroupEntity>lambdaQuery()
.eq(GenGroupEntity::getGroupName, cgtmConfigGroupName + versionFile));
if (exists) {
continue;
}
// 插入新的模板组(名称 + VERSION), 再解析 config.json group 里面的所有模板
insertTemplateFiles(versionFile, configJsonObj, cgtmConfigGroupName);
}
return R.ok("更新成功,版本号:" + versionFile);
}
/**
* 检查版本
*
* @return {@link R }
*/
public R checkVersion() {
// 关闭在线更新提示
if (!defaultProperties.isAutoCheckVersion()) {
return R.ok(true);
}
// 获取 config.json 和 version 文件
Map<String, Object> configAndVersion = getConfigAndVersion();
JSONObject configJsonObj = (JSONObject) configAndVersion.get("configJsonObj");
String versionFile = (String) configAndVersion.get("versionFile");
// 查询出全部的模板组名称
boolean exists = false;
Set<String> cgtmConfigGroupNames = configJsonObj.keySet();
for (String cgtmConfigGroupName : cgtmConfigGroupNames) {
exists = genGroupMapper.exists(Wrappers.<GenGroupEntity>lambdaQuery()
.eq(GenGroupEntity::getGroupName, cgtmConfigGroupName + versionFile));
}
return R.ok(exists);
}
/**
* 获取配置和版本
*
* @return {@link Map }<{@link String }, {@link Object }>
*/
private Map<String, Object> getConfigAndVersion() {
// 获取 config.json 和 version 文件
String configFile = getCGTMFile("config.json");
String versionFile = getCGTMFile("VERSION");
// 解析 config.json
JSONObject configJsonObj = JSONUtil.parseObj(configFile);
// 将 configJsonObj 和 versionFile 放入 Map 中
Map<String, Object> configAndVersion = new HashMap<>();
configAndVersion.put("configJsonObj", configJsonObj);
configAndVersion.put("versionFile", versionFile);
return configAndVersion;
}
/**
* 插入模板文件
*
* @param version 版本
* @param configJsonObj config.json
* @param groupName 组名称
*/
private void insertTemplateFiles(String version, JSONObject configJsonObj, String groupName) {
// 创建新的 group
GenGroupEntity genGroupEntity = new GenGroupEntity();
genGroupEntity.setGroupName(groupName + version);
genGroupMapper.insert(genGroupEntity);
// 解析json配置文件
List<GenTemplateFileVO> templateFileVOList = configJsonObj.getBeanList(groupName, GenTemplateFileVO.class);
for (GenTemplateFileVO genTemplateFileVO : templateFileVOList) {
// 1. 获取模板文件
String templateFile = getCGTMFile(genTemplateFileVO.getTemplateFile());
// 2. 插入模板文件
GenTemplateEntity genTemplateEntity = new GenTemplateEntity();
genTemplateEntity.setTemplateName(genTemplateFileVO.getTemplateName() + version);
genTemplateEntity.setTemplateDesc(genTemplateFileVO.getTemplateName() + version);
genTemplateEntity.setTemplateCode(templateFile);
genTemplateEntity.setGeneratorPath(genTemplateFileVO.getGeneratorPath());
baseMapper.insert(genTemplateEntity);
// 3. 插入模板组关联
GenTemplateGroupEntity genTemplateGroupEntity = new GenTemplateGroupEntity();
genTemplateGroupEntity.setTemplateId(genTemplateEntity.getId());
genTemplateGroupEntity.setGroupId(genGroupEntity.getId());
genTemplateGroupMapper.insert(genTemplateGroupEntity);
}
}
/**
* 获取 cgtmfile
*
* @param fileName 文件名
* @return {@link String }
*/
private String getCGTMFile(String fileName) {
HttpResponse response = HttpRequest.get(String.format("%s/CGTM/raw/master/%s", DefaultConstants.CGTM_URL, fileName))
.execute();
if (response.getStatus() == HttpStatus.HTTP_OK || StrUtil.isNotBlank(response.body())) {
return response.body();
} else {
log.warn("在线更新模板失败:{} ,Http Code:{}", fileName, response.getStatus());
throw new CheckedException("在线更新模板失败,任务终止!");
}
}
}
@@ -21,18 +21,31 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.NamingCase;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.pig4cloud.pigx.admin.api.entity.SysMenu;
import com.pig4cloud.pigx.admin.api.entity.SysRouteConf;
import com.pig4cloud.pigx.admin.api.feign.RemoteMenuService;
import com.pig4cloud.pigx.admin.api.feign.RemoteRouteConfService;
import com.pig4cloud.pigx.codegen.config.PigxCodeGenDefaultProperties;
import com.pig4cloud.pigx.codegen.entity.GenFormConf;
import com.pig4cloud.pigx.codegen.entity.GenTable;
import com.pig4cloud.pigx.codegen.entity.GenTableColumnEntity;
import com.pig4cloud.pigx.codegen.entity.GenTemplateEntity;
import com.pig4cloud.pigx.codegen.service.*;
import com.pig4cloud.pigx.codegen.util.DataModelConstants;
import com.pig4cloud.pigx.codegen.util.GeneratorStyleEnum;
import com.pig4cloud.pigx.codegen.util.VelocityKit;
import com.pig4cloud.pigx.codegen.util.vo.GroupVo;
import com.pig4cloud.pigx.codegen.util.vo.GroupVO;
import com.pig4cloud.pigx.common.core.constant.enums.MenuTypeEnum;
import com.pig4cloud.pigx.common.core.constant.enums.YesNoEnum;
import com.pig4cloud.pigx.common.core.exception.CheckedException;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.core.util.RetOps;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
@@ -55,6 +68,8 @@ import java.util.zip.ZipOutputStream;
@RequiredArgsConstructor
public class GeneratorServiceImpl implements GeneratorService {
private final PigxCodeGenDefaultProperties defaultProperties;
private final GenTableColumnService columnService;
private final GenFormConfService formConfService;
@@ -67,6 +82,10 @@ public class GeneratorServiceImpl implements GeneratorService {
private final GenTemplateService genTemplateService;
private final RemoteMenuService menuService;
private final RemoteRouteConfService routeService;
/**
* 生成代码zip写出
*
@@ -79,22 +98,23 @@ public class GeneratorServiceImpl implements GeneratorService {
// 数据模型
Map<String, Object> dataModel = getDataModel(tableId);
Long style = (Long) dataModel.get("style");
Long style = (Long) dataModel.get(GenTable.Fields.style);
GroupVo groupVo = genGroupService.getGroupVoById(style);
GroupVO groupVo = genGroupService.getGroupVoById(style);
List<GenTemplateEntity> templateList = groupVo.getTemplateList();
Map<String, Object> generatorConfig = tableService.getGeneratorConfig();
JSONObject project = (JSONObject) generatorConfig.get("project");
String frontendPath = project.getStr("frontendPath");
String backendPath = project.getStr("backendPath");
String frontendPath = defaultProperties.getFrontendPath();
String backendPath = defaultProperties.getBackendPath();
// 同步数据
this.syncRouteAndMenu(tableId);
for (GenTemplateEntity template : templateList) {
String templateCode = template.getTemplateCode();
String generatorPath = template.getGeneratorPath();
dataModel.put("frontendPath", frontendPath);
dataModel.put("backendPath", backendPath);
dataModel.put(GenTable.Fields.frontendPath, frontendPath);
dataModel.put(GenTable.Fields.backendPath, backendPath);
String content = VelocityKit.renderStr(templateCode, dataModel);
String path = VelocityKit.renderStr(generatorPath, dataModel);
@@ -119,34 +139,42 @@ public class GeneratorServiceImpl implements GeneratorService {
// 数据模型
Map<String, Object> dataModel = getDataModel(tableId);
Long style = (Long) dataModel.get("style");
Long style = (Long) dataModel.get(GenTable.Fields.style);
// 获取模板列表,Lambda 表达式简化代码
List<GenTemplateEntity> templateList = genGroupService.getGroupVoById(style).getTemplateList();
Map<String, Object> generatorConfig = tableService.getGeneratorConfig();
JSONObject project = (JSONObject) generatorConfig.get("project");
String frontendPath = project.getStr("frontendPath");
String backendPath = project.getStr("backendPath");
String frontendPath = defaultProperties.getFrontendPath();
String backendPath = defaultProperties.getBackendPath();
// 如果是同步菜单的模式则不生成SQL
List<Map<String, String>> result = new ArrayList<>();
Long syncMenuId = MapUtil.getLong(dataModel, GenTable.Fields.syncMenuId);
for (GenTemplateEntity template : templateList) {
// 跳过菜单文件生成
if (Objects.nonNull(syncMenuId) && template.getGeneratorPath().contains("menu.sql")) {
continue;
}
return templateList.stream().map(template -> {
String templateCode = template.getTemplateCode();
String generatorPath = template.getGeneratorPath();
// 预览模式下, 使用相对路径展示
dataModel.put("frontendPath", frontendPath);
dataModel.put("backendPath", backendPath);
dataModel.put(GenTable.Fields.frontendPath, frontendPath);
dataModel.put(GenTable.Fields.backendPath, backendPath);
String content = VelocityKit.renderStr(templateCode, dataModel);
String path = VelocityKit.renderStr(generatorPath, dataModel);
// 使用 map 简化代码
return new HashMap<String, String>(4) {
result.add(new HashMap<String, String>(4) {
{
put("code", content);
put("codePath", path);
}
};
}).collect(Collectors.toList());
});
}
return result;
}
/**
@@ -158,18 +186,24 @@ public class GeneratorServiceImpl implements GeneratorService {
public void generatorCode(Long tableId) {
// 数据模型
Map<String, Object> dataModel = getDataModel(tableId);
Long style = (Long) dataModel.get("style");
Long style = (Long) dataModel.get(GenTable.Fields.style);
// 获取模板列表,Lambda 表达式简化代码
List<GenTemplateEntity> templateList = genGroupService.getGroupVoById(style).getTemplateList();
Long syncMenuId = MapUtil.getLong(dataModel, GenTable.Fields.syncMenuId);
this.syncRouteAndMenu(tableId);
for (GenTemplateEntity template : templateList) {
// 跳过菜单文件生成
if (Objects.nonNull(syncMenuId) && template.getGeneratorPath().contains("menu.sql")) {
continue;
}
templateList.forEach(template -> {
String templateCode = template.getTemplateCode();
String generatorPath = template.getGeneratorPath();
String content = VelocityKit.renderStr(templateCode, dataModel);
String path = VelocityKit.renderStr(generatorPath, dataModel);
FileUtil.writeUtf8String(content, path);
});
}
}
/**
@@ -189,16 +223,17 @@ public class GeneratorServiceImpl implements GeneratorService {
Map<String, Object> dataModel = getDataModel(genTable.getId());
// 获取模板信息,Lambda 表达式简化代码
GenTemplateEntity genTemplateEntity = Optional
.ofNullable(genTemplateService.getById(GeneratorStyleEnum.VFORM_JSON.getTemplateId()))
.orElseThrow(() -> new Exception("模板不存在"));
GenTemplateEntity genTemplateEntity = genTemplateService.getOneOpt(Wrappers.<GenTemplateEntity>lambdaQuery()
.likeRight(GenTemplateEntity::getTemplateName, GeneratorStyleEnum.VFORM_JSON.getDesc())
.orderByDesc(GenTemplateEntity::getCreateTime), false
)
.orElseThrow(() -> new CheckedException("模板不存在"));
// 渲染模板并返回结果
return VelocityKit.renderStr(genTemplateEntity.getTemplateCode(), dataModel);
}
/**
* 获取表单设计器需要的 JSON 方法
* 获取sfc vue
*
* @param id 表单配置 ID
* @return JSON 字符串
@@ -221,15 +256,132 @@ public class GeneratorServiceImpl implements GeneratorService {
// 遍历 widgetList
dataModel.put("resultMap", resultMap);
// 获取模板信息
GenTemplateEntity genTemplateEntity = Optional
.ofNullable(genTemplateService.getById(GeneratorStyleEnum.VFORM_FORM.getTemplateId()))
.orElseThrow(() -> new Exception("模板不存在"));
// 获取模板信息 查询模板中最新的 vform.json 文件
GenTemplateEntity genTemplateEntity = genTemplateService.getOneOpt(Wrappers.<GenTemplateEntity>lambdaQuery()
.likeRight(GenTemplateEntity::getTemplateName, GeneratorStyleEnum.VFORM_VUE.getDesc())
.orderByDesc(GenTemplateEntity::getCreateTime), false
)
.orElseThrow(() -> new CheckedException("模板不存在"));
// 渲染模板并返回结果
return VelocityKit.renderStr(genTemplateEntity.getTemplateCode(), dataModel);
}
/**
* 同步路由和菜单
*
* @param tableId 表ID
*/
@Override
public void syncRouteAndMenu(Long tableId) {
GenTable table = tableService.getById(tableId);
syncMenu(table);
syncRoute(table);
}
/**
* 同步菜单,同步按钮
*
* @param table 表配置
*/
private void syncMenu(GenTable table) {
if (Objects.isNull(table.getSyncMenuId())) {
return;
}
String menuName = String.format("%s管理", table.getTableComment());
SysMenu query = new SysMenu();
query.setName(menuName);
query.setMenuType(MenuTypeEnum.LEFT_MENU.getType());
List<SysMenu> existingMenus = RetOps.of(menuService.getMenuDetails(query)).getData().orElse(Collections.emptyList());
if (!CollUtil.isEmpty(existingMenus)) {
return;
}
SysMenu sysMenu = createMenu(table, menuName);
R<SysMenu> sysMenuR = menuService.saveMenu(sysMenu);
if (sysMenuR.getData() != null) {
createButtons(table, sysMenuR.getData().getMenuId());
}
}
/**
* 创建菜单
*
* @param table 表配置
* @param menuName 菜单名称
* @return {@link SysMenu }
*/
private SysMenu createMenu(GenTable table, String menuName) {
SysMenu sysMenu = new SysMenu();
sysMenu.setParentId(table.getSyncMenuId());
sysMenu.setName(menuName);
sysMenu.setMenuType(MenuTypeEnum.LEFT_MENU.getType());
sysMenu.setPath(String.format("/%s/%s/index", table.getModuleName(), table.getFunctionName()));
return sysMenu;
}
/**
* 创建按钮
*
* @param table 表配置
* @param parentId 父 ID
*/
private void createButtons(GenTable table, Long parentId) {
String[] buttonNames = {"查看", "新增", "编辑", "删除", "导入导出"};
String[] permissions = {"view", "add", "edit", "del", "export"};
for (int i = 0; i < buttonNames.length; i++) {
SysMenu button = new SysMenu();
button.setParentId(parentId);
button.setMenuType(MenuTypeEnum.BUTTON.getType());
button.setName(buttonNames[i]);
button.setPermission(String.format("%s_%s_%s", table.getModuleName(), table.getFunctionName(), permissions[i]));
menuService.saveMenu(button);
}
}
/**
* 同步路由
*
* @param table 表配置
*/
private void syncRoute(GenTable table) {
if (!YesNoEnum.YES.getCode().equals(table.getSyncRoute())) {
return;
}
List<SysRouteConf> existingRoutes = RetOps.of(routeService.getRouteDetails()).getData().orElse(Collections.emptyList());
boolean exist = existingRoutes.stream()
.anyMatch(routeConf -> routeConf.getRouteId().equals(table.getModuleName()));
if (exist) {
return;
}
SysRouteConf sysRouteConf = createRoute(table);
routeService.saveSysRouteConf(sysRouteConf);
}
/**
* 创建路由
*
* @param table 表配置
* @return {@link SysRouteConf }
*/
private SysRouteConf createRoute(GenTable table) {
SysRouteConf sysRouteConf = new SysRouteConf();
sysRouteConf.setRouteId(table.getModuleName());
sysRouteConf.setRouteName(table.getModuleName());
sysRouteConf.setPredicates(String.format("[{\"args\": {\"_genkey_0\": \"/%s/**\"}, \"name\": \"Path\"}]", table.getModuleName()));
sysRouteConf.setFilters("[]");
sysRouteConf.setUri(String.format("lb://%s-biz", table.getModuleName()));
return sysRouteConf;
}
/**
* 通过 Lambda 表达式优化的获取数据模型方法
*
@@ -252,33 +404,34 @@ public class GeneratorServiceImpl implements GeneratorService {
Map<String, Object> dataModel = new HashMap<>();
// 填充数据模型
dataModel.put("isSpringBoot3", isSpringBoot3());
dataModel.put("dbType", table.getDbType());
dataModel.put("package", table.getPackageName());
dataModel.put("packagePath", table.getPackageName().replace(".", "/"));
dataModel.put("version", table.getVersion());
dataModel.put("moduleName", table.getModuleName());
dataModel.put("ModuleName", StrUtil.upperFirst(table.getModuleName()));
dataModel.put("functionName", table.getFunctionName());
dataModel.put("FunctionName", StrUtil.upperFirst(table.getFunctionName()));
dataModel.put("formLayout", table.getFormLayout());
dataModel.put("style", table.getStyle());
dataModel.put("author", table.getAuthor());
dataModel.put("datetime", DateUtil.now());
dataModel.put("date", DateUtil.today());
dataModel.put(DataModelConstants.IS_SPRING_BOOT_3, isSpringBoot3());
dataModel.put(DataModelConstants.SYNC_MENU_ID, Objects.nonNull(table.getSyncMenuId()));
dataModel.put(DataModelConstants.DB_TYPE, table.getDbType());
dataModel.put(DataModelConstants.PACKAGE, table.getPackageName());
dataModel.put(DataModelConstants.PACKAGE_PATH, table.getPackageName().replace(".", "/"));
dataModel.put(DataModelConstants.VERSION, table.getVersion());
dataModel.put(DataModelConstants.MODULE_NAME, table.getModuleName());
dataModel.put(DataModelConstants.MODULE_NAME_UPPER_FIRST, StrUtil.upperFirst(table.getModuleName()));
dataModel.put(DataModelConstants.FUNCTION_NAME, table.getFunctionName());
dataModel.put(DataModelConstants.FUNCTION_NAME_UPPER_FIRST, StrUtil.upperFirst(table.getFunctionName()));
dataModel.put(DataModelConstants.FORM_LAYOUT, table.getFormLayout());
dataModel.put(DataModelConstants.STYLE, table.getStyle());
dataModel.put(DataModelConstants.AUTHOR, table.getAuthor());
dataModel.put(DataModelConstants.DATETIME, DateUtil.now());
dataModel.put(DataModelConstants.DATE, DateUtil.today());
setFieldTypeList(dataModel, table);
// 获取导入的包列表
Set<String> importList = fieldTypeService.getPackageByTableId(table.getDsName(), table.getTableName());
dataModel.put("importList", importList);
dataModel.put("tableName", table.getTableName());
dataModel.put("tableComment", table.getTableComment());
dataModel.put("className", StrUtil.lowerFirst(table.getClassName()));
dataModel.put("ClassName", table.getClassName());
dataModel.put("fieldList", table.getFieldList());
dataModel.put(DataModelConstants.IMPORT_LIST, importList);
dataModel.put(DataModelConstants.TABLE_NAME, table.getTableName());
dataModel.put(DataModelConstants.TABLE_COMMENT, table.getTableComment());
dataModel.put(DataModelConstants.CLASS_NAME, StrUtil.lowerFirst(table.getClassName()));
dataModel.put(DataModelConstants.CLASS_NAME_UPPER_FIRST, table.getClassName());
dataModel.put(DataModelConstants.FIELD_LIST, table.getFieldList());
dataModel.put("backendPath", table.getBackendPath());
dataModel.put("frontendPath", table.getFrontendPath());
dataModel.put(DataModelConstants.BACKEND_PATH, table.getBackendPath());
dataModel.put(DataModelConstants.FRONTEND_PATH, table.getFrontendPath());
// 设置子表
String childTableName = table.getChildTableName();
@@ -287,20 +440,20 @@ public class GeneratorServiceImpl implements GeneratorService {
.eq(GenTableColumnEntity::getDsName, table.getDsName())
.eq(GenTableColumnEntity::getTableName, table.getChildTableName())
.list();
dataModel.put("childFieldList", childFieldList);
dataModel.put("childTableName", childTableName);
dataModel.put("mainField", NamingCase.toCamelCase(table.getMainField()));
dataModel.put("childField", NamingCase.toCamelCase(table.getChildField()));
dataModel.put("ChildClassName", NamingCase.toPascalCase(childTableName));
dataModel.put("childClassName", StrUtil.lowerFirst(NamingCase.toPascalCase(childTableName)));
dataModel.put(DataModelConstants.CHILD_FIELD_LIST, childFieldList);
dataModel.put(DataModelConstants.CHILD_TABLE_NAME, childTableName);
dataModel.put(DataModelConstants.MAIN_FIELD, NamingCase.toCamelCase(table.getMainField()));
dataModel.put(DataModelConstants.CHILD_FIELD, NamingCase.toCamelCase(table.getChildField()));
dataModel.put(DataModelConstants.CHILD_CLASS_NAME_UPPER_FIRST, NamingCase.toPascalCase(childTableName));
dataModel.put(DataModelConstants.CHILD_CLASS_NAME, StrUtil.lowerFirst(NamingCase.toPascalCase(childTableName)));
// 设置是否是多租户模式 (判断字段列表中是否包含 tenant_id 字段)
childFieldList.stream().filter(genTableColumnEntity -> genTableColumnEntity.getFieldName().equals("tenant_id"))
.findFirst().ifPresent(columnEntity -> dataModel.put("isChildTenant", true));
.findFirst().ifPresent(columnEntity -> dataModel.put(DataModelConstants.IS_CHILD_TENANT, true));
}
// 设置是否是多租户模式 (判断字段列表中是否包含 tenant_id 字段)
table.getFieldList().stream().filter(genTableColumnEntity -> genTableColumnEntity.getFieldName().equals("tenant_id"))
.findFirst().ifPresent(columnEntity -> dataModel.put("isTenant", true));
.findFirst().ifPresent(columnEntity -> dataModel.put(DataModelConstants.IS_TENANT, true));
return dataModel;
}
@@ -0,0 +1,58 @@
package com.pig4cloud.pigx.codegen.util;
/**
* 代码生成模板中能使用的变量名称
*
* @author lengleng
* @date 2024/7/16
*/
public class DataModelConstants {
// 基本信息
public static final String IS_SPRING_BOOT_3 = "isSpringBoot3";
public static final String SYNC_MENU_ID = "syncMenuId";
public static final String DB_TYPE = "dbType";
public static final String PACKAGE = "package";
public static final String PACKAGE_PATH = "packagePath";
public static final String VERSION = "version";
// 模块和功能名称
public static final String MODULE_NAME = "moduleName";
public static final String MODULE_NAME_UPPER_FIRST = "ModuleName";
public static final String FUNCTION_NAME = "functionName";
public static final String FUNCTION_NAME_UPPER_FIRST = "FunctionName";
// 布局和样式
public static final String FORM_LAYOUT = "formLayout";
public static final String STYLE = "style";
// 作者和时间
public static final String AUTHOR = "author";
public static final String DATETIME = "datetime";
public static final String DATE = "date";
// 导入列表
public static final String IMPORT_LIST = "importList";
// 表信息
public static final String TABLE_NAME = "tableName";
public static final String TABLE_COMMENT = "tableComment";
public static final String CLASS_NAME = "className";
public static final String CLASS_NAME_UPPER_FIRST = "ClassName";
public static final String FIELD_LIST = "fieldList";
// 路径
public static final String BACKEND_PATH = "backendPath";
public static final String FRONTEND_PATH = "frontendPath";
// 子表信息
public static final String CHILD_FIELD_LIST = "childFieldList";
public static final String CHILD_TABLE_NAME = "childTableName";
public static final String MAIN_FIELD = "mainField";
public static final String CHILD_FIELD = "childField";
public static final String CHILD_CLASS_NAME_UPPER_FIRST = "ChildClassName";
public static final String CHILD_CLASS_NAME = "childClassName";
public static final String IS_CHILD_TENANT = "isChildTenant";
// 租户信息
public static final String IS_TENANT = "isTenant";
}
@@ -1,19 +0,0 @@
package com.pig4cloud.pigx.codegen.util;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 表单布局 枚举
*
* @author 阿沐 babamu@126.com
*/
@Getter
@AllArgsConstructor
public enum FormLayoutEnum {
ONE(1), TWO(2);
private final Integer value;
}
@@ -1,18 +1,7 @@
package com.pig4cloud.pigx.codegen.util;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils;
import com.pig4cloud.pigx.codegen.entity.GenDatasourceConf;
import com.pig4cloud.pigx.codegen.mapper.GenDatasourceConfMapper;
import com.pig4cloud.pigx.codegen.mapper.GeneratorMapper;
import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
import com.pig4cloud.pigx.common.datasource.config.DruidDataSourceProperties;
import lombok.experimental.UtilityClass;
import org.springframework.context.ApplicationContext;
import java.util.Map;
/**
* 代码生成工具类
@@ -41,41 +30,4 @@ public class GenKit {
return StrUtil.subAfter(packageName, ".", true);
}
/**
* 获取数据源对应方言的mapper
* @param dsName 数据源名称
* @return GeneratorMapper
*/
public GeneratorMapper getMapper(String dsName) {
// 获取目标数据源数据库类型
GenDatasourceConfMapper datasourceConfMapper = SpringContextHolder.getBean(GenDatasourceConfMapper.class);
GenDatasourceConf datasourceConf = datasourceConfMapper
.selectOne(Wrappers.<GenDatasourceConf>lambdaQuery().eq(GenDatasourceConf::getName, dsName));
String dbConfType;
// 为空 根据jdbc-url推断数据库类型
if (datasourceConf == null) {
DruidDataSourceProperties dataSourceProperties = SpringContextHolder
.getBean(DruidDataSourceProperties.class);
DbType dbType = JdbcUtils.getDbType(dataSourceProperties.getUrl());
dbConfType = dbType.getDb();
}
else {
dbConfType = datasourceConf.getDsType();
}
// 获取全部数据实现
ApplicationContext context = SpringContextHolder.getApplicationContext();
Map<String, GeneratorMapper> beansOfType = context.getBeansOfType(GeneratorMapper.class);
// 根据数据类型选择mapper
for (String key : beansOfType.keySet()) {
if (StrUtil.containsIgnoreCase(key, dbConfType)) {
return beansOfType.get(key);
}
}
throw new IllegalArgumentException("dsName 不合法: " + dsName);
}
}
@@ -12,9 +12,9 @@ import lombok.Getter;
@AllArgsConstructor
public enum GeneratorStyleEnum {
VFORM_JSON(1L, "element-plus 风格"),
VFORM_JSON(1L, "vform.json"),
VFORM_FORM(2L, "uview 风格");
VFORM_VUE(2L, "vform.vue");
/**
* 对应模板ID
@@ -1,26 +0,0 @@
package com.pig4cloud.pigx.codegen.util;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
/**
* 代码生成方式 枚举
*
* @author 阿沐 babamu@126.com
*/
@Getter
@RequiredArgsConstructor
public enum GeneratorTypeEnum {
/**
* zip压缩包 0
*/
ZIP_DOWNLOAD("0"),
/**
* 自定义目录 1
*/
CUSTOM_DIRECTORY("1");
private final String value;
}
@@ -17,10 +17,9 @@ package com.pig4cloud.pigx.codegen.util.vo;
*/
import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.NotBlank;
import lombok.Data;
import java.io.Serializable;
import javax.validation.constraints.NotBlank;
import java.time.LocalDateTime;
/**
@@ -31,7 +30,7 @@ import java.time.LocalDateTime;
*/
@Data
@Schema(description = "自动创建表管理")
public class GenCreateTableVO implements Serializable {
public class GenCreateTableVO {
private static final long serialVersionUID = 1L;
@@ -0,0 +1,37 @@
package com.pig4cloud.pigx.codegen.util.vo;
import lombok.Data;
/**
* @author lengleng
* @date 2024/7/13
* <p>
* CGTM 文件路径
* <p>
* {
* "templateName": "Controller",
* "generatorPath": "${backendPath}/src/main/java/${packagePath}/${moduleName}/controller/${ClassName}Controller.java",
* "templateDesc": "后台Controller",
* "templateFile": "temps/Controller"
* },
*/
@Data
public class GenTemplateFileVO {
/**
* 模板名称
*/
private String templateName;
/**
* 路径
*/
private String generatorPath;
/**
* 模板 desc
*/
private String templateDesc;
/**
* 模板文件
*/
private String templateFile;
}
@@ -9,7 +9,7 @@ import lombok.Data;
import java.util.List;
@Data
public class GroupVo {
public class GroupVO {
/**
* id
@@ -1,25 +0,0 @@
# 数据源
spring:
redis:
host: pigx-redis
database: 9 #避免和微服务 PIGX 冲突
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
url: jdbc:mysql://pigx-mysql:3306/pigxx_boot_codegen?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true
web:
resources:
static-locations: classpath:/static/,classpath:/views/
# 租户表维护
pigx:
tenant:
column: tenant_id
tables:
- gen_datasource_conf
- gen_form_conf
- gen_template
- gen_group
@@ -3,7 +3,7 @@
<mapper namespace="com.pig4cloud.pigx.codegen.mapper.GenGroupMapper">
<resultMap id="genGroupMap" type="com.pig4cloud.pigx.codegen.util.vo.GroupVo">
<resultMap id="genGroupMap" type="com.pig4cloud.pigx.codegen.util.vo.GroupVO">
<id property="id" column="group_id"/>
<result property="groupName" column="group_name"/>
<result property="groupDesc" column="group_desc"/>
@@ -1,44 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pig4cloud.pigx.codegen.mapper.GeneratorDB2Mapper">
<select id="queryTable" resultType="map">
SELECT
'db2' AS "dbType",
TABNAME AS "tableName",
REMARKS AS "tableComment",
CREATE_TIME AS "createTime"
FROM syscat.TABLES
WHERE TABSCHEMA = (SELECT CURRENT_SCHEMA
FROM SYSIBM.SYSDUMMY1
)
<if test="tableName != null and tableName.trim() != ''">
and TABNAME = #{tableName}
</if>
ORDER BY CREATE_TIME DESC
</select>
<sql id="queryColumn">
SELECT 'db2' AS "dbType",
COLNAME AS "columnName",
TYPENAME AS "dataType",
REMARKS AS "comments",
TYPENAME AS "columnType"
FROM SYSCAT.COLUMNS
WHERE TABSCHEMA = (SELECT CURRENT_SCHEMA
FROM SYSIBM.SYSDUMMY1
)
and TABNAME = #{tableName}
</sql>
<select id="selectTableColumn" resultType="com.pig4cloud.pigx.codegen.entity.ColumnEntity">
<include refid="queryColumn"/>
</select>
<select id="selectMapTableColumn" resultType="map">
<include refid="queryColumn"/>
</select>
</mapper>
@@ -1,70 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pig4cloud.pigx.codegen.mapper.GeneratorDmMapper">
<select id="queryTable" resultType="map">
SELECT
DISTINCT utc.TABLE_NAME AS "tableName",
utc.comments AS "tableComment"
FROM user_tab_comments utc
<where>
<if test="tableName != null and tableName.trim() != ''">
and utc.TABLE_NAME = #{tableName}
</if>
</where>
ORDER BY utc.TABLE_NAME
</select>
<sql id="queryColumn">
SELECT
'dm' AS "dbType",
TEMP.COLUMN_NAME AS "columnName",
TEMP.data_type AS "columnType",
TEMP.data_type AS "dataType",
TEMP.comments AS "comments",
CASE
TEMP.constraint_type
WHEN 'P' THEN
'PRI'
WHEN 'C' THEN
'UNI' ELSE''
END "columnKey"
FROM
(
SELECT
col.column_id,
col.COLUMN_NAME,
col.data_type,
colc.comments,
uc.constraint_type,
ROW_NUMBER ( ) OVER (
PARTITION BY col.COLUMN_NAME
ORDER BY
uc.constraint_type DESC
) AS row_flg
FROM
user_tab_columns col
LEFT JOIN user_col_comments colc ON colc.TABLE_NAME = col.TABLE_NAME
AND colc.COLUMN_NAME = col.
COLUMN_NAME LEFT JOIN user_cons_columns ucc ON ucc.TABLE_NAME = col.TABLE_NAME
AND ucc.COLUMN_NAME = col.
COLUMN_NAME LEFT JOIN user_constraints uc ON uc.CONSTRAINT_NAME = ucc.CONSTRAINT_NAME
WHERE
col.TABLE_NAME = #{tableName}
) TEMP
WHERE
TEMP.row_flg = 1
ORDER BY
TEMP.column_id
</sql>
<select id="selectTableColumn" resultType="com.pig4cloud.pigx.codegen.entity.ColumnEntity">
<include refid="queryColumn"/>
</select>
<select id="selectMapTableColumn" resultType="map">
<include refid="queryColumn"/>
</select>
</mapper>
@@ -1,65 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pig4cloud.pigx.codegen.mapper.GeneratorHighGoMapper">
<select id="queryTable" resultType="map">
SELECT
relname AS "tableName",
obj_description ( oid ) AS "tableComment"
FROM
pg_class
WHERE
relkind = 'r'
<if test="tableName != null and tableName.trim() != ''">
and relname = #{tableName}
</if>
AND relname NOT LIKE'pg_%'
AND relname NOT LIKE'sql_%'
AND relchecks = 0
AND relnamespace = (
SELECT
oid
FROM
pg_namespace
WHERE
nspname = ( SELECT CURRENT_SCHEMA ( ) )
)
ORDER BY relname
</select>
<sql id="queryColumn">
SELECT
'highgo' AS "dbType",
pa.attname AS "columnName",
pg_type.typname AS "columnType",
pg_type.typname AS "dataType",
col_description ( pa.attrelid, pa.attnum ) AS "comments",
(
CASE
pcon.contype
WHEN 'p' THEN
'PRI' ELSE''
END
) AS "columnKey"
FROM
pg_class AS pc,
pg_attribute AS pa
INNER JOIN pg_type ON pg_type.oid = pa.atttypid
LEFT JOIN pg_constraint pcon ON pa.attnum = pcon.conkey[1]
AND pa.attrelid = pcon.conrelid
WHERE
pc.relname = #{ tableName }
AND pa.attrelid = pc.oid
AND pa.attnum > 0
</sql>
<select id="selectTableColumn" resultType="com.pig4cloud.pigx.codegen.entity.ColumnEntity">
<include refid="queryColumn"/>
</select>
<select id="selectMapTableColumn" resultType="map">
<include refid="queryColumn"/>
</select>
</mapper>
@@ -1,86 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pig4cloud.pigx.codegen.mapper.GeneratorMssqlMapper">
<select id="queryTable" resultType="map">
SELECT *
FROM (
SELECT CAST
(so.NAME AS nvarchar(500)) AS tableName,
CAST(sep.VALUE AS nvarchar(500)) AS tableComment
FROM sysobjects so
LEFT JOIN sys.extended_properties sep ON sep.major_id = so.ID
AND sep.minor_id = 0
WHERE (xtype = 'U' OR xtype = 'v')
) T
<where>
<if test="tableName != null and tableName.trim() != ''">
and T.tableName = #{tableName}
</if>
</where>
</select>
<sql id="queryColumn">
SELECT
'mssql' AS dbType,
CAST ( b.NAME AS NVARCHAR ( 500 ) ) AS columnName,
CAST ( sys.types.NAME AS NVARCHAR ( 500 ) ) AS dataType,
CAST ( sys.types.NAME AS NVARCHAR ( 500 ) ) AS columnType,
CAST ( c.VALUE AS NVARCHAR ( 500 ) ) AS comments,
(
SELECT
CASE
COUNT
( 1 )
WHEN 1 THEN
'PRI' ELSE ''
END
FROM
syscolumns,
sysobjects,
sysindexes,
sysindexkeys,
systypes
WHERE
syscolumns.xusertype = systypes.xusertype
AND syscolumns.id = object_id( A.NAME )
AND sysobjects.xtype = 'PK'
AND sysobjects.parent_obj = syscolumns.id
AND sysindexes.id = syscolumns.id
AND sysobjects.NAME = sysindexes.NAME
AND sysindexkeys.id = syscolumns.id
AND sysindexkeys.indid = sysindexes.indid
AND syscolumns.colid = sysindexkeys.colid
AND syscolumns.NAME = B.NAME
) AS columnKey,
'' AS extra
FROM
(
SELECT
name,
object_id
FROM
sys.tables UNION ALL
SELECT
name,
object_id
FROM
sys.views
) a
INNER JOIN sys.COLUMNS b ON b.object_id = a.object_id
LEFT JOIN sys.types ON b.user_type_id = sys.types.user_type_id
LEFT JOIN sys.extended_properties c ON c.major_id = b.object_id
AND c.minor_id = b.column_id
WHERE a.NAME = #{tableName} and sys.types.NAME != 'sysname'
</sql>
<select id="selectTableColumn" resultType="com.pig4cloud.pigx.codegen.entity.ColumnEntity">
<include refid="queryColumn"/>
</select>
<select id="selectMapTableColumn" resultType="map">
<include refid="queryColumn"/>
</select>
</mapper>
@@ -1,48 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pig4cloud.pigx.codegen.mapper.GeneratorMysqlMapper">
<select id="queryTable" resultType="map">
SELECT
'mysql' AS dbType,
table_name AS tableName,
ENGINE,
table_comment AS tableComment,
create_time AS createTime
FROM
information_schema.TABLES
WHERE
table_schema = (
SELECT DATABASE
())
<if test="tableName != null and tableName.trim() != ''">
and table_name = #{tableName}
</if>
order by create_time desc
</select>
<sql id="queryColumn">
SELECT
column_name columnName,
data_type dataType,
column_comment comments,
column_key columnKey,
extra,
is_nullable AS isNullable,
column_type AS columnType
FROM
information_schema.COLUMNS
WHERE
table_name = #{tableName} and table_schema = (select database()) order by ordinal_position
</sql>
<select id="selectTableColumn" resultType="com.pig4cloud.pigx.codegen.entity.ColumnEntity">
<include refid="queryColumn"/>
</select>
<select id="selectMapTableColumn" resultType="map">
<include refid="queryColumn"/>
</select>
</mapper>
@@ -1,72 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pig4cloud.pigx.codegen.mapper.GeneratorOracleMapper">
<select id="queryTable" resultType="map">
SELECT
ut.TABLE_NAME AS "tableName",
utc.comments AS "tableComment"
FROM
user_tables ut,
user_tab_comments utc
WHERE
ut.TABLE_NAME = utc.TABLE_NAME
<if test="tableName != null and tableName.trim() != ''">
and ut.TABLE_NAME = #{tableName}
</if>
ORDER BY ut.TABLE_NAME
</select>
<sql id="queryColumn">
SELECT
'oracle' AS "dbType",
TEMP.COLUMN_NAME AS "columnName",
TEMP.data_type AS "columnType",
TEMP.data_type AS "dataType",
TEMP.comments AS "comments",
CASE
TEMP.constraint_type
WHEN 'P' THEN
'PRI'
WHEN 'C' THEN
'UNI' ELSE''
END "columnKey"
FROM
(
SELECT
col.column_id,
col.COLUMN_NAME,
col.data_type,
colc.comments,
uc.constraint_type,
ROW_NUMBER ( ) OVER (
PARTITION BY col.COLUMN_NAME
ORDER BY
uc.constraint_type DESC
) AS row_flg
FROM
user_tab_columns col
LEFT JOIN user_col_comments colc ON colc.TABLE_NAME = col.TABLE_NAME
AND colc.COLUMN_NAME = col.
COLUMN_NAME LEFT JOIN user_cons_columns ucc ON ucc.TABLE_NAME = col.TABLE_NAME
AND ucc.COLUMN_NAME = col.
COLUMN_NAME LEFT JOIN user_constraints uc ON uc.CONSTRAINT_NAME = ucc.CONSTRAINT_NAME
WHERE
col.TABLE_NAME = #{tableName}
) TEMP
WHERE
TEMP.row_flg = 1
ORDER BY
TEMP.column_id
</sql>
<select id="selectTableColumn" resultType="com.pig4cloud.pigx.codegen.entity.ColumnEntity">
<include refid="queryColumn"/>
</select>
<select id="selectMapTableColumn" resultType="map">
<include refid="queryColumn"/>
</select>
</mapper>
@@ -1,57 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pig4cloud.pigx.codegen.mapper.GeneratorPostgresqlMapper">
<select id="queryTable" resultType="map">
SELECT
relname AS "tableName",
obj_description ( oid ) AS "tableComment"
FROM
pg_class pc
WHERE
relkind = 'r'
AND relname NOT LIKE'pg_%'
AND relname NOT LIKE'sql_%'
AND relchecks = 0
<if test="tableName != null and tableName.trim() != ''">
and pc.relname = #{tableName}
</if>
ORDER BY relname
</select>
<sql id="queryColumn">
SELECT
'pg' AS "dbType",
pa.attname AS "columnName",
pg_type.typname AS "columnType",
pg_type.typname AS "dataType",
col_description ( pa.attrelid, pa.attnum ) AS "comments",
(
CASE
pcon.contype
WHEN 'p' THEN
'PRI' ELSE''
END
) AS "columnKey"
FROM
pg_class AS pc,
pg_attribute AS pa
INNER JOIN pg_type ON pg_type.oid = pa.atttypid
LEFT JOIN pg_constraint pcon ON pa.attnum = pcon.conkey[1]
AND pa.attrelid = pcon.conrelid
WHERE
pc.relname = #{ tableName }
AND pa.attrelid = pc.oid
AND pa.attnum > 0
</sql>
<select id="selectTableColumn" resultType="com.pig4cloud.pigx.codegen.entity.ColumnEntity">
<include refid="queryColumn"/>
</select>
<select id="selectMapTableColumn" resultType="map">
<include refid="queryColumn"/>
</select>
</mapper>
@@ -1,12 +0,0 @@
{
"project": {
"packageName": "com.pig4cloud.pigx",
"version": "1.0.0",
"backendPath": "pigx",
"frontendPath": "pigx-ui"
},
"developer": {
"author": "pig",
"email": "sw@mail.pigx.vip"
}
}
@@ -3,13 +3,11 @@ package com.pig4cloud.pigx.pay.config;
import cn.hutool.core.date.DateUtil;
import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder;
import com.pig4cloud.pigx.common.sequence.builder.DbSeqBuilder;
import com.pig4cloud.pigx.common.sequence.properties.SequenceDbProperties;
import com.pig4cloud.pigx.common.sequence.properties.BaseSequenceProperties;
import com.pig4cloud.pigx.common.sequence.sequence.Sequence;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
/**
* @author lengleng
* @date 2019-05-26
@@ -21,29 +19,34 @@ public class SequenceConfig {
/**
* 订单流水号发号器
* @param dataSource
* @param properties
*
* @param properties 配置
* @return
*/
@Bean
public Sequence paySequence(DataSource dataSource, SequenceDbProperties properties) {
public Sequence paySequence(BaseSequenceProperties properties) {
return DbSeqBuilder.create()
.bizName(() -> String.format("pay_%s_%s", TenantContextHolder.getTenantId(), DateUtil.today()))
.dataSource(dataSource).step(properties.getStep()).retryTimes(properties.getRetryTimes())
.tableName(properties.getTableName()).build();
.step(properties.getStep())
.retryTimes(properties.getDb().getRetryTimes())
.tableName(properties.getDb().getTableName())
.build();
}
/**
* 通道编号发号器
* @param dataSource
* @param properties
*
* @param properties 配置
* @return
*/
@Bean
public Sequence channelSequence(DataSource dataSource, SequenceDbProperties properties) {
return DbSeqBuilder.create().bizName(() -> String.format("channel_%s", TenantContextHolder.getTenantId()))
.dataSource(dataSource).step(properties.getStep()).retryTimes(properties.getRetryTimes())
.tableName(properties.getTableName()).build();
public Sequence channelSequence(BaseSequenceProperties properties) {
return DbSeqBuilder.create()
.bizName(() -> String.format("channel_%s", TenantContextHolder.getTenantId()))
.step(properties.getStep())
.retryTimes(properties.getDb().getRetryTimes())
.tableName(properties.getDb().getTableName())
.build();
}
}