Selaa lähdekoodia

Merge tag 'V1.1.1' into develop

处理真假枪情况下泵码记错导致无订单上传到第三方平台
zheng 1 vuosi sitten
vanhempi
commit
995b2cf8a7

+ 45 - 0
doc/后台接入协议.docx

@@ -0,0 +1,45 @@
+                        数据分发后台接入协议
+                                    作者
+                                    日期
+                                    修改
+                                   郑瀚榉
+                                  2023-06-07
+                              订单数据上传
+                                   郑瀚榉
+                                  2023-06-14
+                              增加响应信息
+                                       
+订单数据上传后台
+通讯方式
+HTTP
+请求
+POST
+数据类型
+JSON
+客户端
+转化器
+服务端
+后台
+                                    例子
+                                      url
+http:ip:port/xxx
+订单数据
+{
+    "carryTime":"2023-02-17 15:59:29", //提枪时间
+    "hangTime":"2023-02-17 16:00:57", //挂枪时间
+    "amount":"324.50",//金额
+    "gunNo":"30", //油枪号
+    "quantity":"41.55",//升数
+    "balance":"2570.86",//卡余额
+    "oilsPrice":"7.81", //油品单价
+    "id":"2023021715553939700",//订单id
+    "oilGrade":"92#",//油品
+    "cardNo":"01000114400024875652" //卡号  
+}
+响应
+{
+    "code":0,  //0表示成功,其他值可自定义
+    "msg":"success",//值自定义
+    "data":"SUCCESS"   //值自定义
+}
+

+ 24 - 0
doc/接入网络控制盒现场升级油机说明.docx

@@ -0,0 +1,24 @@
+接入网络控制盒升级油机配置和注意
+ 正常升级油机程序,待程序完成升级后进行两项的配置,一为网络接入开启,二为使能读卡数据传输开关。
+
+油机环境
+ 中石化后台+油机(如果是,就可以了)
+
+油机配置1(第三方网络配置)
+ 升级版本,待油机启动完成后,通过手持机进入设置,先进入4级菜单,锁定4.5.5菜单,可以看到如下图示:
+  
+
+  进入到选择THIRDPARTY,并且选择Enabled。
+ 如下图左侧点击OK进入配置IP,为油站上的网络控制盒IP
+   
+  继续配置2
+油机配置2(使能开关配置)
+ 升级版本后,待油机启动完成后,通过手持机进入设置,锁定4.16菜单,可以看到如图
+  
+  
+  同时进入Sinopec Setting 如图Fig2:
+  
+  
+  选择ENABLED,随后退出手持机,待保存和配置完成。(稍等配置完成)
+ 可以正常加油。
+ 确认数据是否上传。

+ 84 - 0
doc/智慧加油站数据分发系统说明--1.0.1版本.docx

@@ -0,0 +1,84 @@
+                       智慧加油站数据分发系统
+前言:
+本中间件主要使用者是售后人员,后续有需要可以提供给客户使用,该中间件主要实现将油机的数据进行转换,然后上传到第三方平台,油站管理设计是一个油站有多台油机,一台油机有多把枪进行设计。
+注意:油站编号与油机ip地址必须是唯一!
+一、登录界面
+登录的账号:test     密码:hs666
+
+二、首页
+
+1、工控机ip地址修改
+步骤一:上传编写好的ip地址配置文件interfaces,如:
+
+详细内容请查看interfaces文件
+步骤二:点击按钮"重启工控机"
+完成上面两步骤即可修改工控机ip地址
+2、socket开启
+将上面设置的ip地址输入到下面ip地址的输入框中,填入的是跟油机ip同一个网段的ip地址
+输入之后点击按钮"开启"即可有油机连接上工控机进行数据交互。
+
+三、油站管理
+售后人员可以在油站管理中对油站进行增删改查
+1、添加油站
+添加油站的时候,编号的值必须是唯一的。
+
+
+
+
+
+
+
+
+
+
+
+2、编辑
+油站一旦建立则油站的,油站的编号就不可以再修改,如果填错了可以删除再重新新建油站。
+
+
+3、数据配置
+该页面配置数据上传的后台与组装数据格式。在油站管理的最右边有"数据"配置按钮,点击进入即可选择配置需要上传的数据 与上传后台的地址,数据标识由研发提供,出厂有默认值,一般情况数据头不需要修改,只要修改第三方上传的ip地址。
+注意:数据标识由研发提供,第三方后台地址由第三方提供。
+ 
+在每条数据新建之后都有一个"配置"按钮,可以在"配置"按钮中选择组装需要上传的数据,如果需要可以在数据前面通过勾选来选择。
+
+
+注意:这些数据都是可以在字典管理中配置数据,该数据一般在出厂前已经配置好,如果后续没有程序升级,一般不需要变动。
+
+四、油机配置
+油站的右边有油机的配置按钮,点击"油机"即可进入油机配置页面
+
+
+
+三、油机配置
+进入油机配置页面可以对油机进行增删改查。
+1、添加油机
+添加油机ip必须唯一,有几台油机就新增几台!
+
+
+
+
+
+
+
+
+
+
+2、油枪配置
+在油机配置页面有油枪配置按钮,点击即可进入油枪配置页面。
+
+五、油枪配置
+进入油枪配置可以对油枪进行增删改查,具体请看下面截图
+
+
+
+六、字典管理
+在字典配置页面中需要注意:默认字典编号不可以修改
+
+
+注意:在字典管理页面中配置数据标识,该下面红框中的类别编号是数据标识,该数据标识由研发另外提供文档说明。
+
+
+在每条数据后面都有字典项配置,点击进去可以对该数据进行配置,一般出厂前已经配置,"是否默认"即是否是默认提供给客户的数据,一般是"是"!
+
+

