From 605ade97fb838081beae2ffc7c57b64e7d40cb24 Mon Sep 17 00:00:00 2001 From: xiaowuler Date: Fri, 25 Feb 2022 16:34:21 +0800 Subject: [PATCH] modify some codes --- .../dao/impl/SchemaRepository.java | 3 + .../XxlJobExecutorApplicationTests.java | 78 +++++-- .../apiservice/config/SwaggerConfig.java | 34 ++++ .../controller/BaseDataController.java | 192 ++++++++++++++++++ .../controller/BaseInfoController.java | 147 ++++++++++++++ .../GlobalDefaultExceptionHandler.java | 19 ++ .../model/domain/CoordinateInfo.java | 43 ++++ .../chuan/apiservice/model/vo/PointValue.java | 19 ++ .../apiservice/model/vo/PointValueVo.java | 25 +++ .../apiservice/service/impl/DataService.java | 117 +++++++++++ .../chuan/apiservice/util/RequestResult.java | 38 ++++ 11 files changed, 694 insertions(+), 21 deletions(-) create mode 100644 04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/config/SwaggerConfig.java create mode 100644 04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/controller/BaseDataController.java create mode 100644 04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/controller/BaseInfoController.java create mode 100644 04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/handler/GlobalDefaultExceptionHandler.java create mode 100644 04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/model/domain/CoordinateInfo.java create mode 100644 04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/model/vo/PointValue.java create mode 100644 04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/model/vo/PointValueVo.java create mode 100644 04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/service/impl/DataService.java create mode 100644 04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/util/RequestResult.java diff --git a/04.系统编码/01.xxl-job/xxl-job-executor/src/main/java/com/ping/chuan/ahpmsdp/xxljobexecutor/dao/impl/SchemaRepository.java b/04.系统编码/01.xxl-job/xxl-job-executor/src/main/java/com/ping/chuan/ahpmsdp/xxljobexecutor/dao/impl/SchemaRepository.java index 965e082..0d2bb2a 100644 --- a/04.系统编码/01.xxl-job/xxl-job-executor/src/main/java/com/ping/chuan/ahpmsdp/xxljobexecutor/dao/impl/SchemaRepository.java +++ b/04.系统编码/01.xxl-job/xxl-job-executor/src/main/java/com/ping/chuan/ahpmsdp/xxljobexecutor/dao/impl/SchemaRepository.java @@ -8,6 +8,7 @@ import org.springframework.stereotype.Repository; import com.datastax.driver.core.DataType; import com.datastax.driver.core.ResultSet; import com.datastax.driver.core.schemabuilder.Create; +import com.datastax.driver.core.schemabuilder.Drop; import com.datastax.driver.core.schemabuilder.KeyspaceOptions; import com.datastax.driver.core.schemabuilder.SchemaBuilder; @@ -38,6 +39,8 @@ public class SchemaRepository implements ISchemaRepository { @Override public void prepareTable(String keyspaceName, String tableName, Map partitionKey, Map columns) { +// Drop drop = SchemaBuilder.dropTable(keyspaceName, tableName); +// cassandraTemplate.getSession().execute(drop); Create builder = SchemaBuilder.createTable(keyspaceName, tableName) .ifNotExists(); diff --git a/04.系统编码/01.xxl-job/xxl-job-executor/src/test/java/com/ping/chuan/ahpmsdp/xxljobexecutor/XxlJobExecutorApplicationTests.java b/04.系统编码/01.xxl-job/xxl-job-executor/src/test/java/com/ping/chuan/ahpmsdp/xxljobexecutor/XxlJobExecutorApplicationTests.java index a009d56..5d32880 100644 --- a/04.系统编码/01.xxl-job/xxl-job-executor/src/test/java/com/ping/chuan/ahpmsdp/xxljobexecutor/XxlJobExecutorApplicationTests.java +++ b/04.系统编码/01.xxl-job/xxl-job-executor/src/test/java/com/ping/chuan/ahpmsdp/xxljobexecutor/XxlJobExecutorApplicationTests.java @@ -13,6 +13,7 @@ import com.ping.chuan.ahpmsdp.xxljobexecutor.service.IDealInfoService; import com.ping.chuan.ahpmsdp.xxljobexecutor.service.ISchemaService; import com.ping.chuan.ahpmsdp.xxljobexecutor.service.ITianQingCLDASDataService; import com.ping.chuan.ahpmsdp.xxljobexecutor.service.ITianQingSCMOCDataService; +import com.ping.chuan.ahpmsdp.xxljobexecutor.service.impl.SchemaService; import com.ping.chuan.ahpmsdp.xxljobexecutor.template.CassandraTemplate; import com.ping.chuan.ahpmsdp.xxljobexecutor.util.FileUtil; import org.apache.cassandra.cql3.Term; @@ -36,6 +37,7 @@ import java.util.*; import com.datastax.driver.core.DataType; import com.datastax.driver.core.querybuilder.Insert; import com.datastax.driver.core.querybuilder.QueryBuilder; +import com.google.common.collect.Lists; @SpringBootTest class XxlJobExecutorApplicationTests { @@ -122,29 +124,58 @@ class XxlJobExecutorApplicationTests { columns.put("time_convert_value", DataType.cint()); columns.put("lat_clip_count", DataType.cint()); columns.put("lon_clip_count", DataType.cint()); + columns.put("full_name_escaped", DataType.varchar()); +// schemaRepository.prepareTable("data_config", "meta_infos", partitionKey, columns); -// List columnNames = new ArrayList<>(partitionKey.keySet()); -// columnNames.addAll(columns.keySet()); + List columnNames = new ArrayList<>(partitionKey.keySet()); + columnNames.addAll(columns.keySet()); // List elementCodes = Lists.newArrayList("TMAX", "TMIN"); -// for(String elementCode : elementCodes){ -// List values = new ArrayList<>(columnNames.size()); -// values.add("SPCC"); -// values.add("BEHF"); -// values.add(elementCode); -// values.add(1440); -// values.add(14400); -// values.add(1010); -// values.add("243_221_0.025_0.025_29_35.05_114.5_120"); -// values.add(1440); -// values.add("H"); -// values.add(60); -// values.add(30); -// values.add(30); -// Insert builder = QueryBuilder.insertInto("data_config", "meta_infos") -// .ifNotExists() -// .values(columnNames, values); -// cassandraTemplate.getSession().execute(builder); -// } + List> metaInfos = createMetaInfos(); + for(List metaInfo : metaInfos){ + List values = new ArrayList<>(columnNames.size()); + values.add(metaInfo.get(0)); + values.add(metaInfo.get(1)); + values.add(metaInfo.get(2)); + values.add(metaInfo.get(3)); + values.add(metaInfo.get(4)); + values.add(metaInfo.get(5)); + values.add(metaInfo.get(6)); + values.add(metaInfo.get(7)); + values.add(metaInfo.get(8)); + values.add(metaInfo.get(9)); + values.add(metaInfo.get(10)); + values.add(metaInfo.get(11)); + values.add(metaInfo.get(12)); + Insert builder = QueryBuilder.insertInto("data_config", "meta_infos") + .ifNotExists() + .values(columnNames, values); + cassandraTemplate.getSession().execute(builder); + } + } + + private List> createMetaInfos(){ + List> metaInfos = new ArrayList<>(); +// metaInfos.add(Lists.newArrayList("CLDAS", "BABJ", "VIS", 60, 60, 1010, "1201_1401_0.05_0.05_0_60_70_140", 0, "H", 60, 60, 70, "Visibility_surface")); +// metaInfos.add(Lists.newArrayList("CLDAS", "BABJ", "RHU", 60, 60, 1010, "1201_1401_0.05_0.05_0_60_70_140", 0, "H", 60, 60, 70, "Relative_humidity_height_above_ground")); +// metaInfos.add(Lists.newArrayList("CLDAS", "BABJ", "TEM", 60, 60, 1010, "1201_1401_0.05_0.05_0_60_70_140", 0, "H", 60, 60, 70, "Temperature_height_above_ground")); +// metaInfos.add(Lists.newArrayList("CLDAS", "BABJ", "WIN_U", 60, 60, 1010, "1201_1401_0.05_0.05_0_60_70_140", 0, "H", 60, 60, 70, "u-component_of_wind_height_above_ground")); +// metaInfos.add(Lists.newArrayList("CLDAS", "BABJ", "WIN_V", 60, 60, 1010, "1201_1401_0.05_0.05_0_60_70_140", 0, "H", 60, 60, 70, "v-component_of_wind_height_above_ground")); +// metaInfos.add(Lists.newArrayList("CLDAS", "BABJ", "MNRHU", 60, 60, 1010, "1201_1401_0.05_0.05_0_60_70_140", 0, "H", 60, 60, 70, "Fraction_of_snow_cover_height_above_ground")); +// metaInfos.add(Lists.newArrayList("CLDAS", "BABJ", "MNT", 60, 60, 1010, "1201_1401_0.05_0.05_0_60_70_140", 0, "H", 60, 60, 70, "Minimum_temperature_height_above_ground")); +// metaInfos.add(Lists.newArrayList("CLDAS", "BABJ", "MXRHU", 60, 60, 1010, "1201_1401_0.05_0.05_0_60_70_140", 0, "H", 60, 60, 70, "VAR0-1-122_FROM_38-0--1_height_above_ground")); +// metaInfos.add(Lists.newArrayList("CLDAS", "BABJ", "MXT", 60, 60, 1010, "1201_1401_0.05_0.05_0_60_70_140", 0, "H", 60, 60, 70, "Maximum_temperature_height_above_ground")); +// metaInfos.add(Lists.newArrayList("CLDAS", "BABJ", "MXWIN_U", 60, 60, 1010, "1201_1401_0.05_0.05_0_60_70_140", 0, "H", 60, 60, 70, "VAR0-2-102_FROM_38-0--1_height_above_ground")); +// metaInfos.add(Lists.newArrayList("CLDAS", "BABJ", "MXWIN_V", 60, 60, 1010, "1201_1401_0.05_0.05_0_60_70_140", 0, "H", 60, 60, 70, "VAR0-2-103_FROM_38-0--1_height_above_ground")); + metaInfos.add(Lists.newArrayList("SPCC", "BEHF", "TMP", 180, 4320, 1010, "243_221_0.025_0.025_29_35.05_114.5_120", 180, "H", 60, 30, 30, "Temperature_height_above_ground")); + metaInfos.add(Lists.newArrayList("SPCC", "BEHF", "EDA10_U", 180, 4320, 1010, "243_221_0.025_0.025_29_35.05_114.5_120", 180, "H", 60, 30, 30, "u-component_of_wind_height_above_ground")); + metaInfos.add(Lists.newArrayList("SPCC", "BEHF", "EDA10_V", 180, 4320, 1010, "243_221_0.025_0.025_29_35.05_114.5_120", 180, "H", 60, 30, 30, "v-component_of_wind_height_above_ground")); + metaInfos.add(Lists.newArrayList("SPCC", "BEHF", "ER03", 180, 4320, 1010, "243_221_0.025_0.025_29_35.05_114.5_120", 180, "H", 60, 30, 30, "Total_precipitation_surface_3_Hour_Accumulation")); + metaInfos.add(Lists.newArrayList("SPCC", "BEHF", "PPH", 180, 4320, 1010, "243_221_0.025_0.025_29_35.05_114.5_120", 180, "H", 60, 30, 30, "Precipitation_type_surface_3_Hour_Accumulation")); + metaInfos.add(Lists.newArrayList("SPCC", "BEHF", "TMAX", 1440, 4320, 1010, "243_221_0.025_0.025_29_35.05_114.5_120", 1440, "H", 60, 30, 30, "Maximum_temperature_height_above_ground_24_Hour_Maximum")); + metaInfos.add(Lists.newArrayList("SPCC", "BEHF", "TMIN", 1440, 4320, 1010, "243_221_0.025_0.025_29_35.05_114.5_120", 1440, "H", 60, 30, 30, "Minimum_temperature_height_above_ground_24_Hour_Minimum")); + metaInfos.add(Lists.newArrayList("CMPA", "BABJ", "PRE", 60, 60, 1010, "1201_1401_0.05_0.05_0_60_70_140", 0, "H", 60, 60, 70, "Total_precipitation_surface")); + + return metaInfos; } @Test @@ -249,4 +280,9 @@ class XxlJobExecutorApplicationTests { return; } + @Test + void buildDataConfig(){ + schemaService.buildKeySpace(); + } + } diff --git a/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/config/SwaggerConfig.java b/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/config/SwaggerConfig.java new file mode 100644 index 0000000..3c71c0c --- /dev/null +++ b/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/config/SwaggerConfig.java @@ -0,0 +1,34 @@ +package com.ping.chuan.apiservice.config; + +import io.swagger.annotations.Api; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +@Configuration +@EnableSwagger2 +public class SwaggerConfig { + @Bean + public Docket createRestApi() { + return new Docket(DocumentationType.SWAGGER_2) + .useDefaultResponseMessages(false) + .apiInfo(apiInfo()) + .select() + .apis(RequestHandlerSelectors.withClassAnnotation(Api.class)) + .paths(PathSelectors.any()) + .build(); + } + private ApiInfo apiInfo() { + return new ApiInfoBuilder() + .title("安徽省公共气象服务基础数据平台") + .description("测试") + .version("5.2.1") + .build(); + } +} \ No newline at end of file diff --git a/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/controller/BaseDataController.java b/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/controller/BaseDataController.java new file mode 100644 index 0000000..e6d7aa4 --- /dev/null +++ b/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/controller/BaseDataController.java @@ -0,0 +1,192 @@ +package com.ping.chuan.apiservice.controller; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import io.swagger.annotations.*; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import com.ping.chuan.apiservice.model.constant.TimeConstant; +import com.ping.chuan.apiservice.model.dao.Coordinate; +import com.ping.chuan.apiservice.model.dao.MetaInfo; +import com.ping.chuan.apiservice.service.IDataService; +import com.ping.chuan.apiservice.template.CacheTemplate; +import com.ping.chuan.apiservice.util.RequestResult; + +/** + * @describe: + * @author: xiaowuler + * @createTime: 2021-11-12 15:20 + */ +@Api(tags = "获取要素模式数据") +@RestController +@RequestMapping("baseData") +public class BaseDataController { + + private final ObjectMapper objectMapper = new ObjectMapper(); + private final IDataService dataService; + public BaseDataController(IDataService dataService){ + this.dataService = dataService; + } + + @ApiOperation(value="用户根据起报时间、要素编码获取SPCC模式要素预报数据", notes="用户根据起报时间、要素编码获取SPCC模式要素预报数据", produces="application/json", httpMethod = "POST") + @ApiImplicitParams({ + @ApiImplicitParam(name = "elementCode", value = "要素编码", required = true, example = "TMP"), + @ApiImplicitParam(name = "initialTime", value = "起报时间", required = true, example = "20211110080000"), + @ApiImplicitParam(name = "forecastTime", value = "预报时间", required = true, example = "20211110110000"), + @ApiImplicitParam(name = "latLons", value = "经纬度", required = true, example = "[[31.5509, 116.97061], [32.5509, 116.97061], [ 29.8, 118.55], [29.888, 118.77]]") + }) + @PostMapping("getSPCCFcstByTargetTimeAndLatlons") + public RequestResult getSPCCFcstByInitialTimeAndLatlons(String elementCode, String initialTime, String forecastTime, String latLons) throws Exception { + String error = verifyParams(elementCode, initialTime, forecastTime, latLons); + if (Objects.nonNull(error)){ + return RequestResult.fail(error); + } + + Object initialTimeValue = convertTime(initialTime); + if (initialTimeValue instanceof String e){ + return RequestResult.fail(e); + } + Object forecastTimeValue = convertTime(forecastTime); + if (forecastTimeValue instanceof String e){ + return RequestResult.fail(e); + } + Object latLonValue = convertLatLon(latLons); + if (latLonValue instanceof String e){ + return RequestResult.fail(e); + } + + Map.Entry entry = CacheTemplate.findOne("SPCC", elementCode, "BEHF", 180, 4320, 1010); + if (Objects.isNull(entry)){ + return RequestResult.fail("未录入当前要素编码数据"); + } + + return RequestResult.success(dataService.findPoints(entry, (LocalDateTime) initialTimeValue, (LocalDateTime) forecastTimeValue, (List) latLonValue)); + } + + @ApiOperation(value="用户根据起报时间、要素编码获取CLDAS模式要素预报数据", notes="用户根据起报时间、要素编码获取CLDAS模式要素预报数据", produces="application/json", httpMethod = "POST") + @ApiImplicitParams({ + @ApiImplicitParam(name = "elementCode", value = "要素编码", required = true, example = "RHU"), + @ApiImplicitParam(name = "realTime", value = "实况时间", required = true, example = "20211112230000"), + @ApiImplicitParam(name = "latLons", value = "经纬度", required = true, example = "[[31.5509, 116.97061], [32.5509, 116.97061], [ 29.8, 118.55], [29.888, 118.77]]") + }) + @PostMapping("getCLDASRealByTargetTimeAndLatlons") + public RequestResult getCLDASRealByInitialTimeAndLatlons(String elementCode, String realTime, String latLons) throws Exception { + String error = verifyParams(elementCode, realTime, realTime, latLons); + if (Objects.nonNull(error)){ + return RequestResult.fail(error); + } + + Object initialTimeValue = convertTime(realTime); + if (initialTimeValue instanceof String e){ + return RequestResult.fail(e); + } + Object forecastTimeValue = convertTime(realTime); + if (forecastTimeValue instanceof String e){ + return RequestResult.fail(e); + } + Object latLonValue = convertLatLon(latLons); + if (latLonValue instanceof String e){ + return RequestResult.fail(e); + } + + Map.Entry entry = CacheTemplate.findOne("CLDAS", elementCode, "BABJ", 60, 60, 1010); + if (Objects.isNull(entry)){ + return RequestResult.fail("未录入当前要素编码数据"); + } + + return RequestResult.success(dataService.findPoints(entry, (LocalDateTime) initialTimeValue, (LocalDateTime) forecastTimeValue, (List) latLonValue)); + } + + @ApiOperation(value="用户根据起报时间、要素编码获取CMPA模式要素预报数据", notes="用户根据起报时间、要素编码获取CMPA模式要素预报数据", produces="application/json", httpMethod = "POST") + @ApiImplicitParams({ + @ApiImplicitParam(name = "elementCode", value = "要素编码", required = true, example = "PRE"), + @ApiImplicitParam(name = "realTime", value = "实况时间", required = true, example = "20211112230000"), + @ApiImplicitParam(name = "latLons", value = "经纬度", required = true, example = "[[31.5509, 116.97061], [32.5509, 116.97061], [ 29.8, 118.55], [29.888, 118.77]]") + }) + @PostMapping("getCMPARealByInitialTimeAndLatlons") + public RequestResult getCMPARealByInitialTimeAndLatlons(String elementCode, String realTime, String latLons) throws Exception { + String error = verifyParams(elementCode, realTime, realTime, latLons); + if (Objects.nonNull(error)){ + return RequestResult.fail(error); + } + + Object initialTimeValue = convertTime(realTime); + if (initialTimeValue instanceof String e){ + return RequestResult.fail(e); + } + Object forecastTimeValue = convertTime(realTime); + if (forecastTimeValue instanceof String e){ + return RequestResult.fail(e); + } + Object latLonValue = convertLatLon(latLons); + if (latLonValue instanceof String e){ + return RequestResult.fail(e); + } + + Map.Entry entry = CacheTemplate.findOne("CMPA", elementCode, "BABJ", 60, 60, 1010); + if (Objects.isNull(entry)){ + return RequestResult.fail("未录入当前要素编码数据"); + } + + return RequestResult.success(dataService.findPoints(entry, (LocalDateTime) initialTimeValue, (LocalDateTime) forecastTimeValue, (List) latLonValue)); + } + + private String verifyParams(String elementCode, String initialTime, String forecastTime, String latLons){ + List errors = new ArrayList<>(4); + if (Objects.isNull(elementCode)){ + errors.add("要素编码不能为空"); + } + + if (Objects.isNull(initialTime)){ + errors.add("起报时间不能为空"); + } + + if (Objects.isNull(forecastTime)){ + errors.add("预报时间不能为空"); + } + + if (Objects.isNull(latLons)){ + errors.add("经纬度不能为空"); + } + + if (errors.isEmpty()){ + return null; + } + + return errors.stream().collect(Collectors.joining(", ")); + } + + private Object convertTime(String timeStr){ + try{ + return LocalDateTime.parse(timeStr, TimeConstant.YYYYMMDDHHMMSS); + }catch (Exception e){ + return "时间格式是yyyyMMddHHmmss"; + } + } + + private Object convertLatLon(String latLons){ + try { + List newLocations = new ArrayList<>(); + List locations = objectMapper.readValue(latLons, new TypeReference>() {}); + for (BigDecimal[] loc : locations) { + if (loc.length != 2) { + return "latlons 格式不正确,格式应为'[[lat,lon],...,[lat,lon]]'"; + } + newLocations.add(new BigDecimal[]{loc[0], loc[1]}); + } + return newLocations; + } catch (Exception e) { + return "latlons 格式不正确,格式应为'[[lat,lon],...,[lat,lon]]'"; + } + } +} diff --git a/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/controller/BaseInfoController.java b/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/controller/BaseInfoController.java new file mode 100644 index 0000000..f4cb0be --- /dev/null +++ b/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/controller/BaseInfoController.java @@ -0,0 +1,147 @@ +package com.ping.chuan.apiservice.controller; + +import com.ping.chuan.apiservice.model.dao.Coordinate; +import com.ping.chuan.apiservice.model.dao.MetaInfo; +import com.ping.chuan.apiservice.service.IDataService; +import com.ping.chuan.apiservice.template.CacheTemplate; +import com.ping.chuan.apiservice.util.RequestResult; +import com.ping.chuan.apiservice.util.TimeUtil; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author zhangjian + */ +@Api(tags = "获取要素元信息") +@RestController +@RequestMapping("baseInfo") +public class BaseInfoController { + + private final IDataService dataService; + public BaseInfoController(IDataService dataService){ + this.dataService = dataService; + } + + @ApiOperation(value="用户根据模式编码获取要素编码", notes="用户根据模式编码获取要素编码", produces="application/json", httpMethod = "POST") + @ApiImplicitParam(name="modeCode", value="modeCode", required=true, example = "SPCC", paramType="query") + @RequestMapping("getElementCodes") + public RequestResult getElementCodes(String modeCode){ + if(Objects.isNull(modeCode)){ + return RequestResult.fail("modeCode不能为空"); + } + + String targetModeCode = modeCode.toUpperCase(Locale.ROOT); + List result = CacheTemplate.metaInfos.keySet().stream() + .filter(m -> m.getModeCode().equals(targetModeCode)) + .map(m -> m.getElementCode()) + .distinct() + .collect(Collectors.toList()); + + if (result.isEmpty()){ + return RequestResult.fail("当前模式未录入相关要素信息"); + } + + return RequestResult.success(result); + } + + @ApiOperation(value="用户获取所有模式编码", notes="用户获取所有模式编码", produces="application/json", httpMethod = "POST") + @RequestMapping("getAllModeCode") + public RequestResult getAllModeCode(){ + List result = CacheTemplate.metaInfos.keySet().stream() + .map(m -> m.getModeCode()) + .distinct() + .collect(Collectors.toList()); + + if (result.isEmpty()){ + return RequestResult.fail("当前无相关模式信息"); + } + + return RequestResult.success(result); + } + + @ApiOperation(value="用户根据模式编码和要素编码获取起报时间", notes="用户根据模式编码和要素编码获取起报时间", produces="application/json", httpMethod = "POST") + @ApiImplicitParams({ + @ApiImplicitParam(name="modeCode", value="模式编码", example = "SPCC", required=true, paramType="query"), + @ApiImplicitParam(name="elementCode", value="要素编码", example = "TMP", required=true, paramType="query") + }) + @RequestMapping("getInitialTimeByModeCodeAndElementCode") + public RequestResult getInitialTimeByModeCodeAndElementCode(String modeCode, String elementCode) throws Exception { + if(Objects.isNull(modeCode)){ + return RequestResult.fail("modeCode不能为空"); + } + if(Objects.isNull(elementCode)){ + return RequestResult.fail("elementCode不能为空"); + } + + int timeInterval = 60; + int timeLength = 60; + String memberCode = "BABJ"; + modeCode = modeCode.toUpperCase(Locale.ROOT); + elementCode = elementCode.toUpperCase(Locale.ROOT); + if ("SPCC".equals(modeCode)){ + timeInterval = 180; + timeLength = 4320; + memberCode = "BEHF"; + } + + Map.Entry entry = CacheTemplate.findOne(modeCode, elementCode, memberCode, timeInterval, timeLength, 1010); + if (Objects.isNull(entry)){ + return RequestResult.fail("当前无相关模式信息"); + } + + return RequestResult.success(dataService.findInitialTime(entry)); + } + + @ApiOperation(value="用户根据模式编码、要素编码、起报时间获取预报时间", notes="用户根据模式编码、要素编码、起报时间获取预报时间", produces="application/json", httpMethod = "POST") + @ApiImplicitParams({ + @ApiImplicitParam(name="modeCode", value="模式编码", example = "SPCC", required=true, paramType="query"), + @ApiImplicitParam(name="elementCode", value="要素编码", example = "TMP", required=true, paramType="query"), + @ApiImplicitParam(name="initialTime", value="起报时间", example = "20211112080000", required=true, paramType="query") + }) + @RequestMapping("getForecastTimeByModeCodeAndElementCode") + public RequestResult getForecastTimeByModeCodeAndElementCode(String modeCode, String elementCode, String initialTime) throws Exception { + if(Objects.isNull(modeCode)){ + return RequestResult.fail("modeCode不能为空"); + } + if(Objects.isNull(elementCode)){ + return RequestResult.fail("elementCode不能为空"); + } + + if (Objects.isNull(initialTime)){ + return RequestResult.fail("initialTime不能为空"); + } + + int timeInterval = 60; + int timeLength = 60; + String memberCode = "BABJ"; + modeCode = modeCode.toUpperCase(Locale.ROOT); + elementCode = elementCode.toUpperCase(Locale.ROOT); + if ("SPCC".equals(modeCode)){ + timeInterval = 180; + timeLength = 4320; + memberCode = "BEHF"; + } + + Map.Entry entry = CacheTemplate.findOne(modeCode, elementCode, memberCode, timeInterval, timeLength, 1010); + if (Objects.isNull(entry)){ + return RequestResult.fail("当前无相关模式信息"); + } + + Object initialTimeValue = TimeUtil.convertTime(initialTime); + if (initialTimeValue instanceof String e){ + return RequestResult.fail(e); + } + + return RequestResult.success(dataService.findForecastTime(entry, Date.from(((LocalDateTime) initialTimeValue).atZone(ZoneId.systemDefault()).toInstant()))); + } +} diff --git a/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/handler/GlobalDefaultExceptionHandler.java b/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/handler/GlobalDefaultExceptionHandler.java new file mode 100644 index 0000000..ed8bb70 --- /dev/null +++ b/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/handler/GlobalDefaultExceptionHandler.java @@ -0,0 +1,19 @@ +package com.ping.chuan.apiservice.handler; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; + +import com.ping.chuan.apiservice.util.RequestResult; + +@ControllerAdvice +@Slf4j +public class GlobalDefaultExceptionHandler { + @ExceptionHandler(Exception.class) + @ResponseBody + public RequestResult defaultExceptionHandler(Exception e) { + log.error("An error has occurred", e); + return RequestResult.fail(e.getMessage()); + } +} diff --git a/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/model/domain/CoordinateInfo.java b/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/model/domain/CoordinateInfo.java new file mode 100644 index 0000000..3b4c5f9 --- /dev/null +++ b/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/model/domain/CoordinateInfo.java @@ -0,0 +1,43 @@ +package com.ping.chuan.apiservice.model.domain; + +import java.math.BigDecimal; + +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @describe: + * @author: xiaowuler + * @createTime: 2021-11-12 16:16 + */ +@Data +public class CoordinateInfo { + private BigDecimal originalLon; + private BigDecimal originalLat; + private BigDecimal gridLon; + private BigDecimal gridLat; + + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + private int lonIndex; + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + private int latIndex; + + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + private int sliceLon; + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + private int sliceLat; + + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + private int sliceLonIndex; + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + private int sliceLatIndex; + + private int targetLatIndex; + private int targetLonIndex; + + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + private String column; + + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + private boolean isHandler = true; +} diff --git a/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/model/vo/PointValue.java b/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/model/vo/PointValue.java new file mode 100644 index 0000000..8b0e067 --- /dev/null +++ b/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/model/vo/PointValue.java @@ -0,0 +1,19 @@ +package com.ping.chuan.apiservice.model.vo; + +import java.math.BigDecimal; + +import lombok.Data; + +/** + * @describe: 点数据返回实体类 + * @author: xiaowuler + * @createTime: 2021-11-13 11:03 + */ +@Data +public class PointValue { + private BigDecimal originalLon; + private BigDecimal originalLat; + private BigDecimal gridLon; + private BigDecimal gridLat; + private BigDecimal value; +} diff --git a/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/model/vo/PointValueVo.java b/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/model/vo/PointValueVo.java new file mode 100644 index 0000000..3519a82 --- /dev/null +++ b/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/model/vo/PointValueVo.java @@ -0,0 +1,25 @@ +package com.ping.chuan.apiservice.model.vo; + +import java.time.LocalDateTime; +import java.util.List; + +import lombok.Data; + +import com.fasterxml.jackson.annotation.JsonFormat; + +import com.ping.chuan.apiservice.model.dao.MetaInfo; + +/** + * @describe: 点数据 传输类 + * @author: xiaowuler + * @createTime: 2021-11-13 11:10 + */ +@Data +public class PointValueVo { + private MetaInfo metaInfo; + @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyyMMddHHmmss") + private LocalDateTime initialTime; + @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyyMMddHHmmss") + private LocalDateTime targetTime; + private List pointValues; +} diff --git a/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/service/impl/DataService.java b/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/service/impl/DataService.java new file mode 100644 index 0000000..7eb3f4c --- /dev/null +++ b/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/service/impl/DataService.java @@ -0,0 +1,117 @@ +package com.ping.chuan.apiservice.service.impl; + +import java.math.BigDecimal; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; + +import org.springframework.stereotype.Service; + +import com.ping.chuan.apiservice.dao.IDataRepository; +import com.ping.chuan.apiservice.dao.ISchemaRepository; +import com.ping.chuan.apiservice.model.constant.TimeConstant; +import com.ping.chuan.apiservice.model.dao.Coordinate; +import com.ping.chuan.apiservice.model.dao.DealInfo; +import com.ping.chuan.apiservice.model.dao.MetaInfo; +import com.ping.chuan.apiservice.model.domain.CoordinateInfo; +import com.ping.chuan.apiservice.model.vo.PointValue; +import com.ping.chuan.apiservice.model.vo.PointValueVo; +import com.ping.chuan.apiservice.service.IDataService; +import com.ping.chuan.apiservice.util.CalcUtil; + +/** + * @describe: 数据服务 + * @author: xiaowuler + * @createTime: 2021-11-12 15:58 + */ +@Service +public class DataService implements IDataService { + + private final ISchemaRepository schemaRepository; + private final IDataRepository dataRepository; + public DataService(ISchemaRepository schemaRepository, IDataRepository dataRepository){ + this.schemaRepository = schemaRepository; + this.dataRepository = dataRepository; + } + + @Override + public void readRoutineElement(Map.Entry> entry, boolean isTmp) { + + } + + @Override + public void readWindElement(Map.Entry> entry) { + + } + + @Override + public PointValueVo findPoints(Map.Entry entry, LocalDateTime initialTime, LocalDateTime forecastTime, List latLons) throws Exception { + String keyspace = toKeyspace(initialTime); + String tableName = entry.getKey().toTableName(); + boolean isExist = schemaRepository.exist(keyspace, tableName); + if (!isExist){ + throw new Exception("当前数据未建立库,请调整时间查询。"); + } + + List coordinateInfos = new ArrayList<>(latLons.size()); + for(BigDecimal[] latLon : latLons){ + coordinateInfos.add(CalcUtil.calcLocation(entry.getValue(), entry.getKey(), latLon)); + } + List pointValues = dataRepository.findPoint(keyspace, tableName, initialTime, forecastTime, coordinateInfos); + return toPointValueVo(initialTime, forecastTime, entry.getKey(), pointValues); + } + + @Override + public List findInitialTime(Map.Entry entry) throws Exception { + LocalDateTime now = LocalDateTime.now(); + List times = new ArrayList<>(); + SimpleDateFormat sdf = new SimpleDateFormat(TimeConstant.YYYYMMDDHHMMSS_STR); + for(int index = 0; index < 3; index++){ + LocalDateTime time = now.minusMonths(index); + String keyspace = "data_%s".formatted(time.format(TimeConstant.YYYYMM)); + String tableName = entry.getKey().toTableName(); + if (!schemaRepository.exist(keyspace, tableName)){ + break; + } + + List sourceTimes = dataRepository.findInitialTime(keyspace, tableName); + times.addAll(sourceTimes.stream().map(t -> sdf.format(t)).collect(Collectors.toList())); + if (times.size() >= 10){ + break; + } + } + + if (times.isEmpty()){ + throw new Exception("未查到相关信息,请调整参数查询"); + } + + return times.stream().limit(10).sorted().collect(Collectors.toList()); + } + + @Override + public List findForecastTime(Map.Entry entry, Date initialTime) throws Exception { + SimpleDateFormat sdf = new SimpleDateFormat(TimeConstant.YYYYMM_STR); + String keyspace = "data_%s".formatted(sdf.format(initialTime)); + String tableName = entry.getKey().toTableName(); + if (!schemaRepository.exist(keyspace, tableName)){ + throw new Exception("当前查询数据未入库,请调整参数查询"); + } + List time = dataRepository.findForecastTime(keyspace, tableName, initialTime); + SimpleDateFormat convertSdf = new SimpleDateFormat(TimeConstant.YYYYMMDDHHMMSS_STR); + return time.stream().map(t -> convertSdf.format(t)).sorted().collect(Collectors.toList()); + } + + private PointValueVo toPointValueVo(LocalDateTime initialTime, LocalDateTime forecastTime, MetaInfo metaInfo, List pointValues){ + PointValueVo pointValueVo = new PointValueVo(); + pointValueVo.setPointValues(pointValues); + pointValueVo.setMetaInfo(metaInfo); + pointValueVo.setInitialTime(initialTime); + pointValueVo.setTargetTime(forecastTime); + return pointValueVo; + } + + private String toKeyspace(LocalDateTime initialTime){ + return "data_%s".formatted(initialTime.format(TimeConstant.YYYYMM)); + } +} diff --git a/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/util/RequestResult.java b/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/util/RequestResult.java new file mode 100644 index 0000000..083ae20 --- /dev/null +++ b/04.系统编码/02.api-service/src/main/java/com/ping/chuan/apiservice/util/RequestResult.java @@ -0,0 +1,38 @@ +package com.ping.chuan.apiservice.util; + +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class RequestResult { + private int error; + private String message; + private T data; + + public static RequestResult success() { + return new RequestResult(0, null, null); + } + + public static RequestResult success(Object data) { + return new RequestResult(0, null, data); + } + + public static RequestResult success(String message, Object data){ + return new RequestResult(0, message, data); + } + + public static RequestResult fail() { + return new RequestResult(1, null, null); + } + + public static RequestResult fail(int code, String message) { + return new RequestResult(code, message, null); + } + + public static RequestResult fail(String message) { + return new RequestResult(1, message, null); + } +} \ No newline at end of file