From c078f7eb5ef7c149586c42c022e97021bcb409f8 Mon Sep 17 00:00:00 2001 From: RGK Date: Thu, 26 Dec 2024 13:52:59 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E9=81=BF=E5=85=8D=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E8=A7=A3=E6=9E=90=E5=85=83=E6=95=B0=E6=8D=AE?= =?UTF-8?q?-=E5=A6=82=E6=9E=9C=E8=A1=A8=E8=BE=BE=E5=BC=8F=E4=B8=AD?= =?UTF-8?q?=E5=AD=98=E5=9C=A8=E9=80=97=E5=8F=B7(,)=EF=BC=8C=E4=BC=9A?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E8=A7=A3=E6=9E=90=E5=87=BA=E7=9A=84=E5=85=83?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E4=B8=A2=E5=A4=B1=E9=80=97=E5=8F=B7=E5=90=8E?= =?UTF-8?q?=E9=9D=A2=E9=83=A8=E5=88=86=E6=AF=94=E5=A6=82:=20##=20filename?= =?UTF-8?q?=3D$\{context.javaBeanName\}Client.java,=20folder=3Dsrc/main/ja?= =?UTF-8?q?va/\{context.packageName.replace('.','/')\}/mapper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/gitee/gen/util/TemplateMetaUtils.java | 43 +++++++++++++++++-- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/gen/src/main/java/com/gitee/gen/util/TemplateMetaUtils.java b/gen/src/main/java/com/gitee/gen/util/TemplateMetaUtils.java index 7dc5384..feba0d4 100644 --- a/gen/src/main/java/com/gitee/gen/util/TemplateMetaUtils.java +++ b/gen/src/main/java/com/gitee/gen/util/TemplateMetaUtils.java @@ -31,11 +31,46 @@ public final class TemplateMetaUtils { * 解析元数据信息 */ public static Map parseMetaRow(String row) { + char[] charArray = row.toCharArray(); + Map data = new HashMap<>(); - String[] paris = row.split("\\s*,\\s*"); - for (String item : paris) { - String[] kv = item.split("="); - data.put(kv[0].trim(), kv.length == 1 ? null : kv[1].trim()); + + StringBuilder kvBuilder = new StringBuilder(); + // 剩余未闭合表达式数量 + int leftExpr = 0; + for (int i = 0, len = charArray.length, end = len - 1; i < len; i++) { + char c = charArray[i]; + boolean kvEnd = false; + if (i == end) { + kvBuilder.append(c); + kvEnd = true; + } else if (',' == c && leftExpr == 0) { + kvEnd = true; + } + + if (kvEnd) { + String[] kv = kvBuilder.toString().trim().split("="); + data.put(kv[0].trim(), kv.length == 1 ? null : kv[1].trim()); + kvBuilder = new StringBuilder(); + continue; + } + + kvBuilder.append(c); + switch (c) { + case '{': + case '(': + leftExpr++; + break; + case '}': + case ')': + leftExpr--; + break; + default: + break; + } + } + if (leftExpr > 0) { + throw new RuntimeException("读取元数据失败,有" + leftExpr + "个表达式未闭合"); } return data; } -- Gitee From 47e8cc35b33a1f11e76f07f2b449e56cb6d0ed4f Mon Sep 17 00:00:00 2001 From: hq1913451454 <1913451454@qq.com> Date: Fri, 31 Oct 2025 12:51:25 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=20=E5=AF=BC?= =?UTF-8?q?=E5=87=BA=E5=88=B0=E6=9C=AC=E5=9C=B0=E7=9B=AE=E5=BD=95=E7=9A=84?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../views/generate/GenerateConfig/index.vue | 12 ++- front/src/views/generate/result.vue | 41 ++++++++- .../com/gitee/gen/common/GeneratorParam.java | 10 +++ .../java/com/gitee/gen/common/MemCache.java | 84 ++++++++++++++++++ .../gen/config/AppRouterInterceptor.java | 2 + .../gen/controller/GeneratorController.java | 54 ++++++++++- .../gitee/gen/entity/DatasourceConfig.java | 11 +++ .../gitee/gen/service/GeneratorService.java | 49 ++++++++++ gen/src/main/resources/gen_init.db | Bin 69632 -> 69632 bytes .../mybatis/DatasourceConfigMapper.xml | 11 +++ 10 files changed, 271 insertions(+), 3 deletions(-) create mode 100644 gen/src/main/java/com/gitee/gen/common/MemCache.java diff --git a/front/src/views/generate/GenerateConfig/index.vue b/front/src/views/generate/GenerateConfig/index.vue index aea8b71..7990300 100644 --- a/front/src/views/generate/GenerateConfig/index.vue +++ b/front/src/views/generate/GenerateConfig/index.vue @@ -37,6 +37,10 @@ + + + + @@ -188,9 +192,12 @@ - + + + + + + 下载全部 + >下载全部 导出到项目路径 + + @@ -56,6 +68,7 @@ import JSZip from 'jszip' import { saveAs } from 'file-saver' import { codemirror } from 'vue-codemirror' import 'codemirror/theme/neat.css' +import {configs} from "eslint-plugin-vue"; require('codemirror/mode/javascript/javascript') require('codemirror/mode/clike/clike') require('codemirror/mode/htmlembedded/htmlembedded') @@ -72,6 +85,11 @@ const mode_map = { 'xml': 'application/xml' } export default { + computed: { + configs() { + return configs + } + }, components: { codemirror }, data() { return { @@ -80,6 +98,7 @@ export default { datasourceConfigId: '', tableNames: [], templateConfigIdList: [], + outPath: "", packageName: '' }, treeData: [], @@ -217,7 +236,27 @@ export default { // see FileSaver.js saveAs(content, `code-${new Date().getTime()}.zip`) }) + }, + exportToProject() { + if (!this.clientParam.outPath) { + this.tip('项目路径为空', 'error') + return + } + if (this.loading) { + return + } + this.loading = true + this.post(`/generate/export`, { + ...this.clientParam, + + }, function(resp) { + this.tip('导出成功', 'success') + this.loading = false + }) + } + + } } diff --git a/gen/src/main/java/com/gitee/gen/common/GeneratorParam.java b/gen/src/main/java/com/gitee/gen/common/GeneratorParam.java index f2b9241..bd2ccce 100644 --- a/gen/src/main/java/com/gitee/gen/common/GeneratorParam.java +++ b/gen/src/main/java/com/gitee/gen/common/GeneratorParam.java @@ -13,6 +13,7 @@ public class GeneratorParam { private List templateConfigIdList; private String packageName; + private String outPath; private String delPrefix; @@ -20,6 +21,14 @@ public class GeneratorParam { private String charset = "UTF-8"; + public String getOutPath() { + return outPath; + } + + public void setOutPath(String outPath) { + this.outPath = outPath; + } + public int getDatasourceConfigId() { return datasourceConfigId; } @@ -83,6 +92,7 @@ public class GeneratorParam { ", tableNames=" + tableNames + ", templateConfigIdList=" + templateConfigIdList + ", packageName='" + packageName + '\'' + + ", projectRoot='" + outPath + '\'' + ", delPrefix='" + delPrefix + '\'' + ", author='" + author + '\'' + ", charset='" + charset + '\'' + diff --git a/gen/src/main/java/com/gitee/gen/common/MemCache.java b/gen/src/main/java/com/gitee/gen/common/MemCache.java new file mode 100644 index 0000000..7e4b056 --- /dev/null +++ b/gen/src/main/java/com/gitee/gen/common/MemCache.java @@ -0,0 +1,84 @@ +package com.gitee.gen.common; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * 简易内存缓存:LRU + 10 分钟过期(最后一次访问) + */ +public class MemCache { + + private final int maxSize; + private final long expireMillis; + + /* 存数据 + 时间戳 */ + private static class ValueWrapper { + V value; + long lastAccess; + + ValueWrapper(V v) { + this.value = v; + this.lastAccess = System.currentTimeMillis(); + } + } + + private final Map> map; + private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + + public MemCache(int maxSize, long expireMinutes) { + this.maxSize = maxSize; + this.expireMillis = expireMinutes * 60 * 1000; + + // LinkedHashMap 实现 LRU + this.map = new LinkedHashMap>(16, 0.75f, true) { + @Override + protected boolean removeEldestEntry(Map.Entry> eldest) { + return size() > MemCache.this.maxSize; + } + }; + } + + public void put(K key, V value) { + lock.writeLock().lock(); + try { + map.put(key, new ValueWrapper<>(value)); + } finally { + lock.writeLock().unlock(); + } + } + + public V get(K key) { + lock.readLock().lock(); + try { + ValueWrapper w = map.get(key); + if (w == null) return null; + // 过期判断 + if (System.currentTimeMillis() - w.lastAccess > expireMillis) { + lock.readLock().unlock(); + lock.writeLock().lock(); + try { + map.remove(key); + } finally { + lock.writeLock().unlock(); + } + return null; + } + // 更新时间戳 + w.lastAccess = System.currentTimeMillis(); + return w.value; + } finally { + lock.readLock().unlock(); + } + } + + public V remove(K key) { + lock.writeLock().lock(); + try { + ValueWrapper w = map.remove(key); + return w == null ? null : w.value; + } finally { + lock.writeLock().unlock(); + } + } +} \ No newline at end of file diff --git a/gen/src/main/java/com/gitee/gen/config/AppRouterInterceptor.java b/gen/src/main/java/com/gitee/gen/config/AppRouterInterceptor.java index 0d92977..ca27cbf 100644 --- a/gen/src/main/java/com/gitee/gen/config/AppRouterInterceptor.java +++ b/gen/src/main/java/com/gitee/gen/config/AppRouterInterceptor.java @@ -19,8 +19,10 @@ public class AppRouterInterceptor implements RouterInterceptor { ctx.render(Action.err("资源不存在")); } } catch (ValidatorException e) { + e.printStackTrace(); ctx.render(Action.err(e.getMessage())); //e.getResult().getDescription() } catch (Throwable e) { + e.printStackTrace(); ctx.render(Action.err(e.getMessage())); } } diff --git a/gen/src/main/java/com/gitee/gen/controller/GeneratorController.java b/gen/src/main/java/com/gitee/gen/controller/GeneratorController.java index f92d73d..f8fdaaf 100644 --- a/gen/src/main/java/com/gitee/gen/controller/GeneratorController.java +++ b/gen/src/main/java/com/gitee/gen/controller/GeneratorController.java @@ -4,13 +4,21 @@ import com.gitee.gen.common.Action; import com.gitee.gen.common.GeneratorParam; import com.gitee.gen.common.Result; import com.gitee.gen.entity.DatasourceConfig; +import com.gitee.gen.gen.CodeFile; import com.gitee.gen.gen.GeneratorConfig; import com.gitee.gen.service.DatasourceConfigService; import com.gitee.gen.service.GeneratorService; +import com.gitee.gen.common.MemCache; import org.noear.solon.annotation.Controller; import org.noear.solon.annotation.Inject; import org.noear.solon.annotation.Mapping; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + /** * @author tanghc */ @@ -24,6 +32,12 @@ public class GeneratorController { @Inject private GeneratorService generatorService; + +private final MemCache> codeCache = + new MemCache<>(100, 10); // 最大 100 条,10 分钟过期 + + + /** * 生成代码 * @@ -35,7 +49,45 @@ public class GeneratorController { int datasourceConfigId = generatorParam.getDatasourceConfigId(); DatasourceConfig datasourceConfig = datasourceConfigService.getById(datasourceConfigId); GeneratorConfig generatorConfig = GeneratorConfig.build(datasourceConfig); - return Action.ok(generatorService.generate(generatorParam, generatorConfig)); + + List generate = generatorService.generate(generatorParam, generatorConfig); + + String key = generatorParam.getDatasourceConfigId() + "_" + String.join(",", generatorParam.getTableNames()); + codeCache.put(key, generate); + return Action.ok(generate); + } + /** + * 导出文件到指定路径 + * + * @param generatorParam 生成参数 + * @return 返回代码内容 + */ + @Mapping("/export") + public Result export(GeneratorParam generatorParam) throws IOException { + System.out.println(generatorParam); + String key = generatorParam.getDatasourceConfigId() + "_" + String.join(",", generatorParam.getTableNames()); + System.out.println(key); + List generate = null; + List cacheFiles = codeCache.get(key); + if (cacheFiles == null) { + // 缓存中没有找到代码 + System.out.println("缓存中没有找到代码"); + int datasourceConfigId = generatorParam.getDatasourceConfigId(); + DatasourceConfig datasourceConfig = datasourceConfigService.getById(datasourceConfigId); + GeneratorConfig generatorConfig = GeneratorConfig.build(datasourceConfig); + generate = generatorService.generate(generatorParam, generatorConfig); + }else { + generate = cacheFiles; + } + + + System.out.println("导出代码文件:" + generate); + String result = generatorService.export(generate, generatorParam); + + System.out.println(result); + return Action.ok(result); + } + } diff --git a/gen/src/main/java/com/gitee/gen/entity/DatasourceConfig.java b/gen/src/main/java/com/gitee/gen/entity/DatasourceConfig.java index 42e87c5..2719d61 100644 --- a/gen/src/main/java/com/gitee/gen/entity/DatasourceConfig.java +++ b/gen/src/main/java/com/gitee/gen/entity/DatasourceConfig.java @@ -41,6 +41,17 @@ public class DatasourceConfig { /** 数据库分组名称 */ private String dbGroupName; + /** 导出路径 */ + private String outPath; + + public String getOutPath() { + return outPath; + } + + public void setOutPath(String outPath) { + this.outPath = outPath; + } + public Integer getId() { return id; } diff --git a/gen/src/main/java/com/gitee/gen/service/GeneratorService.java b/gen/src/main/java/com/gitee/gen/service/GeneratorService.java index f5912aa..7e9db9f 100644 --- a/gen/src/main/java/com/gitee/gen/service/GeneratorService.java +++ b/gen/src/main/java/com/gitee/gen/service/GeneratorService.java @@ -13,9 +13,17 @@ import com.gitee.gen.util.FormatUtil; import com.gitee.gen.util.VelocityUtil; import org.apache.commons.lang.StringUtils; import org.apache.velocity.VelocityContext; +import org.apache.velocity.texen.util.FileUtil; import org.noear.solon.annotation.Component; import org.noear.solon.annotation.Inject; +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -169,4 +177,45 @@ public class GeneratorService { return VelocityUtil.generate(context, template); } + public String export(List generate, GeneratorParam generatorParam) throws IOException { + + Path outPath = Paths.get(generatorParam.getOutPath()); + // 判断导出路径是否存在 + if (!Files.exists(outPath)) { + try { + Files.createDirectories(outPath); + } catch (IOException e) { + e.printStackTrace(); + return "创建导出路径失败"; + } + } + System.out.println("导出路径:" + outPath); + String packagePath = generatorParam.getPackageName().replace(".", File.separator); + Path packageDir = outPath.resolve(packagePath); + System.out.println("导出包路径:" + packageDir); + boolean success = true; + + for (CodeFile codeFile : generate) { + try { + Path folder = packageDir.resolve(codeFile.getFolder()); + Files.createDirectories(folder); + System.out.println("导出文件夹路径:" + folder); + // 文件:folder + fileName + Path target = folder.resolve(codeFile.getFileName()); + System.out.println("导出文件路径:" + target); + Files.write(target, codeFile.getContent().getBytes(StandardCharsets.UTF_8), + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING); + } catch (Exception e) { + e.printStackTrace(); + System.out.println("导出文件失败:" + codeFile.getFileName()); + success = false; + } + } + if (success) { + return "导出成功"; + } + return "导出失败"; + } + } diff --git a/gen/src/main/resources/gen_init.db b/gen/src/main/resources/gen_init.db index 795f8f18ac3765db61be902861cd92d74cccccf6..ebfbffcc186c948cfcfa5f59d976d7b8b6aaa9c3 100644 GIT binary patch delta 113 zcmZozz|ydQWrDO|E&~IDAP{o{F(VMmPSi1$&SlUm>*VF|VPI$JXW~1}y_IJo*LRkF z-c9VD8yiJgxLVD**v0kr8M|aRhjA=m63|h|FD;2LNG!=v2yu-F(cJ9G&dkWd!_Kt2 NIe=q(00-j+b^wYl8q@#) delta 81 zcmZozz|ydQWrDO|4g&*&AP{o{F(VMmOw=)!&SB8=p1{k)&cM#@$;5Y>dn?aGuJ0T^ hyqnlPHwy}!XWQ(_&dkWts=>wH9Kf+XfP--ZI{=M?5m5jD diff --git a/gen/src/main/resources/mybatis/DatasourceConfigMapper.xml b/gen/src/main/resources/mybatis/DatasourceConfigMapper.xml index 0e96a7f..45bb314 100644 --- a/gen/src/main/resources/mybatis/DatasourceConfigMapper.xml +++ b/gen/src/main/resources/mybatis/DatasourceConfigMapper.xml @@ -18,6 +18,7 @@ + @@ -38,6 +39,7 @@ , t.group_id , t.author , t.db_group_name + , t.out_path @@ -77,6 +79,7 @@ group_id, author, db_group_name, + out_path, #{dbType}, @@ -94,6 +97,7 @@ #{groupId}, #{author}, #{dbGroupName}, + #{out_path}, @@ -148,6 +152,8 @@ db_group_name, + + out_path, @@ -195,6 +201,8 @@ #{dbGroupName}, + + #{outPath}, @@ -218,6 +226,7 @@ group_id=#{groupId}, author=#{author}, db_group_name=#{dbGroupName}, + out_path=#{outPath}, WHERE id = #{id} @@ -271,6 +280,8 @@ db_group_name=#{dbGroupName}, + + out_path=#{outPath}, WHERE id = #{id} -- Gitee