From b4e7ea95934ccf139e569a009f7bf53827b109f0 Mon Sep 17 00:00:00 2001 From: xingjinshuang <xingjs@qq.com> Date: 星期二, 24 十二月 2024 16:22:08 +0800 Subject: [PATCH] @xingjs@20241224@添加解析CSV文件相关实体类、方法;添加文件上传配置;添加开发文件上传相关工具类 --- src/main/java/com/se/simu/controller/FilesUploadController.java | 183 ++++++++++++++++++ src/main/resources/application-zyy.yml | 6 src/main/resources/application-prod.yml | 4 src/main/java/com/se/simu/controller/SimuController.java | 153 ++++++++++++++ src/main/java/com/se/simu/service/SimuFilesService.java | 213 +++++++++++++++++++++ 5 files changed, 550 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/se/simu/controller/FilesUploadController.java b/src/main/java/com/se/simu/controller/FilesUploadController.java new file mode 100644 index 0000000..4727136 --- /dev/null +++ b/src/main/java/com/se/simu/controller/FilesUploadController.java @@ -0,0 +1,183 @@ +package com.se.simu.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.zip.ZipEntry; + +@Api(tags = "0-鏂囦欢鐩稿叧鎺ュ彛") +@Slf4j +@CrossOrigin(origins = "*") +@RestController +@RequestMapping("/v1/files") +public class FilesUploadController { + + + @Value("${simu-app.filePath}") + // private final String uploadedFolder = "D:/home/scheme/upload"; + private String uploadedFolder; + + + @ApiOperation("0-鏂囦欢涓婁紶鍦板潃") + @GetMapping("/getUploadPath") + public ResponseEntity<String> getUploadPath() throws Exception { + return ResponseEntity.ok("鏂囦欢涓婁紶鍦板潃涓猴細" + uploadedFolder); + } + + + @ApiOperation("1-涓婁紶鍗曚釜鏂囦欢") + @ApiImplicitParam(name = "filePathName", value = "鏂囦欢澶瑰悕绉�", required = true, dataType = "String", paramType = "query", example = "upload", dataTypeClass = String.class) + @PostMapping("/uploadSingleFile") + public ResponseEntity<String> uploadSingleFile(@RequestParam("file") MultipartFile file, @RequestParam("filePathName") String filePathName) throws IOException { + if (file.isEmpty()) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("鏂囦欢涓嶈兘涓虹┖"); + } + // 鍒ゆ柇 filePathName 鏄惁涓虹┖ + if (filePathName == null || filePathName.isEmpty()) { + filePathName = "upload"; + //return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("鏂囦欢澶瑰悕绉颁笉鑳戒负绌�"); + } + String targetDir = Paths.get(uploadedFolder, filePathName).toString(); + log.info("鐩爣鐩綍: {}", targetDir); + createDirectoriesIfNotExists(targetDir); + try { + file.transferTo(Paths.get(targetDir, file.getOriginalFilename())); + return ResponseEntity.ok("鏂囦欢涓婁紶鎴愬姛"); + } catch (IOException e) { + log.error("鏂囦欢涓婁紶澶辫触", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("鏂囦欢涓婁紶澶辫触"); + } + } + + @ApiOperation("2-涓婁紶澶氫釜鏂囦欢") + @ApiImplicitParam(name = "filePathName", value = "鏂囦欢澶瑰悕绉�", required = true, dataType = "String", paramType = "query", example = "upload", dataTypeClass = String.class) + @PostMapping("/uploadMultipleFiles") + public ResponseEntity<String> uploadMultipleFiles(List<MultipartFile> files, @RequestParam("filePathName") String filePathName) throws IOException { + // 鍒ゆ柇 filePathName 鏄惁涓虹┖ + if (filePathName == null || filePathName.isEmpty()) { + // return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("鏂囦欢澶瑰悕绉颁笉鑳戒负绌�"); + filePathName = "upload"; + } + // 涓婁紶鏂囦欢璺緞 + String targetDir = Paths.get(uploadedFolder, filePathName).toString(); + log.info("鐩爣鐩綍: {}", targetDir); + createDirectoriesIfNotExists(targetDir); + CompletableFuture<Void> allUploadTasks = CompletableFuture.allOf(files.stream() + .map(file -> CompletableFuture.runAsync(() -> { + try { + file.transferTo(Paths.get(targetDir, file.getOriginalFilename())); + } catch (IOException e) { + log.error("鏂囦欢涓婁紶澶辫触", e); + throw new RuntimeException("鏂囦欢涓婁紶澶辫触"); + } + })).toArray(CompletableFuture[]::new)); + try { + allUploadTasks.get(); + return ResponseEntity.ok("鎵�鏈夋枃浠朵笂浼犳垚鍔�!涓婁紶鐩綍涓猴細" + targetDir); + } catch (InterruptedException | ExecutionException e) { + log.error("鏂囦欢涓婁紶澶辫触", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("鏂囦欢涓婁紶澶辫触"); + } + } + + + @ApiOperation("2-1涓婁紶澶氫釜鏂囦欢") + @ApiImplicitParam(name = "filePathName", value = "鏂囦欢澶瑰悕绉�", required = true, dataType = "String", paramType = "query", example = "upload", dataTypeClass = String.class) + @PostMapping("/uploadMultipleFile") + public ResponseEntity<String> uploadMultipleFile(List<MultipartFile> files, @RequestParam("filePathName") String filePathName) throws IOException { + // 涓婁紶鏂囦欢璺緞 + String targetDir = Paths.get(uploadedFolder, filePathName).toString(); + log.info("鐩爣鐩綍: {}", targetDir); + createDirectoriesIfNotExists(targetDir); + try { + for (MultipartFile file : files) { + String fileName = file.getOriginalFilename(); + File targetFile = new File(targetDir, fileName); + file.transferTo(targetFile); + } + return ResponseEntity.ok("鎵�鏈夋枃浠朵笂浼犳垚鍔�!涓婁紶鐩綍涓猴細" + targetDir); + } catch (IOException e) { + log.error("鏂囦欢涓婁紶澶辫触", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("鏂囦欢涓婁紶澶辫触"); + } + } + + + private File newFile(File destinationDir, ZipEntry zipEntry) throws Exception { + File destFile = new File(destinationDir, zipEntry.getName()); + + String destDirPath = destinationDir.getCanonicalPath(); + String destFilePath = destFile.getCanonicalPath(); + + if (!destFilePath.startsWith(destDirPath + File.separator)) { + throw new Exception("Entry is outside of the target dir: " + zipEntry.getName()); + } + + return destFile; + } + + + /** + * 鎸夋枃浠惰矾寰勫垹闄ゆ枃浠跺す + * 閫掑綊鍒犻櫎鏂囦欢澶瑰強鏂囦欢鐨勬柟娉� + * + * @param folder 鏂囦欢澶� + */ + private void deleteFolderByFilePath(File folder) { + if (folder.exists()) { + File[] files = folder.listFiles(); + if (files != null) { + for (File file : files) { + if (file.isDirectory()) { + // 閫掑綊鍒犻櫎瀛愭枃浠跺す + deleteFolderByFilePath(file); + } else { + // 鍒犻櫎鏂囦欢 + file.delete(); + } + } + } + // 鍒犻櫎鏂囦欢澶规湰韬� + folder.delete(); + } + } + + + /** + * @param targetDir 鐩爣鐩綍 + * @throws IOException + */ + private void createDirectoriesIfNotExists(String targetDir) throws IOException { + Path path = Paths.get(targetDir); + if (!Files.exists(path)) { + Files.createDirectories(path); + } + } + + private Boolean directoriesIfNotExists(String targetDir) throws IOException { + Path path = Paths.get(targetDir); + if (!Files.exists(path)) { + // Files.createDirectories(path); + return false; + } else { + return true; + } + } + + +} diff --git a/src/main/java/com/se/simu/controller/SimuController.java b/src/main/java/com/se/simu/controller/SimuController.java index 20c39b0..00c08ac 100644 --- a/src/main/java/com/se/simu/controller/SimuController.java +++ b/src/main/java/com/se/simu/controller/SimuController.java @@ -1,6 +1,7 @@ package com.se.simu.controller; import com.baomidou.mybatisplus.core.metadata.IPage; +import com.se.simu.config.PropertiesConfig; import com.se.simu.domain.dto.GeDb; import com.se.simu.domain.dto.GeLayer; import com.se.simu.domain.po.DataPo; @@ -8,19 +9,26 @@ import com.se.simu.domain.vo.CreateSimuVo; import com.se.simu.domain.vo.R; import com.se.simu.domain.vo.SimuVo; -import com.se.simu.service.GedbService; -import com.se.simu.service.ResultService; -import com.se.simu.service.SimuService; -import com.se.simu.service.UwService; +import com.se.simu.service.*; import io.swagger.annotations.*; import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.stream.Collectors; @Api(tags = "浠跨湡绠$悊") @Slf4j @@ -36,6 +44,12 @@ @Resource SimuService simuService; + + @Resource + SimuFilesService simuFilesService; + + @Resource + PropertiesConfig config; @Resource ResultService resultService; @@ -164,4 +178,135 @@ return fail(ex, false); } } + + @ApiOperation("test-涓婁紶澶氫釜鏂囦欢") + @ApiImplicitParam(name = "schemeName", value = "鏂规鍚嶇О", required = true, dataType = "String", paramType = "query", example = "edf243d3-3bec-4c51-9930-1ba862d9b5a3", dataTypeClass = String.class) + @PostMapping("/uploadMultipleFiles") + public ResponseEntity<String> uploadMultipleFiles(List<MultipartFile> files, @RequestParam("schemeName") String schemeName) throws IOException { + // 涓婁紶鏂囦欢璺緞 + String targetDir = Paths.get(config.getOutPath(), schemeName).toString(); + log.info("鐩爣鐩綍: {}", targetDir); + createDirectoriesIfNotExists(targetDir); + List<CompletableFuture<Void>> uploadTasks = files.stream() + .map(file -> CompletableFuture.runAsync(() -> { + try { + file.transferTo(Paths.get(targetDir, file.getOriginalFilename())); + } catch (IOException e) { + log.error("鏂囦欢涓婁紶澶辫触", e); + throw new RuntimeException("鏂囦欢涓婁紶澶辫触"); + } + })) + .collect(Collectors.toList()); + + CompletableFuture<Void> allUploadTasks = CompletableFuture.allOf(uploadTasks.toArray(new CompletableFuture[0])); + + try { + allUploadTasks.get(); + return ResponseEntity.ok("鎵�鏈夋枃浠朵笂浼犳垚鍔�"); + } catch (InterruptedException | ExecutionException e) { + log.error("鏂囦欢涓婁紶澶辫触", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("鏂囦欢涓婁紶澶辫触"); + } + } + + + /** + * @param targetDir 鐩爣鐩綍 + * @throws IOException + */ + private void createDirectoriesIfNotExists(String targetDir) throws IOException { + Path path = Paths.get(targetDir); + if (!Files.exists(path)) { + Files.createDirectories(path); + } + } + + /** + * 鏂囦欢鍒涘缓妯℃嫙 + * + * @param vo VO + * @return {@link R}<{@link Object}> + */ + @ApiOperation(value = "鏂囦欢鍒涘缓") + @PostMapping(value = "/file_create", produces = "application/json; charset=UTF-8") + public R<Object> fileCreate(List<MultipartFile> files,@RequestBody @ApiParam("鍒涘缓浠跨湡瑙嗗浘绫�") CreateSimuVo vo) throws IOException { + // 涓婁紶鏂囦欢璺緞 + String targetDir = Paths.get(config.getOutPath(), "files").toString(); + log.info("鐩爣鐩綍: {}", targetDir); + createDirectoriesIfNotExists(targetDir); + List<CompletableFuture<Void>> uploadTasks = files.stream() + .map(file -> CompletableFuture.runAsync(() -> { + try { + file.transferTo(Paths.get(targetDir, file.getOriginalFilename())); + } catch (IOException e) { + log.error("鏂囦欢涓婁紶澶辫触", e); + throw new RuntimeException("鏂囦欢涓婁紶澶辫触"); + } + })) + .collect(Collectors.toList()); + CompletableFuture<Void> allUploadTasks = CompletableFuture.allOf(uploadTasks.toArray(new CompletableFuture[0])); + try { + allUploadTasks.get(); + log.info("鏂囦欢涓婁紶鎴愬姛"); + } catch (InterruptedException | ExecutionException e) { + log.error("鏂囦欢涓婁紶澶辫触", e); + } + + try { + if (null == vo.getTotal() || vo.getTotal() < 1 || vo.getTotal() > 1000) { + return fail("闄嶉洦閲忎笉鑳戒负绌猴紝涓斿彇鍊煎湪1~1000涔嬮棿"); + } + if (null == vo.getDuration() || vo.getDuration() < 1 || vo.getDuration() > 10080) { + return fail("浠跨湡鏃堕暱涓嶈兘涓虹┖锛屼笖鍙栧�煎湪1~10080涔嬮棿"); + } + if (null == vo.getMinx() || null == vo.getMiny() || null == vo.getMaxx() || null == vo.getMaxy()) { + return fail("閫夋嫨鑼冨洿涓嶈兘涓虹┖", false); + } + if (null == vo.getPid() || vo.getPid() < 0) { + vo.setPid(0); + } + if (null == vo.getNum() || vo.getNum() < 1) { + vo.setNum(simuService.getMaxId() + 1); + } + if (null == vo.getPid() || vo.getPid() < 0) { + vo.setPid(0); + } + if (null == vo.getStartTime()) { + vo.setStartTime(new Date()); + } + if (vo.getPid() > 0) { + SimuPo pp = simuService.getSimuByPid(vo.getPid()); + if (null == pp) { + return fail("pid涓嶅瓨鍦�"); + } + if (null == vo.getFloodStart() || vo.getFloodStart() < 1 || vo.getFloodStart() > vo.getDuration() * 60) { + return fail("闃叉睕寮�濮嬫椂闂翠笉鑳戒负绌猴紝涓斿彇鍊煎湪1~" + (vo.getDuration() * 60) + "涔嬮棿"); + } + if (null == vo.getFloodEnd() || vo.getFloodEnd() < vo.getFloodStart() || vo.getFloodEnd() > vo.getDuration() * 60) { + return fail("闃叉睕缁撴潫鏃堕棿涓嶈兘涓虹┖锛屼笖鍙栧�煎湪" + vo.getFloodStart() + "~" + (vo.getDuration() * 60) + "涔嬮棿"); + } + if (null == vo.getFloodHeight() || vo.getFloodHeight() < 1 || vo.getFloodHeight() > 2000) { + return fail("闃叉睕楂樺害涓嶈兘涓虹┖锛屼笖鍙栧�煎湪1~2000涔嬮棿"); + } + if (!FLOOD_TYPE.contains(vo.getFloodType())) { + return fail("闃叉睕绫诲瀷涓嶈兘涓虹┖锛屼笖鍙兘鏄矙琚嬪拰闃叉按鏉�"); + } + if (null == vo.getFloodMinx() || null == vo.getFloodMiny() || null == vo.getFloodMaxx() || null == vo.getFloodMaxy()) { + return fail("闃叉睕鑼冨洿涓嶈兘涓虹┖", false); + } + } + boolean flag = simuFilesService.createByfiles(vo); + return success(flag, flag ? "鎴愬姛" : "澶辫触"); + } catch (Exception ex) { + return fail(ex, null); + } + } + + + + + + + + } diff --git a/src/main/java/com/se/simu/service/SimuFilesService.java b/src/main/java/com/se/simu/service/SimuFilesService.java new file mode 100644 index 0000000..35f52f7 --- /dev/null +++ b/src/main/java/com/se/simu/service/SimuFilesService.java @@ -0,0 +1,213 @@ +package com.se.simu.service; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.io.FileUtil; +import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.metadata.OrderItem; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.se.simu.config.PropertiesConfig; +import com.se.simu.domain.dto.GeDb; +import com.se.simu.domain.po.DataPo; +import com.se.simu.domain.po.SimuPo; +import com.se.simu.domain.vo.CreateSimuVo; +import com.se.simu.domain.vo.SimuVo; +import com.se.simu.helper.StringHelper; +import com.se.simu.helper.WebHelper; +import com.se.simu.mapper.SimuMapper; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.File; +import java.sql.Timestamp; +import java.util.Date; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * SIMU 鏂囦欢鏈嶅姟 + * + * @author xingjinshuang@smartearth.cn + * @date 2024/12/24 + */ +@Slf4j +@Service + +public class SimuFilesService { + + @Resource + SimuMapper simuMapper; + + @Resource + PropertiesConfig config; + + @Resource + GedbService gedbService; + + @Resource + UwService uwService; + + @Resource + ResultService resultService; + + public IPage<SimuPo> get(SimuVo vo) { + QueryWrapper<SimuPo> wrapper = getPageWrapper(vo); + + Page<SimuPo> page = new Page<>(vo.getPageIndex(), vo.getPageSize()); + page.addOrder(OrderItem.desc("id")); + + IPage<SimuPo> paged = simuMapper.selectPage(page, wrapper); + + return paged; + } + + private QueryWrapper<SimuPo> getPageWrapper(SimuVo vo) { + QueryWrapper<SimuPo> wrapper = new QueryWrapper<>(); + if (null != vo.getId()) { + wrapper.eq("id", vo.getId()); + } + if (null != vo.getPid()) { + wrapper.eq("pid", vo.getPid()); + } + if (null != vo.getNum()) { + wrapper.eq("num", vo.getNum()); + } + if (!StringHelper.isEmpty(vo.getName())) { + wrapper.like("lower(name)", vo.getName().trim().toLowerCase()); + } + if (!CollUtil.isEmpty(vo.getStatus())) { + wrapper.in("status", vo.getStatus()); + } + + return wrapper; + } + + + private boolean delDir(String dir) { + File file = new File(dir); + if (!file.exists() || !file.isDirectory()) { + return false; + } + + return FileUtil.del(dir); + } + + + public boolean createByfiles(CreateSimuVo vo) { + Date now = new Date(); + String date = StringHelper.YMDHMS2_FORMAT.format(now); + if (StringHelper.isEmpty(vo.getName())) { + vo.setName(date); + } + + DataPo data = BeanUtil.copyProperties(vo, DataPo.class); + data.setPath(date, date); + initPath(data); + + SimuPo simu = new SimuPo(vo.getNum(), vo.getPid(), vo.getName(), JSONUtil.toJsonStr(data), 0, vo.getBak()); + simu.setServiceName(date); + simu.setCreateTime(new Timestamp(now.getTime())); + + int rows = simuMapper.insert(simu); + if (rows > 0) { + asyncCall(simu); + } + + return rows > 0; + } + + private void initPath(DataPo data) { + createDir(config.getInPath() + File.separator + data.getInPath()); + createDir(config.getOutPath() + File.separator + data.getOutPath()); + } + + private void createDir(String path) { + File f = new File(path); + if (f.exists() && f.isDirectory()) { + FileUtil.del(f); + } + f.mkdirs(); + } + + private void asyncCall(SimuPo simu) { + ExecutorService executor = Executors.newSingleThreadExecutor(); + executor.execute(new Runnable() { + @Override + @SneakyThrows + public void run() { + cope(simu); + } + }); + executor.shutdown(); + } + + + /** + * "鐘舵�侊細 + * 0-鍒涘缓浠跨湡浠诲姟锛� + * 1-杩炴帴GEDB搴擄紝 + * 2-涓嬭浇绌洪棿鏁版嵁锛� + * 3-涓嬭浇楂樼▼鏁版嵁锛� + * 4-鐢熸垚闄嶉洦鏂囦欢锛� + * 5-鐢熸垚閰嶇疆鏂囦欢锛� + * 6-妯℃嫙鍐呮稘浠跨湡锛� + * 7-澶勭悊姘翠綅鏂囦欢锛� + * 8-澶勭悊鎺掓按鏂囦欢锛� + * 9-澶勭悊浠跨湡缁撴灉锛� + * 10-瀹屾垚锛�-10-鍑洪敊 + * + * @param simu 妯℃嫙 + */ + + private void cope(SimuPo simu) { + try { + DataPo data = JSONUtil.toBean(simu.getData(), DataPo.class); + + update(simu, 1, null); + String token = gedbService.getToken(); + GeDb db = gedbService.connectGedb(token, data); + simu.setData(JSONUtil.toJsonStr(data)); + + update(simu, 2, null); + gedbService.copeVectors(token, data, db); + + update(simu, 3, null); + gedbService.copeDem(token, data); + + update(simu, 4, null); + uwService.createRainFile(data); + + update(simu, 5, null); + uwService.createConfig(data); + + update(simu, 6, null); + uwService.callExe(data); + + update(simu, 7, null); + //uwService.copeWaterFiles(); + + update(simu, 8, null); + uwService.copeDrainFiles(data); + + update(simu, 9, null); + resultService.process(data); + + update(simu, 10, "瀹屾垚"); + } catch (Exception ex) { + log.error(ex.getMessage(), ex); + update(simu, -simu.getStatus(), ex.getMessage()); + } + } + + private void update(SimuPo simu, int status, String rs) { + simu.setStatus(status); + if (null != rs) simu.setResult(rs); + simu.setUpdateTime(WebHelper.getCurrentTimestamp()); + + simuMapper.updateById(simu); + } +} diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index fa26f5a..5da03d4 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -104,8 +104,8 @@ # 鏌ヨ涓嶅悓鏁版嵁搴撶被鍨嬩笅鐨勬暟鎹湴鍧� queryUrl: http://106.120.22.26:8024/geo-service/entitydbdata/layer/query -# 椤圭洰妯℃嫙鏂囦欢涓婁紶瀛樻斁鐨勪綅缃� -simu-file: +# 妯℃嫙椤圭洰 +simu-app: # 椤圭洰妯℃嫙鏂囦欢涓婁紶瀛樻斁鐨勪綅缃� filePath: D:\simu\app\upload diff --git a/src/main/resources/application-zyy.yml b/src/main/resources/application-zyy.yml index d5a0454..91e5d15 100644 --- a/src/main/resources/application-zyy.yml +++ b/src/main/resources/application-zyy.yml @@ -102,10 +102,10 @@ # 鏌ヨ涓嶅悓鏁版嵁搴撶被鍨嬩笅鐨勬暟鎹湴鍧� queryUrl: http://106.120.22.26:8024/geo-service/entitydbdata/layer/query -# 椤圭洰妯℃嫙鏂囦欢涓婁紶瀛樻斁鐨勪綅缃� -simu-file: +# 妯℃嫙椤圭洰 +simu-app: # 椤圭洰妯℃嫙鏂囦欢涓婁紶瀛樻斁鐨勪綅缃� - filePath: D:\simu\app\upload + filePath: D:\simu\files config: ver: 0.2 -- Gitblit v1.9.3