TRX 1 год назад
Родитель
Сommit
d2d1f1d6db

+ 30 - 4
src/main/java/com/zswl/dataservice/domain/mqtt/OperationMessage.java

@@ -51,6 +51,7 @@ public class OperationMessage extends SuperEntity {
 
     //------------------------关联的消息
 
+    @Schema(description = "消息的类型")
     private String messageClass;
 
     @Schema(description = "关于的设备信息")
@@ -68,6 +69,13 @@ public class OperationMessage extends SuperEntity {
     @Schema(description = "消息创建时间")
     private String time;
 
+    @Schema(description = "mqtt消息类型: 发送 接收")
+    OperationType operationType;
+
+    @Indexed(expireAfterSeconds = 0)
+    private Date ttl;
+
+    // --------------------- 消息处理结果信息 start -------------------
     @Schema(description = "是否收到信息")
     private Boolean isReceive;
 
@@ -77,9 +85,27 @@ public class OperationMessage extends SuperEntity {
     @Schema(description = "接收到的时间可阅读的")
     private String receiveTimeStr;
 
-    @Schema(description = "mqtt消息类型: 发送 接收")
-    OperationType operationType;
+    //--------------------返回数据 start ------------------
+
+    @Schema(description = "")
+    private Boolean isResult = Boolean.FALSE;
+
+    @Schema(description = "返回结果数据")
+    private Object resultData;
+
+    @Schema(description = "返回的topic")
+    private String reTopic;
+
+    @Schema(description = "返回时间")
+    private Long reTime;
+
+    @Schema(description = "返回时间可阅读")
+    private String reTimeStr;
+
+    @Schema(description = "响应结果")
+    private String reMsg;
+
+    @Schema(description = "是否响应成功")
+    private Boolean reIsSuccess;
 
-    @Indexed(expireAfterSeconds = 0)
-    private Date ttl;
 }

+ 12 - 10
src/main/java/com/zswl/dataservice/model/hxz/ConsumTransactionsModel.java

@@ -5,41 +5,43 @@ import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.io.Serializable;
+
 @Data
 @AllArgsConstructor
 @NoArgsConstructor
-public class ConsumTransactionsModel {
+public class ConsumTransactionsModel implements Serializable {
 
     @JsonProperty("Order")
-    private String order;
+    private String Order;
 
     @JsonProperty("CardNo")
-    private String cardNo;
+    private String CardNo;
 
     @JsonProperty("CardMode")
-    private Integer cardMode;
+    private Integer CardMode;
 
     @JsonProperty("Mode")
-    private Integer mode;
+    private Integer Mode;
 
     @JsonProperty("PayType")
-    private Integer payType;
+    private Integer PayType;
 
     @JsonProperty("Amount")
-    private String amount;
+    private String Amount;
 
     @JsonProperty("Menus")
-    private Menus[] menus;
+    private Menus[] Menus;
 
     @Data
     @AllArgsConstructor
     @NoArgsConstructor
     public static class Menus {
         @JsonProperty("MenuID")
-        private String menuID;
+        private String MenuID;
 
         @JsonProperty("Count")
-        private String count;
+        private String Count;
     }
 }
 

+ 61 - 0
src/main/java/com/zswl/dataservice/model/hxz/ConsumTransactionsResult.java

@@ -0,0 +1,61 @@
+package com.zswl.dataservice.model.hxz;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@Accessors(chain = true)
+public class ConsumTransactionsResult {
+
+    @JsonProperty("Status")
+    private Integer status = 0;
+
+    @JsonProperty("Msg")
+    private String msg = "";
+
+    @JsonProperty("Name")
+    private String name = "²âÊÔ";
+
+    @JsonProperty("CardNo")
+    private String cardNo = "";
+
+    @JsonProperty("Money")
+    private String money = "";
+
+    @JsonProperty("Subsidy")
+    private String subsidy = "";
+
+    @JsonProperty("Times")
+    private String times = "";
+
+    @JsonProperty("Integral")
+    private String integral = "";
+
+    @JsonProperty("InTime")
+    private String inTime = "";
+
+    @JsonProperty("OutTime")
+    private String outTime = "";
+
+    @JsonProperty("CumulativeTime")
+    private String cumulativeTime = "";
+
+    @JsonProperty("Amount")
+    private String amount = "";
+
+    @JsonProperty("VoiceID")
+    private String voiceID = "";
+
+    @JsonProperty("Text")
+    private String text = "";
+
+
+}
+

+ 2 - 3
src/main/java/com/zswl/dataservice/service/artemis/ArtemisService.java

@@ -89,6 +89,7 @@ public class ArtemisService extends SuperService {
             String id = json.getString("id");
             Long time = json.getLong("time");
             Long ttl = json.getLong("ttl");
+            String event = json.getString("event");
             boolean isTimeOut = false;
             if (System.currentTimeMillis() > (time + ttl)) {
                 isTimeOut = true;
@@ -101,9 +102,7 @@ public class ArtemisService extends SuperService {
             operationMessage.setSendTime(time);
             operationMessage.setDataId(id);
             operationMessage.setIsTimeOut(isTimeOut);
-            if (!isTimeOut) {
-
-            }
+            operationMessage.setEvent(event);
             operationMessageService.addOperationMessage(operationMessage);
         } catch (Exception e) {
             e.printStackTrace();

+ 89 - 0
src/main/java/com/zswl/dataservice/service/artemis/OperationMessageService.java

@@ -1,14 +1,17 @@
 package com.zswl.dataservice.service.artemis;
 
 import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
 import com.google.gson.JsonObject;
 import com.zswl.dataservice.dao.mqtt.DeviceInfoDao;
 import com.zswl.dataservice.dao.mqtt.OperationMessageDao;
 import com.zswl.dataservice.domain.mqtt.DeviceInfo;
 import com.zswl.dataservice.domain.mqtt.OperationMessage;
+import com.zswl.dataservice.model.hxz.ConsumTransactionsModel;
 import com.zswl.dataservice.model.mqtt.*;
 import com.zswl.dataservice.service.mqtt.DeviceInfoService;
 import com.zswl.dataservice.service.mqtt.GateWayInfoService;
+import com.zswl.dataservice.service.payment.HxzService;
 import com.zswl.dataservice.utils.DateUtils;
 import com.zswl.dataservice.utils.bean.BeanUtils;
 import com.zswl.dataservice.utils.mqtt.MqttTopicUtils;
@@ -50,6 +53,9 @@ public class OperationMessageService {
     @Autowired
     DeviceInfoDao deviceInfoDao;
 
+    @Autowired
+    HxzService hxzService;
+
     // 保存90天
     private Long ttlMill = 90 * 24L * 60 * 60 * 1000L;
 
@@ -114,6 +120,89 @@ public class OperationMessageService {
         entity.setTime(DateUtils.paresTime(System.currentTimeMillis(), DateUtils.FORMAT_LONG));
         entity.setTtl(new Date(System.currentTimeMillis() + ttlMill));
         operationMessageDao.save(entity);
+        // 处理消息
+        handleOperationMessage(entity);
+        return ResultContent.buildSuccess();
+    }
+
+    /**
+     * 处理消息
+     *
+     * @param entity
+     * @return
+     */
+    public ResultContent handleOperationMessage(OperationMessage entity) {
+        boolean isTimeOut = entity.getIsTimeOut();
+
+        String event = entity.getEvent();
+        String data = (String) entity.getData();
+        JSONObject json = JSONUtil.parseObj(data);
+        if (json.containsKey("data")) {
+            Object result = null;
+            String dataStr = json.getStr("data");
+
+            try {
+                // 判断那个业务处理
+                if (event.equals("consum")) {
+                    ConsumTransactionsModel model = JSONUtil.toBean(dataStr, ConsumTransactionsModel.class);
+
+                    ResultContent<Object> resultContent = hxzService.consumTransactions(model);
+                    if (resultContent.isSuccess()) {
+                        result = resultContent.getContent();
+                    }
+                }
+            } catch (Exception e) {
+                entity.setReIsSuccess(Boolean.FALSE);
+                entity.setReMsg(String.format("业务出错出错:%S", e.getMessage()));
+                entity.setReTime(System.currentTimeMillis());
+                entity.setReTimeStr(DateUtils.paresTime(System.currentTimeMillis(), DateUtils.patternyyyySSS));
+                operationMessageDao.save(entity);
+                return ResultContent.buildFail(e.getMessage());
+            }
+            // 返回结果
+            entity.setResultData(result);
+            responseMessage(entity);
+        }
+        return ResultContent.buildSuccess();
+    }
+
+    /**
+     * 响应数据
+     *
+     * @param entity
+     * @return
+     */
+    public ResultContent responseMessage(OperationMessage entity) {
+        JSONObject jsonObject = new JSONObject();
+
+        jsonObject.append("id", entity.getDataId());
+        Object data = entity.getResultData();
+        JSONObject object = new JSONObject();
+        if (ObjectUtils.isNotEmpty(data)) {
+            String _str = JSONUtil.toJsonStr(data);
+            object = JSONUtil.parseObj(_str);
+        }
+        jsonObject.append("data", object);
+        jsonObject.append("time", System.currentTimeMillis());
+        jsonObject.append("ttl", entity.getTtlTime());
+        jsonObject.append("event", entity.getEvent());
+        String reTopic = String.format("%s/reply", entity.getTopic());
+
+        String reMsg = "响应成功";
+        Boolean reIsSuccess = Boolean.TRUE;
+        try {
+            mqClient.sendObject(reTopic, jsonObject);
+        } catch (Exception e) {
+            e.printStackTrace();
+            reIsSuccess = Boolean.FALSE;
+            reMsg = "响应出错:" + e.getMessage();
+        }
+        entity.setReIsSuccess(reIsSuccess);
+        entity.setReMsg(reMsg);
+        entity.setReTime(System.currentTimeMillis());
+        entity.setReTimeStr(DateUtils.paresTime(System.currentTimeMillis(), DateUtils.patternyyyySSS));
+        entity.setReTopic(reTopic);
+        operationMessageDao.save(entity);
         return ResultContent.buildSuccess();
     }
 

+ 35 - 3
src/main/java/com/zswl/dataservice/service/payment/HxzService.java

@@ -5,9 +5,13 @@ import com.zswl.dataservice.domain.mqtt.DeviceInfo;
 import com.zswl.dataservice.httpRequest.ApiRequestService;
 import com.zswl.dataservice.httpRequest.apiConf.APIResponseModel;
 import com.zswl.dataservice.httpRequest.conf.FullCardAPIConfig;
+import com.zswl.dataservice.model.hxz.ConsumTransactionsModel;
+import com.zswl.dataservice.model.hxz.ConsumTransactionsResult;
 import com.zswl.dataservice.model.payment.ServerTimeModel;
 import com.zswl.dataservice.model.payment.ServerTimeResult;
 import com.zswl.dataservice.service.base.SuperService;
+import com.zswl.dataservice.utils.CardUtil;
+import com.zswl.dataservice.utils.net.JsonUtil;
 import com.zswl.dataservice.utils.result.ResultContent;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
@@ -21,6 +25,7 @@ import java.time.LocalDate;
 import java.util.Date;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.Objects;
 
 /**
  * @author TRX
@@ -71,9 +76,36 @@ public class HxzService extends SuperService {
         return result;
     }
 
-    public ResultContent consumTransactions() {
-
-        return ResultContent.buildSuccess();
+    /**
+     * 刷卡扣费
+     *
+     * @param params
+     * @return
+     */
+    public ResultContent<Object> consumTransactions(ConsumTransactionsModel params) {
+        ConsumTransactionsResult ret = null;
+        //十进制转16进制
+        final String cardNumber = params.getCardNo();
+        final String amount = params.getAmount();
+        //查询卡(钱包)
+        if (params.getMode() == 2) {
+            ret = new ConsumTransactionsResult()
+                    .setStatus(0)
+                    .setMsg("不支持查询钱包")
+                    .setCardNo(params.getCardNo())
+                    .setAmount(amount);
+            return ResultContent.buildSuccess(ret);
+        }
+        //刷卡消费
+        log.info("consumTransactions : {} - {} - {}", params.getOrder(), cardNumber, amount);
+         ret = new ConsumTransactionsResult()
+                .setStatus(1)
+                .setCardNo(params.getCardNo())
+                .setMoney(amount)
+                .setSubsidy("0.0")
+                .setAmount(amount);
+        log.info("ConsumTransactions : {} - {}", params, JsonUtil.toJson(ret));
+        return ResultContent.buildSuccess(ret);
     }
 
 }

+ 349 - 0
src/main/java/com/zswl/dataservice/utils/BytesUtil.java

@@ -0,0 +1,349 @@
+package com.zswl.dataservice.utils;
+
+import lombok.SneakyThrows;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ * @功能:字节集工具类
+ * @作者:练书锋
+ * @创建日期 : 2013-8-29
+ */
+public class BytesUtil {
+
+    /**
+     * 填充算法,将字节集填充到8的整数倍
+     *
+     * @param bin
+     * @return
+     * @throws IOException
+     */
+    public static byte[] fillCode(byte[] bin) throws IOException {
+        ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
+        int n = (bin.length + 10) % 8;
+        if (n != 0) {
+            n = 8 - n;
+        }
+        // 将随即码改为数据完整度的校验
+        int r = 0;
+        for (int i = 0; i < bin.length; i++) {
+            r = (r + (bin[i] & 0xFF)) % 256;
+        }
+        int first = (r & 248) | n;
+        arrayOutputStream.write(first);
+        arrayOutputStream.write(r);
+        arrayOutputStream.write(bin);
+        for (int i = 0; i < n; i++) {
+            arrayOutputStream.write(r);
+        }
+        byte[] result = arrayOutputStream.toByteArray();
+        arrayOutputStream.close();
+        return result;
+    }
+
+    /**
+     * 将填充算法的数据还原
+     *
+     * @param bin
+     * @return
+     * @throws IOException
+     */
+    public static byte[] unFillCode(byte[] bin) throws IOException {
+        ByteArrayInputStream arrayInputStream = new ByteArrayInputStream(bin);
+        int first = arrayInputStream.read();// 第一位
+        // 校验码
+        int r = arrayInputStream.read();// 第二位
+        int n = (r & 248) ^ first;
+        if (n < 0 || n > 14 || arrayInputStream.available() < n) {
+            return null;// 长度不正确,解密失败
+        }
+        byte[] result = new byte[arrayInputStream.available() - n];
+        arrayInputStream.read(result);
+        arrayInputStream.close();
+        int d = 0;
+        for (int i = 0; i < result.length; i++) {
+            d = (d + (result[i] & 0xFF)) % 256;
+        }
+        return d == r ? result : null;
+    }
+
+    /**
+     * 倒找字节集
+     *
+     * @param bin
+     * @param queryBin
+     * @return
+     */
+    public static int findLast(byte[] bin, byte[] queryBin) {
+        int total = bin.length - queryBin.length + 1;
+        for (int i = 0; i < total; i++) {
+            int lastIndex = total - i - 1;
+            byte[] target = subBytes(bin, lastIndex, queryBin.length + lastIndex);
+            if (isEquery(target, queryBin)) {
+                return lastIndex;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * 从一个字节中查询出现的字节
+     *
+     * @param bin
+     * @param queryBin
+     * @return
+     */
+    public static int find(byte[] bin, byte[] queryBin) {
+        for (int i = 0; i < bin.length - queryBin.length + 1; i++) {
+            byte[] target = subBytes(bin, i, queryBin.length + i);
+            if (isEquery(target, queryBin)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * 两个字节集数组是否相等
+     *
+     * @param bin1
+     * @param bin2
+     * @return
+     */
+    public static boolean isEquery(byte[] bin1, byte[] bin2) {
+        for (int i = 0; i < bin1.length; i++) {
+            if (bin1[i] != bin2[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 取字节集中间
+     *
+     * @param bin
+     * @param start
+     * @param end
+     * @return
+     */
+    public static byte[] subBytes(final byte[] bin, final int start, final int end) {
+        if (start == 0 && end == bin.length) {
+            return bin;
+        }
+        byte[] result = new byte[end - start];
+        System.arraycopy(bin, start, result, 0, result.length);
+        return result;
+    }
+
+    /**
+     * 将字节集转换为long类
+     *
+     * @param b
+     * @return
+     */
+    public static long binToLong(byte[] b) {
+        long l = 0;
+        for (int i = 0; i < b.length; i++) {
+            long j_tmp = 1;
+            for (int j = 0; j < b.length - i - 1; j++) {
+                j_tmp <<= 8;
+            }
+            l += j_tmp * (b[i] & 0xFF);
+        }
+        return l;
+    }
+
+    /**
+     * 将字节集转换为int类型
+     *
+     * @param b
+     * @return
+     */
+    public static int binToInt(byte[] b) {
+        return (int) binToLong(b);
+    }
+
+    /**
+     * 将字节集转换为short类型
+     *
+     * @param b
+     * @return
+     */
+    public static short binToShort(byte[] b) {
+        return (short) binToLong(b);
+    }
+
+    /**
+     * 将long类转字节集
+     *
+     * @param l
+     * @param size 保证长度
+     * @return
+     * @throws IOException
+     */
+    @SneakyThrows
+    public static byte[] longToBin(long l, int size) {
+        byte[] result = new byte[size];
+        for (int i = 0; i < size; i++) {
+            result[i] = (byte) ((l >> ((size - 1 - i) << 3)) & 0xFF);
+        }
+        return result;
+    }
+
+    /**
+     * 将int类转字节集
+     *
+     * @param
+     * @return
+     * @throws IOException
+     * @throws NumberFormatException
+     */
+    public static byte[] intToBin(int i, int size) throws IOException {
+        return longToBin(i, size);
+    }
+
+    /**
+     * 将short类型转换为字节集
+     *
+     * @param i
+     * @param size
+     * @return
+     * @throws IOException
+     */
+    public static byte[] shortToBin(short i, int size) throws IOException {
+        return longToBin(i, size);
+    }
+
+    /**
+     * 将字节集转换为16进制
+     *
+     * @param bin
+     * @return
+     */
+    public static String binToHex(byte[] bin) {
+        return binToHex(bin, false);
+    }
+
+    /**
+     * 将字节集转换16进制
+     *
+     * @param bin
+     * @param format 格式化显示
+     * @return
+     */
+    public static String binToHex(byte[] bin, boolean format) {
+        StringBuffer stringBuffer = new StringBuffer();
+        for (byte b : bin) {
+            int i = (int) b;
+            if (i < 0) {
+                i = i + 256;
+            }
+            String hex = Integer.toHexString(i);
+            while (hex.length() < 2) {
+                hex = "0" + hex;
+            }
+            stringBuffer.append(hex);
+            if (format) {
+                stringBuffer.append(" ");
+            }
+        }
+        return stringBuffer.toString();
+    }
+
+    /**
+     * 十六进制转换为字节集
+     *
+     * @param
+     * @return
+     * @throws IOException
+     */
+    public static byte[] hexToBin(String str) throws IOException {
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        String hex = str;
+        if (hex.length() % 2 != 0)
+            hex = "0" + hex;
+        for (int i = 0; i < hex.length() / 2; i++) {
+            int point = i * 2;
+            byteArrayOutputStream.write(Integer.parseInt(hex.substring(point, point + 2), 16));
+        }
+        byteArrayOutputStream.flush();
+        byte[] bin = byteArrayOutputStream.toByteArray();
+        byteArrayOutputStream.close();
+        return bin;
+    }
+
+
+    public static byte[] reverse(byte[] bin) {
+        var items = new ArrayList<Byte>();
+        for (var b : bin) {
+            items.add(b);
+        }
+        Collections.reverse(items);
+        byte[] ret = new byte[items.size()];
+        for (int i = 0; i < items.size(); i++) {
+            ret[i] = items.get(i);
+        }
+        return ret;
+    }
+
+
+    /**
+     * 合并两个字节集
+     *
+     * @param bin1
+     * @param
+     * @return
+     * @throws IOException
+     */
+    public static byte[] merge(byte[] bin1, byte[]... bins) throws IOException {
+        ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
+        arrayOutputStream.write(bin1);
+        for (byte[] bin : bins) {
+            arrayOutputStream.write(bin);
+        }
+        arrayOutputStream.flush();
+        byte[] bin = arrayOutputStream.toByteArray();
+        arrayOutputStream.close();
+        return bin;
+    }
+
+    /**
+     * 对象到字节集
+     *
+     * @param
+     * @return
+     * @throws IOException
+     */
+    public static byte[] objectToBytes(Object object) throws IOException {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(out);
+        oos.writeObject(object);
+        oos.flush();
+        byte[] bin = out.toByteArray();
+        oos.close();
+        out.close();
+        return bin;
+    }
+
+    /**
+     * 字节集到对象
+     *
+     * @param buffer
+     * @return
+     * @throws IOException
+     * @throws ClassNotFoundException
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T bytesToObject(byte[] buffer) throws IOException, ClassNotFoundException {
+        ByteArrayInputStream in = new ByteArrayInputStream(buffer);
+        ObjectInputStream inputStream = new ObjectInputStream(in);
+        Object o = inputStream.readObject();
+        inputStream.close();
+        in.close();
+        return (T) o;
+    }
+
+}

+ 10 - 0
src/main/java/com/zswl/dataservice/utils/CardUtil.java

@@ -0,0 +1,10 @@
+package com.zswl.dataservice.utils;
+
+public class CardUtil {
+
+    public static String toNumber(long cardNo) {
+        byte[] bins = BytesUtil.longToBin(cardNo, 4);
+        var ret = BytesUtil.reverse(bins);
+        return BytesUtil.binToHex(ret);
+    }
+}