From 8e82a5f852402062e583975c7e770e820e3dc3e2 Mon Sep 17 00:00:00 2001 From: lu17301156525 Date: Thu, 31 Oct 2024 02:24:06 -0700 Subject: [PATCH 1/5] fix: i18n bug --- .../com/tinyengine/it/common/utils/Utils.java | 58 +++++ .../it/controller/I18nEntryController.java | 55 +---- .../tinyengine/it/model/dto/EntriesItem.java | 12 + .../com/tinyengine/it/model/dto/FileInfo.java | 19 ++ .../tinyengine/it/model/dto/SchemaI18n.java | 3 - .../it/service/app/I18nEntryService.java | 21 +- .../app/impl/I18nEntryServiceImpl.java | 211 ++++++------------ src/main/resources/application-dev.yml | 4 +- src/main/resources/application.yml | 2 +- 9 files changed, 172 insertions(+), 213 deletions(-) create mode 100644 src/main/java/com/tinyengine/it/model/dto/EntriesItem.java create mode 100644 src/main/java/com/tinyengine/it/model/dto/FileInfo.java diff --git a/src/main/java/com/tinyengine/it/common/utils/Utils.java b/src/main/java/com/tinyengine/it/common/utils/Utils.java index fdfe96d0..6dd8fbd1 100644 --- a/src/main/java/com/tinyengine/it/common/utils/Utils.java +++ b/src/main/java/com/tinyengine/it/common/utils/Utils.java @@ -5,8 +5,11 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.tinyengine.it.model.dto.FileInfo; import lombok.extern.slf4j.Slf4j; +import java.io.*; +import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; @@ -17,6 +20,8 @@ import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; /** * The type Utils. @@ -198,4 +203,57 @@ private static int compareVersions(String v1, String v2) { } return 0; } + + /** + * 解压并处理zip文件,把读取到的JSON文件内容以字符串返回 + * + * @param zipFile zipFile + * @param destDir destDir + * @return String + * @throws IOException IOException + */ + public static List unzip(File zipFile, String destDir) throws IOException { + List fileInfoList = new ArrayList<>(); + File dir = new File(destDir); + if (!dir.exists()) { + dir.mkdirs(); // 创建目标目录 + } + + try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(zipFile.toPath()))) { + ZipEntry zipEntry; + while ((zipEntry = zis.getNextEntry()) != null) { + File newFile = new File(destDir, zipEntry.getName()); + boolean isDirectory = zipEntry.isDirectory(); + + if (isDirectory) { + newFile.mkdirs(); // 创建目录 + } else { + new File(newFile.getParent()).mkdirs(); // 确保父目录存在 + try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile))) { + byte[] buffer = new byte[1024]; + int length; + while ((length = zis.read(buffer)) >= 0) { + bos.write(buffer, 0, length); + } + } + // 添加文件信息到列表 + fileInfoList.add(new FileInfo(newFile.getName(), readFileContent(newFile), false)); + } + zis.closeEntry(); + } + } + return fileInfoList; + } + + private static String readFileContent(File file) throws IOException { + StringBuilder contentBuilder = new StringBuilder(); + try (BufferedReader br = new BufferedReader(new FileReader(file))) { + String line; + while ((line = br.readLine()) != null) { + contentBuilder.append(line).append(System.lineSeparator()); + } + } + return contentBuilder.toString(); + } + } diff --git a/src/main/java/com/tinyengine/it/controller/I18nEntryController.java b/src/main/java/com/tinyengine/it/controller/I18nEntryController.java index 79c281c4..feef6766 100644 --- a/src/main/java/com/tinyengine/it/controller/I18nEntryController.java +++ b/src/main/java/com/tinyengine/it/controller/I18nEntryController.java @@ -5,11 +5,7 @@ import com.tinyengine.it.common.exception.ExceptionEnum; import com.tinyengine.it.common.exception.ServiceException; import com.tinyengine.it.config.log.SystemControllerLog; -import com.tinyengine.it.model.dto.DeleteI18nEntry; -import com.tinyengine.it.model.dto.I18nEntryDto; -import com.tinyengine.it.model.dto.I18nEntryListResult; -import com.tinyengine.it.model.dto.OperateI18nBatchEntries; -import com.tinyengine.it.model.dto.OperateI18nEntries; +import com.tinyengine.it.model.dto.*; import com.tinyengine.it.model.entity.I18nEntry; import com.tinyengine.it.service.app.I18nEntryService; @@ -213,13 +209,11 @@ public Result> deleteI18nEntries(@RequestBody DeleteI18nEntry @ApiResponse(responseCode = "400", description = "请求失败")}) @SystemControllerLog(description = "应用下上传单文件处理国际化词条") @PostMapping("/apps/{id}/i18n/entries/update") - public Result> updateI18nSingleFile(@PathVariable Integer id, - @RequestParam Map filesMap) throws Exception { - Result> result = new Result<>(); + public Result> updateI18nSingleFile(@PathVariable Integer id, + @RequestParam Map filesMap) throws Exception { + List entriesItemList = new ArrayList<>(); // 处理上传的文件 for (Map.Entry entry : filesMap.entrySet()) { - // 获取动态的参数名 - String key = entry.getKey(); // 获取对应的文件 MultipartFile file = entry.getValue(); @@ -228,45 +222,12 @@ public Result> updateI18nSingleFile(@PathVariable Integer id } // 返回插入和更新的条数 - result = i18nEntryService.readSingleFileAndBulkCreate(key, file, id); + Result> entriesItemResult = i18nEntryService.readSingleFileAndBulkCreate(file, id); + entriesItemList.addAll(entriesItemResult.getData()); + } - return result; + return Result.success(entriesItemList); } - /** - * 应用下批量上传国际化词条文件 - * - * @param id the id - * @param filesMap the files map - * @return result - * @throws Exception the exception - */ - @Operation(summary = "应用下批量上传国际化词条文件", description = "应用下批量上传国际化词条文件", parameters = { - @Parameter(name = "id", description = "appId"), - @Parameter(name = "filesMap", description = "文件参数对象")}, responses = { - @ApiResponse(responseCode = "200", description = "返回信息", - content = @Content(mediaType = "application/json", schema = @Schema())), - @ApiResponse(responseCode = "400", description = "请求失败")}) - @SystemControllerLog(description = "应用下批量上传国际化词条文件") - @PostMapping("/apps/{id}/i18n/entries/multiUpdate") - public Result> updateI18nMultiFile(@PathVariable Integer id, - @RequestParam Map filesMap) throws Exception { - Result> result = new Result<>(); - // 处理上传的文件 - for (Map.Entry entry : filesMap.entrySet()) { - // 获取动态的参数名 - String key = entry.getKey(); - // 获取对应的文件 - MultipartFile file = entry.getValue(); - - if (file.isEmpty()) { - return Result.failed(ExceptionEnum.CM307); - } - - // 返回插入和更新的条数 - result = i18nEntryService.readFilesAndbulkCreate(key, file, id); - } - return result; - } } diff --git a/src/main/java/com/tinyengine/it/model/dto/EntriesItem.java b/src/main/java/com/tinyengine/it/model/dto/EntriesItem.java new file mode 100644 index 00000000..3e2b25aa --- /dev/null +++ b/src/main/java/com/tinyengine/it/model/dto/EntriesItem.java @@ -0,0 +1,12 @@ +package com.tinyengine.it.model.dto; + +import lombok.Getter; +import lombok.Setter; + +import java.util.Map; +@Setter +@Getter +public class EntriesItem { + private Integer lang; + private Map entries; +} diff --git a/src/main/java/com/tinyengine/it/model/dto/FileInfo.java b/src/main/java/com/tinyengine/it/model/dto/FileInfo.java new file mode 100644 index 00000000..7c4048d4 --- /dev/null +++ b/src/main/java/com/tinyengine/it/model/dto/FileInfo.java @@ -0,0 +1,19 @@ +package com.tinyengine.it.model.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class FileInfo { + private String name; + private String content; + private boolean isDirectory; + + public FileInfo(String name, String content, boolean isDirectory) { + this.name = name; + this.content = content; + this.isDirectory = isDirectory; + } + +} \ No newline at end of file diff --git a/src/main/java/com/tinyengine/it/model/dto/SchemaI18n.java b/src/main/java/com/tinyengine/it/model/dto/SchemaI18n.java index 0a2e78f3..25457fa6 100644 --- a/src/main/java/com/tinyengine/it/model/dto/SchemaI18n.java +++ b/src/main/java/com/tinyengine/it/model/dto/SchemaI18n.java @@ -1,6 +1,5 @@ package com.tinyengine.it.model.dto; -import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import lombok.Setter; @@ -14,8 +13,6 @@ @Getter @Setter public class SchemaI18n { - private Map en_US; - private Map zh_CN; } diff --git a/src/main/java/com/tinyengine/it/service/app/I18nEntryService.java b/src/main/java/com/tinyengine/it/service/app/I18nEntryService.java index 9063b614..001aff01 100644 --- a/src/main/java/com/tinyengine/it/service/app/I18nEntryService.java +++ b/src/main/java/com/tinyengine/it/service/app/I18nEntryService.java @@ -2,12 +2,7 @@ package com.tinyengine.it.service.app; import com.tinyengine.it.common.base.Result; -import com.tinyengine.it.model.dto.DeleteI18nEntry; -import com.tinyengine.it.model.dto.I18nEntryDto; -import com.tinyengine.it.model.dto.I18nEntryListResult; -import com.tinyengine.it.model.dto.OperateI18nBatchEntries; -import com.tinyengine.it.model.dto.OperateI18nEntries; -import com.tinyengine.it.model.dto.SchemaI18n; +import com.tinyengine.it.model.dto.*; import com.tinyengine.it.model.entity.I18nEntry; import org.apache.ibatis.annotations.Param; @@ -96,22 +91,12 @@ public interface I18nEntryService { /** * 上传单个文件 * - * @param lang the lang * @param file the file * @param host the host * @return the result * @throws Exception the exception */ - Result> readSingleFileAndBulkCreate(String lang, MultipartFile file, int host) throws Exception; + Result> readSingleFileAndBulkCreate(MultipartFile file, int host) throws Exception; + - /** - * 批量上传词条数据 - * - * @param lang the lang - * @param file the file - * @param host the host - * @return the result - * @throws Exception the exception - */ - Result> readFilesAndbulkCreate(String lang, MultipartFile file, int host) throws Exception; } diff --git a/src/main/java/com/tinyengine/it/service/app/impl/I18nEntryServiceImpl.java b/src/main/java/com/tinyengine/it/service/app/impl/I18nEntryServiceImpl.java index 790fdb5d..3ee2559c 100644 --- a/src/main/java/com/tinyengine/it/service/app/impl/I18nEntryServiceImpl.java +++ b/src/main/java/com/tinyengine/it/service/app/impl/I18nEntryServiceImpl.java @@ -1,22 +1,19 @@ package com.tinyengine.it.service.app.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.tinyengine.it.common.base.Result; import com.tinyengine.it.common.enums.Enums; import com.tinyengine.it.common.exception.ExceptionEnum; import com.tinyengine.it.common.exception.ServiceException; +import com.tinyengine.it.common.utils.Utils; import com.tinyengine.it.config.log.SystemServiceLog; import com.tinyengine.it.mapper.I18nEntryMapper; import com.tinyengine.it.mapper.I18nLangMapper; -import com.tinyengine.it.model.dto.DeleteI18nEntry; -import com.tinyengine.it.model.dto.Entry; -import com.tinyengine.it.model.dto.I18nEntryDto; -import com.tinyengine.it.model.dto.I18nEntryListResult; -import com.tinyengine.it.model.dto.OperateI18nBatchEntries; -import com.tinyengine.it.model.dto.OperateI18nEntries; -import com.tinyengine.it.model.dto.SchemaI18n; +import com.tinyengine.it.model.dto.*; import com.tinyengine.it.model.entity.I18nEntry; import com.tinyengine.it.model.entity.I18nLang; import com.tinyengine.it.service.app.I18nEntryService; @@ -359,7 +356,6 @@ public List deleteI18nEntriesByHostAndHostTypeAndKey(DeleteI18nEnt /** * 上传单个文件 * - * @param lang the lang * @param file the file * @param host the host * @return bulk Create Or Update number @@ -367,27 +363,27 @@ public List deleteI18nEntriesByHostAndHostTypeAndKey(DeleteI18nEnt */ @SystemServiceLog(description = "readSingleFileAndBulkCreate 上传单个国际化文件") @Override - public Result> readSingleFileAndBulkCreate(String lang, MultipartFile file, int host) + public Result> readSingleFileAndBulkCreate(MultipartFile file, int host) throws Exception { - List entriesArr = new ArrayList<>(); + List entriesArr = new ArrayList<>(); String contentType = file.getContentType(); if (Objects.equals(contentType, Enums.MimeType.JSON.getValue())) { - Result> parseJsonFileStreamResult = parseJsonFileStream(lang, file); + Result parseJsonFileStreamResult = parseJsonFileStream(file); if (!parseJsonFileStreamResult.isSuccess()) { - return parseJsonFileStreamResult; + return Result.failed(ExceptionEnum.CM001); } entriesArr.add(parseJsonFileStreamResult.getData()); } else { - entriesArr.add(parseZipFileStream(lang, file)); + entriesArr.addAll(parseZipFileStream(file)); } // 批量上传接口未提交任何文件流时报错 if (entriesArr.isEmpty()) { throw new ServiceException(ExceptionEnum.CM002.getResultCode(), "No file uploaded"); } - Map bulkCreateOrUpdateNumReturn = bulkCreateOrUpdate(entriesArr, host); - return Result.success(bulkCreateOrUpdateNumReturn); + + return bulkCreateOrUpdate(entriesArr, host); } /** @@ -398,58 +394,19 @@ public Result> readSingleFileAndBulkCreate(String lang, Mult * @return map */ @SystemServiceLog(description = "bulkCreateOrUpdate 批量创建或修改") - public Map bulkCreateOrUpdate(List entriesArr, int host) { + public Result> bulkCreateOrUpdate(List entriesArr, int host) { List entries = new ArrayList<>(); - Map resultMap = new HashMap<>(); - entriesArr.forEach(langEntry -> { - if (langEntry instanceof Map) { - resultMap.putAll((Map) langEntry); - } + entriesArr.forEach(entriesItem -> { + - int lang = (int) resultMap.get("lang"); - Map langEntries = (Map) resultMap.get("entries"); - langEntries.forEach((key, value) -> { I18nEntry i18nEntries = new I18nEntry(); - i18nEntries.setKey(key); - i18nEntries.setLang(lang); - i18nEntries.setHost(host); - i18nEntries.setHostType("app"); - i18nEntries.setContent((String) value); + entries.add(i18nEntries); - }); }); // 超大量数据更新,如上传国际化文件,不返回插入或更新的词条 - return bulkInsertOrUpdate(entries); + return null; // bulkInsertOrUpdate(entries); } - /** - * 批量上传词条数据 - * - * @param lang the lang - * @param file the file - * @param host the host - * @return bulk Create Or Update - */ - @SystemServiceLog(description = "readFilesAndbulkCreate 批量上传词条数据") - @Override - public Result> readFilesAndbulkCreate(String lang, MultipartFile file, int host) { - List entriesArr = new ArrayList<>(); - - Result> parseJsonFileStreamResult = parseJsonFileStream(lang, file); - // 解析 JSON 数据 - if (!parseJsonFileStreamResult.isSuccess()) { - return parseJsonFileStreamResult; - } - Map entriesItem = parseJsonFileStreamResult.getData(); - entriesArr.add(entriesItem); - // 批量上传接口未提交任何文件流时报错 - if (entriesArr.isEmpty()) { - throw new ServiceException(ExceptionEnum.CM002.getResultCode(), "No file uploaded"); - } - - Map bulkCreateOrUpdateNumReturn = bulkCreateOrUpdate(entriesArr, host); - return Result.success(bulkCreateOrUpdateNumReturn); - } /** * 超大量数据更新,如上传国际化文件,不返回插入或更新的词条 @@ -489,31 +446,25 @@ public Map bulkInsertOrUpdate(List entries) { /** * 解析JSON文件 - * - * @param lang the lang * @param file the file * @return result */ - public Result> parseJsonFileStream(String lang, MultipartFile file) { - // 默认使用UTF-8 - String encoding = StandardCharsets.UTF_8.name(); - // fieldname 为i18n_langs的id - String filename = file.getOriginalFilename(); - logger.info("parseJsonFileStream field:{} , filename:{} ", lang, filename); + public Result parseJsonFileStream(MultipartFile file) { + String fileName = file.getOriginalFilename(); + logger.info("parseJsonFileStream filename:{} ", fileName); // 校验文件流合法性 validateFileStream(file, ExceptionEnum.CM308.getResultCode(), Arrays.asList(Enums.MimeType.JSON.getValue())); + // 根据文件名判断lang value + EntriesItem entriesItem = setLang(fileName); // 解析国际化词条文件 - Map entriesItem = new HashMap<>(); - entriesItem.put("lang", Integer.parseInt(lang)); - entriesItem.put("entries", new HashMap()); Path target = null; try { // 读取上传的 JSON 文件内容 String jsonContent = new String(file.getBytes(), StandardCharsets.UTF_8); - String jsonFileName = UUID.randomUUID() + "_" + filename.toLowerCase(Locale.ROOT); + String jsonFileName = UUID.randomUUID() + "_" + fileName.toLowerCase(Locale.ROOT); target = Paths.get("/path/to/tmp", jsonFileName); try (FileOutputStream fos = new FileOutputStream(String.valueOf(target))) { @@ -524,7 +475,7 @@ public Result> parseJsonFileStream(String lang, MultipartFil Map jsonData = objectMapper.readValue(jsonContent, new TypeReference>() {}); - entriesItem.put("entries", flat(jsonData)); + entriesItem.setEntries(flat(jsonData)); } catch (IOException e) { return Result.validateFailed("parse Json error"); } finally { @@ -544,69 +495,59 @@ public Result> parseJsonFileStream(String lang, MultipartFil /** * 解析zip文件 * - * @param lang the lang * @param file the file * @return map * @throws Exception the exception */ - public Map parseZipFileStream(String lang, MultipartFile file) throws Exception { - // 默认使用UTF-8 - String encoding = StandardCharsets.UTF_8.name(); - String filename = file.getOriginalFilename(); - logger.info("parseZipFileStream field:{} , filename:{} ", lang, filename); + public List parseZipFileStream(MultipartFile file) throws Exception { // 校验文件流合法性 validateFileStream(file, ExceptionEnum.CM314.getResultCode(), Arrays.asList(Enums.MimeType.ZIP.getValue(), Enums.MimeType.XZIP.getValue())); - ObjectMapper objectMapper = new ObjectMapper(); - Map entriesItem = new HashMap<>(); - entriesItem.put("lang", Integer.parseInt(lang)); - entriesItem.put("entries", new HashMap()); + List entriesItems = new ArrayList<>(); + File tempFile = null; - // 解压zip文件 - String target = null; try { // 将上传的文件保存到临时文件中 - File tempFile = File.createTempFile("/path/to/tmp", ".zip"); - target = tempFile.getCanonicalPath(); + tempFile = File.createTempFile("tmp", ".zip"); // 去掉路径前缀,使用系统默认临时目录 file.transferTo(tempFile); // 解压ZIP文件并处理 - String content = extractAndProcessZipFile(tempFile); - // 对返回的内容字符串进行组装 - Map jsonData = new LinkedHashMap<>(); - - // 分割字符串并处理每个JSON对象 - String[] jsonObjects = content.split("\\}\\s*\\{"); - for (String json : jsonObjects) { - // 加上缺失的花括号 - int num = checkMissingBrace(json); - if (num == 1) { - json = json + "}"; + List fileInfos = Utils.unzip(tempFile, tempFile.getCanonicalPath()); + ObjectMapper objectMapper = new ObjectMapper(); // 移到 try 块外,避免每次循环都创建 + + for (FileInfo fileInfo : fileInfos) { + if (fileInfo.isDirectory()) { + EntriesItem entriesItem = setLang(fileInfo.getName()); + + // 处理 JSON 内容 + try { + JsonNode jsonNode = objectMapper.readTree(fileInfo.getContent()); + Map entriesMap = objectMapper.convertValue(jsonNode, Map.class); + entriesItem.setEntries(entriesMap); + } catch (JsonProcessingException e) { + log.error("JSON processing error for file: " + fileInfo.getName(), e); + throw new RuntimeException(e); + } + + entriesItems.add(entriesItem); } - if (num == 2) { - json = "{" + json; - } - - // 将JSON字符串转换为Map对象 - Map map = objectMapper.readValue(json, new TypeReference>() { - }); - // 把转换后的map铺平合并到总的Map中 - jsonData.putAll(flat(map)); } - entriesItem.put("entries", jsonData); } catch (IOException e) { - log.error(e.getMessage()); + log.error("File processing error: " + e.getMessage(), e); throw e; } finally { // 清理临时文件 - cleanUp(target); + if (tempFile != null) { + cleanUp(tempFile.getCanonicalPath()); + } } - return entriesItem; + return entriesItems; } + /** * 校验文件流合法性 * @@ -631,38 +572,6 @@ public void validateFileStream(MultipartFile file, String code, List mim throw new ServiceException(code, "validate file fail"); } - /** - * 解压并处理zip文件,把读取到的JSON文件内容以字符串返回 - * - * @param zipFile zipFile - * @return String - * @throws IOException IOException - */ - private String extractAndProcessZipFile(File zipFile) throws IOException { - StringBuilder jsonResult = new StringBuilder(); - try (ZipInputStream zipInputStream = new ZipInputStream(Files.newInputStream(zipFile.toPath()))) { - ZipEntry entry; - while ((entry = zipInputStream.getNextEntry()) != null) { - String entryName = entry.getName(); - jsonResult.append(processJsonFileContent(entryName, zipInputStream)); - } - } - return jsonResult.toString(); - } - - private StringBuilder processJsonFileContent(String entryName, ZipInputStream zipFile) throws IOException { - StringBuilder result = new StringBuilder(); - if (entryName.endsWith(".json")) { - // 处理JSON文件 - byte[] buffer = new byte[1024]; - int len; - while ((len = zipFile.read(buffer)) > 0) { - result.append(new String(buffer, 0, len, StandardCharsets.UTF_8)); - } - result.append("\n"); - } - return result; - } /** * 删除临时目录以及内容 @@ -722,4 +631,22 @@ public List findI18nEntryByCondition(I18nEntry i18nEntry) throws S public Integer updateI18nEntryById(I18nEntry i18nEntry) { return i18nEntryMapper.updateI18nEntryById(i18nEntry); } + + /** + * 根据文件名判断lang值 + * + * @param fileName the fileName + * @return EntriesItem the entriesItem + */ + private EntriesItem setLang(String fileName){ + EntriesItem entriesItem = new EntriesItem(); + if(Enums.I18nLangs.EN_US.getValue().equals(fileName)){ + entriesItem.setLang(2); + return entriesItem; + }else if(Enums.I18nLangs.ZH_CN.getValue().equals(fileName)){ + entriesItem.setLang(1); + return entriesItem; + } + return entriesItem; + } } diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index b8bf3f37..7ca2fdb9 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -7,8 +7,8 @@ spring: datasource: driver-class-name: org.mariadb.jdbc.Driver username: root - password: 123456 - url: jdbc:mariadb://localhost:3306/tiny?useUnicode=true&useSSL=false&characterEncoding=utf8 + password: 111111 + url: jdbc:mariadb://localhost:3306/tiny_engine_data_java?useUnicode=true&useSSL=false&characterEncoding=utf8 type: com.alibaba.druid.pool.DruidDataSource druid: initial-size: 5 # 连接池初始化时建立的连接数,默认值为 0。 diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index ef46c2ad..caf4dfcd 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,3 +1,3 @@ spring: profiles: - active: local \ No newline at end of file + active: dev \ No newline at end of file From 4639e7abddcde5f3ed88e0b49855bc42d8373e9f Mon Sep 17 00:00:00 2001 From: lu17301156525 Date: Fri, 1 Nov 2024 03:19:20 -0700 Subject: [PATCH 2/5] fix: i18n bug --- .../com/tinyengine/it/common/utils/Utils.java | 32 +++++++--- .../app/impl/I18nEntryServiceImpl.java | 59 ++----------------- 2 files changed, 29 insertions(+), 62 deletions(-) diff --git a/src/main/java/com/tinyengine/it/common/utils/Utils.java b/src/main/java/com/tinyengine/it/common/utils/Utils.java index 6288c844..7a2dd1ac 100644 --- a/src/main/java/com/tinyengine/it/common/utils/Utils.java +++ b/src/main/java/com/tinyengine/it/common/utils/Utils.java @@ -10,14 +10,7 @@ import java.io.*; import java.nio.file.Files; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.ZipEntry; @@ -225,4 +218,27 @@ public static byte[] readAllBytes(InputStream inputStream) throws IOException { return byteArrayOutputStream.toByteArray(); } + + /** + * 将一个嵌套的 JSON 对象扁平化 + * + * @param jsonData the json data + * @return map + */ + public static Map flat(Map jsonData) { + Map flattenedMap = new HashMap<>(); + flatten("", jsonData, flattenedMap); + return flattenedMap; + } + + private static void flatten(String prefix, Map data, Map flattenedMap) { + for (Map.Entry entry : data.entrySet()) { + String key = prefix.isEmpty() ? entry.getKey() : prefix + "." + entry.getKey(); + if (entry.getValue() instanceof Map) { + flatten(key, (Map) entry.getValue(), flattenedMap); + } else { + flattenedMap.put(key, entry.getValue()); + } + } + } } diff --git a/src/main/java/com/tinyengine/it/service/app/impl/I18nEntryServiceImpl.java b/src/main/java/com/tinyengine/it/service/app/impl/I18nEntryServiceImpl.java index 4df84d1b..667cdf4a 100644 --- a/src/main/java/com/tinyengine/it/service/app/impl/I18nEntryServiceImpl.java +++ b/src/main/java/com/tinyengine/it/service/app/impl/I18nEntryServiceImpl.java @@ -62,56 +62,7 @@ public class I18nEntryServiceImpl implements I18nEntryService { @Autowired private I18nLangMapper i18nLangMapper; - /** - * 将一个嵌套的 JSON 对象扁平化 - * - * @param jsonData the json data - * @return map - */ - public static Map flat(Map jsonData) { - Map flattenedMap = new HashMap<>(); - flatten("", jsonData, flattenedMap); - return flattenedMap; - } - private static void flatten(String prefix, Map data, Map flattenedMap) { - for (Map.Entry entry : data.entrySet()) { - String key = prefix.isEmpty() ? entry.getKey() : prefix + "." + entry.getKey(); - if (entry.getValue() instanceof Map) { - flatten(key, (Map) entry.getValue(), flattenedMap); - } else { - flattenedMap.put(key, entry.getValue()); - } - } - } - - /** - * 检查对于读取到的JSON文件中的字符串缺失的是前花括号还是后花括号 (1: 缺失后花括号, 2: 缺失前花括号, 3:不缺) - * - * @param jsonString the json string - * @return the int - */ - public static int checkMissingBrace(String jsonString) { - int openBraceCount = 0; - int closeBraceCount = 0; - - for (char c : jsonString.toCharArray()) { - if (c == '{') { - openBraceCount++; - } - if (c == '}') { - closeBraceCount++; - } - } - - if (openBraceCount > closeBraceCount) { - return 1; - } else if (closeBraceCount > openBraceCount) { - return 2; - } else { - return 3; - } - } /** * 查询表t_i18n_entry所有数据 @@ -425,7 +376,7 @@ public Result readFilesAndbulkCreate(String lang, MultipartFile * * @param entriesArr the entries arr * @param host the host - * @return map + * @return result */ @SystemServiceLog(description = "bulkCreateOrUpdate 批量创建或修改") public Result bulkCreateOrUpdate(List entriesArr, int host) { @@ -452,7 +403,7 @@ public Result bulkCreateOrUpdate(List entriesArr, i * 超大量数据更新,如上传国际化文件,不返回插入或更新的词条 * * @param entries the entries - * @return the map + * @return I18nFileResult the I18nFileResult */ @SystemServiceLog(description = "bulkInsertOrUpdate 超大量数据更新") public I18nFileResult bulkInsertOrUpdate(List entries) { @@ -507,7 +458,7 @@ public Result parseJsonFileStream(MultipartFile file) { ObjectMapper objectMapper = new ObjectMapper(); Map jsonData = objectMapper.readValue(jsonContent, new TypeReference>() { }); - entriesItem.setEntries(flat(jsonData)); + entriesItem.setEntries(Utils.flat(jsonData)); } catch (IOException e) { log.error("Error parsing JSON: {}", e.getMessage()); @@ -523,7 +474,7 @@ public Result parseJsonFileStream(MultipartFile file) { * 解析zip文件 * * @param file the file - * @return map + * @return EntriesItem * @throws Exception the exception */ public List parseZipFileStream(MultipartFile file) throws Exception { @@ -544,7 +495,7 @@ public List parseZipFileStream(MultipartFile file) throws Exception try { Map jsonData = objectMapper.readValue(fileInfo.getContent(), new TypeReference>() { }); - entriesItem.setEntries(flat(jsonData)); + entriesItem.setEntries(Utils.flat(jsonData)); } catch (JsonProcessingException e) { log.error("JSON processing error for file: " + fileInfo.getName(), e); throw new RuntimeException(e); From b532229d92b58a20e572cb62235e4f142fa6297c Mon Sep 17 00:00:00 2001 From: lu17301156525 Date: Fri, 1 Nov 2024 03:27:48 -0700 Subject: [PATCH 3/5] fix: i18n bug --- src/main/resources/application-dev.yml | 4 ++-- src/main/resources/application.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index b8bf3f37..7ca2fdb9 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -7,8 +7,8 @@ spring: datasource: driver-class-name: org.mariadb.jdbc.Driver username: root - password: 123456 - url: jdbc:mariadb://localhost:3306/tiny?useUnicode=true&useSSL=false&characterEncoding=utf8 + password: 111111 + url: jdbc:mariadb://localhost:3306/tiny_engine_data_java?useUnicode=true&useSSL=false&characterEncoding=utf8 type: com.alibaba.druid.pool.DruidDataSource druid: initial-size: 5 # 连接池初始化时建立的连接数,默认值为 0。 diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index ef46c2ad..caf4dfcd 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,3 +1,3 @@ spring: profiles: - active: local \ No newline at end of file + active: dev \ No newline at end of file From 70941ccc00f506730b3730bec9d04b2f7466841d Mon Sep 17 00:00:00 2001 From: lu17301156525 Date: Fri, 1 Nov 2024 03:28:30 -0700 Subject: [PATCH 4/5] fix: i18n bug --- src/main/resources/application-dev.yml | 4 ++-- src/main/resources/application.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 7ca2fdb9..b8bf3f37 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -7,8 +7,8 @@ spring: datasource: driver-class-name: org.mariadb.jdbc.Driver username: root - password: 111111 - url: jdbc:mariadb://localhost:3306/tiny_engine_data_java?useUnicode=true&useSSL=false&characterEncoding=utf8 + password: 123456 + url: jdbc:mariadb://localhost:3306/tiny?useUnicode=true&useSSL=false&characterEncoding=utf8 type: com.alibaba.druid.pool.DruidDataSource druid: initial-size: 5 # 连接池初始化时建立的连接数,默认值为 0。 diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index caf4dfcd..ef46c2ad 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,3 +1,3 @@ spring: profiles: - active: dev \ No newline at end of file + active: local \ No newline at end of file From 43a2b6c9053a9440c3b9a8ae69eb09342515ae7a Mon Sep 17 00:00:00 2001 From: lu17301156525 Date: Sun, 3 Nov 2024 19:17:06 -0800 Subject: [PATCH 5/5] fix: i18n bug --- src/main/java/com/tinyengine/it/model/dto/DeleteI18nEntry.java | 3 +++ .../java/com/tinyengine/it/model/dto/OperateI18nEntries.java | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/main/java/com/tinyengine/it/model/dto/DeleteI18nEntry.java b/src/main/java/com/tinyengine/it/model/dto/DeleteI18nEntry.java index b475d111..e3e1206d 100644 --- a/src/main/java/com/tinyengine/it/model/dto/DeleteI18nEntry.java +++ b/src/main/java/com/tinyengine/it/model/dto/DeleteI18nEntry.java @@ -1,5 +1,6 @@ package com.tinyengine.it.model.dto; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; import java.util.List; @@ -12,6 +13,8 @@ @Data public class DeleteI18nEntry { private String host; + @JsonProperty("host_type") private String hostType; + @JsonProperty("key_in") private List keyIn; } diff --git a/src/main/java/com/tinyengine/it/model/dto/OperateI18nEntries.java b/src/main/java/com/tinyengine/it/model/dto/OperateI18nEntries.java index cef33adc..30c1a576 100644 --- a/src/main/java/com/tinyengine/it/model/dto/OperateI18nEntries.java +++ b/src/main/java/com/tinyengine/it/model/dto/OperateI18nEntries.java @@ -1,5 +1,6 @@ package com.tinyengine.it.model.dto; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; import lombok.NoArgsConstructor; @@ -15,6 +16,8 @@ public class OperateI18nEntries { private String key; private String host; + + @JsonProperty("host_type") private String hostType; private Map contents; }