diff --git a/bonus-common-biz/src/main/java/com/bonus/common/houqin/constant/GlobalConstants.java b/bonus-common-biz/src/main/java/com/bonus/common/houqin/constant/GlobalConstants.java index e8e52c3..3e746ab 100644 --- a/bonus-common-biz/src/main/java/com/bonus/common/houqin/constant/GlobalConstants.java +++ b/bonus-common-biz/src/main/java/com/bonus/common/houqin/constant/GlobalConstants.java @@ -5,6 +5,7 @@ package com.bonus.common.houqin.constant; * @author bns_han */ public class GlobalConstants { + public static final Long TENANT_ID = 99999999L; /** * 字符串 MSIE */ diff --git a/bonus-common-biz/src/main/java/com/bonus/common/houqin/mq/constant/LeMqConstant.java b/bonus-common-biz/src/main/java/com/bonus/common/houqin/mq/constant/LeMqConstant.java new file mode 100644 index 0000000..7cfdfb7 --- /dev/null +++ b/bonus-common-biz/src/main/java/com/bonus/common/houqin/mq/constant/LeMqConstant.java @@ -0,0 +1,222 @@ +package com.bonus.common.houqin.mq.constant; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public interface LeMqConstant { + public static enum DataChangeType { + ADD(1, "新增"), + UPDATE(2, "修改"), + REMOVE(3, "移除"); + + private final Integer key; + private final String desc; + + public Integer getKey() { + return this.key; + } + + public String getDesc() { + return this.desc; + } + + private DataChangeType(final Integer key, final String desc) { + this.key = key; + this.desc = desc; + } + + // $FF: synthetic method + private static DataChangeType[] $values() { + return new DataChangeType[]{ADD, UPDATE, REMOVE}; + } + } + + public static enum Topic { + DEVICE_UPDATE_BIND_DISHES("device-update-bind-dishes", "设备更新绑定菜品"), + DEVICE_UPDATE_DEVICE_BASICSETTING("update-device-basicsetting", "设备基础设置(商家)"), + DEVICE_UPDATE_DEVICE_METADATA("update-device-metadata", "设备基础设置(设备)"), + DEVICE_UPDATE_PERSON("update-person", "下发人员至设备(设备)"), + DEVICE_UPDATE_PERSON_BATCH("update-person-batch", "下发人员至设备(批量)(设备)"), + DEVICE_UPDATE_PERSONALFEATURE_BATCH("update-personalfeature-batch", "下发人员特征至设备(批量)(设备) "), + DEVICE_DOOR_OPERATOR("door_operator", "推送到web端"), + DEVICE_HAIQING_DEVICE_COMMUNICATION("haiqing", "推送海清设备"), + DEVICE_HAIQING_DEVICE_TRANSIT("device:haiqing_transit", "推送海清设备中间队列"), + DEVICE_PUSH_USER_DATA("device:push_user_data", "推送用户信息到设备"), + DEVICE_SBLS_DEVICE_TRANSIT("device:sbls_transit", "推送塞伯罗斯设备中间队列"), + DEVICE_SBLS_CR02EN_COMMUNICATION("sbls-send", "推送塞伯罗斯"), + DEVICE_DC_DEVICE_DELEAY("device:dc_delayed", "门禁延迟消息队列"), + DEVICE_LOCKER_STATUS("device-locker-status", "推送更新智能餐柜状态"), + DEVICE_NEW_MAKING_ORDER("device-new-making-order", "推送新的制作中订单"), + DEVICE_ATTENDANCE_ACCEPT_DOOR_CONTROL("device:attendance-accept-door-control", "门禁推送打卡信息至考勤模块"), + DEVICE_ATTENDANCE_ACCEPT_DOOR_CONTROL_VISITOR("device:attendance-accept-door-control-visitor", "门禁推送打卡信息至访客模块"), + CUSTOMER_VISITOR_INVITE("customer:visitor-invite", "访客邀约"), + CUSTOMER_VISITOR_AUDIT_PASS("customer:visitor-audit-pass", "访客审核通过"), + CUSTOMER_VISITOR_WAITING_AUDIT("customer:visitor-waiting-audit", "访客待审核"), + CUSTOMER_VISITOR_SIGN_IN("customer:visitor-sign-in", "访客签到"), + DATA_CHANGE_ORG("customer:data-change-org", "组织数据变更"), + DATA_CHANGE_CUSTOMER("customer:data-change-customer", "人员数据变更"), + CUSTOMER_CHANGE_DELAY("customer:customer-data-change-delay", "人员模块数据变更延迟队列"), + DATA_CHANGE_AREA("canteen:data-change-area", "区域数据变更"), + DATA_CHANGE_WAREHOUSE("drp:data-change-warehouse", "仓库数据变更"), + BACK_DEVICE_HAIQING_DEVICE_TRANSIT("backfield:back-haiqing-transit", "后场推送海清设备中间队列"), + BACK_DEVICE_HAIQING_DEVICE_COMMUNICATION("backhaiqing", "后场推送海清设备"), + BACK_DEVICE_SBLS_DEVICE_TRANSIT("backfield:back-sbls-transit", "后场推送塞伯罗斯设备中间队列"), + BACK_DEVICE_SBLS_CR02EN_COMMUNICATION("b-sbls-send", "后场推送塞伯罗斯"), + BACK_DEVICE_IOT_GATEWAY("back_device_iot_gateway", "后场推送网关设备信息"), + BACK_ATTENDANCE_CARD_DATA("backfield:back-attendance-card-data", "后场门禁考勤信息"), + BACK_TH_ALARM_DATA("backfield:back-th-alarm-data", "后场仓库温湿度告警"), + DATA_CHANGE_CANTEEN("canteen:data-change-canteen", "食堂数据变更"), + DATA_CHANGE_SHOP_STALL("canteen:data-change-shop-stall", "档口数据变更"), + DATA_CHANGE_DISHES("dishes:data-change-dishes", "菜品数据变更"), + DATA_CHANGE_RECIPE("dishes:data-change-recipe", "菜谱数据变更"), + DATA_CHANGE_RECIPE_RELEASE("dishes:data-change-recipe-release", "菜谱发布"), + DATA_CHANGE_ORDER("canteen:data-change-order", "食堂订单数据变更"), + DATA_CHANGE_SUPERMARKET("supermarket:data-change-market", "商超数据变更"), + DATA_CHANGE_SUPERMARKET_ORDER("supermarket:data-change-supermarket-order", "商超订单数据变更"), + DATA_CHANGE_SUPERMARKET_GOODS("supermarket:data-change-supermarket-goods", "超市商品数据变更"), + DATA_CHANGE_RULE("marketing:data-change-rule", "规则数据变更"), + DATA_CHANGE_SUPERMARKET_RULE("marketing:data-change-supermarket-rule", "规则数据变更"), + DATA_CHANGE_RECHARGE("acc:data-change-recharge", "充值数据变更"), + BUFFET_BIND_NOTIFY("order:buffet-bind", "用户绑盘/用户解绑"), + BUFFET_ORD_PAY("order:buffet-ord-pay", "定时自助餐支付"), + ORDER_V3_ASYNC_SAVE("order:order-v3-async-save", "订单异步保存"), + ORDER_V3_ASYNC_SAVE_WEIGHT("order:order-v3-async-save-weight", "订单异步保存自助餐缓存"), + ORDER_V3_ASYNC_PAY_RESULT("order:order-v3-async-pay-result", "订单异步处理支付结果"), + ORDER_V3_ASYNC_TIMEOUT("order:order-v3-async-timeout", "订单异步超时处理"), + ORDER_V3_ASYNC_IMAGE_UPDATE("order:order-v3-async-img-queue", "订单图片保存"), + ORDER_CHANGE("order:order-change", "订单变更"), + ORDER_V3_PLACED("order:order-v3-placed", "订单已下单"), + ORDER_V3_REFUNDED("order:order-v3-refunded", "订单已退款"), + ORDER_V3_CANCELED("order:order-v3-canceled", "订单已取消"), + ORDER_V3_DISHES_STATE_UPDATED("order:order-v3-dishes-state-updated", "订单制作配送更新状态(制作/配送/核销)"), + ORDER_V3_ADD_DISHES("order:order-v3-add-dishes", "未支付订单添加菜品"), + ORDER_V3_REMOVE_DISHES("order:order-v3-remove-dishes", "未支付订单移除菜品"), + PAY_ASYNC_PAY_QUERY("pay:order-v3-async-pay-query", "支付异步查询支付结果"), + PAY_ZHIFUFEN_ORDER_DELAY_CONFIRM("pay:zhifufen-delay-confirm", "创建支付分订单延时处理"), + PAY_RESULT("pay:pay-result", "支付结果"), + REFUND_RESULT("pay:pay-refund-result", "退款结果"), + PAY_ABC_NATIVE_RECHARGE_RESULT("pay:pay-abc-native-recharge-result", "农行掌银充值结果"), + PAY_ALI_ENTERPRISE_CODE_PAY_ASYNC("pay:ali-enterprise-code-pay-async", "支付宝企业码异步提交"), + DATA_CHANGE_CUSTOMER_DINING_PLACE("customer:data-change-customer-dining-place", "人员就餐地数据变更"), + ORDER_PRINT("order:order-print", "订单打印"), + ROOM_ORDER_PRINT("order:room-order-print", "包间餐桌订单打印"), + ACC_STATUS_CHANGE("acc:acc-status-change-queue", "账户状态变动记录"), + ACC_TRADE_REPORT("acc:acc-trade-report-queue", "账户交易记录"), + MENUAI_REGIST("menuai:menuai-regist", "菜品注册"), + NOTICE_SUMMARY_COLLECT("notice:notice-summary-collect", "消息统计收集"), + NOTICE_USER_BUSINESS_SEND("notice:notice-user-business-send", "通知发布"), + NOTICE_VERIFICATION_CODE("notice:notice-verification-code-send", "验证码消息"), + JIABO_PRINTER_FAIL("notice:jiabo-printer-fail", "佳博打印机失败队列"), + JIABO_PRINTER_SUCCESS("notice:jiabo-printer-success", "佳博打印机成功队列"), + AUTH_OPS_USER_EXPIRE("auth:auth-ops-user-expire", "临时运维账号过期队列"), + DEVICE_HEARTBEAT("device:device-heart-send", "设备心跳消息(兼容2.2.14前版本接口)"), + BACK_DEVICE_HEARTBEAT_DELAY("backfield:back-device-heart-delay", "后场设备心跳延迟队列"), + DASHBOARD_DATA_SEND("dashboard-data-send", "数据大屏下发数据"), + NOTICE_DRP_GENERAL("drp:drp-notice", "出入库发送短信通知"), + NOTICE_DRP_GENERAL_RESULT("drp:drp-notice-result", "出入库发送短信通知结果"), + DRP_INTO_AND_OUT_DETAIL("drp:drp-into-and-out-detail", "出入库详情"), + DRP_CANCEL_INTO_AND_OUT("drp:drp-cancel-into-and-out", "取消出入库"), + DRP_OUT_NOTICE_BACKFIELD_MATERIAL("drp:drp-out-notice-backfield-material", "出库告知后场货品信息"), + DRP_ALLOCATION_DETAIL("drp:drp-allocation-detail", "调拨详情"), + DRP_SYNC_MATERIAL("drp_sync_material", "同步货品"), + DRP_SYNC_MATERIAL_BIG_CATEGORY("drp_sync_material_big_category", "同步货品前10大类"), + BACK_STAFF_CHANGE("backfield:back-change-staff", "后场人员变更队列"), + BACK_DEVICE_CONTROL("back-device-control", "后场推送至设备端控制设备状态"), + BACK_ALARM_NOTICE("backfield:back-alarm-notice", "后场告警通知"), + BACK_ALARM_NOTICE_TO_DASHBOARD("back-device-alarm-to-dashboard", "告警通知推送到食安公示大屏"), + BACK_CABINET_STORAGE_STATUS("backfield:back-cabinet-storage-status", "后场留样柜自动离柜延迟队列"), + BACK_TRAIN_AUTO_FINISH("backfield:back-train-auto-finish", "后场培训签到后自动完成"), + BACK_EXAM_AUTO_FINISH("backfield:back-exam-auto-finish", "后场培训考试到点自动交卷"), + BACK_DISINFECT_MISSION_AUTO_FINISH("backfield:back-disinfect-mission-finish", "消毒任务超过最大消毒时长自动结束"), + BACK_DISINFECT_PHOTO("backfield:back-disinfect-photo", "自动获取消毒现场照片"), + BACK_FOLLOW_PHOTO("backfield:back-follow-photo", "自动获取晨检尾随照片"), + BACK_DH_BACK_ILLEGAL_WARNING("backfield:dh-back-illegal-warning", "处理dataBridge接受的大华盒子智能事件"), + BACK_DH_BACK_ILLEGAL_WARNING_STAFF("backfield:dh-back-illegal-warning-staff", "处理dataBridge接受的大华盒子智能事件关联的人员信息:编号-姓名"), + DEVICE_LOG_INFO_DELETE_v4("device:device-log-info-delete-v4", "设备日志定时处理"), + DEVICE_ORDER_DELAY("device:device-order-delay", "前场设备订单延迟消息"), + DEVICE_UPDATE_PERSONALINFO_V2("update-personinfo-v2", "下发跟新人员信息通知"), + DEVICE_ONLINE_REPORT_V2("device-online-report-v2", "通知商户下设备上下线"), + DEVICE_UPDATE_DEVICE_BASICSETTING_V2("update-device-basicsetting-v2", "下发设备商家层级基础设置"), + DEVICE_UPDATE_DEVICE_METADATASETTING_V2("update-device-metadatasetting-v2", "设备设置"), + DEVICE_TIME_CALIBRATION_V2("time-calibration-v2", "设备时间校准"), + DEVICE_DISTRIBUTE_RECIPE_V2("distribute-recipe-v2", "设备下发菜谱"), + DEVICE_SWITCH_DEVICE_MENU_V2("switch-device-menu-v2", "设备切菜主题"), + DEVICE_SWITCH_DEVICE_MENU_PRICE_V2("switch-device-menu-price-v2", "设备切价格主题"), + DEVICE_STALL_UPDATE_WEIGHTINFO_V2("device-stall-update-weightinfo-v2", "通知计量主机状态(余量看板)"), + DEVICE_TIME_CALIBRATION_V4("time-calibration-v4", "设备时间校准"), + DEVICE_UPDATE_PERSONAL_CONFIG_V4("device-update-person-config-v4", "通知设备人员和特征值更新"), + DEVICE_SYNC_ACCOUNT_BALANCE_V1("device-sync-acc-balance-v1", "设备实时同步账户余额v1"), + DEVICE_SYNC_ACCOUNT_BALANCE_V4("device-sync-acc-balance-v4", "设备实时同步账户余额v4"), + DEVICE_UPDATE_MENU_CONFIG_V4("device-update-menu-config-v4", "设备下发菜谱通知"), + DEVICE_UPDATE_INTERVAL_CONFIG_V4("device-update-interval-config-v4", "餐次变动通知"), + DEVICE_UPDATE_SYSTEM_CARD_V4("device-update-system-card-v4", "后台系统卡息更新"), + DEVICE_UPDATE_INFO_V4("device-update-info-v4", "后台设备信息(包含自定义)更新"), + DEVICE_ONLINE_REPORT_V4("device-online-report-v4", "通知商户下所有设备设备上下线"), + DEVICE_ORDER_DISHES_STATE_UPDATE_V4("device-order-dishes-state-update-v4", "推送订单制作配送状态更新"), + DEVICE_LOCKER_STATUS_V4("device-locker-status-v4", "推送更新智能餐柜状态"), + BACK_DEVICE_IOT_GATEWAY_V4("back-device-iot-gateway-v4", "后场推送网关设备信息"), + BACK_DEVICE_UPDATE_PERSONAL_CONFIG_V4("back-device-update-person-config-v4", "通知设备后场人员和特征值更新"), + BACK_CABINET_UPDATE_SETTING_CONFIG_V4("back-cabinet-update-setting-config-v4", "通知设备留样柜基础设置更新"), + BACK_CABINET_OPEN_V4("back-cabinet-open-v4", "通知留样柜开柜"), + DEVICE_UPDATE_BUFFET_MERCHANT_V4("device-update-buffet-merchant-config-v4", "自助餐商家层级设置"), + DEVICE_STALL_UPDATE_WEIGHTINFO_V4("device-stall-update-weightinfo-v4", "通知计量主机状态(余量看板)"), + DEVICE_PULL_LOG_NOTICE_V4("device-pull-log-notice-v4", "获取设备日志下发通知"), + DEVICE_SWITCH_DEVICE_MENU_V4("switch-device-menu-v4", "计量主机切菜"), + DEVICE_SWITCH_DEVICE_MENU_PRICE_V4("switch-device-menu-price-v4", "计量主机改价"), + DEVICE_STALL_BUFFET_ALARM_V4("device-stall-buffet-alarm-v4", "通知计量主机报警状态(余量看板)"), + DEVICE_PRICE_TAG_V4("device-price-tag-v4", "营养价签通知给设备"), + DEVICE_UPDATE_AD_V4("device-update-ad-config-v4", "设备更新广告菜品"), + DEVICE_UPDATE_APK_V4("device-update-apk-config-v4", "设备更新广告菜品"), + BACK_DEVICE_PASSENGER_FLOW("backfield:back-device-passenger-flow", "客流统计"), + DATA_BRIDGE_DEVICE_HEART("backfield:data-bridge-device-heart", "数据桥接设备心跳"), + DEVICE_CAMERA_CONTROL("data_bridge:device_camera_control", "摄像头云台控制"), + BACK_DEVICE_HEART("backfield:back_device_heart", "设备心跳"), + BACK_DEVICE_IOT("backfield:back_device_iot", "传感器数据"), + MERCHANT_LIMIT_FLAG_CHANGE("merchant:limit-flag-change", "商户人数限制标识变更"), + DEVICE_VOICE("voice", "发送MQTT消息给收银播报音箱"), + AI_GATEWAY_MQTT("ai_gateway_mqtt", "菜品识别"), + DEVICE_SYNC_PADDLE_FAISS("device_sync_paddle_faiss", "通知设备更新向量库"), + DEVICE_SYNC_PADDLE_PICODET("device_sync_paddle_picodet", "通知设备更新主体检测模型"); + + private final String key; + private final String value; + + private Topic(String key, String value) { + this.key = key; + this.value = value; + } + + + public static Topic getTopic(String key) { + return (Topic)Arrays.stream(values()).filter((topic) -> { + return topic.getKey().equals(key); + }).findFirst().orElse((Topic) null); + } + + public static List deviceTopics() { + return (List)Arrays.stream(values()).filter((topic) -> { + return topic.name().startsWith("DEVICE_"); + }).collect(Collectors.toList()); + } + + public static List orderTopics() { + return (List)Arrays.stream(values()).filter((topic) -> { + return topic.name().startsWith("ORDER_") || topic.name().startsWith("MAC_ORDER_") || topic.name().startsWith("BUFFET_"); + }).collect(Collectors.toList()); + } + + public String getKey() { + return this.key; + } + + public String getValue() { + return this.value; + } + + // $FF: synthetic method + private static Topic[] $values() { + return new Topic[]{DEVICE_UPDATE_BIND_DISHES, DEVICE_UPDATE_DEVICE_BASICSETTING, DEVICE_UPDATE_DEVICE_METADATA, DEVICE_UPDATE_PERSON, DEVICE_UPDATE_PERSON_BATCH, DEVICE_UPDATE_PERSONALFEATURE_BATCH, DEVICE_DOOR_OPERATOR, DEVICE_HAIQING_DEVICE_COMMUNICATION, DEVICE_HAIQING_DEVICE_TRANSIT, DEVICE_PUSH_USER_DATA, DEVICE_SBLS_DEVICE_TRANSIT, DEVICE_SBLS_CR02EN_COMMUNICATION, DEVICE_DC_DEVICE_DELEAY, DEVICE_LOCKER_STATUS, DEVICE_NEW_MAKING_ORDER, DEVICE_ATTENDANCE_ACCEPT_DOOR_CONTROL, DEVICE_ATTENDANCE_ACCEPT_DOOR_CONTROL_VISITOR, CUSTOMER_VISITOR_INVITE, CUSTOMER_VISITOR_AUDIT_PASS, CUSTOMER_VISITOR_WAITING_AUDIT, CUSTOMER_VISITOR_SIGN_IN, DATA_CHANGE_ORG, DATA_CHANGE_CUSTOMER, CUSTOMER_CHANGE_DELAY, DATA_CHANGE_AREA, DATA_CHANGE_WAREHOUSE, BACK_DEVICE_HAIQING_DEVICE_TRANSIT, BACK_DEVICE_HAIQING_DEVICE_COMMUNICATION, BACK_DEVICE_SBLS_DEVICE_TRANSIT, BACK_DEVICE_SBLS_CR02EN_COMMUNICATION, BACK_DEVICE_IOT_GATEWAY, BACK_ATTENDANCE_CARD_DATA, BACK_TH_ALARM_DATA, DATA_CHANGE_CANTEEN, DATA_CHANGE_SHOP_STALL, DATA_CHANGE_DISHES, DATA_CHANGE_RECIPE, DATA_CHANGE_RECIPE_RELEASE, DATA_CHANGE_ORDER, DATA_CHANGE_SUPERMARKET, DATA_CHANGE_SUPERMARKET_ORDER, DATA_CHANGE_SUPERMARKET_GOODS, DATA_CHANGE_RULE, DATA_CHANGE_SUPERMARKET_RULE, DATA_CHANGE_RECHARGE, BUFFET_BIND_NOTIFY, BUFFET_ORD_PAY, ORDER_V3_ASYNC_SAVE, ORDER_V3_ASYNC_SAVE_WEIGHT, ORDER_V3_ASYNC_PAY_RESULT, ORDER_V3_ASYNC_TIMEOUT, ORDER_V3_ASYNC_IMAGE_UPDATE, ORDER_CHANGE, ORDER_V3_PLACED, ORDER_V3_REFUNDED, ORDER_V3_CANCELED, ORDER_V3_DISHES_STATE_UPDATED, ORDER_V3_ADD_DISHES, ORDER_V3_REMOVE_DISHES, PAY_ASYNC_PAY_QUERY, PAY_ZHIFUFEN_ORDER_DELAY_CONFIRM, PAY_RESULT, REFUND_RESULT, PAY_ABC_NATIVE_RECHARGE_RESULT, PAY_ALI_ENTERPRISE_CODE_PAY_ASYNC, DATA_CHANGE_CUSTOMER_DINING_PLACE, ORDER_PRINT, ROOM_ORDER_PRINT, ACC_STATUS_CHANGE, ACC_TRADE_REPORT, MENUAI_REGIST, NOTICE_SUMMARY_COLLECT, NOTICE_USER_BUSINESS_SEND, NOTICE_VERIFICATION_CODE, JIABO_PRINTER_FAIL, JIABO_PRINTER_SUCCESS, AUTH_OPS_USER_EXPIRE, DEVICE_HEARTBEAT, BACK_DEVICE_HEARTBEAT_DELAY, DASHBOARD_DATA_SEND, NOTICE_DRP_GENERAL, NOTICE_DRP_GENERAL_RESULT, DRP_INTO_AND_OUT_DETAIL, DRP_CANCEL_INTO_AND_OUT, DRP_OUT_NOTICE_BACKFIELD_MATERIAL, DRP_ALLOCATION_DETAIL, DRP_SYNC_MATERIAL, DRP_SYNC_MATERIAL_BIG_CATEGORY, BACK_STAFF_CHANGE, BACK_DEVICE_CONTROL, BACK_ALARM_NOTICE, BACK_ALARM_NOTICE_TO_DASHBOARD, BACK_CABINET_STORAGE_STATUS, BACK_TRAIN_AUTO_FINISH, BACK_EXAM_AUTO_FINISH, BACK_DISINFECT_MISSION_AUTO_FINISH, BACK_DISINFECT_PHOTO, BACK_FOLLOW_PHOTO, BACK_DH_BACK_ILLEGAL_WARNING, BACK_DH_BACK_ILLEGAL_WARNING_STAFF, DEVICE_LOG_INFO_DELETE_v4, DEVICE_ORDER_DELAY, DEVICE_UPDATE_PERSONALINFO_V2, DEVICE_ONLINE_REPORT_V2, DEVICE_UPDATE_DEVICE_BASICSETTING_V2, DEVICE_UPDATE_DEVICE_METADATASETTING_V2, DEVICE_TIME_CALIBRATION_V2, DEVICE_DISTRIBUTE_RECIPE_V2, DEVICE_SWITCH_DEVICE_MENU_V2, DEVICE_SWITCH_DEVICE_MENU_PRICE_V2, DEVICE_STALL_UPDATE_WEIGHTINFO_V2, DEVICE_TIME_CALIBRATION_V4, DEVICE_UPDATE_PERSONAL_CONFIG_V4, DEVICE_SYNC_ACCOUNT_BALANCE_V1, DEVICE_SYNC_ACCOUNT_BALANCE_V4, DEVICE_UPDATE_MENU_CONFIG_V4, DEVICE_UPDATE_INTERVAL_CONFIG_V4, DEVICE_UPDATE_SYSTEM_CARD_V4, DEVICE_UPDATE_INFO_V4, DEVICE_ONLINE_REPORT_V4, DEVICE_ORDER_DISHES_STATE_UPDATE_V4, DEVICE_LOCKER_STATUS_V4, BACK_DEVICE_IOT_GATEWAY_V4, BACK_DEVICE_UPDATE_PERSONAL_CONFIG_V4, BACK_CABINET_UPDATE_SETTING_CONFIG_V4, BACK_CABINET_OPEN_V4, DEVICE_UPDATE_BUFFET_MERCHANT_V4, DEVICE_STALL_UPDATE_WEIGHTINFO_V4, DEVICE_PULL_LOG_NOTICE_V4, DEVICE_SWITCH_DEVICE_MENU_V4, DEVICE_SWITCH_DEVICE_MENU_PRICE_V4, DEVICE_STALL_BUFFET_ALARM_V4, DEVICE_PRICE_TAG_V4, DEVICE_UPDATE_AD_V4, DEVICE_UPDATE_APK_V4, BACK_DEVICE_PASSENGER_FLOW, DATA_BRIDGE_DEVICE_HEART, DEVICE_CAMERA_CONTROL, BACK_DEVICE_HEART, BACK_DEVICE_IOT, MERCHANT_LIMIT_FLAG_CHANGE, DEVICE_VOICE, AI_GATEWAY_MQTT, DEVICE_SYNC_PADDLE_FAISS, DEVICE_SYNC_PADDLE_PICODET}; + } + } +} diff --git a/bonus-common-biz/src/main/java/com/bonus/common/houqin/mq/constant/MqPayload.java b/bonus-common-biz/src/main/java/com/bonus/common/houqin/mq/constant/MqPayload.java new file mode 100644 index 0000000..4db5e71 --- /dev/null +++ b/bonus-common-biz/src/main/java/com/bonus/common/houqin/mq/constant/MqPayload.java @@ -0,0 +1,67 @@ +package com.bonus.common.houqin.mq.constant; + +import com.bonus.common.houqin.constant.GlobalConstants; +import com.bonus.common.houqin.utils.LogUtil; + +public class MqPayload { + private Long tenantId; + private String traceId; + private LeMqConstant.Topic topic; + private String routingKey; + private T data; + + public String destination() { + String var10000 = this.topic.getKey(); + return var10000 + "." + this.tenantId; + } + + public static MqPayload of(T data, LeMqConstant.Topic topic, String routingKey) { + MqPayload payload = new MqPayload(); + payload.setData(data); + payload.setTopic(topic); + payload.setRoutingKey(routingKey); + payload.setTenantId(GlobalConstants.TENANT_ID); + payload.setTraceId(LogUtil.getCurrentTraceId()); + return payload; + } + + public Long getTenantId() { + return this.tenantId; + } + + public String getTraceId() { + return this.traceId; + } + + public LeMqConstant.Topic getTopic() { + return this.topic; + } + + public String getRoutingKey() { + return this.routingKey; + } + + public T getData() { + return this.data; + } + + public void setTenantId(final Long tenantId) { + this.tenantId = tenantId; + } + + public void setTraceId(final String traceId) { + this.traceId = traceId; + } + + public void setTopic(final LeMqConstant.Topic topic) { + this.topic = topic; + } + + public void setRoutingKey(final String routingKey) { + this.routingKey = routingKey; + } + + public void setData(final T data) { + this.data = data; + } +} diff --git a/bonus-common-biz/src/main/java/com/bonus/common/houqin/mq/domain/MqDataChangeMessageDto.java b/bonus-common-biz/src/main/java/com/bonus/common/houqin/mq/domain/MqDataChangeMessageDto.java new file mode 100644 index 0000000..702f3e9 --- /dev/null +++ b/bonus-common-biz/src/main/java/com/bonus/common/houqin/mq/domain/MqDataChangeMessageDto.java @@ -0,0 +1,110 @@ +package com.bonus.common.houqin.mq.domain; + +import com.bonus.common.houqin.framework.config.deserializer.DateTimeDeserializer; +import com.bonus.common.houqin.framework.config.serializer.DateTimeSerializer; +import com.bonus.common.houqin.mq.constant.LeMqConstant; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import io.swagger.annotations.ApiModelProperty; +import java.time.LocalDateTime; + +public class MqDataChangeMessageDto { + @ApiModelProperty("商户") + private Long tenantId; + @ApiModelProperty("变更数据") + private JsonNode data; + @ApiModelProperty("数据更新类型") + private LeMqConstant.DataChangeType changeType; + @ApiModelProperty("数据更新主题") + private LeMqConstant.Topic changeTopic; + @JsonSerialize( + using = DateTimeSerializer.YYYY_MM_DD_HH_MM_SS.class + ) + @JsonDeserialize( + using = DateTimeDeserializer.class + ) + @ApiModelProperty("发送时间") + private LocalDateTime sendTime; + @ApiModelProperty("用户") + private String userName; + @ApiModelProperty("操作员id") + private Long userId; + + public Long getTenantId() { + return this.tenantId; + } + + public JsonNode getData() { + return this.data; + } + + public LeMqConstant.DataChangeType getChangeType() { + return this.changeType; + } + + public LeMqConstant.Topic getChangeTopic() { + return this.changeTopic; + } + + public LocalDateTime getSendTime() { + return this.sendTime; + } + + public String getUserName() { + return this.userName; + } + + public Long getUserId() { + return this.userId; + } + + public void setTenantId(final Long tenantId) { + this.tenantId = tenantId; + } + + public void setData(final JsonNode data) { + this.data = data; + } + + public void setChangeType(final LeMqConstant.DataChangeType changeType) { + this.changeType = changeType; + } + + public void setChangeTopic(final LeMqConstant.Topic changeTopic) { + this.changeTopic = changeTopic; + } + + @JsonDeserialize( + using = DateTimeDeserializer.class + ) + public void setSendTime(final LocalDateTime sendTime) { + this.sendTime = sendTime; + } + + public void setUserName(final String userName) { + this.userName = userName; + } + + public void setUserId(final Long userId) { + this.userId = userId; + } + + + public MqDataChangeMessageDto() { + } + + private MqDataChangeMessageDto(final Long tenantId, final JsonNode data, final LeMqConstant.DataChangeType changeType, final LeMqConstant.Topic changeTopic, final LocalDateTime sendTime, final String userName, final Long userId) { + this.tenantId = tenantId; + this.data = data; + this.changeType = changeType; + this.changeTopic = changeTopic; + this.sendTime = sendTime; + this.userName = userName; + this.userId = userId; + } + + public static MqDataChangeMessageDto of(final Long tenantId, final JsonNode data, final LeMqConstant.DataChangeType changeType, final LeMqConstant.Topic changeTopic, final LocalDateTime sendTime, final String userName, final Long userId) { + return new MqDataChangeMessageDto(tenantId, data, changeType, changeTopic, sendTime, userName, userId); + } +} diff --git a/bonus-common-biz/src/main/java/com/bonus/common/houqin/mq/util/MqUtil.java b/bonus-common-biz/src/main/java/com/bonus/common/houqin/mq/util/MqUtil.java new file mode 100644 index 0000000..ac6bfcc --- /dev/null +++ b/bonus-common-biz/src/main/java/com/bonus/common/houqin/mq/util/MqUtil.java @@ -0,0 +1,152 @@ +package com.bonus.common.houqin.mq.util; + +import com.bonus.common.houqin.constant.GlobalConstants; +import com.bonus.common.houqin.mq.MQTemplate; +import com.bonus.common.houqin.mq.constant.LeMqConstant; +import com.bonus.common.houqin.mq.constant.MqPayload; +import com.bonus.common.houqin.mq.domain.MqDataChangeMessageDto; +import com.bonus.common.houqin.mq.tx.TxHolder; +import com.bonus.common.houqin.utils.JacksonUtil; +import com.bonus.common.houqin.utils.SpringContextHolder; +import com.bonus.common.security.utils.SecurityUtils; +import lombok.SneakyThrows; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Lazy; +import java.time.LocalDateTime; + +public class MqUtil { + private static final Logger log = LoggerFactory.getLogger(MqUtil.class); + @Lazy + public static final MQTemplate mqTemplate = (MQTemplate) SpringContextHolder.getBean(MQTemplate.class); + + public static void send(T data, LeMqConstant.Topic topic) { + try { + log.info("发送消息,topic:{}", topic.getKey()); + log.info("消息体", data); + String routing = topic.getKey(); + mqTemplate.send(routing, MqPayload.of(data, topic, routing)); + } catch (Exception var3) { + log.error("发送MQ消息失败", var3); + } + + } + + public static void send(T data, LeMqConstant.Topic topic, String routing) { + try { + log.info("发送消息,topic:{},routing:{}", topic.getKey(), routing); + log.info("消息体", data); + mqTemplate.send(routing, MqPayload.of(data, topic, routing)); + } catch (Exception var4) { + log.error("发送MQ消息失败", var4); + } + + } + + @SneakyThrows + public static TxHolder sendByTx(T data, LeMqConstant.Topic topic) { + String routing = topic.getKey(); + log.info("发送事务消息,topic:{}", topic.getKey()); + log.info("消息体", data); + return mqTemplate.txBegin(routing, MqPayload.of(data, topic, routing)); + } + @SneakyThrows + public static void sendByTxEnd(T data, LeMqConstant.Topic topic) { + String routing = topic.getKey(); + log.info("发送事务消息,topic:{}", topic.getKey()); + log.info("消息体", data); + mqTemplate.txBegin(routing, MqPayload.of(data, topic, routing)).end(); + } + @SneakyThrows + public static void sendByTxCommit(T data, LeMqConstant.Topic topic) { + log.info("发送事务消息,topic:{}", topic.getKey()); + log.info("消息体", data); + String routing = topic.getKey(); + mqTemplate.txBegin(routing, MqPayload.of(data, topic, routing)).commit(); + } + + public static void sendDelay(T data, LeMqConstant.Topic topic, int delayMileSecond) { + try { + log.info("发送延迟消息,topic:{},delayMileSecond:{}", topic.getKey(), delayMileSecond); + log.info("消息体", data); + String routing = topic.getKey(); + mqTemplate.sendDelay(routing, MqPayload.of(data, topic, routing), (int)delayMileSecond); + } catch (Exception var4) { + log.error("发送事务MQ消息失败", var4); + } + + } + + public static void sendDataChange(T data, LeMqConstant.DataChangeType changeType, LeMqConstant.Topic topic) { + Long userId = null; + + try { + userId = SecurityUtils.getUserId(); + } catch (Exception var5) { + } + + MqDataChangeMessageDto dto = MqDataChangeMessageDto.of(GlobalConstants.TENANT_ID, JacksonUtil.valueToTree(data), changeType, topic, LocalDateTime.now(), SecurityUtils.getUsername(), userId); + send(dto, topic); + } + + @SneakyThrows + public static void pushToSingleDevice(T data, LeMqConstant.Topic topic, String deviceSn) { + String var10000 = topic.getKey(); + String routing = var10000 + "/" + GlobalConstants.TENANT_ID + "/" + deviceSn; + log.info("推送给单条设备,routing:{}", routing); + log.info("消息体", data); + mqTemplate.sendMqtt(routing, data); + } + + @SneakyThrows + public static void pushToSingleDevice(T data, LeMqConstant.Topic topic, String deviceSn, Long merchantId) { + String routing = topic.getKey() + "/" + GlobalConstants.TENANT_ID + "/" + deviceSn; + log.info("推送给单条设备,routing:{}", routing); + log.info("消息体", data); + mqTemplate.sendMqtt(routing, data); + } + + @SneakyThrows + public static void pushToSingleTxDevice(T data, LeMqConstant.Topic topic, String deviceSn) { + String var10000 = topic.getKey(); + String routing = var10000 + "/" + GlobalConstants.TENANT_ID + "/" + deviceSn; + log.info("推送给单条设备,routing:{}", routing); + log.info("消息体", data); + mqTemplate.mqttTxBegin(routing, data).end(); + } + + @SneakyThrows + public static void pushToSingleDevice(T data, String routing, String deviceSn) { + routing = routing + "/" + GlobalConstants.TENANT_ID; + if (deviceSn != null) { + routing = routing + "/" + deviceSn; + } + + log.info("推送给单条设备,routing:{}", routing); + log.info("消息体", data); + mqTemplate.sendMqtt(routing, data); + } + @SneakyThrows + public static void pushToTenantAllDevice(T data, LeMqConstant.Topic topic) { + String var10000 = topic.getKey(); + String routing = var10000 + "/" + GlobalConstants.TENANT_ID; + log.info("推送给商户下所有设备,routing:{}", routing); + mqTemplate.sendMqtt(routing, data); + } + @SneakyThrows + public static void pushToTenantAllDeviceWithTenantId(T data, LeMqConstant.Topic topic, Long tenantId) { + String var10000 = topic.getKey(); + String routing = var10000 + "/" + GlobalConstants.TENANT_ID; + log.info("推送给商户下所有设备,routing:{}", routing); + log.info("消息体", data); + mqTemplate.sendMqtt(routing, data); + } + @SneakyThrows + public static void pushToAllDevice(T data, LeMqConstant.Topic topic) { + mqTemplate.sendMqtt(topic.getKey(), data); + } + @SneakyThrows + public static void pushToSingleDeviceCustomed(T data, String routing) { + mqTemplate.sendMqtt(routing, data); + } +} diff --git a/bonus-common-biz/src/main/java/com/bonus/common/houqin/utils/JacksonUtil.java b/bonus-common-biz/src/main/java/com/bonus/common/houqin/utils/JacksonUtil.java new file mode 100644 index 0000000..5f542bb --- /dev/null +++ b/bonus-common-biz/src/main/java/com/bonus/common/houqin/utils/JacksonUtil.java @@ -0,0 +1,501 @@ +package com.bonus.common.houqin.utils; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.text.CharSequenceUtil; +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.StrUtil; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.stream.Collectors; + +public class JacksonUtil { + private static final ObjectMapper objectMapper; + private static final ObjectMapper objectMapperIgnoreNull; + private static final Logger logger; + + public static ObjectMapper getInstance() { + return objectMapper; + } + + public static ObjectMapper getInstanceIgnoreNull() { + return objectMapperIgnoreNull; + } + + public static ObjectNode objectNode() { + return getInstance().createObjectNode(); + } + + public static ArrayNode arrayNode() { + return getInstance().createArrayNode(); + } + + public static boolean isNull(JsonNode jsonNode) { + return jsonNode == null || jsonNode.isNull() || jsonNode.isMissingNode(); + } + + public static boolean isNullOrEmpty(JsonNode jsonNode) { + return jsonNode == null || jsonNode.isNull() || jsonNode.isMissingNode() || jsonNode.isEmpty(); + } + + public static String writeValueAsString(Object obj) { + try { + return getInstance().writeValueAsString(obj); + } catch (IOException var2) { + logger.error(var2.getMessage(), var2); + return null; + } + } + + public static Optional writeValueAsStringOptional(Object obj) { + return Optional.ofNullable(writeValueAsString(obj)); + } + + public static String writeValueAsStringIgnoreNull(Object obj) { + try { + return getInstanceIgnoreNull().writeValueAsString(obj); + } catch (IOException var2) { + logger.error(var2.getMessage(), var2); + return null; + } + } + + public static Optional writeValueAsStringIgnoreNullOptional(Object obj) { + return Optional.ofNullable(writeValueAsStringIgnoreNull(obj)); + } + + public static T readValue(String jsonStr, TypeReference valueTypeRef) { + try { + return getInstance().readValue(jsonStr, valueTypeRef); + } catch (JsonParseException var3) { + logger.error(var3.getMessage(), var3); + } catch (JsonMappingException var4) { + logger.error(var4.getMessage(), var4); + } catch (IOException var5) { + logger.error(var5.getMessage(), var5); + } + + return null; + } + + public static Optional readValueOptional(String jsonStr, TypeReference valueTypeRef) { + return Optional.ofNullable(readValue(jsonStr, valueTypeRef)); + } + + public static T readValue(String jsonStr, Class clazz) { + try { + return getInstance().readValue(jsonStr, clazz); + } catch (JsonParseException var3) { + logger.error(var3.getMessage(), var3); + } catch (JsonMappingException var4) { + logger.error(var4.getMessage(), var4); + } catch (Exception var5) { + logger.error(var5.getMessage(), var5); + } + + return null; + } + + public static Optional readValueOptional(String jsonStr, Class clazz) { + return Optional.ofNullable(readValue(jsonStr, clazz)); + } + + public static T readValueOrEmpty(String jsonStr, Class clazz) throws InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException { + try { + T t = readValue(jsonStr, clazz); + return t != null ? t : clazz.getDeclaredConstructor().newInstance(); + } catch (Throwable var3) { + throw var3; + } + } + + public static T readValue(String jsonStr, Class parametrized, Class... parameterClasses) { + try { + JavaType javaType = getInstance().getTypeFactory().constructParametricType(parametrized, parameterClasses); + return getInstance().readValue(jsonStr, javaType); + } catch (JsonParseException var4) { + logger.error(var4.getMessage(), var4); + } catch (JsonMappingException var5) { + logger.error(var5.getMessage(), var5); + } catch (IOException var6) { + logger.error(var6.getMessage(), var6); + } + + return null; + } + + public static List readList(String jsonStr, Class... parameterClasses) { + List list = (List)readValue(jsonStr, List.class, parameterClasses); + return (List)(list != null ? list : CollUtil.newArrayList(new Object[0])); + } + + public static JsonNode readTree(String jsonStr) { + try { + return getInstance().readTree(jsonStr); + } catch (IOException var2) { + logger.error(var2.getMessage(), var2); + return null; + } + } + + public static JsonNode readTreeOrMissing(String jsonStr) { + JsonNode jsonNode = readTree(jsonStr); + return jsonNode != null ? jsonNode : getInstance().missingNode(); + } + + public static T treeToValue(JsonNode node, Class clz) { + try { + return getInstance().treeToValue(node, clz); + } catch (IOException var3) { + logger.error(var3.getMessage(), var3); + return null; + } + } + + public static Optional treeToValueOptional(JsonNode node, Class clz) { + return Optional.ofNullable(treeToValue(node, clz)); + } + + public static T treeToValueOrEmpty(JsonNode node, Class clz) throws InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException { + try { + T t = treeToValue(node, clz); + return t != null ? t : clz.getDeclaredConstructor().newInstance(); + } catch (Throwable var3) { + throw var3; + } + } + + public static T treeToValue(JsonNode node, TypeReference typeR) { + try { + JavaType javaType = getInstance().getTypeFactory().constructType(typeR); + return getInstance().treeToValue(node, javaType); + } catch (IOException var3) { + logger.error(var3.getMessage(), var3); + return null; + } + } + + public static T treeToValue(JsonNode node, Class parametrized, Class... parameterClasses) { + try { + JavaType javaType = getInstance().getTypeFactory().constructParametricType(parametrized, parameterClasses); + return getInstance().treeToValue(node, javaType); + } catch (IOException var4) { + logger.error(var4.getMessage(), var4); + return null; + } + } + + public static Optional treeToValueOptional(JsonNode node, Class parametrized, Class... parameterClasses) { + return Optional.ofNullable(treeToValue(node, parametrized, parameterClasses)); + } + + public static List treeToList(JsonNode node, Class... parameterClasses) { + List list = (List)treeToValue(node, List.class, parameterClasses); + return (List)(list != null ? list : CollUtil.newArrayList(new Object[0])); + } + + public static JsonNode valueToTree(Object obj) { + return getInstance().valueToTree(obj); + } + + public static JsonNode valueToTreeIgnoreNull(Object obj) { + return getInstanceIgnoreNull().valueToTree(obj); + } + + public static int getIntValue(JsonNode jsonNode, String key, int defaultValue) { + if (jsonNode != null && !jsonNode.isNull() && !jsonNode.isMissingNode()) { + JsonNode node = jsonNode.get(key); + return node != null && !node.isNull() && !node.isMissingNode() ? node.asInt(defaultValue) : defaultValue; + } else { + return defaultValue; + } + } + + public static Integer getInt(JsonNode jsonNode, String key) { + if (jsonNode != null && !jsonNode.isNull() && !jsonNode.isMissingNode()) { + JsonNode node = jsonNode.get(key); + return node != null && !node.isNull() && !node.isMissingNode() ? node.asInt() : null; + } else { + return null; + } + } + + public static long getLongValue(JsonNode jsonNode, String key, long defaultValue) { + if (jsonNode != null && !jsonNode.isNull() && !jsonNode.isMissingNode()) { + JsonNode node = jsonNode.get(key); + return node != null && !node.isNull() && !node.isMissingNode() ? node.asLong(defaultValue) : defaultValue; + } else { + return defaultValue; + } + } + + public static Long getLong(JsonNode jsonNode, String key) { + if (jsonNode != null && !jsonNode.isNull() && !jsonNode.isMissingNode()) { + JsonNode node = jsonNode.get(key); + return node != null && !node.isNull() && !node.isMissingNode() ? node.asLong() : null; + } else { + return null; + } + } + + public static double getDoubleValue(JsonNode jsonNode, String key, double defaultValue) { + if (jsonNode != null && !jsonNode.isNull() && !jsonNode.isMissingNode()) { + JsonNode node = jsonNode.get(key); + return node != null && !node.isNull() && !node.isMissingNode() ? node.asDouble(defaultValue) : defaultValue; + } else { + return defaultValue; + } + } + + public static Double getDouble(JsonNode jsonNode, String key) { + if (jsonNode != null && !jsonNode.isNull() && !jsonNode.isMissingNode()) { + JsonNode node = jsonNode.get(key); + return node != null && !node.isNull() && !node.isMissingNode() ? node.asDouble() : null; + } else { + return null; + } + } + + public static String getStringValue(JsonNode jsonNode, String key, String defaultValue) { + return jsonNode.path(key).asText(defaultValue); + } + + public static String getString(JsonNode jsonNode, String key) { + return getStringValue(jsonNode, key, (String)null); + } + + public static JsonNode getByPath(JsonNode node, String expression) { + if (StringUtils.isEmpty(expression)) { + return node; + } else { + JsonNode result = node; + String[] var3 = StringUtils.split(expression, "."); + int var4 = var3.length; + + for(int var5 = 0; var5 < var4; ++var5) { + String path = var3[var5]; + if (StrUtil.contains(path, "[") && StrUtil.contains(path, "]")) { + String aryPath = StrUtil.subBefore(path, "[", false); + int idxPath = NumberUtil.parseInt(StrUtil.subBetween(path, "[", "]")); + if (idxPath < 0) { + idxPath += result.path(aryPath).size(); + } + + result = result.path(aryPath).path(idxPath); + } else { + result = result.path(path); + } + } + + return result; + } + } + + public static T getValueByPath(String jsonStr, String expression, T defaultValue) { + JsonNode jsonNode = readTreeOrMissing(jsonStr); + return getValueByPath(jsonNode, expression, defaultValue); + } + + public static T getValueByPath(JsonNode jsonNode, String expression, T defaultValue) { + if (jsonNode == null) { + return defaultValue; + } else { + JsonNode nodeByPath = getByPath(jsonNode, expression); + T value = treeToValue(nodeByPath, new TypeReference() { + }); + return value != null ? value : defaultValue; + } + } + + public static void putByPath(JsonNode node, String expression, Object value) { + if (node.isObject()) { + JsonNode currentNode = node; + Iterator iterator = Arrays.stream(StringUtils.split(expression, ".")).iterator(); + + while(true) { + while(iterator.hasNext()) { + String path = (String)iterator.next(); + if (StrUtil.contains(path, "[") && StrUtil.contains(path, "]")) { + String aryPath = StrUtil.subBefore(path, "[", false); + int idxPath = NumberUtil.parseInt(StrUtil.subBetween(path, "[", "]")); + if (idxPath < 0) { + idxPath += currentNode.path(aryPath).size(); + } + + if (!currentNode.path(aryPath).isArray()) { + ((ObjectNode)currentNode).putArray(aryPath); + } + + currentNode = currentNode.path(aryPath); + if (idxPath >= currentNode.size()) { + ((ArrayNode)currentNode).add(objectNode()); + idxPath = currentNode.size() - 1; + } + + if (!iterator.hasNext()) { + if (value instanceof String) { + ((ArrayNode)currentNode).set(idxPath, (String)value); + } else if (value instanceof JsonNode) { + ((ArrayNode)currentNode).set(idxPath, (JsonNode)value); + } else { + ((ArrayNode)currentNode).set(idxPath, valueToTree(value)); + } + } else { + JsonNode nodeByPath = currentNode.path(idxPath); + if (nodeByPath.isObject()) { + currentNode = nodeByPath; + } else { + ((ObjectNode)currentNode).putObject(path); + currentNode = currentNode.path(path); + } + } + } else if (!iterator.hasNext()) { + if (value instanceof String) { + ((ObjectNode)currentNode).put(path, (String)value); + } else if (value instanceof JsonNode) { + ((ObjectNode)currentNode).set(path, (JsonNode)value); + } else { + ((ObjectNode)currentNode).set(path, valueToTree(value)); + } + } else { + JsonNode nodeByPath = currentNode.path(path); + if (nodeByPath.isObject()) { + currentNode = nodeByPath; + } else { + ((ObjectNode)currentNode).putObject(path); + currentNode = currentNode.path(path); + } + } + } + + return; + } + } + } + + public static ArrayNode treeToList(JsonNode param, String childrenColumn, String idColumn, String parentIdColumn, String parentIdValue, String sortColumn) { + if (param != null && !param.isMissingNode()) { + ArrayNode result = doTreeToList(param.deepCopy(), childrenColumn, idColumn, parentIdColumn, parentIdValue); + if (CharSequenceUtil.isNotBlank(sortColumn)) { + ArrayList jsonNodes = CollUtil.newArrayList(result.elements()); + jsonNodes.sort((o1, o2) -> { + String column1 = o1.path(sortColumn).asText(); + String column2 = o2.path(sortColumn).asText(); + return NumberUtil.isNumber(column1) && NumberUtil.isNumber(column2) ? NumberUtil.toBigDecimal(column1).compareTo(NumberUtil.toBigDecimal(column2)) : CharSequenceUtil.compare(column1, column2, true); + }); + result.removeAll(); + result.addAll(jsonNodes); + } + + return result; + } else { + return arrayNode(); + } + } + + public static ArrayNode listToTree(JsonNode param, String childrenColumn, String idColumn, String parentIdColumn, String rootParentIdValue) { + if (param != null && !param.isMissingNode() && !param.isEmpty() && param.isArray()) { + ArrayNode nodeList = (ArrayNode)param.deepCopy(); + Map nodeMap = (Map)CollUtil.newArrayList(nodeList.elements()).stream().collect(Collectors.toMap((nodex) -> { + return nodex.path(idColumn).asText(); + }, (nodex) -> { + return nodex; + })); + Iterator elements = nodeList.iterator(); + + JsonNode node; + while(elements.hasNext()) { + node = (JsonNode)elements.next(); + JsonNode paramNode = (JsonNode)nodeMap.get(node.path(parentIdColumn).asText()); + if (paramNode != null) { + if (paramNode.get(childrenColumn) == null) { + ((ObjectNode)paramNode).putArray(childrenColumn); + } + + ((ArrayNode)paramNode.get(childrenColumn)).add(node); + } + } + + elements = nodeList.elements(); + + while(elements.hasNext()) { + node = (JsonNode)elements.next(); + if (CharSequenceUtil.isBlank(rootParentIdValue)) { + if (!node.path(parentIdColumn).isMissingNode() && !node.path(parentIdColumn).isNull()) { + elements.remove(); + } + } else if (!rootParentIdValue.equals(node.path(parentIdColumn).asText())) { + elements.remove(); + } + } + + return nodeList; + } else { + return arrayNode(); + } + } + + private static ArrayNode doTreeToList(JsonNode param, String childrenColumn, String idColumn, String parentIdColumn, String parentIdValue) { + ArrayNode result = arrayNode(); + if (param.isArray()) { + Iterator var6 = param.iterator(); + + while(var6.hasNext()) { + JsonNode node = (JsonNode)var6.next(); + result.addAll(doTreeToList(node, childrenColumn, idColumn, parentIdColumn, parentIdValue)); + } + } else if (param.isObject()) { + ObjectNode node = (ObjectNode)param; + String nodeId = node.path(idColumn).asText(); + JsonNode children = node.get(childrenColumn); + if (children != null && !children.isMissingNode()) { + result.addAll(doTreeToList(children, childrenColumn, idColumn, parentIdColumn, nodeId)); + } + + if (node.path(parentIdColumn).isMissingNode()) { + node.put(parentIdColumn, parentIdValue); + } + + node.remove(childrenColumn); + result.add(node); + } + + return result; + } + + static { + objectMapper = (new ObjectMapper()).configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).registerModule((new SimpleModule()).addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))).addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))).addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss"))).addSerializer(Long.class, new JsonSerializer() { + public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeString(String.valueOf(value)); + } + }).addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))).addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))).addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")))); + objectMapperIgnoreNull = (new ObjectMapper()).configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).setSerializationInclusion(Include.NON_NULL).registerModule((new SimpleModule()).addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))).addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))).addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss"))).addSerializer(Long.class, new JsonSerializer() { + public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeString(String.valueOf(value)); + } + }).addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))).addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))).addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")))); + logger = LoggerFactory.getLogger(JacksonUtil.class); + } +} diff --git a/bonus-common-biz/src/main/java/com/bonus/common/houqin/utils/LogUtil.java b/bonus-common-biz/src/main/java/com/bonus/common/houqin/utils/LogUtil.java new file mode 100644 index 0000000..67c8c1a --- /dev/null +++ b/bonus-common-biz/src/main/java/com/bonus/common/houqin/utils/LogUtil.java @@ -0,0 +1,216 @@ +package com.bonus.common.houqin.utils; + +import cn.hutool.core.bean.BeanDesc; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.UUID; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.ClassUtil; +import cn.hutool.core.util.StrUtil; +import io.swagger.annotations.ApiModelProperty; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; +import org.springframework.context.annotation.Lazy; +import org.springframework.core.env.Environment; +import java.lang.reflect.Field; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +public class LogUtil { + private static final Logger log = LoggerFactory.getLogger(LogUtil.class); + private static final String TRACE_KEY = "X-Trace-Id"; + private static final String ARG_SEPERATOR = " --> "; + private static final ThreadLocal THREAD_LOCAL_FLAG = new InheritableThreadLocal(); + @Lazy + private static final Environment environment = (Environment)SpringContextHolder.getBean(Environment.class); + + public static void generateNewLogTraceId() { + MDC.put("X-Trace-Id", UUID.fastUUID().toString(true)); + } + + public static void putLogTraceId(String traceId) { + MDC.put("X-Trace-Id", traceId); + } + + public static String getCurrentTraceId() { + return MDC.get("X-Trace-Id"); + } + + public static void printArgsIn(String tag, Object... args) { + if ((Boolean)environment.getProperty("system.args-print.enable", Boolean.class, Boolean.FALSE)) { + info(StrUtil.concat(true, new CharSequence[]{tag, "][入参"}), args); + } + } + + public static void printArgsOut(String tag, Object... args) { + if ((Boolean)environment.getProperty("system.args-print.enable", Boolean.class, Boolean.FALSE)) { + info(StrUtil.concat(true, new CharSequence[]{tag, "][出参"}), args); + } + } + + public static void printArgs(String tag, Object... args) { + if ((Boolean)environment.getProperty("system.args-print.enable", Boolean.class, Boolean.FALSE)) { + info(tag, args); + } + } + + public static void printF(String tag, Object... args) { + if (!Boolean.FALSE.equals(THREAD_LOCAL_FLAG.get())) { + info(tag, args); + } + } + + public static void setF(boolean flag) { + THREAD_LOCAL_FLAG.set(flag); + } + + public static void removeF() { + THREAD_LOCAL_FLAG.remove(); + } + + public static void info(String tag, Object... args) { + StringBuilder sb = new StringBuilder(); + sb.append(tag); + if (ArrayUtil.isNotEmpty(args)) { + Object[] var3 = args; + int var4 = args.length; + + for(int var5 = 0; var5 < var4; ++var5) { + Object arg = var3[var5]; + Object argStr = isBasicType(arg) ? arg : JacksonUtil.writeValueAsStringIgnoreNull(arg); + sb.append(" --> ").append(argStr); + } + } + + log.info(sb.toString()); + } + + public static void infoFields(String tag, Object arg, String... fieldNames) { + StringBuilder sb = new StringBuilder(); + sb.append(tag); + concatString(sb, arg, fieldNames); + log.info(sb.toString()); + } + + public static void infoFieldsX(String tag, Object... args) { + StringBuilder sb = new StringBuilder(); + sb.append(tag); + + for(int i = 0; i < args.length; ++i) { + if (i % 2 == 0) { + Object arg = args[i]; + String[] fieldNames = (String[])args[i + 1]; + concatString(sb, arg, fieldNames); + } + } + + log.info(sb.toString()); + } + + public static void infoDesc(String tag, Object... args) { + infoFieldsDesc(tag, args); + } + + public static void infoFieldsDesc(String tag, Object arg, String... fieldNames) { + StringBuilder sb = new StringBuilder(); + sb.append(tag); + concatStringWithDesc(sb, arg, fieldNames); + log.info(sb.toString()); + } + + public static String getDescOfField(Class aClass, String filedName) { + BeanDesc beanDesc = BeanUtil.getBeanDesc(aClass); + Field declaredField = beanDesc.getField(filedName); + if (declaredField == null) { + Class superclass = aClass.getSuperclass(); + return superclass != null ? getDescOfField(superclass, filedName) : ""; + } else { + return getDescOfField(declaredField); + } + } + + private static String getDescOfField(Field field) { + ApiModelProperty annotation = (ApiModelProperty)field.getAnnotation(ApiModelProperty.class); + if (annotation != null) { + StringBuilder sb = new StringBuilder(); + String annotationRemark = annotation.value(); + if (StrUtil.isNotEmpty(annotationRemark)) { + sb.append("【").append(StrUtil.isNotEmpty(annotationRemark) ? annotationRemark : "").append("】"); + } + + return sb.toString(); + } else { + return ""; + } + } + + private static Map descMapFroObj(Object arg, Class aClass, String... propertyNames) { + Map descMap = MapUtil.newHashMap(); + CopyOptions copyOptions = CopyOptions.create().setIgnoreNullValue(false).setFieldNameEditor((s) -> { + return !ArrayUtil.isEmpty(propertyNames) && !ArrayUtil.contains(propertyNames, s) ? null : s + getDescOfField(aClass, s); + }).setFieldValueEditor((s, o) -> { + if (isBasicType(o)) { + return o; + } else if (o instanceof Collection) { + List> listProps = CollUtil.newArrayList(new Map[0]); + ((Collection)o).forEach((o1) -> { + listProps.add(descMapFroObj(o1, ClassUtil.getClass(o1))); + }); + return listProps; + } else { + return descMapFroObj(o, ClassUtil.getClass(o)); + } + }); + BeanUtil.beanToMap(arg, descMap, copyOptions); + return descMap; + } + + private static void concatStringWithDesc(StringBuilder sb, Object arg, String... fieldNames) { + if (arg instanceof Collection) { + ArrayList list = CollUtil.newArrayList(new Object[0]); + ((Collection)arg).forEach((o) -> { + Class aClass = ClassUtil.getClass(arg); + Map descMap = descMapFroObj(arg, aClass, fieldNames); + list.add(descMap); + }); + sb.append(" --> ").append(JacksonUtil.writeValueAsStringIgnoreNull(list)); + } else if (arg != null) { + Class aClass = ClassUtil.getClass(arg); + Map descMap = descMapFroObj(arg, aClass, fieldNames); + sb.append(" --> ").append(JacksonUtil.writeValueAsStringIgnoreNull(descMap)); + } + + } + + private static void concatString(StringBuilder sb, Object arg, String[] fieldNames) { + if (arg instanceof Collection) { + ArrayList list = CollUtil.newArrayList(new Object[0]); + ((Collection)arg).forEach((o) -> { + Map descMap = MapUtil.newHashMap(); + Map stringObjectMap = BeanUtil.beanToMap(o, descMap, false, (s) -> { + return !ArrayUtil.isEmpty(fieldNames) && !ArrayUtil.contains(fieldNames, s) ? null : s; + }); + list.add(stringObjectMap); + }); + sb.append(" --> ").append(JacksonUtil.writeValueAsStringIgnoreNull(list)); + } else if (arg != null) { + Map descMap = MapUtil.newHashMap(); + BeanUtil.beanToMap(arg, descMap, false, (s) -> { + return !ArrayUtil.isEmpty(fieldNames) && !ArrayUtil.contains(fieldNames, s) ? null : s; + }); + sb.append(" --> ").append(JacksonUtil.writeValueAsStringIgnoreNull(descMap)); + } + + } + + private static boolean isBasicType(Object obj) { + return obj == null || ClassUtil.isBasicType(obj.getClass()) || ClassUtil.isSimpleValueType(obj.getClass()) || obj instanceof LocalDate || obj instanceof LocalDateTime || obj instanceof Map; + } +} diff --git a/bonus-common-biz/src/main/java/com/bonus/common/houqin/utils/SpringContextHolder.java b/bonus-common-biz/src/main/java/com/bonus/common/houqin/utils/SpringContextHolder.java new file mode 100644 index 0000000..0fffece --- /dev/null +++ b/bonus-common-biz/src/main/java/com/bonus/common/houqin/utils/SpringContextHolder.java @@ -0,0 +1,53 @@ +package com.bonus.common.houqin.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; + +@Service +@Lazy(false) +public class SpringContextHolder implements ApplicationContextAware, DisposableBean { + private static final Logger log = LoggerFactory.getLogger(SpringContextHolder.class); + private static ApplicationContext applicationContext = null; + + public static ApplicationContext getApplicationContext() { + return applicationContext; + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) { + SpringContextHolder.applicationContext = applicationContext; + } + + public static T getBean(String name) { + return (T) applicationContext.getBean(name); + } + + public static T getBean(Class requiredType) { + return applicationContext.getBean(requiredType); + } + + public static void clearHolder() { + if (log.isDebugEnabled()) { + log.debug("清除SpringContextHolder中的ApplicationContext:" + String.valueOf(applicationContext)); + } + + applicationContext = null; + } + + public static void publishEvent(ApplicationEvent event) { + if (applicationContext != null) { + applicationContext.publishEvent(event); + } + } + + @Override + public void destroy() { + clearHolder(); + } +}