+ 73 - 0
doc/生产使用文档说明.docx

@@ -0,0 +1,73 @@
+                  智慧油站数据分发系统部署说明
+步骤一:拷贝文件
+用U盘拷贝click.sh和sgs-master.zip文件到桌面
+
+
+
+
+
+
+
+
+
+
+步骤二:打开命令行终端
+双击桌面的LXTerminal即可打开
+
+
+
+
+
+
+
+
+
+
+
+注意:如果桌面没有LXTerminal命令行终端可以在桌面的最右下角中将其添加到桌面或打开
+
+
+
+
+
+
+
+
+
+
+
+
+
+步骤三:切换root用户(sudo su)
+命令:sudo su
+输入上面的命令回车即可
+
+
+
+
+
+
+
+
+
+
+
+
+
+步骤四:打开桌面文件夹(cd /home/linaro/Desktop)
+命令:cd /home/linaro/Desktop
+输入上面命令回车即可
+
+步骤五:授权click.sh文件(chmod 777 click.sh)
+命令:chmod 777 click.sh
+输入上面指令回车即可
+
+步骤六:执行click.sh文件(./click.sh)
+命令:./click.sh
+执行上面的命令回车即可,上面是点斜杠
+注意:执行上面的斜杠之后等待系统重启即可完成升级
+
+步骤七:验证(top | grep java)
+命令:top |grep java
+系统重启之后再次调用终端命令行,输入上面命令如果有下面值出现可说明已经升级或部署完成,若没有值可升级或部署失败!
+

+ 0 - 0
doc/网络通讯控制器通信协议20211109.doc


+ 20 - 0
sgs-middleware-v3/src/main/java/com/tokheim/sgs/v3/common/utils/DateTimeUtils.java

@@ -8,7 +8,10 @@ package com.tokheim.sgs.v3.common.utils;
  * To change this template use File | Settings | File Templates.
  */
 
+import lombok.extern.slf4j.Slf4j;
+
 import java.text.DateFormat;
+import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Date;
@@ -18,6 +21,7 @@ import java.util.Date;
  *
  * @author wuxw
  */
