zrj
2024-09-23 df847a2500eb99f890bf3847ac2cc49a92c0d221
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
package cn.gistack.nky.service.impl;
 
import cn.gistack.nky.constant.OpenApiConstant;
import cn.gistack.nky.constant.ZtConfigConstant;
import cn.gistack.nky.entity.DamAlarmRecord;
import cn.gistack.nky.entity.DamAlarmRecordDetail;
import cn.gistack.nky.enums.DamEnum;
import cn.gistack.nky.mapper.OpenApiMapper;
import cn.gistack.nky.service.DamAlarmRecordDetailService;
import cn.gistack.nky.service.DamAlarmRecordService;
import cn.gistack.nky.service.IOpenApiService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springblade.core.redis.cache.BladeRedis;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
/**
 * 南科院水库预警算法api调用服务接口
 * @author zhongrj
 * @date 2024-07-25
 */
@Service
@Slf4j
public class OpenApiServiceImpl implements IOpenApiService {
 
    @Autowired
    private OpenApiMapper openApiMapper;
 
    @Autowired
    private RestTemplate restTemplate;
 
    @Autowired
    private DamAlarmRecordService damAlarmRecordService;
 
    @Autowired
    private DamAlarmRecordDetailService damAlarmRecordDetailService;
 
    @Autowired
    private BladeRedis bladeRedis;
 
    /**
     * 水库及测点信息注册-调用南科院接口
     * @param resGuidList 水库编号集合
     * @return
     */
    @Override
    public boolean waterAndPointRegister(List<String> resGuidList) {
        boolean damResFlag = false;
        boolean pointResFlag = false;
        // 查询水库信息
        List<Map<String,String>> resInfoList = openApiMapper.getResInfo(resGuidList);
        // 查询水库测点信息
//        List<Map<String,String>> resPointInfo = openApiMapper.getResPointInfo(resGuidList);
        // 发送水库注册请求
        String response = sendPostJsonRequest(OpenApiConstant.DAM_REGISTER_URL,resInfoList);
        // 输出响应
        System.out.println(response);
        JSONObject jsonObject = JSON.parseObject(response);
        Integer status = jsonObject.getInteger("status");
        damResFlag = status==200?true:false;
        // 查询
        return damResFlag && pointResFlag;
    }
 
    /**
     * 发送post 请求
     * @param url
     * @param object
     * @return
     */
    private String sendPostJsonRequest(String url,Object object) {
        // 转换为JSON
        ObjectMapper objectMapper = new ObjectMapper();
        String json = "";
        try {
            json = objectMapper.writeValueAsString(object);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 设置HTTP头信息
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        // 创建HttpEntity
        HttpEntity<String> entity = new HttpEntity<>(json, headers);
        // 发送POST请求
        return restTemplate.postForObject(url, entity, String.class);
    }
 
    /**
     * 实时测点测值输入-调用南科院接口
     * @param type 1:渗压,2:渗流,3:X位移,4:Y位移,5:Z位移
     * @return
     */
    @Override
    public void realStationInput(String type) {
        boolean flag = false;
        // 获取当前时间及前一个小时
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 减去一个小时
        LocalDateTime oneHourAgo = now.minusHours(8);
        // 格式化时间
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
        String oneHour = oneHourAgo.format(formatter) + ":00";
        String nowHour = now.format(formatter) + ":00";
        // 调用中台接口获取实时测点数据
        JSONArray ztData = getZtData("",
            ZtConfigConstant.url_prefix + DamEnum.ofType(type).getApiUrl() + "?start_tm=" + oneHour + "&end_tm=" + nowHour + "");
        // 解析数据
        for (int i = 0; i < ztData.size(); i++) {
            JSONObject jsonObject = ztData.getJSONObject(i);
            Map<String,Object> map = new HashMap<>();
            // 水库信息设置
            flag = waterInfoSet(jsonObject, map);
            if (flag) {
                // 测点信息设置
                flag = pointValueInfoSet(jsonObject, map, type,flag);
            }
            if (flag) {
                map.put("batchId",UUID.randomUUID());
                map.put("serialNo",getSerialNo());
                log.info("发送数据:{}",map);
                // 发送请求
                String response = sendPostJsonRequest(OpenApiConstant.POINT_VALUE_INLET_URL, map);
                JSONObject parseObject = JSON.parseObject(response);
                Integer status = parseObject.getInteger("status");
                flag = status==200?true:false;
                log.info("测点输入结果:" + flag);
            }
        }
    }
 
    /**
     * 水库信息设置
     * @param jsonObject
     * @param map
     */
    private boolean waterInfoSet(JSONObject jsonObject, Map<String, Object> map) {
        String rz = jsonObject.getString("rz");
        if(Strings.isBlank(rz)){
            return false;
        }
        // 需要过滤2022高标准水库才发送
        String res_cd = replaceSpecialStr(jsonObject.getString("res_cd"));
        String flag = openApiMapper.getResInfoBy2022(res_cd);
        if (Strings.isBlank(flag)){
            return false;
        }
        List<Map<String, Object>> waterLevelInfoList = new ArrayList<>();
        Map<String, Object> waterLevelInfoMap = new HashMap<>();
        waterLevelInfoMap.put("damCode", res_cd);
        waterLevelInfoMap.put("waterLevel", jsonObject.getString("rz"));
        waterLevelInfoMap.put("waterLevelTime", jsonObject.getString("rz_tm"));
        waterLevelInfoMap.put("rainCondition", jsonObject.getString("drp"));
        waterLevelInfoMap.put("rainConditionTime", jsonObject.getString("drp_tm"));
        waterLevelInfoList.add(waterLevelInfoMap);
        map.put("waterLevelInfo", waterLevelInfoList);
        return true;
    }
 
    /**
     * 测点信息设置
     * @param map
     */
    private boolean pointValueInfoSet(JSONObject jsonObject,Map<String, Object> map,String type,boolean flag) {
        flag = false;
        int num = 0;
        List<Map<String,Object>> pointValueInfoList = new ArrayList<>();
        JSONArray childArray = jsonObject.getJSONArray("child");
        //遍历处理
        for (int i = 0; i < childArray.size(); i++) {
            JSONObject childArrayJSONObject = childArray.getJSONObject(i);
            String sy_val = childArrayJSONObject.getString("sy_val");
            // type 为3 时为位移,位移返回数据格式不一致
            if (type.equals("3")){
                // 获取-位移_z 垂直 du是数值位移(垂直),de向东位移(上下游),dn向北位移(左右岸)
                String du = childArrayJSONObject.getString("du");
                String de = childArrayJSONObject.getString("de");
                String dn = childArrayJSONObject.getString("dn");
                if (!Strings.isBlank(du)){
                    num = setPointValue(jsonObject, DamEnum.ofType("5").getName(), num, pointValueInfoList, childArrayJSONObject, du);
                }
                if (!Strings.isBlank(dn)){
                    num = setPointValue(jsonObject, DamEnum.ofType("4").getName(), num, pointValueInfoList, childArrayJSONObject, dn);
                }
                if (!Strings.isBlank(de)){
                    num = setPointValue(jsonObject, DamEnum.ofType("3").getName(), num, pointValueInfoList, childArrayJSONObject, de);
                }
            }else {
                // 有测点值才加入
                if (!Strings.isBlank(sy_val)) {
                    // 设置测点信息
                    num = setPointValue(jsonObject, DamEnum.ofType(type).getName(), num, pointValueInfoList, childArrayJSONObject, sy_val);
                }
            }
        }
        // 只要有一个测点值设置
        if (num>0) {
            flag = true;
            map.put("pointValueInfo", pointValueInfoList);
        }
        return flag;
    }
 
    /**
     * 设置测点数据
     * @param jsonObject
     * @param type
     * @param num
     * @param pointValueInfoList
     * @param childArrayJSONObject
     * @param sy_val
     * @return
     */
    private int setPointValue(JSONObject jsonObject, String type, int num, List<Map<String, Object>> pointValueInfoList, JSONObject childArrayJSONObject, String sy_val) {
        num++;
        String res_cd = replaceSpecialStr(jsonObject.getString("res_cd"));
        // 测点编码:水库GUID+测点编码+类型
        String pointCodeTemp = res_cd + "_"
            + childArrayJSONObject.getString("cd")
            + "_" + type;
        Map<String, Object> pointValueInfoMap = new HashMap<>();
        pointValueInfoMap.put("damCode", res_cd);
        pointValueInfoMap.put("pointCode", pointCodeTemp);
        pointValueInfoMap.put("type", type);
        pointValueInfoMap.put("value", sy_val);
        pointValueInfoMap.put("time", childArrayJSONObject.getString("tm"));
        pointValueInfoList.add(pointValueInfoMap);
        return num;
    }
 
    /**
     * 获取序列号
     * @return
     */
    private Integer getSerialNo() {
        //设置默认从1开始
        Integer serialNo = 1;
        //先从redis中获取,拼接当天日期
        String format = new SimpleDateFormat("yyyyMMdd").format(new Date());
        Integer redisSerialNo = bladeRedis.get(OpenApiConstant.serial_no_key + format);
        //如果为空则按默认的来
        if (null==redisSerialNo){
            // 先设置到 redis 序号+1
            bladeRedis.setEx(OpenApiConstant.serial_no_key + format,serialNo+1,9*60*60L);
            // 返回
            return serialNo;
        }
        serialNo = redisSerialNo;
        //更新 序号+1 ,8小时执行一次任务,设置9个小时为过期时间
        bladeRedis.setEx(OpenApiConstant.serial_no_key + format,serialNo+1,9*60*60L);
        //返回
        return serialNo;
    }
 
    /**
     * 调用中台接口查询数据
     *
     * @param params
     * @param url
     * @return
     */
    public JSONArray getZtData(String params, String url) {
        //设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.add(ZtConfigConstant.header_key, ZtConfigConstant.header_value);
        //封装请求头
        HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<MultiValueMap<String, Object>>(headers);
        try {
            //有请求头,有参数请求
            ResponseEntity<String> responseEntity =
                restTemplate.exchange(url + params,
                    HttpMethod.GET,
                    formEntity,
                    String.class);
            JSONObject jsonObject = JSON.parseObject(responseEntity.getBody());
            // 返回
            return JSONArray.parseArray(jsonObject.get("data").toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
 
    /**
     * 预警回调
     * @param data
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean alarmCallBack(String data) {
        boolean flag = false;
        // 解析数据
        JSONObject jsonObject = JSON.parseObject(data);
        JSONArray dataJsonArray = jsonObject.getJSONArray("data");
        for (int i = 0; i < dataJsonArray.size(); i++) {
            DamAlarmRecord damAlarmRecord = new DamAlarmRecord();
            JSONObject alarmRecordJSONObject = dataJsonArray.getJSONObject(i);
            damAlarmRecord.setPointId(alarmRecordJSONObject.getString("pointId"));
            damAlarmRecord.setResGuid(alarmRecordJSONObject.getString("RS_CODE"));
            damAlarmRecord.setCollecTime(alarmRecordJSONObject.getDate("collecTime"));
            damAlarmRecord.setPointValue(alarmRecordJSONObject.getString("ponitValue"));
            JSONObject generalInfo = alarmRecordJSONObject.getJSONObject("generalInfo");
            damAlarmRecord.setPointWarnLevel(generalInfo.getInteger("pointWarnLevel"));
            damAlarmRecord.setPointWarnInfo(generalInfo.getString("pointWarnInfo"));
            damAlarmRecord.setCreateTime(new Date());
            // 保存
            flag = damAlarmRecordService.save(damAlarmRecord);
            if (flag){
                flag = saveDamAlarmRecordDetail(alarmRecordJSONObject.getJSONArray("detailInfo"),damAlarmRecord);
            }
        }
        return flag;
    }
 
    /**
     * 详情
     * @param detailInfo
     * @param damAlarmRecord
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean saveDamAlarmRecordDetail(JSONArray detailInfo,DamAlarmRecord damAlarmRecord) {
        boolean flag = false;
        List<DamAlarmRecordDetail> list = new ArrayList<>();
        for (int i = 0; i < detailInfo.size(); i++) {
            DamAlarmRecordDetail damAlarmRecordDetail = new DamAlarmRecordDetail();
            JSONObject jsonObject = detailInfo.getJSONObject(i);
            damAlarmRecordDetail.setDamAlarmRecordId(damAlarmRecord.getId());
            damAlarmRecordDetail.setAlgorithmName(jsonObject.getString("algorithmName"));
            damAlarmRecordDetail.setAlgorithmWarnLevel(jsonObject.getInteger("algorithmWarnLevel"));
            damAlarmRecordDetail.setAlgorithmWarnInfo(jsonObject.getString("algorithmWarnInfo"));
            damAlarmRecordDetail.setAlgorithmWarnExplain(jsonObject.getString("algorithmWarnExplain"));
            damAlarmRecordDetail.setCreateTime(new Date());
            // 加入集合
            list.add(damAlarmRecordDetail);
        }
        // 保存
        if (list.size()>0) {
            flag = damAlarmRecordDetailService.saveBatch(list);
        }else {
            flag = true;
        }
        return flag;
    }
 
    /**
     * 去除字符串中的空格、回车、换行符、制表符等
     * @param str
     * @return
     */
    public static String replaceSpecialStr(String str) {
        String repl = "";
        if (str!=null) {
            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
            Matcher m = p.matcher(str);
            repl = m.replaceAll("");
        }
        return repl;
    }
}