+@Slf4j
 public class DateTimeUtils {
     /**
      * 日期格式 **
@@ -108,6 +112,22 @@ public class DateTimeUtils {
         return sDate;
     }
 
+    /**
+     * 将字符串日期转为 Date ,yyyyMMdd HH:mm:ss
+     * @param date
+     * @return
+     */
+    public static Date parse(String date) {
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
+        Date result = null;
+        try {
+            result = simpleDateFormat.parse(date);
+        } catch (Exception e) {
+            log.error(date + " 转换失败",e);
+        }
+        return result;
+    }
+
     /**
      * 获取当前月份
      *

+ 14 - 0
sgs-middleware-v3/src/main/java/com/tokheim/sgs/v3/socket/convert/FuelMsgCardNoHandler.java

@@ -23,6 +23,12 @@ public class FuelMsgCardNoHandler {
     public static Map<String, String> respMap = new HashMap<>();
 
     private static TwoKeyMap<String,String,String> perOrderTime = new TwoKeyMap<>(); //记录上一笔订单的时间,用于过滤重复发送的订单信息
+    /**油机会偶发以下现象
+     * 实时加油信息携带了正确的卡号,而订单信息会先发一条错误卡号的信息,后续的重发信息中又带上了正确的卡号
+     * 所以记录一下实时加油信息的卡号,在收到订单信息时做对比,如与实时加油信息的卡号一致,则发到第三方;
+     * 若不一致,便不发,等重发的订单信息
+     */
+    private static TwoKeyMap<String,String,String> cacheCardNums = new TwoKeyMap<>();//记录卡号信息
 
     public static void setPerOrderTime(String ip,String fuelPoint,String time) {
         perOrderTime.set(ip, fuelPoint, time);
@@ -32,6 +38,14 @@ public class FuelMsgCardNoHandler {
         return perOrderTime.get(ip, fuelPoint);
     }
 
+    public static void setCacheCardNums(String ip,String fuelPoint,String cardNum) {
+        cacheCardNums.set(ip, fuelPoint, cardNum);
+    }
+
+    public static String getCacheCardNums(String ip,String fuelPoint){
+        return cacheCardNums.get(ip, fuelPoint);
+    }
+
     public static Map<String, String> getFuelMsg(String msg, String oilHeaderPackageCard) {
         try {
             //msg = msg.substring(msg.indexOf(oilHeaderPackage));

+ 68 - 47
sgs-middleware-v3/src/main/java/com/tokheim/sgs/v3/socket/handler/CloudInfoHandler.java

@@ -21,11 +21,11 @@ import org.springframework.transaction.annotation.Transactional;
 
 import java.lang.reflect.Field;
 import java.math.BigDecimal;
+import java.text.DateFormat;
 import java.util.*;
 import java.util.concurrent.Executors;
 
-import static com.tokheim.sgs.v3.socket.ServerHandler.ENV;
-import static com.tokheim.sgs.v3.socket.ServerHandler.prevPump;
+import static com.tokheim.sgs.v3.socket.ServerHandler.*;
 
 /**
  * @author xgm
@@ -98,6 +98,8 @@ public class CloudInfoHandler {
 //                String pump = ServerHandler.pumpMap.get(stationIp, gunNo_);
                 String pump = ServerHandler.pumpMap.get(stationIp, gunNo_,activeNozzle.get(gunNo_));
 
+                //记录卡号,用于收到订单信息时判断
+                FuelMsgCardNoHandler.setCacheCardNums(stationIp,gunNo_,realTimeMsg.get(DataConfig.RealTimeConfig.cardNo));
                 if (pump == null) {
                     orderNo = SeqKit.genPayOrderId();
                     ServerHandler.orderNoMap.set(stationIp, gunNo_, orderNo);
@@ -180,9 +182,26 @@ public class CloudInfoHandler {
                     String stationIp = getStationIp(msg, oilHeaderPackageCard);
                     String gunNo_ = String.valueOf(ByteUtils.hexToDecimal(fuelMsg.get(DataConfig.OrderConfig.gunNo)) - ByteUtils.hexToDecimal("20"));
 
+                    //出现过订单数据中卡号信息错误而实时数据卡号正确,因此对比实时数据中的卡号信息
+                    String cardNum = FuelMsgCardNoHandler.getCacheCardNums(stationIp, gunNo_);
+                    if (cardNum != null && !cardNum.isEmpty() && !fuelMsg.get(DataConfig.OrderConfig.cardNo).equals(cardNum)) {
+                        //null: 初始化;empty:实时记录没有卡号;实时记录的卡号 == 当前订单数据的卡号
+                        log.info("订单数据错误,实时数据卡号" + cardNum + "订单数据:" + fuelMsg);
+                        return;
+                    }
+
+                    //记录订单时间是否大于上一笔订单的时间,不是则为旧单或同一单,不上传
                     String orderTime = fuelMsg.get(DataConfig.OrderConfig.date) + " " + fuelMsg.get(DataConfig.OrderConfig.time);
                     String perOrderTime = FuelMsgCardNoHandler.getPerOrderTime(stationIp, gunNo_);
-                    if (orderTime.equals(perOrderTime)) return; //表示同一单
+                    Date orderTimeDate = DateTimeUtils.parse(orderTime);
+                    Date perOrderTimeDate = DateTimeUtils.parse(perOrderTime);
+                    if (orderTimeDate != null && perOrderTimeDate != null) {
+                        int intervalSeconds = DateTimeUtils.getIntervalSeconds(perOrderTimeDate,orderTimeDate);
+                        if (intervalSeconds <= 0) return; //表示同一单或者是旧单
+                    } else {
+                        if (orderTime.equals(perOrderTime)) return; //表示同一单
+                    }
+
                     //记录订单时间
                     FuelMsgCardNoHandler.setPerOrderTime(stationIp,gunNo_,orderTime);
 
@@ -230,58 +249,60 @@ public class CloudInfoHandler {
                        if (!(addValBigDecimalValue == Double.valueOf(fuelMsg.get(DataConfig.OrderConfig.pump)))){
                            log.info("油机ip地址--【" + stationIp + "】--漏单时间--addValBigDecimalValue--"+addValBigDecimalValue+"--" + DateTimeUtils.getFormatCurrentTime() + "--当前泵码【" + fuelMsg.get(DataConfig.OrderConfig.pump) + "】--上一个泵码【" + prevPump + "】--差值【" + v + "】--" + msg);
                        }
-                        log.info("加油记录包头(含卡号)--当前泵码【" + fuelMsg.get(DataConfig.OrderConfig.pump) + "】--上一个泵码【" + prevPump + "】--差值【" + v + "】--" + msg);
-                        //System.err.println("油机ip地址--【" + stationIp + "】--云平台数据(交易数据-含卡号):" + jsonString);
-                        log.info("油机ip地址--【" + stationIp + "】--云平台数据(交易数据-含卡号):" + jsonString);
-                        JSONObject jsonObject = JSONObject.parseObject(jsonString);
-                        //记录上传泵码
-                        ServerHandler.prevPump = fuelMsg.get(DataConfig.OrderConfig.pump);
+
+                    }
+
+                    log.info("加油记录包头(含卡号)--当前泵码【" + fuelMsg.get(DataConfig.OrderConfig.pump) + "】--上一个泵码【" + prevPump + "】" + msg);
+                    //System.err.println("油机ip地址--【" + stationIp + "】--云平台数据(交易数据-含卡号):" + jsonString);
+                    log.info("油机ip地址--【" + stationIp + "】--云平台数据(交易数据-含卡号):" + jsonString);
+                    JSONObject jsonObject = JSONObject.parseObject(jsonString);
+                    //记录上传泵码
+                    ServerHandler.prevPump = fuelMsg.get(DataConfig.OrderConfig.pump);
 //                        ServerHandler.pumpMap.set(stationIp, gunNo_, ServerHandler.prevPump);
-                        ServerHandler.pumpMap.set(stationIp, gunNo_, activeNozzle.get(gunNo_),ServerHandler.prevPump);
-                        //log.info("上一个泵码--" + prevPump + ",当前泵码---" + fuelMsg.get(DataConfig.OrderConfig.pump));
+                    ServerHandler.pumpMap.set(stationIp, gunNo_, activeNozzle.get(gunNo_),ServerHandler.prevPump);
+                    //log.info("上一个泵码--" + prevPump + ",当前泵码---" + fuelMsg.get(DataConfig.OrderConfig.pump));
 
 
-                        String orderNo2 = SeqKit.genPayOrderId();
-                        ServerHandler.orderNoMap.set(stationIp, gunNo_, orderNo2);
-                        //nextOrderNoMap.set(stationIp, gunNo_, orderNo2);
-                        OrderMapper orderMapper = SpringUtils.getBean("orderMapper");
+                    String orderNo2 = SeqKit.genPayOrderId();
+                    ServerHandler.orderNoMap.set(stationIp, gunNo_, orderNo2);
+                    //nextOrderNoMap.set(stationIp, gunNo_, orderNo2);
+                    OrderMapper orderMapper = SpringUtils.getBean("orderMapper");
                         /*if (ServerHandler.ENV.equals("test")){
                             target.put("id", SeqKit.genPayOrderId()); //开发环境生成订单号,生成环境在实时数据中生成
                         }*/
-                        String json = JSONObject.toJSONString(target, SerializerFeature.WriteNullStringAsEmpty);
-                        Order order = JSONObject.parseObject(json, Order.class);
-                        log.info("保存订单"+json);
-                        orderMapper.insertSelective(order);
-
-                        if (ServerHandler.ENV.equals("prod")) { //dev  prod test  http://47.107.51.26:8086/oilmachine/postOilData
-                            try {
-                                //OrderMapper orderMapper = SpringUtils.getBean("orderMapper");
-                                ////target.put("id",SeqKit.genPayOrderId());
-                                ////String json = JSONObject.toJSONString(target, SerializerFeature.WriteNullStringAsEmpty);
-                                //Order order = JSONObject.parseObject(jsonString, Order.class);
-                                //orderMapper.insertSelective(order);
-
-                                ThreadUtil.execAsync(new Runnable() { //异步执行
-                                    @Override
-                                    public void run() {
-                                        //System.out.println("异步请求---" + Thread.currentThread().getName());
-                                        String resp = HttpUtils.sendPost3(data.getUrl(), jsonObject); //url
-                                        if (resp != null) {
-                                            //System.err.println("响应数据:" + resp);
-                                            log.info("响应数据:" + resp);
-                                            orderMapper.deleteByPrimaryKey(order);
-                                        }
+                    String json = JSONObject.toJSONString(target, SerializerFeature.WriteNullStringAsEmpty);
+                    Order order = JSONObject.parseObject(json, Order.class);
+                    log.info("保存订单"+json);
+                    orderMapper.insertSelective(order);
+
+                    if (ServerHandler.ENV.equals("prod")) { //dev  prod test  http://47.107.51.26:8086/oilmachine/postOilData
+                        try {
+                            //OrderMapper orderMapper = SpringUtils.getBean("orderMapper");
+                            ////target.put("id",SeqKit.genPayOrderId());
+                            ////String json = JSONObject.toJSONString(target, SerializerFeature.WriteNullStringAsEmpty);
+                            //Order order = JSONObject.parseObject(jsonString, Order.class);
+                            //orderMapper.insertSelective(order);
+
+                            ThreadUtil.execAsync(new Runnable() { //异步执行
+                                @Override
+                                public void run() {
+                                    //System.out.println("异步请求---" + Thread.currentThread().getName());
+                                    String resp = HttpUtils.sendPost3(data.getUrl(), jsonObject); //url
+                                    if (resp != null) {
+                                        //System.err.println("响应数据:" + resp);
+                                        log.info("响应数据:" + resp);
+                                        orderMapper.deleteByPrimaryKey(order);
                                     }
-                                });
-                            } catch (Exception e) {
+                                }
+                            });
+                        } catch (Exception e) {
 //                                ServerHandler.pumpMap.set(stationIp, gunNo_, ServerHandler.prevPump);
-                                ServerHandler.pumpMap.set(stationIp, gunNo_,activeNozzle.get(gunNo_), ServerHandler.prevPump);
-                                //String orderNo = ID.get().next().toString();
-                                String orderNo = SeqKit.genPayOrderId();
-                                ServerHandler.orderNoMap.set(stationIp, gunNo_, orderNo);
-                                e.printStackTrace();
-                                log.error("threadPoolExecutor(order)--发送订单json数据【" + jsonString + "】--" + e);
-                            }
+                            ServerHandler.pumpMap.set(stationIp, gunNo_,activeNozzle.get(gunNo_), ServerHandler.prevPump);
+                            //String orderNo = ID.get().next().toString();
+                            String orderNo = SeqKit.genPayOrderId();
+                            ServerHandler.orderNoMap.set(stationIp, gunNo_, orderNo);
+                            e.printStackTrace();
+                            log.error("threadPoolExecutor(order)--发送订单json数据【" + jsonString + "】--" + e);
                         }
                     }
                 }

+ 1 - 1
sgs-middleware-v3/src/main/resources/application-dev.yml

@@ -1,6 +1,6 @@
 # server
 server:
-  port: 9000
+  port: 9001
   tomcat:
     uri-encoding: utf-8
     #配置内置tomcat的访问日志

+ 2 - 2
sgs-middleware-v3/src/main/resources/application-prod.yml

@@ -37,7 +37,7 @@ spring:
       max-request-size: 100Mb
   datasource:
     username: root
-    password: 123456 # 192.168.12.130  192.168.4.18   东莞:10.199.82.212
+    password: TKhs@123 # 192.168.12.130  192.168.4.18   东莞:10.199.82.212
     url: jdbc:mariadb://localhost:3306/sgs-master?characterEncoding=utf-8
     driverClassName: org.mariadb.jdbc.Driver # com.mysql.jdbc.Driver
     type: com.alibaba.druid.pool.DruidDataSource # 连接池指定
@@ -159,7 +159,7 @@ socketInfo:
   realUrl: http://47.107.51.26:8086/oilmachine/realOilData  # 实时加油数据
   filePath: /app/configure_dev.json # C:/token/info__manager_system/configure_dev.json
   urlBackup: http://47.107.51.26:8086/oilmachine/postOilData
-  lanSegments: 192 # 10 172 192
+  lanSegments: 10 # 10 172 192
   inPort: 20002
   socketPath: /etc/network/interfaces  #C:\token\info__manager_system\file\interfaces  /etc/network/interfaces /home/linaro/Desktop
   restartScript: /home/linaro/Desktop/restart.sh

+ 2 - 0
sgs-middleware-v3/src/main/resources/application.yml

@@ -30,6 +30,8 @@ logging:
 
 login.check: 0
 
+version: 1.1.1
+