mirror of
https://gitee.com/NexIoT/Universal-IoT-Java.git
synced 2026-10-31 02:52:27 +08:00
news:合并2.0商业版代码:完整模块
版本更新汇总 (2025-08-10 至 2025-09-23) 核心功能优化: - 新增UDP模块并默认开启,TCP基础上增加UDP适配 - 支持网关绑定多产品子设备,优化设备重连机制 - 新增Ezviz(萤石)接入模块,调整imoulife支持自有平台账号 性能与稳定性: - 优化设备影子热数据存储,增加强制刷盘功能 - 产品列表及MQTT查询增加多级缓存策略 - 强化TCP安全机制,新增异常攻击封禁策略 功能完善: - 集成rulego可视化规则引擎基础框架 - Web-IDE新增20+ modbus/hex封装方法 - 优化乐城播放器界面及TCP连接信息展示 问题修复: - 解决系统间强依赖及注入相关问题 - 修复时间格式化、设备创建时间显示问题 - 完善日志处理及应用推送相关异常 其他改进: - 重构TCP粘包处理,删除冗余代码 - 增加Docker部署配置 - 细化权限控制策略
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
package cn.universal.admin.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 连接配置管理
|
||||
* 复用现有配置,减少重复配置项
|
||||
*/
|
||||
@Data
|
||||
@Component
|
||||
public class ConnectionConfig {
|
||||
|
||||
// TCP配置 - 复用现有配置
|
||||
@Value("${tcp.protocol.sni.host.out:#productKey.tcp.nexiot.xyz}")
|
||||
private String tcpSniHostTemplate;
|
||||
|
||||
@Value("${tcp.protocol.sni.port.out:38883}")
|
||||
private Integer tcpSniPort;
|
||||
|
||||
@Value("${connection.tcp.connection-type:TLS SNI方式}")
|
||||
private String tcpConnectionType;
|
||||
|
||||
@Value("${connection.tcp.description:}")
|
||||
private String tcpDescription;
|
||||
|
||||
// MQTT配置 - 复用现有配置
|
||||
@Value("${mqtt.cfg.host.out:tcp://localhost:1883}")
|
||||
private String mqttHostOut;
|
||||
|
||||
@Value("${mqtt.cfg.host:tcp://localhost:1883}")
|
||||
private String mqttHost;
|
||||
|
||||
@Value("${mqtt.cfg.clientIdPrefix:univ_iot_test}")
|
||||
private String mqttClientIdPrefix;
|
||||
|
||||
@Value("${connection.mqtt.connection-type:内置MQTT Broker}")
|
||||
private String mqttConnectionType;
|
||||
|
||||
@Value("${connection.mqtt.description:}")
|
||||
private String mqttDescription;
|
||||
|
||||
// MQTT主题配置 - 直接在代码中定义默认值,避免Spring占位符解析问题
|
||||
@Value("${connection.mqtt.default-topics.thing-topics.property-up:}")
|
||||
private String mqttThingPropertyUp;
|
||||
|
||||
@Value("${connection.mqtt.default-topics.thing-topics.event-up:}")
|
||||
private String mqttThingEventUp;
|
||||
|
||||
@Value("${connection.mqtt.default-topics.thing-topics.command-down:}")
|
||||
private String mqttThingCommandDown;
|
||||
|
||||
@Value("${connection.mqtt.default-topics.passthrough-topics.data-up:}")
|
||||
private String mqttPassthroughDataUp;
|
||||
|
||||
@Value("${connection.mqtt.default-topics.passthrough-topics.command-down:}")
|
||||
private String mqttPassthroughCommandDown;
|
||||
|
||||
// 默认主题模板常量
|
||||
private static final String DEFAULT_THING_PROPERTY_UP = "$thing/up/property/{productKey}/{deviceId}";
|
||||
private static final String DEFAULT_THING_EVENT_UP = "$thing/up/event/{productKey}/{deviceId}";
|
||||
private static final String DEFAULT_THING_COMMAND_DOWN = "$thing/down/{productKey}/{deviceId}";
|
||||
private static final String DEFAULT_PASSTHROUGH_DATA_UP = "$thing/up/{productKey}/{deviceId}";
|
||||
private static final String DEFAULT_PASSTHROUGH_COMMAND_DOWN = "$thing/down/{productKey}/{deviceId}";
|
||||
|
||||
// UDP配置
|
||||
@Value("${connection.udp.connection-type:}")
|
||||
private String udpConnectionType;
|
||||
|
||||
@Value("${connection.udp.description:}")
|
||||
private String udpDescription;
|
||||
|
||||
@Value("${udp.cfg.port:1884}")
|
||||
private Integer udpPort;
|
||||
|
||||
/**
|
||||
* 获取TCP主机地址
|
||||
*/
|
||||
public String getTcpHost(String productKey) {
|
||||
return tcpSniHostTemplate.replace("#productKey", productKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取MQTT主机地址(优先使用外部配置)
|
||||
*/
|
||||
public String getMqttHost() {
|
||||
return mqttHostOut != null && !mqttHostOut.isEmpty() ? mqttHostOut : mqttHost;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从主机地址中提取端口
|
||||
*/
|
||||
public Integer extractPortFromHost(String host) {
|
||||
if (host == null || host.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (host.contains(":")) {
|
||||
String[] parts = host.split(":");
|
||||
if (parts.length >= 2) {
|
||||
try {
|
||||
return Integer.parseInt(parts[parts.length - 1]);
|
||||
} catch (NumberFormatException e) {
|
||||
// 忽略解析错误
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取MQTT物模型属性上报主题
|
||||
*/
|
||||
public String getMqttThingPropertyUp() {
|
||||
return mqttThingPropertyUp.isEmpty() ? DEFAULT_THING_PROPERTY_UP : mqttThingPropertyUp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取MQTT物模型事件上报主题
|
||||
*/
|
||||
public String getMqttThingEventUp() {
|
||||
return mqttThingEventUp.isEmpty() ? DEFAULT_THING_EVENT_UP : mqttThingEventUp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取MQTT物模型指令下发主题
|
||||
*/
|
||||
public String getMqttThingCommandDown() {
|
||||
return mqttThingCommandDown.isEmpty() ? DEFAULT_THING_COMMAND_DOWN : mqttThingCommandDown;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取MQTT透传数据上报主题
|
||||
*/
|
||||
public String getMqttPassthroughDataUp() {
|
||||
return mqttPassthroughDataUp.isEmpty() ? DEFAULT_PASSTHROUGH_DATA_UP : mqttPassthroughDataUp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取MQTT透传指令下发主题
|
||||
*/
|
||||
public String getMqttPassthroughCommandDown() {
|
||||
return mqttPassthroughCommandDown.isEmpty() ? DEFAULT_PASSTHROUGH_COMMAND_DOWN : mqttPassthroughCommandDown;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package cn.universal.admin.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 安全配置
|
||||
* 管理敏感字段的加密密钥
|
||||
*/
|
||||
@Data
|
||||
@Component
|
||||
public class SecurityConfig {
|
||||
|
||||
/**
|
||||
* 产品密钥加密密钥
|
||||
* 建议在生产环境中使用环境变量或配置中心
|
||||
*/
|
||||
@Value("${security.product-secret.key:cn-universal-product-secret-key-2024}")
|
||||
private String productSecretKey;
|
||||
|
||||
/**
|
||||
* 是否启用敏感字段加密
|
||||
*/
|
||||
@Value("${security.sensitive-field.enabled:true}")
|
||||
private Boolean sensitiveFieldEnabled;
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
package cn.universal.admin.platform.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/** 连接信息数据传输对象 */
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ConnectionInfoDTO {
|
||||
|
||||
/** 内置连接信息 */
|
||||
private BuiltinConnection builtin;
|
||||
|
||||
/** 网络组件连接信息 */
|
||||
private NetworkConnection network;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class BuiltinConnection {
|
||||
/** 连接方式 */
|
||||
private String connectionType;
|
||||
|
||||
/** 连接地址 */
|
||||
private String host;
|
||||
|
||||
/** 端口 */
|
||||
private Integer port;
|
||||
|
||||
/** 用户名 */
|
||||
private String username;
|
||||
|
||||
/** 密码(默认不显示,需要点击查看) */
|
||||
private String password;
|
||||
|
||||
/** 配置说明 */
|
||||
private String description;
|
||||
|
||||
/** MQTT主题信息(仅MQTT类型有) */
|
||||
private TopicInfo topics;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class NetworkConnection {
|
||||
/** 是否启用网络组件 */
|
||||
private Boolean enabled;
|
||||
|
||||
/** 组件名称 */
|
||||
private String name;
|
||||
|
||||
/** 组件类型 */
|
||||
private String type;
|
||||
|
||||
/** 连接地址 */
|
||||
private String host;
|
||||
|
||||
/** 端口 */
|
||||
private Integer port;
|
||||
|
||||
/** 用户名 */
|
||||
private String username;
|
||||
|
||||
/** 密码(默认不显示,需要点击查看) */
|
||||
private String password;
|
||||
|
||||
/** 运行状态 */
|
||||
private Boolean state;
|
||||
|
||||
/** 订阅主题信息 */
|
||||
private TopicInfo subscribeTopics;
|
||||
|
||||
/** 错误信息(当enabled为false时) */
|
||||
private String message;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class TopicInfo {
|
||||
/** 物模型主题 */
|
||||
private ThingTopics thingTopics;
|
||||
|
||||
/** 透传主题 */
|
||||
private PassthroughTopics passthroughTopics;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class ThingTopics {
|
||||
private String propertyUp;
|
||||
private String eventUp;
|
||||
private String commandDown;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class PassthroughTopics {
|
||||
private String dataUp;
|
||||
private String commandDown;
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package cn.universal.admin.platform.service;
|
||||
|
||||
import cn.universal.admin.platform.dto.ConnectionInfoDTO;
|
||||
|
||||
/**
|
||||
* 连接信息服务接口
|
||||
*/
|
||||
public interface ConnectionInfoService {
|
||||
|
||||
/**
|
||||
* 获取产品的连接信息
|
||||
* @param productKey 产品Key
|
||||
* @return 连接信息
|
||||
*/
|
||||
ConnectionInfoDTO getConnectionInfo(String productKey);
|
||||
|
||||
/**
|
||||
* 获取产品的MQTT密码信息
|
||||
* @param productKey 产品Key
|
||||
* @return 密码信息
|
||||
*/
|
||||
ConnectionInfoDTO getMqttPasswordInfo(String productKey);
|
||||
}
|
||||
+272
@@ -0,0 +1,272 @@
|
||||
package cn.universal.admin.platform.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.universal.admin.config.ConnectionConfig;
|
||||
import cn.universal.admin.platform.dto.ConnectionInfoDTO;
|
||||
import cn.universal.admin.platform.service.ConnectionInfoService;
|
||||
import cn.universal.persistence.entity.IoTProduct;
|
||||
import cn.universal.persistence.entity.Network;
|
||||
import cn.universal.persistence.mapper.IoTProductMapper;
|
||||
import cn.universal.persistence.mapper.NetworkMapper;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/** 连接信息服务实现 */
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ConnectionInfoServiceImpl implements ConnectionInfoService {
|
||||
|
||||
private final IoTProductMapper productMapper;
|
||||
private final NetworkMapper networkMapper;
|
||||
private final ConnectionConfig connectionConfig;
|
||||
|
||||
@Override
|
||||
public ConnectionInfoDTO getConnectionInfo(String productKey) {
|
||||
log.debug("获取产品连接信息: productKey={}", productKey);
|
||||
|
||||
// 查询产品信息
|
||||
IoTProduct product = productMapper.getProductByProductKey(productKey);
|
||||
if (product == null) {
|
||||
throw new RuntimeException("产品不存在: " + productKey);
|
||||
}
|
||||
|
||||
// 构建内置连接信息
|
||||
ConnectionInfoDTO.BuiltinConnection builtin = buildBuiltinConnection(product);
|
||||
|
||||
// 构建网络组件连接信息
|
||||
ConnectionInfoDTO.NetworkConnection network = buildNetworkConnection(product);
|
||||
|
||||
return ConnectionInfoDTO.builder().builtin(builtin).network(network).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionInfoDTO getMqttPasswordInfo(String productKey) {
|
||||
log.debug("获取产品MQTT密码信息: productKey={}", productKey);
|
||||
|
||||
// 查询产品信息
|
||||
IoTProduct product = productMapper.getProductByProductKey(productKey);
|
||||
if (product == null) {
|
||||
throw new RuntimeException("产品不存在: " + productKey);
|
||||
}
|
||||
|
||||
// 构建内置MQTT密码信息
|
||||
ConnectionInfoDTO.BuiltinConnection builtin = buildBuiltinMqttPassword(product);
|
||||
|
||||
// 构建网络组件MQTT密码信息
|
||||
ConnectionInfoDTO.NetworkConnection network = buildNetworkMqttPassword(product);
|
||||
|
||||
return ConnectionInfoDTO.builder().builtin(builtin).network(network).build();
|
||||
}
|
||||
|
||||
/** 构建内置连接信息 */
|
||||
private ConnectionInfoDTO.BuiltinConnection buildBuiltinConnection(IoTProduct product) {
|
||||
String platform = product.getThirdPlatform();
|
||||
|
||||
ConnectionInfoDTO.BuiltinConnection.BuiltinConnectionBuilder builder =
|
||||
ConnectionInfoDTO.BuiltinConnection.builder();
|
||||
|
||||
switch (platform) {
|
||||
case "tcp":
|
||||
return builder
|
||||
.connectionType(connectionConfig.getTcpConnectionType())
|
||||
.host(connectionConfig.getTcpHost(product.getProductKey()))
|
||||
.port(connectionConfig.getTcpSniPort())
|
||||
.description(connectionConfig.getTcpDescription())
|
||||
.build();
|
||||
|
||||
case "mqtt":
|
||||
ConnectionInfoDTO.BuiltinConnection builtinMqtt =
|
||||
builder
|
||||
.connectionType(connectionConfig.getMqttConnectionType())
|
||||
.host(connectionConfig.getMqttHost())
|
||||
.port(connectionConfig.extractPortFromHost(connectionConfig.getMqttHost()))
|
||||
.username(product.getProductKey())
|
||||
.password("点击查看密码")
|
||||
.description(connectionConfig.getMqttDescription())
|
||||
.topics(buildDefaultTopics(product.getProductKey()))
|
||||
.build();
|
||||
return builtinMqtt;
|
||||
|
||||
case "udp":
|
||||
return builder
|
||||
.connectionType(connectionConfig.getUdpConnectionType())
|
||||
.host(connectionConfig.getTcpHost(product.getProductKey()))
|
||||
.port(connectionConfig.getUdpPort())
|
||||
.description(connectionConfig.getUdpDescription())
|
||||
.build();
|
||||
default:
|
||||
return builder
|
||||
.connectionType("请联系管理员")
|
||||
.host("请联系管理员")
|
||||
.port(0)
|
||||
.description("暂无")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** 构建网络组件连接信息 */
|
||||
private ConnectionInfoDTO.NetworkConnection buildNetworkConnection(IoTProduct product) {
|
||||
if (StrUtil.isBlank(product.getNetworkUnionId())) {
|
||||
return ConnectionInfoDTO.NetworkConnection.builder()
|
||||
.enabled(false)
|
||||
.message("未绑定网络组件")
|
||||
.build();
|
||||
}
|
||||
|
||||
// 查询网络组件
|
||||
List<Network> networks = networkMapper.selectByUnionId(product.getNetworkUnionId());
|
||||
if (networks.isEmpty()) {
|
||||
return ConnectionInfoDTO.NetworkConnection.builder()
|
||||
.enabled(false)
|
||||
.message("绑定的网络组件不存在")
|
||||
.build();
|
||||
}
|
||||
|
||||
Network network = networks.get(0);
|
||||
JSONObject config = JSONUtil.parseObj(network.getConfiguration());
|
||||
|
||||
ConnectionInfoDTO.NetworkConnection.NetworkConnectionBuilder builder =
|
||||
ConnectionInfoDTO.NetworkConnection.builder()
|
||||
.enabled(true)
|
||||
.name(network.getName())
|
||||
.type(network.getType())
|
||||
.state(network.getState())
|
||||
.host(config.getStr("host"))
|
||||
.port(config.getInt("port"))
|
||||
.username(config.getStr("username"))
|
||||
.password("点击查看密码");
|
||||
|
||||
// 处理MQTT主题信息
|
||||
if ("mqtt".equals(product.getThirdPlatform())) {
|
||||
ConnectionInfoDTO.TopicInfo subscribeTopics =
|
||||
buildSubscribeTopics(config, product.getProductKey());
|
||||
builder.subscribeTopics(subscribeTopics);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/** 构建内置MQTT密码信息 */
|
||||
private ConnectionInfoDTO.BuiltinConnection buildBuiltinMqttPassword(IoTProduct product) {
|
||||
if (!"mqtt".equals(product.getThirdPlatform())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return ConnectionInfoDTO.BuiltinConnection.builder()
|
||||
.connectionType(connectionConfig.getMqttConnectionType())
|
||||
.host(connectionConfig.getMqttHost())
|
||||
.port(connectionConfig.extractPortFromHost(connectionConfig.getMqttHost()))
|
||||
.username(product.getProductKey())
|
||||
.password(product.getProductSecret())
|
||||
.description(connectionConfig.getMqttDescription())
|
||||
.build();
|
||||
}
|
||||
|
||||
/** 构建网络组件MQTT密码信息 */
|
||||
private ConnectionInfoDTO.NetworkConnection buildNetworkMqttPassword(IoTProduct product) {
|
||||
if (StrUtil.isBlank(product.getNetworkUnionId())) {
|
||||
return ConnectionInfoDTO.NetworkConnection.builder()
|
||||
.enabled(false)
|
||||
.message("未绑定网络组件")
|
||||
.build();
|
||||
}
|
||||
|
||||
List<Network> networks = networkMapper.selectByUnionId(product.getNetworkUnionId());
|
||||
if (networks.isEmpty()) {
|
||||
return ConnectionInfoDTO.NetworkConnection.builder()
|
||||
.enabled(false)
|
||||
.message("绑定的网络组件不存在")
|
||||
.build();
|
||||
}
|
||||
|
||||
Network network = networks.get(0);
|
||||
JSONObject config = JSONUtil.parseObj(network.getConfiguration());
|
||||
|
||||
return ConnectionInfoDTO.NetworkConnection.builder()
|
||||
.enabled(true)
|
||||
.name(network.getName())
|
||||
.type(network.getType())
|
||||
.host(config.getStr("host"))
|
||||
.port(config.getInt("port"))
|
||||
.username(config.getStr("username"))
|
||||
.password(config.getStr("password"))
|
||||
.build();
|
||||
}
|
||||
|
||||
/** 构建默认主题信息 */
|
||||
private ConnectionInfoDTO.TopicInfo buildDefaultTopics(String productKey) {
|
||||
ConnectionInfoDTO.ThingTopics thingTopics =
|
||||
ConnectionInfoDTO.ThingTopics.builder()
|
||||
.propertyUp(replaceProductKey(connectionConfig.getMqttThingPropertyUp(), productKey))
|
||||
.eventUp(replaceProductKey(connectionConfig.getMqttThingEventUp(), productKey))
|
||||
.commandDown(replaceProductKey(connectionConfig.getMqttThingCommandDown(), productKey))
|
||||
.build();
|
||||
|
||||
ConnectionInfoDTO.PassthroughTopics passthroughTopics =
|
||||
ConnectionInfoDTO.PassthroughTopics.builder()
|
||||
.dataUp(replaceProductKey(connectionConfig.getMqttPassthroughDataUp(), productKey))
|
||||
.commandDown(
|
||||
replaceProductKey(connectionConfig.getMqttPassthroughCommandDown(), productKey))
|
||||
.build();
|
||||
|
||||
return ConnectionInfoDTO.TopicInfo.builder()
|
||||
.thingTopics(thingTopics)
|
||||
.passthroughTopics(passthroughTopics)
|
||||
.build();
|
||||
}
|
||||
|
||||
/** 构建订阅主题信息 */
|
||||
private ConnectionInfoDTO.TopicInfo buildSubscribeTopics(JSONObject config, String productKey) {
|
||||
JSONObject subscribeTopics = config.getJSONObject("subscribeTopics");
|
||||
|
||||
if (subscribeTopics == null || subscribeTopics.isEmpty()) {
|
||||
// 使用默认主题
|
||||
return buildDefaultTopics(productKey);
|
||||
}
|
||||
|
||||
ConnectionInfoDTO.ThingTopics thingTopics = null;
|
||||
ConnectionInfoDTO.PassthroughTopics passthroughTopics = null;
|
||||
|
||||
JSONObject thingTopicsConfig = subscribeTopics.getJSONObject("thingTopics");
|
||||
if (thingTopicsConfig != null) {
|
||||
thingTopics =
|
||||
ConnectionInfoDTO.ThingTopics.builder()
|
||||
.propertyUp(thingTopicsConfig.getStr("propertyUp"))
|
||||
.eventUp(thingTopicsConfig.getStr("eventUp"))
|
||||
.commandDown(thingTopicsConfig.getStr("commandDown"))
|
||||
.build();
|
||||
}
|
||||
|
||||
JSONObject passthroughTopicsConfig = subscribeTopics.getJSONObject("passthroughTopics");
|
||||
if (passthroughTopicsConfig != null) {
|
||||
passthroughTopics =
|
||||
ConnectionInfoDTO.PassthroughTopics.builder()
|
||||
.dataUp(passthroughTopicsConfig.getStr("dataUp"))
|
||||
.commandDown(passthroughTopicsConfig.getStr("commandDown"))
|
||||
.build();
|
||||
}
|
||||
|
||||
return ConnectionInfoDTO.TopicInfo.builder()
|
||||
.thingTopics(thingTopics)
|
||||
.passthroughTopics(passthroughTopics)
|
||||
.build();
|
||||
}
|
||||
|
||||
/** 替换主题中的产品Key占位符 */
|
||||
private String replaceProductKey(String topic, String productKey) {
|
||||
if (StrUtil.isBlank(topic)) {
|
||||
return topic;
|
||||
}
|
||||
// 支持两种格式:{productKey} 和 ${productKey}
|
||||
return topic
|
||||
.replace("{productKey}", productKey)
|
||||
.replace("${productKey}", productKey)
|
||||
.replace("{deviceId}", "${deviceId}")
|
||||
.replace("${deviceId}", "${deviceId}");
|
||||
}
|
||||
}
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
package cn.universal.admin.system.notice;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.universal.admin.common.utils.SecurityUtils;
|
||||
import cn.universal.admin.system.web.BaseController;
|
||||
import cn.universal.manager.notice.dto.NoticeChannelDTO;
|
||||
import cn.universal.manager.notice.model.NoticeChannel;
|
||||
import cn.universal.manager.notice.service.NoticeChannelService;
|
||||
import cn.universal.manager.notice.util.JsonDesensitizationUtil;
|
||||
import cn.universal.persistence.page.TableDataInfo;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/v1/notice/channel")
|
||||
public class NoticeChannelController extends BaseController {
|
||||
|
||||
private final NoticeChannelService noticeChannelService;
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
@Autowired
|
||||
public NoticeChannelController(
|
||||
NoticeChannelService noticeChannelService, ObjectMapper objectMapper) {
|
||||
this.noticeChannelService = noticeChannelService;
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<NoticeChannelDTO> list(
|
||||
@RequestParam(defaultValue = "1") Integer pageNum,
|
||||
@RequestParam(defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(required = false) String name,
|
||||
@RequestParam(required = false) String channelType) {
|
||||
startPage();
|
||||
List<NoticeChannel> list = noticeChannelService.search(name, channelType, null);
|
||||
|
||||
List<NoticeChannelDTO> dtoList =
|
||||
list.stream()
|
||||
.map(
|
||||
channel -> {
|
||||
NoticeChannelDTO dto = new NoticeChannelDTO();
|
||||
dto.setId(channel.getId());
|
||||
dto.setName(channel.getName());
|
||||
dto.setChannelType(channel.getChannelType());
|
||||
dto.setStatus(channel.getStatus());
|
||||
dto.setRemark(channel.getRemark());
|
||||
dto.setCreator(channel.getCreator());
|
||||
dto.setCreateTime(channel.getCreateTime());
|
||||
dto.setUpdateTime(channel.getUpdateTime());
|
||||
|
||||
// 将config字符串转换为对象并进行脱敏处理
|
||||
if (channel.getConfig() != null && !channel.getConfig().isEmpty()) {
|
||||
try {
|
||||
JSONObject desensitizedConfig =
|
||||
JsonDesensitizationUtil.desensitize(channel.getConfig());
|
||||
dto.setConfig(desensitizedConfig);
|
||||
} catch (Exception e) {
|
||||
dto.setConfig(null);
|
||||
}
|
||||
}
|
||||
|
||||
return dto;
|
||||
})
|
||||
.toList();
|
||||
|
||||
return getDataTable(dtoList);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
public NoticeChannelDTO get(@RequestParam Long id) {
|
||||
try {
|
||||
NoticeChannel channel = noticeChannelService.getById(id);
|
||||
if (channel == null) {
|
||||
return null;
|
||||
}
|
||||
NoticeChannelDTO dto = new NoticeChannelDTO();
|
||||
dto.setId(channel.getId());
|
||||
dto.setName(channel.getName());
|
||||
dto.setChannelType(channel.getChannelType());
|
||||
dto.setStatus(channel.getStatus());
|
||||
dto.setRemark(channel.getRemark());
|
||||
dto.setCreator(channel.getCreator());
|
||||
dto.setCreateTime(channel.getCreateTime());
|
||||
dto.setUpdateTime(channel.getUpdateTime());
|
||||
|
||||
// 将config字符串转换为对象并进行脱敏处理
|
||||
if (channel.getConfig() != null && !channel.getConfig().isEmpty()) {
|
||||
JSONObject desensitizedConfig = JsonDesensitizationUtil.desensitize(channel.getConfig());
|
||||
dto.setConfig(desensitizedConfig);
|
||||
}
|
||||
|
||||
return dto;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/save")
|
||||
public Map<String, Object> save(@RequestBody NoticeChannelDTO channelDTO) {
|
||||
try {
|
||||
NoticeChannel channel = new NoticeChannel();
|
||||
channel.setId(channelDTO.getId());
|
||||
channel.setName(channelDTO.getName());
|
||||
channel.setChannelType(channelDTO.getChannelType());
|
||||
channel.setStatus(channelDTO.getStatus());
|
||||
channel.setRemark(channelDTO.getRemark());
|
||||
channel.setCreator(SecurityUtils.getUnionId());
|
||||
channel.setCreateTime(channelDTO.getCreateTime());
|
||||
channel.setUpdateTime(channelDTO.getUpdateTime());
|
||||
// 将config对象转换为JSON字符串
|
||||
if (channelDTO.getConfig() != null) {
|
||||
channel.setConfig(objectMapper.writeValueAsString(channelDTO.getConfig()));
|
||||
}
|
||||
|
||||
noticeChannelService.save(channel);
|
||||
return Map.of("code", 0, "msg", "操作成功");
|
||||
} catch (Exception e) {
|
||||
return Map.of("code", 1, "msg", "操作失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public Map<String, Object> delete(@RequestBody List<Long> ids) {
|
||||
try {
|
||||
if (ids != null && !ids.isEmpty()) {
|
||||
noticeChannelService.deleteBatch(ids);
|
||||
return Map.of("code", 0, "msg", "删除成功");
|
||||
} else {
|
||||
return Map.of("code", 1, "msg", "未提供有效的ID");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return Map.of("code", 1, "msg", "删除失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package cn.universal.admin.system.notice;
|
||||
|
||||
import cn.universal.admin.system.web.BaseController;
|
||||
import cn.universal.manager.notice.model.NoticeSendRecord;
|
||||
import cn.universal.manager.notice.service.NoticeRecordService;
|
||||
import cn.universal.persistence.page.TableDataInfo;
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/** 通知记录 */
|
||||
@RestController
|
||||
@RequestMapping("/admin/v1/notice/record")
|
||||
public class NoticeRecordController extends BaseController {
|
||||
|
||||
private final NoticeRecordService recordService;
|
||||
|
||||
@Autowired
|
||||
public NoticeRecordController(NoticeRecordService recordService) {
|
||||
this.recordService = recordService;
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
public TableDataInfo<NoticeSendRecord> page(
|
||||
@RequestParam(required = false) String keyword,
|
||||
@RequestParam(required = false) String type,
|
||||
@RequestParam(required = false) String status) {
|
||||
startPage();
|
||||
List<NoticeSendRecord> list = recordService.search(keyword, type, status);
|
||||
return getDataTable(list);
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package cn.universal.admin.system.notice;
|
||||
|
||||
import cn.universal.manager.notice.model.NoticeSendRequest;
|
||||
import cn.universal.manager.notice.service.NoticeService;
|
||||
import java.util.Map;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/** 通知发送 */
|
||||
@RestController
|
||||
@RequestMapping("/admin/v1/notice")
|
||||
public class NoticeSendController {
|
||||
|
||||
private final NoticeService noticeService;
|
||||
|
||||
@Autowired
|
||||
public NoticeSendController(NoticeService noticeService) {
|
||||
this.noticeService = noticeService;
|
||||
}
|
||||
|
||||
@PostMapping("/send")
|
||||
public Map<String, Object> send(@RequestBody Map<String, Object> request) {
|
||||
Long templateId = Long.valueOf(request.get("templateId").toString());
|
||||
String receivers = (String) request.get("receivers");
|
||||
Object params = request.get("params");
|
||||
|
||||
if (templateId == null) {
|
||||
throw new IllegalArgumentException("模板ID不能为空");
|
||||
}
|
||||
|
||||
NoticeSendRequest req = new NoticeSendRequest();
|
||||
req.setTemplateId(templateId);
|
||||
req.setReceivers(receivers);
|
||||
if (params instanceof Map) {
|
||||
req.setParams((Map<String, Object>) params);
|
||||
}
|
||||
noticeService.send(req);
|
||||
|
||||
return Map.of("code", 0, "msg", "发送成功");
|
||||
}
|
||||
}
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
package cn.universal.admin.system.notice;
|
||||
|
||||
import cn.universal.admin.common.utils.SecurityUtils;
|
||||
import cn.universal.admin.system.web.BaseController;
|
||||
import cn.universal.manager.notice.dto.NoticeTemplateDTO;
|
||||
import cn.universal.manager.notice.model.NoticeTemplate;
|
||||
import cn.universal.manager.notice.service.NoticeTemplateService;
|
||||
import cn.universal.persistence.page.TableDataInfo;
|
||||
import cn.universal.persistence.query.AjaxResult;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/v1/notice/template")
|
||||
public class NoticeTemplateController extends BaseController {
|
||||
|
||||
private final NoticeTemplateService noticeTemplateService;
|
||||
|
||||
@Autowired
|
||||
public NoticeTemplateController(NoticeTemplateService noticeTemplateService) {
|
||||
this.noticeTemplateService = noticeTemplateService;
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<NoticeTemplateDTO> list(
|
||||
@RequestParam(defaultValue = "1") Integer pageNum,
|
||||
@RequestParam(defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(required = false) String name,
|
||||
@RequestParam(required = false) String channelType) {
|
||||
startPage();
|
||||
List<NoticeTemplate> list = noticeTemplateService.search(name, channelType, null);
|
||||
|
||||
List<NoticeTemplateDTO> dtoList =
|
||||
list.stream()
|
||||
.map(
|
||||
template -> {
|
||||
NoticeTemplateDTO dto = new NoticeTemplateDTO();
|
||||
dto.setId(template.getId());
|
||||
dto.setName(template.getName());
|
||||
dto.setChannelType(template.getChannelType());
|
||||
dto.setChannelId(template.getChannelId());
|
||||
dto.setContent(template.getContent());
|
||||
dto.setReceivers(template.getReceivers());
|
||||
dto.setStatus(template.getStatus());
|
||||
dto.setRemark(template.getRemark());
|
||||
dto.setCreator(template.getCreator());
|
||||
dto.setCreateTime(template.getCreateTime());
|
||||
dto.setUpdateTime(template.getUpdateTime());
|
||||
|
||||
return dto;
|
||||
})
|
||||
.toList();
|
||||
return getDataTable(dtoList);
|
||||
}
|
||||
|
||||
@PostMapping("/save")
|
||||
public AjaxResult save(@RequestBody NoticeTemplateDTO templateDTO) {
|
||||
try {
|
||||
NoticeTemplate template = new NoticeTemplate();
|
||||
template.setId(templateDTO.getId());
|
||||
template.setName(templateDTO.getName());
|
||||
template.setChannelType(templateDTO.getChannelType());
|
||||
template.setChannelId(templateDTO.getChannelId());
|
||||
template.setContent(templateDTO.getContent());
|
||||
template.setReceivers(templateDTO.getReceivers());
|
||||
template.setStatus(templateDTO.getStatus());
|
||||
template.setRemark(templateDTO.getRemark());
|
||||
template.setCreator(SecurityUtils.getUnionId());
|
||||
template.setCreateTime(templateDTO.getCreateTime());
|
||||
template.setUpdateTime(templateDTO.getUpdateTime());
|
||||
|
||||
noticeTemplateService.save(template);
|
||||
return AjaxResult.success("操作成功");
|
||||
} catch (Exception e) {
|
||||
return AjaxResult.error("操作失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public AjaxResult delete(@RequestBody List<Long> ids) {
|
||||
try {
|
||||
if (ids != null && !ids.isEmpty()) {
|
||||
noticeTemplateService.deleteBatch(ids);
|
||||
return AjaxResult.success("删除成功");
|
||||
} else {
|
||||
return AjaxResult.success("未提供有效的ID");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return AjaxResult.success("删除失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/** 批量启用通知模板 */
|
||||
@PostMapping("/enable")
|
||||
public AjaxResult enable(@RequestBody List<Long> ids) {
|
||||
try {
|
||||
if (ids != null && !ids.isEmpty()) {
|
||||
noticeTemplateService.enableBatch(ids);
|
||||
return AjaxResult.success("启用成功");
|
||||
} else {
|
||||
return AjaxResult.success("未提供有效的ID");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return AjaxResult.error("启用失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/** 批量停用通知模板 */
|
||||
@PostMapping("/disable")
|
||||
public AjaxResult disable(@RequestBody List<Long> ids) {
|
||||
try {
|
||||
if (ids != null && !ids.isEmpty()) {
|
||||
noticeTemplateService.disableBatch(ids);
|
||||
return AjaxResult.success("停用成功");
|
||||
} else {
|
||||
return AjaxResult.success("未提供有效的ID");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return AjaxResult.error("停用失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
public NoticeTemplateDTO get(@RequestParam Long id) {
|
||||
try {
|
||||
NoticeTemplate template = noticeTemplateService.getById(id);
|
||||
if (template == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
NoticeTemplateDTO dto = new NoticeTemplateDTO();
|
||||
dto.setId(template.getId());
|
||||
dto.setName(template.getName());
|
||||
dto.setChannelType(template.getChannelType());
|
||||
dto.setChannelId(template.getChannelId());
|
||||
dto.setContent(template.getContent());
|
||||
dto.setReceivers(template.getReceivers());
|
||||
dto.setStatus(template.getStatus());
|
||||
dto.setRemark(template.getRemark());
|
||||
dto.setCreator(template.getCreator());
|
||||
dto.setCreateTime(template.getCreateTime());
|
||||
dto.setUpdateTime(template.getUpdateTime());
|
||||
|
||||
return dto;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/test")
|
||||
public AjaxResult test(@RequestBody Map<String, Object> request) {
|
||||
Long templateId = Long.valueOf(request.get("templateId").toString());
|
||||
String receivers = (String) request.get("receivers");
|
||||
Object params = request.get("params");
|
||||
noticeTemplateService.testTemplate(templateId, receivers, params);
|
||||
return AjaxResult.success("成功");
|
||||
}
|
||||
}
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2025, IoT-Universal. All Rights Reserved.
|
||||
*
|
||||
* @Description: 本文件由 Aleo 开发并拥有版权,未经授权严禁擅自商用、复制或传播。
|
||||
* @Author: Aleo
|
||||
* @Email: wo8335224@gmail.com
|
||||
* @Wechat: outlookFil
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package cn.universal.admin.system.web;
|
||||
|
||||
import cn.universal.admin.common.annotation.Log;
|
||||
import cn.universal.admin.common.enums.BusinessType;
|
||||
import cn.universal.admin.common.utils.SecurityUtils;
|
||||
import cn.universal.persistence.entity.bo.RulegoChainBO;
|
||||
import cn.universal.persistence.entity.vo.RulegoChainVO;
|
||||
import cn.universal.persistence.page.TableDataInfo;
|
||||
import cn.universal.persistence.query.AjaxResult;
|
||||
import cn.universal.rule.rulego.service.RulegoChainService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* rulego规则链管理控制器
|
||||
*
|
||||
* @author Aleo
|
||||
* @since 2025/01/15
|
||||
*/
|
||||
@RestController
|
||||
@Tag(name = "rulego规则链管理", description = "rulego规则链管理")
|
||||
@RequestMapping("/admin/v1/rulego")
|
||||
public class RulegoChainController extends BaseController {
|
||||
|
||||
@Resource private RulegoChainService rulegoChainService;
|
||||
|
||||
@Operation(summary = "查询规则链列表")
|
||||
@GetMapping("/chain/list")
|
||||
public TableDataInfo<RulegoChainVO> pageList(RulegoChainBO bo) {
|
||||
bo.setCreatorId(loginIoTUnionUser(SecurityUtils.getUnionId()).getUnionId());
|
||||
startPage();
|
||||
return getDataTable(rulegoChainService.queryRulegoChainList(bo));
|
||||
}
|
||||
|
||||
@Operation(summary = "查询规则链详情")
|
||||
@GetMapping("/chain/{id}")
|
||||
public AjaxResult<RulegoChainVO> detail(@PathVariable @Parameter(description = "规则链ID") Long id) {
|
||||
String creatorId = loginIoTUnionUser(SecurityUtils.getUnionId()).getUnionId();
|
||||
RulegoChainVO rulegoChain = rulegoChainService.queryRulegoChainById(id, creatorId);
|
||||
return AjaxResult.success(rulegoChain);
|
||||
}
|
||||
|
||||
@Operation(summary = "根据rulegoId查询规则链详情")
|
||||
@GetMapping("/chain/detail")
|
||||
public AjaxResult<RulegoChainVO> detailByRulegoId(
|
||||
@RequestParam @Parameter(description = "rulego规则链ID") String rulegoId) {
|
||||
RulegoChainVO rulegoChain = rulegoChainService.queryRulegoChainByRulegoId(rulegoId);
|
||||
return AjaxResult.success(rulegoChain);
|
||||
}
|
||||
|
||||
@Operation(summary = "新增规则链")
|
||||
@PostMapping("/chain")
|
||||
@Log(title = "新增rulego规则链", businessType = BusinessType.INSERT)
|
||||
public AjaxResult<Long> addRulegoChain(@RequestBody RulegoChainBO bo) {
|
||||
bo.setCreatorId(loginIoTUnionUser(SecurityUtils.getUnionId()).getUnionId());
|
||||
bo.setCreatorName(loginIoTUnionUser(SecurityUtils.getUnionId()).getUsername());
|
||||
Long chainId = rulegoChainService.saveRulegoChain(bo);
|
||||
return AjaxResult.success(chainId);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新规则链")
|
||||
@PutMapping("/chain")
|
||||
@Log(title = "更新rulego规则链", businessType = BusinessType.UPDATE)
|
||||
public AjaxResult<Void> updateRulegoChain(@RequestBody RulegoChainBO bo) {
|
||||
bo.setCreatorId(loginIoTUnionUser(SecurityUtils.getUnionId()).getUnionId());
|
||||
boolean result = rulegoChainService.updateRulegoChain(bo);
|
||||
return result ? AjaxResult.success() : AjaxResult.error("更新失败");
|
||||
}
|
||||
|
||||
@Operation(summary = "删除规则链")
|
||||
@DeleteMapping("/chain/{id}")
|
||||
@Log(title = "删除rulego规则链", businessType = BusinessType.DELETE)
|
||||
public AjaxResult<Void> deleteRulegoChain(
|
||||
@PathVariable @Parameter(description = "规则链ID") Long id) {
|
||||
String creatorId = loginIoTUnionUser(SecurityUtils.getUnionId()).getUnionId();
|
||||
boolean result = rulegoChainService.deleteRulegoChain(id, creatorId);
|
||||
return result ? AjaxResult.success() : AjaxResult.error("删除失败");
|
||||
}
|
||||
|
||||
@Operation(summary = "部署规则链")
|
||||
@PostMapping("/chain/{id}/deploy")
|
||||
@Log(title = "部署rulego规则链", businessType = BusinessType.UPDATE)
|
||||
public AjaxResult<Void> deployRulegoChain(
|
||||
@PathVariable @Parameter(description = "规则链ID") Long id) {
|
||||
String creatorId = loginIoTUnionUser(SecurityUtils.getUnionId()).getUnionId();
|
||||
boolean result = rulegoChainService.deployRulegoChain(id, creatorId);
|
||||
return result ? AjaxResult.success() : AjaxResult.error("部署失败");
|
||||
}
|
||||
|
||||
@Operation(summary = "停止规则链")
|
||||
@PostMapping("/chain/{id}/stop")
|
||||
@Log(title = "停止rulego规则链", businessType = BusinessType.UPDATE)
|
||||
public AjaxResult<Void> stopRulegoChain(@PathVariable @Parameter(description = "规则链ID") Long id) {
|
||||
String creatorId = loginIoTUnionUser(SecurityUtils.getUnionId()).getUnionId();
|
||||
boolean result = rulegoChainService.stopRulegoChain(id, creatorId);
|
||||
return result ? AjaxResult.success() : AjaxResult.error("停止失败");
|
||||
}
|
||||
|
||||
@Operation(summary = "同步规则链DSL")
|
||||
@PostMapping("/chain/{id}/sync")
|
||||
@Log(title = "同步rulego规则链DSL", businessType = BusinessType.UPDATE)
|
||||
public AjaxResult<Void> syncRulegoChainDsl(
|
||||
@PathVariable @Parameter(description = "规则链ID") Long id) {
|
||||
String creatorId = loginIoTUnionUser(SecurityUtils.getUnionId()).getUnionId();
|
||||
RulegoChainVO rulegoChain = rulegoChainService.queryRulegoChainById(id, creatorId);
|
||||
boolean result = rulegoChainService.syncRulegoChainDsl(rulegoChain.getRulegoId());
|
||||
return result ? AjaxResult.success() : AjaxResult.error("同步失败");
|
||||
}
|
||||
|
||||
@Operation(summary = "获取设计器URL")
|
||||
@GetMapping("/chain/{id}/designer")
|
||||
public AjaxResult<String> getDesignerUrl(@PathVariable @Parameter(description = "规则链ID") Long id) {
|
||||
String creatorId = loginIoTUnionUser(SecurityUtils.getUnionId()).getUnionId();
|
||||
RulegoChainVO rulegoChain = rulegoChainService.queryRulegoChainById(id, creatorId);
|
||||
String designerUrl = rulegoChainService.getDesignerUrl(rulegoChain.getRulegoId());
|
||||
AjaxResult<String> result = new AjaxResult<>();
|
||||
result.setCode(0);
|
||||
result.setMsg("success");
|
||||
result.setData(designerUrl);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2025, IoT-Universal. All Rights Reserved.
|
||||
*
|
||||
* @Description: 本文件由 Aleo 开发并拥有版权,未经授权严禁擅自商用、复制或传播。
|
||||
* @Author: Aleo
|
||||
* @Email: wo8335224@gmail.com
|
||||
* @Wechat: outlookFil
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package cn.universal.common.constant;
|
||||
|
||||
/**
|
||||
* 摄像头操作命令枚举
|
||||
* 直接对应物模型函数名
|
||||
*
|
||||
* @version 1.0
|
||||
* @since 2025/1/15
|
||||
*/
|
||||
public enum CameraCommand {
|
||||
|
||||
// 摄像头相关物模型函数
|
||||
CAMERA_LIVE_STREAM("cameraLiveStream"),
|
||||
CAMERA_PLAYBACK("cameraPlayback"),
|
||||
CAMERA_SNAPSHOT("cameraSnapshot"),
|
||||
CAMERA_TURN("cameraTurn"),
|
||||
CAMERA_FLIP_SET("cameraFlipSet");
|
||||
|
||||
private final String functionName;
|
||||
|
||||
CameraCommand(String functionName) {
|
||||
this.functionName = functionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取物模型函数名
|
||||
*
|
||||
* @return 物模型函数名
|
||||
*/
|
||||
public String getFunctionName() {
|
||||
return functionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据物模型函数名获取对应的命令枚举
|
||||
*
|
||||
* @param functionName 物模型函数名
|
||||
* @return 对应的命令枚举,如果未找到返回null
|
||||
*/
|
||||
public static CameraCommand fromFunctionName(String functionName) {
|
||||
for (CameraCommand command : values()) {
|
||||
if (command.functionName.equals(functionName)) {
|
||||
return command;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package cn.universal.common.event.processer;
|
||||
|
||||
import cn.universal.common.event.EventMessage;
|
||||
|
||||
/**
|
||||
* UDP下行指令处理器接口
|
||||
*
|
||||
* @author Aleo
|
||||
* @version 1.0
|
||||
* @since 2025/1/9
|
||||
*/
|
||||
public interface UdpDownProcessor {
|
||||
|
||||
/**
|
||||
* 处理UDP下行指令事件
|
||||
*
|
||||
* @param message 事件消息字符串
|
||||
*/
|
||||
void handleUdpDownEvent(EventMessage message);
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2025, IoT-Universal. All Rights Reserved.
|
||||
*
|
||||
* @Description: 本文件由 Aleo 开发并拥有版权,未经授权严禁擅自商用、复制或传播。
|
||||
* @Author: Aleo
|
||||
* @Email: wo8335224@gmail.com
|
||||
* @Wechat: outlookFil
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package cn.universal.common.monitor;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.universal.common.utils.DingTalkUtil;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/** 网络监测单例 */
|
||||
@Slf4j
|
||||
public class NetworkMonitorSingleton {
|
||||
|
||||
private NetworkMonitorSingleton() {}
|
||||
|
||||
private static class SingleTonHolder {
|
||||
|
||||
private static NetworkMonitorSingleton INSTANCE = new NetworkMonitorSingleton();
|
||||
}
|
||||
|
||||
public static NetworkMonitorSingleton getInstance() {
|
||||
return SingleTonHolder.INSTANCE;
|
||||
}
|
||||
|
||||
private static volatile Map<String, Boolean> networkMap = new HashMap<>();
|
||||
|
||||
public static void freshConnectionStatus(String serverURI, Boolean status) {
|
||||
if (StrUtil.isBlank(serverURI)) {
|
||||
return;
|
||||
}
|
||||
boolean lastStatusNormal =
|
||||
!networkMap.containsKey(serverURI) || networkMap.get(serverURI).equals(Boolean.TRUE);
|
||||
if (lastStatusNormal && Boolean.FALSE.equals(status)) {
|
||||
DingTalkUtil.send("IoT Universal,[" + serverURI + "] 断开异常!");
|
||||
log.warn("[网络监控] 服务断开: serverURI={}, status={},请注意!", serverURI, status);
|
||||
}
|
||||
boolean lastStatusAbnormal =
|
||||
!networkMap.containsKey(serverURI) || networkMap.get(serverURI).equals(Boolean.FALSE);
|
||||
if (lastStatusAbnormal && Boolean.TRUE.equals(status)) {
|
||||
DingTalkUtil.send("IoT Universal,指标[" + serverURI + "] 状态正常!!!");
|
||||
}
|
||||
if (!networkMap.containsKey(serverURI)) {
|
||||
networkMap.put(serverURI, status);
|
||||
}
|
||||
if (!networkMap.get(serverURI).equals(status)) {
|
||||
networkMap.put(serverURI, status);
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeMosquittoServer(String serverId) {
|
||||
NetworkMonitorSingleton.networkMap.remove(serverId);
|
||||
}
|
||||
|
||||
public static Map<String, Boolean> getConnectionStatus() {
|
||||
return networkMap;
|
||||
}
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2025, IoT-Universal. All Rights Reserved.
|
||||
*
|
||||
* @Description: 本文件由 Aleo 开发并拥有版权,未经授权严禁擅自商用、复制或传播。
|
||||
* @Author: Aleo
|
||||
* @Email: wo8335224@gmail.com
|
||||
* @Wechat: outlookFil
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package cn.universal.common.utils;
|
||||
|
||||
import cn.hutool.core.codec.Base64;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class DingTalkUtil {
|
||||
|
||||
// @Value("${notice.dingTalk.dingTalk-addr}")
|
||||
private static final String token =
|
||||
"https://oapi.dingtalk.com/robot/send?access_token=f731085dd9ef094114794a0f5ff2cc09e017d18acea205415cc03039af472661";
|
||||
// @Value("${notice.dingTalk.dingTalk-secret}")
|
||||
private static final String secret =
|
||||
"SEC34946b12a19f67f32f0e7a1a42b1ca110f6c2ddb224214ce474e594b025efd1e";
|
||||
// @Value("${notice.dingTalk.sign}")
|
||||
private static final String mark = "platform Universal";
|
||||
private static Set<String> prodProfileActive =
|
||||
Stream.of("test","test2", "prod").collect(Collectors.toSet());
|
||||
|
||||
// 第三方调用失败钉钉通知
|
||||
public static void send(String msg) {
|
||||
String actProfiles = SpringUtil.getActiveProfile();
|
||||
if (StrUtil.isBlank(actProfiles) || !prodProfileActive.contains(actProfiles)) {
|
||||
log.warn("非正式环境,中止发送钉钉告警,msg={}", msg);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
String res = "";
|
||||
Long timestamp = System.currentTimeMillis();
|
||||
String stringToSign = timestamp + "\n" + secret;
|
||||
Mac mac = Mac.getInstance("HmacSHA256");
|
||||
mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));
|
||||
byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
|
||||
String sign = URLEncoder.encode(Base64.encode(signData), "UTF-8");
|
||||
String url = token + "×tamp=" + timestamp + "&sign=" + sign;
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
JSONObject text = new JSONObject();
|
||||
JSONObject at = new JSONObject();
|
||||
msg = mark + ":" + actProfiles + ":" + msg;
|
||||
jsonObject.set("msgtype", "text");
|
||||
text.set("content", msg);
|
||||
jsonObject.set("text", text);
|
||||
List<String> phone = new ArrayList<>();
|
||||
at.set("atMobiles", phone);
|
||||
jsonObject.set("at", at);
|
||||
String response = HttpUtil.post(url, JSONUtil.toJsonStr(jsonObject));
|
||||
JSONObject result = JSONUtil.parseObj(response);
|
||||
Integer errCode = result.getInt("errcode");
|
||||
if (errCode == 0) {
|
||||
res = "成功";
|
||||
} else {
|
||||
switch (errCode) {
|
||||
case -1:
|
||||
res = "系统繁忙";
|
||||
break;
|
||||
case 88:
|
||||
res = "鉴权异常";
|
||||
break;
|
||||
case 404:
|
||||
res = "请求的URI地址不存在";
|
||||
break;
|
||||
case 34015:
|
||||
res = "发送群会话消息失败";
|
||||
break;
|
||||
case 34016:
|
||||
res = "会话消息的内容超长";
|
||||
break;
|
||||
case 40001:
|
||||
res = "获取access_token时Secret错误,或者access_token无效";
|
||||
break;
|
||||
case 40002:
|
||||
res = "不合法的凭证类型";
|
||||
break;
|
||||
default:
|
||||
res = result.getStr("errmsg");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!"".equals(res) && !"成功".equals(res)) {
|
||||
log.error("钉钉系统监测推送失败,原因{}", res);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("钉钉调用异常:", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>cn-universal-framework</artifactId>
|
||||
<groupId>cn.universal.iot</groupId>
|
||||
<version>1.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>cn-universal-notice</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<!--阿里短信-->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>dysmsapi20170525</artifactId>
|
||||
<version>2.0.24</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>jaxb-impl</artifactId>
|
||||
<groupId>com.sun.xml.bind</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<groupId>org.slf4j</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<!--排除这个slf4j-log4j12-->
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<artifactId>cn-universal-core</artifactId>
|
||||
<groupId>cn.universal.iot</groupId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.universal.iot</groupId>
|
||||
<artifactId>cn-universal-persistence</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>2.0.57</version>
|
||||
</dependency>
|
||||
<!-- 腾讯云短信 -->
|
||||
<dependency>
|
||||
<groupId>com.tencentcloudapi</groupId>
|
||||
<artifactId>tencentcloud-sdk-java</artifactId>
|
||||
<version>3.1.822</version>
|
||||
</dependency>
|
||||
<!-- JavaMail -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
package cn.universal.manager.notice.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
public class NoticeChannelDTO implements Serializable {
|
||||
|
||||
private Long id;
|
||||
private String name;
|
||||
|
||||
@JsonProperty("channelType")
|
||||
private String channelType;
|
||||
|
||||
private Object config;
|
||||
private String status;
|
||||
private String remark;
|
||||
private String creator;
|
||||
|
||||
@JsonProperty("createTime")
|
||||
private Date createTime;
|
||||
|
||||
@JsonProperty("updateTime")
|
||||
private Date updateTime;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getChannelType() {
|
||||
return channelType;
|
||||
}
|
||||
|
||||
public void setChannelType(String channelType) {
|
||||
this.channelType = channelType;
|
||||
}
|
||||
|
||||
public Object getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public void setConfig(Object config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getRemark() {
|
||||
return remark;
|
||||
}
|
||||
|
||||
public void setRemark(String remark) {
|
||||
this.remark = remark;
|
||||
}
|
||||
|
||||
public String getCreator() {
|
||||
return creator;
|
||||
}
|
||||
|
||||
public void setCreator(String creator) {
|
||||
this.creator = creator;
|
||||
}
|
||||
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public Date getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(Date updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
package cn.universal.manager.notice.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
public class NoticeConfigDTO implements Serializable {
|
||||
|
||||
private Long id;
|
||||
private String name;
|
||||
private String type;
|
||||
private Object config;
|
||||
private String remark;
|
||||
private String creator;
|
||||
|
||||
@JsonProperty("createTime")
|
||||
private Date createTime;
|
||||
|
||||
@JsonProperty("updateTime")
|
||||
private Date updateTime;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Object getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public void setConfig(Object config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public String getRemark() {
|
||||
return remark;
|
||||
}
|
||||
|
||||
public void setRemark(String remark) {
|
||||
this.remark = remark;
|
||||
}
|
||||
|
||||
public String getCreator() {
|
||||
return creator;
|
||||
}
|
||||
|
||||
public void setCreator(String creator) {
|
||||
this.creator = creator;
|
||||
}
|
||||
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public Date getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(Date updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
package cn.universal.manager.notice.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
public class NoticeTemplateDTO implements Serializable {
|
||||
|
||||
private Long id;
|
||||
private String name;
|
||||
|
||||
@JsonProperty("channelType")
|
||||
private String channelType;
|
||||
|
||||
@JsonProperty("channelId")
|
||||
private Long channelId;
|
||||
|
||||
private String content;
|
||||
private String receivers;
|
||||
private String status;
|
||||
private String remark;
|
||||
private String creator;
|
||||
|
||||
@JsonProperty("createTime")
|
||||
private Date createTime;
|
||||
|
||||
@JsonProperty("updateTime")
|
||||
private Date updateTime;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getChannelType() {
|
||||
return channelType;
|
||||
}
|
||||
|
||||
public void setChannelType(String channelType) {
|
||||
this.channelType = channelType;
|
||||
}
|
||||
|
||||
public Long getChannelId() {
|
||||
return channelId;
|
||||
}
|
||||
|
||||
public void setChannelId(Long channelId) {
|
||||
this.channelId = channelId;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public String getReceivers() {
|
||||
return receivers;
|
||||
}
|
||||
|
||||
public void setReceivers(String receivers) {
|
||||
this.receivers = receivers;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getRemark() {
|
||||
return remark;
|
||||
}
|
||||
|
||||
public void setRemark(String remark) {
|
||||
this.remark = remark;
|
||||
}
|
||||
|
||||
public String getCreator() {
|
||||
return creator;
|
||||
}
|
||||
|
||||
public void setCreator(String creator) {
|
||||
this.creator = creator;
|
||||
}
|
||||
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public Date getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(Date updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package cn.universal.manager.notice.mapper;
|
||||
|
||||
import cn.universal.manager.notice.model.NoticeChannel;
|
||||
import tk.mybatis.mapper.common.Mapper;
|
||||
|
||||
public interface NoticeChannelMapper extends Mapper<NoticeChannel> {}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package cn.universal.manager.notice.mapper;
|
||||
|
||||
import cn.universal.manager.notice.model.NoticeSendRecord;
|
||||
import cn.universal.persistence.common.BaseMapper;
|
||||
|
||||
public interface NoticeSendRecordMapper extends BaseMapper<NoticeSendRecord> {}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package cn.universal.manager.notice.mapper;
|
||||
|
||||
import cn.universal.manager.notice.model.NoticeTemplate;
|
||||
import tk.mybatis.mapper.common.Mapper;
|
||||
|
||||
public interface NoticeTemplateMapper extends Mapper<NoticeTemplate> {}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
package cn.universal.manager.notice.model;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Table(name = "notice_channel")
|
||||
public class NoticeChannel implements Serializable {
|
||||
|
||||
@Id private Long id;
|
||||
private String name;
|
||||
|
||||
@Column(name = "channel_type")
|
||||
private String channelType;
|
||||
|
||||
@Column(columnDefinition = "TEXT")
|
||||
private String config;
|
||||
|
||||
private String status;
|
||||
private String remark;
|
||||
private String creator;
|
||||
|
||||
@Column(name = "create_time")
|
||||
private Date createTime;
|
||||
|
||||
@Column(name = "update_time")
|
||||
private Date updateTime;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getChannelType() {
|
||||
return channelType;
|
||||
}
|
||||
|
||||
public void setChannelType(String channelType) {
|
||||
this.channelType = channelType;
|
||||
}
|
||||
|
||||
public String getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public void setConfig(String config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getRemark() {
|
||||
return remark;
|
||||
}
|
||||
|
||||
public void setRemark(String remark) {
|
||||
this.remark = remark;
|
||||
}
|
||||
|
||||
public String getCreator() {
|
||||
return creator;
|
||||
}
|
||||
|
||||
public void setCreator(String creator) {
|
||||
this.creator = creator;
|
||||
}
|
||||
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public Date getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(Date updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
package cn.universal.manager.notice.model;
|
||||
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Table(name = "notice_send_record")
|
||||
public class NoticeSendRecord implements Serializable {
|
||||
|
||||
@Id private Long id;
|
||||
private Long templateId;
|
||||
private Long configId;
|
||||
private String receivers;
|
||||
private String params;
|
||||
private String status;
|
||||
private String result;
|
||||
private Date sendTime;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getTemplateId() {
|
||||
return templateId;
|
||||
}
|
||||
|
||||
public void setTemplateId(Long templateId) {
|
||||
this.templateId = templateId;
|
||||
}
|
||||
|
||||
public Long getConfigId() {
|
||||
return configId;
|
||||
}
|
||||
|
||||
public void setConfigId(Long configId) {
|
||||
this.configId = configId;
|
||||
}
|
||||
|
||||
public String getReceivers() {
|
||||
return receivers;
|
||||
}
|
||||
|
||||
public void setReceivers(String receivers) {
|
||||
this.receivers = receivers;
|
||||
}
|
||||
|
||||
public String getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
public void setParams(String params) {
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(String result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public Date getSendTime() {
|
||||
return sendTime;
|
||||
}
|
||||
|
||||
public void setSendTime(Date sendTime) {
|
||||
this.sendTime = sendTime;
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package cn.universal.manager.notice.model;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class NoticeSendRequest {
|
||||
|
||||
private Long templateId;
|
||||
private Map<String, Object> params;
|
||||
private String receivers;
|
||||
|
||||
public Long getTemplateId() {
|
||||
return templateId;
|
||||
}
|
||||
|
||||
public void setTemplateId(Long templateId) {
|
||||
this.templateId = templateId;
|
||||
}
|
||||
|
||||
public Map<String, Object> getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
public void setParams(Map<String, Object> params) {
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public String getReceivers() {
|
||||
return receivers;
|
||||
}
|
||||
|
||||
public void setReceivers(String receivers) {
|
||||
this.receivers = receivers;
|
||||
}
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
package cn.universal.manager.notice.model;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Table(name = "notice_template")
|
||||
public class NoticeTemplate implements Serializable {
|
||||
|
||||
@Id private Long id;
|
||||
private String name;
|
||||
|
||||
@Column(name = "channel_type")
|
||||
private String channelType;
|
||||
|
||||
@Column(name = "channel_id")
|
||||
private Long channelId;
|
||||
|
||||
private String content;
|
||||
private String receivers;
|
||||
private String status;
|
||||
private String remark;
|
||||
private String creator;
|
||||
|
||||
@Column(name = "create_time")
|
||||
private Date createTime;
|
||||
|
||||
@Column(name = "update_time")
|
||||
private Date updateTime;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getChannelType() {
|
||||
return channelType;
|
||||
}
|
||||
|
||||
public void setChannelType(String channelType) {
|
||||
this.channelType = channelType;
|
||||
}
|
||||
|
||||
public Long getChannelId() {
|
||||
return channelId;
|
||||
}
|
||||
|
||||
public void setChannelId(Long channelId) {
|
||||
this.channelId = channelId;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public String getReceivers() {
|
||||
return receivers;
|
||||
}
|
||||
|
||||
public void setReceivers(String receivers) {
|
||||
this.receivers = receivers;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getRemark() {
|
||||
return remark;
|
||||
}
|
||||
|
||||
public void setRemark(String remark) {
|
||||
this.remark = remark;
|
||||
}
|
||||
|
||||
public String getCreator() {
|
||||
return creator;
|
||||
}
|
||||
|
||||
public void setCreator(String creator) {
|
||||
this.creator = creator;
|
||||
}
|
||||
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public Date getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(Date updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package cn.universal.manager.notice.service;
|
||||
|
||||
import cn.universal.manager.notice.model.NoticeChannel;
|
||||
import java.util.List;
|
||||
|
||||
public interface NoticeChannelService {
|
||||
|
||||
List<NoticeChannel> list();
|
||||
|
||||
List<NoticeChannel> search(String name, String channelType, String status);
|
||||
|
||||
void save(NoticeChannel channel);
|
||||
|
||||
void delete(Long id);
|
||||
|
||||
void deleteBatch(List<Long> ids);
|
||||
|
||||
NoticeChannel getById(Long id);
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package cn.universal.manager.notice.service;
|
||||
|
||||
import cn.universal.manager.notice.model.NoticeSendRecord;
|
||||
import java.util.List;
|
||||
|
||||
public interface NoticeRecordService {
|
||||
|
||||
void save(NoticeSendRecord record);
|
||||
|
||||
List<NoticeSendRecord> list();
|
||||
|
||||
List<NoticeSendRecord> search(String keyword, String type, String status);
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package cn.universal.manager.notice.service;
|
||||
|
||||
import cn.universal.manager.notice.model.NoticeSendRequest;
|
||||
import cn.universal.manager.notice.service.channel.NoticeSendResult;
|
||||
|
||||
public interface NoticeService {
|
||||
|
||||
void send(NoticeSendRequest req);
|
||||
|
||||
default NoticeSendResult sendR(NoticeSendRequest request) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package cn.universal.manager.notice.service;
|
||||
|
||||
import cn.universal.manager.notice.model.NoticeTemplate;
|
||||
import java.util.List;
|
||||
|
||||
public interface NoticeTemplateService {
|
||||
|
||||
List<NoticeTemplate> list();
|
||||
|
||||
void save(NoticeTemplate template);
|
||||
|
||||
void delete(Long id);
|
||||
|
||||
NoticeTemplate getById(Long id);
|
||||
|
||||
List<NoticeTemplate> search(String name, String channelType, String status);
|
||||
|
||||
void deleteBatch(List<Long> ids);
|
||||
|
||||
void testTemplate(Long templateId, String receivers, Object params);
|
||||
|
||||
void enableBatch(List<Long> ids);
|
||||
|
||||
void disableBatch(List<Long> ids);
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package cn.universal.manager.notice.service.channel;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/** 抽象通知渠道基类 提供通用的配置解析和日志记录功能 */
|
||||
public abstract class AbstractNoticeSendChannel implements NoticeSendChannel {
|
||||
|
||||
protected final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
/** 从配置中解析JSON对象 */
|
||||
protected JSONObject parseConfig(cn.universal.manager.notice.model.NoticeChannel config) {
|
||||
if (config == null || config.getConfig() == null) {
|
||||
return new JSONObject();
|
||||
}
|
||||
try {
|
||||
return JSONUtil.parseObj(config.getConfig());
|
||||
} catch (Exception e) {
|
||||
logger.error("解析配置失败: {}", config.getConfig(), e);
|
||||
return new JSONObject();
|
||||
}
|
||||
}
|
||||
|
||||
/** 记录发送日志 */
|
||||
protected void logSend(
|
||||
String channelType, String content, String receivers, boolean success, String message) {
|
||||
if (success) {
|
||||
logger.info("[{}] 发送成功 - 接收者: {}, 内容: {}", channelType, receivers, content);
|
||||
} else {
|
||||
logger.error("[{}] 发送失败 - 接收者: {}, 内容: {}, 错误: {}", channelType, receivers, content, message);
|
||||
}
|
||||
}
|
||||
|
||||
/** 验证配置是否完整 */
|
||||
protected boolean validateConfig(JSONObject config, String... requiredFields) {
|
||||
for (String field : requiredFields) {
|
||||
if (!config.containsKey(field)
|
||||
|| config.getStr(field) == null
|
||||
|| config.getStr(field).trim().isEmpty()) {
|
||||
logger.error("配置缺少必需字段: {}", field);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** 构建并记录发送结果 */
|
||||
protected NoticeSendResult buildAndLogResult(
|
||||
String channelType, String content, String receivers, boolean success, String errorMessage) {
|
||||
logSend(channelType, content, receivers, success, errorMessage);
|
||||
return NoticeSendResult.builder()
|
||||
.success(success)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(errorMessage)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package cn.universal.manager.notice.service.channel;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import java.util.Map;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class AudioAliNoticeSendChannel extends AbstractNoticeSendChannel {
|
||||
|
||||
@Override
|
||||
public boolean support(String type) {
|
||||
return "audio_ali".equalsIgnoreCase(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoticeSendResult send(
|
||||
String content,
|
||||
String receivers,
|
||||
cn.universal.manager.notice.model.NoticeChannel config,
|
||||
Map<String, Object> params) {
|
||||
try {
|
||||
JSONObject configObj = parseConfig(config);
|
||||
if (!validateConfig(configObj, "accessKey", "secretKey", "signName", "templateCode")) {
|
||||
String errMsg = "配置不完整";
|
||||
logSend("AudioAli", content, receivers, false, errMsg);
|
||||
return NoticeSendResult.builder()
|
||||
.success(false)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(errMsg)
|
||||
.build();
|
||||
}
|
||||
// TODO: 实现阿里云语音API调用
|
||||
logger.info(
|
||||
"阿里云语音发送 - 接收者: {}, 内容: {}, 配置: {}", receivers, content, configObj.toString());
|
||||
logSend("AudioAli", content, receivers, true, "发送成功(模拟)");
|
||||
return NoticeSendResult.builder()
|
||||
.success(true)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(null)
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
String errMsg = "发送异常: " + e.getMessage();
|
||||
logSend("AudioAli", content, receivers, false, errMsg);
|
||||
logger.error("阿里云语音发送异常", e);
|
||||
return NoticeSendResult.builder()
|
||||
.success(false)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(errMsg)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
package cn.universal.manager.notice.service.channel;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.tencentcloudapi.common.Credential;
|
||||
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||
import com.tencentcloudapi.tts.v20190823.TtsClient;
|
||||
import com.tencentcloudapi.tts.v20190823.models.TextToVoiceRequest;
|
||||
import com.tencentcloudapi.tts.v20190823.models.TextToVoiceResponse;
|
||||
import java.util.Map;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class AudioTencentNoticeSendChannel extends AbstractNoticeSendChannel {
|
||||
|
||||
@Override
|
||||
public boolean support(String type) {
|
||||
return "audio_tencent".equalsIgnoreCase(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoticeSendResult send(
|
||||
String content,
|
||||
String receivers,
|
||||
cn.universal.manager.notice.model.NoticeChannel config,
|
||||
Map<String, Object> params) {
|
||||
try {
|
||||
JSONObject configObj = parseConfig(config);
|
||||
if (!validateConfig(
|
||||
configObj, "secretId", "secretKey", "signName", "templateCode", "receivers")) {
|
||||
String errMsg = "配置不完整";
|
||||
logSend("AudioTencent", content, receivers, false, errMsg);
|
||||
return NoticeSendResult.builder()
|
||||
.success(false)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(errMsg)
|
||||
.build();
|
||||
}
|
||||
Credential cred =
|
||||
new Credential(configObj.getStr("secretId"), configObj.getStr("secretKey"));
|
||||
TtsClient client = new TtsClient(cred, "ap-guangzhou");
|
||||
String[] templateParams;
|
||||
if (params != null && !params.isEmpty()) {
|
||||
templateParams = params.values().stream().map(Object::toString).toArray(String[]::new);
|
||||
} else {
|
||||
templateParams = new String[] {content};
|
||||
}
|
||||
TextToVoiceRequest request = new TextToVoiceRequest();
|
||||
request.setText(content);
|
||||
request.setSessionId(String.valueOf(System.currentTimeMillis()));
|
||||
request.setModelType(1L); // 默认模型
|
||||
request.setVolume(0.0f); // 默认音量
|
||||
request.setSpeed(0.0f); // 默认语速
|
||||
request.setProjectId(0L); // 默认项目ID
|
||||
request.setSampleRate(16000L); // 采样率
|
||||
TextToVoiceResponse response = client.TextToVoice(request);
|
||||
if (response.getAudio() != null) {
|
||||
logSend("AudioTencent", content, receivers, true, "发送成功");
|
||||
return NoticeSendResult.builder()
|
||||
.success(true)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(null)
|
||||
.build();
|
||||
} else {
|
||||
String errMsg = "腾讯云返回空响应";
|
||||
logSend("AudioTencent", content, receivers, false, errMsg);
|
||||
return NoticeSendResult.builder()
|
||||
.success(false)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(errMsg)
|
||||
.build();
|
||||
}
|
||||
} catch (TencentCloudSDKException e) {
|
||||
String errMsg = "腾讯云SDK异常: " + e.getMessage();
|
||||
logSend("AudioTencent", content, receivers, false, errMsg);
|
||||
logger.error("腾讯云语音发送异常", e);
|
||||
return NoticeSendResult.builder()
|
||||
.success(false)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(errMsg)
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
String errMsg = "发送异常: " + e.getMessage();
|
||||
logSend("AudioTencent", content, receivers, false, errMsg);
|
||||
logger.error("腾讯云语音发送异常", e);
|
||||
return NoticeSendResult.builder()
|
||||
.success(false)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(errMsg)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
package cn.universal.manager.notice.service.channel;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.Map;
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@Component
|
||||
public class DingTalkNoticeSendChannel extends AbstractNoticeSendChannel {
|
||||
|
||||
private final RestTemplate restTemplate = new RestTemplate();
|
||||
|
||||
@Override
|
||||
public boolean support(String type) {
|
||||
return "dingTalk".equalsIgnoreCase(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoticeSendResult send(
|
||||
String content,
|
||||
String receivers,
|
||||
cn.universal.manager.notice.model.NoticeChannel config,
|
||||
Map<String, Object> params) {
|
||||
try {
|
||||
JSONObject configObj = parseConfig(config);
|
||||
if (!validateConfig(configObj, "webhook")) {
|
||||
String errMsg = "配置不完整";
|
||||
return buildAndLogResult("DingTalk", content, receivers, false, errMsg);
|
||||
}
|
||||
String webhook = configObj.getStr("webhook");
|
||||
String secret = configObj.getStr("secret");
|
||||
JSONObject message = new JSONObject();
|
||||
message.set("msgtype", "text");
|
||||
JSONObject text = new JSONObject();
|
||||
text.set("content", content);
|
||||
message.set("text", text);
|
||||
if (StrUtil.isNotBlank(receivers)) {
|
||||
text.set("atMobiles", StrUtil.split(receivers, ',', true, true));
|
||||
message.set("at", text);
|
||||
}
|
||||
if (secret != null && !secret.trim().isEmpty()) {
|
||||
long timestamp = System.currentTimeMillis();
|
||||
String stringToSign = timestamp + "\n" + secret;
|
||||
String sign = calculateHmacSHA256(stringToSign, secret);
|
||||
String signedUrl = webhook + "×tamp=" + timestamp + "&sign=" + sign;
|
||||
webhook = signedUrl;
|
||||
}
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
HttpEntity<String> request = new HttpEntity<>(message.toString(), headers);
|
||||
ResponseEntity<String> response = restTemplate.postForEntity(webhook, request, String.class);
|
||||
if (response.getStatusCode().is2xxSuccessful()) {
|
||||
JSONObject responseBody = JSONUtil.parseObj(response.getBody());
|
||||
if (responseBody.getInt("errcode") == 0) {
|
||||
return buildAndLogResult("DingTalk", content, receivers, true, null);
|
||||
} else {
|
||||
String errMsg = "钉钉返回错误: " + responseBody.getStr("errmsg");
|
||||
return buildAndLogResult("DingTalk", content, receivers, false, errMsg);
|
||||
}
|
||||
} else {
|
||||
String errMsg = "HTTP请求失败: " + response.getStatusCode();
|
||||
return buildAndLogResult("DingTalk", content, receivers, false, errMsg);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String errMsg = "发送异常: " + e.getMessage();
|
||||
logger.error("钉钉发送异常", e);
|
||||
return buildAndLogResult("DingTalk", content, receivers, false, errMsg);
|
||||
}
|
||||
}
|
||||
|
||||
/** 计算HMAC-SHA256签名 */
|
||||
private String calculateHmacSHA256(String data, String key) throws Exception {
|
||||
Mac mac = Mac.getInstance("HmacSHA256");
|
||||
SecretKeySpec secretKeySpec =
|
||||
new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
|
||||
mac.init(secretKeySpec);
|
||||
byte[] hash = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
|
||||
return Base64.getEncoder().encodeToString(hash);
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package cn.universal.manager.notice.service.channel;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import org.springframework.mail.SimpleMailMessage;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class EmailNoticeSendChannel extends AbstractNoticeSendChannel {
|
||||
|
||||
@Override
|
||||
public boolean support(String type) {
|
||||
return "email".equalsIgnoreCase(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoticeSendResult send(
|
||||
String content,
|
||||
String receivers,
|
||||
cn.universal.manager.notice.model.NoticeChannel config,
|
||||
Map<String, Object> params) {
|
||||
try {
|
||||
JSONObject configObj = parseConfig(config);
|
||||
if (!validateConfig(
|
||||
configObj, "smtpHost", "smtpPort", "username", "password", "fromEmail", "receivers")) {
|
||||
String errMsg = "配置不完整";
|
||||
return buildAndLogResult("Email", content, receivers, false, errMsg);
|
||||
}
|
||||
JavaMailSender mailSender = createMailSender(configObj);
|
||||
SimpleMailMessage message = new SimpleMailMessage();
|
||||
message.setFrom(configObj.getStr("fromEmail"));
|
||||
message.setTo(receivers.split(","));
|
||||
message.setSubject("系统通知");
|
||||
message.setText(content);
|
||||
mailSender.send(message);
|
||||
return buildAndLogResult("Email", content, receivers, true, null);
|
||||
} catch (Exception e) {
|
||||
String errMsg = "发送异常: " + e.getMessage();
|
||||
logger.error("邮件发送异常", e);
|
||||
return buildAndLogResult("Email", content, receivers, false, errMsg);
|
||||
}
|
||||
}
|
||||
|
||||
/** 创建邮件发送器 */
|
||||
private JavaMailSender createMailSender(JSONObject config) {
|
||||
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
|
||||
mailSender.setHost(config.getStr("smtpHost"));
|
||||
mailSender.setPort(config.getInt("smtpPort"));
|
||||
mailSender.setUsername(config.getStr("username"));
|
||||
mailSender.setPassword(config.getStr("password"));
|
||||
|
||||
Properties props = mailSender.getJavaMailProperties();
|
||||
props.put("mail.transport.protocol", "smtp");
|
||||
props.put("mail.smtp.auth", "true");
|
||||
props.put("mail.smtp.starttls.enable", "true");
|
||||
props.put("mail.debug", "false");
|
||||
|
||||
return mailSender;
|
||||
}
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
package cn.universal.manager.notice.service.channel;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import java.util.Map;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@Component
|
||||
public class FeishuNoticeSendChannel extends AbstractNoticeSendChannel {
|
||||
|
||||
private final RestTemplate restTemplate = new RestTemplate();
|
||||
|
||||
@Override
|
||||
public boolean support(String type) {
|
||||
return "feishu".equalsIgnoreCase(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoticeSendResult send(
|
||||
String content,
|
||||
String receivers,
|
||||
cn.universal.manager.notice.model.NoticeChannel config,
|
||||
Map<String, Object> params) {
|
||||
try {
|
||||
JSONObject configObj = parseConfig(config);
|
||||
if (!validateConfig(configObj, "webhook")) {
|
||||
String errMsg = "配置不完整";
|
||||
logSend("Feishu", content, receivers, false, errMsg);
|
||||
return NoticeSendResult.builder()
|
||||
.success(false)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(errMsg)
|
||||
.build();
|
||||
}
|
||||
String webhook = configObj.getStr("webhook");
|
||||
JSONObject message = new JSONObject();
|
||||
message.set("msg_type", "text");
|
||||
JSONObject text = new JSONObject();
|
||||
text.set("text", content);
|
||||
message.set("content", text);
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
HttpEntity<String> request = new HttpEntity<>(message.toString(), headers);
|
||||
ResponseEntity<String> response = restTemplate.postForEntity(webhook, request, String.class);
|
||||
if (response.getStatusCode().is2xxSuccessful()) {
|
||||
JSONObject responseBody = JSONUtil.parseObj(response.getBody());
|
||||
if (responseBody.getInt("code") == 0) {
|
||||
logSend("Feishu", content, receivers, true, "发送成功");
|
||||
return NoticeSendResult.builder()
|
||||
.success(true)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(null)
|
||||
.build();
|
||||
} else {
|
||||
String errMsg = "飞书返回错误: " + responseBody.getStr("msg");
|
||||
logSend("Feishu", content, receivers, false, errMsg);
|
||||
return NoticeSendResult.builder()
|
||||
.success(false)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(errMsg)
|
||||
.build();
|
||||
}
|
||||
} else {
|
||||
String errMsg = "HTTP请求失败: " + response.getStatusCode();
|
||||
logSend("Feishu", content, receivers, false, errMsg);
|
||||
return NoticeSendResult.builder()
|
||||
.success(false)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(errMsg)
|
||||
.build();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String errMsg = "发送异常: " + e.getMessage();
|
||||
logSend("Feishu", content, receivers, false, errMsg);
|
||||
logger.error("飞书发送异常", e);
|
||||
return NoticeSendResult.builder()
|
||||
.success(false)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(errMsg)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package cn.universal.manager.notice.service.channel;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/** 通知渠道工厂类 用于管理和获取各种通知渠道 */
|
||||
@Component
|
||||
public class NoticeChannelFactory {
|
||||
|
||||
private final List<NoticeSendChannel> channels;
|
||||
|
||||
@Autowired
|
||||
public NoticeChannelFactory(List<NoticeSendChannel> channels) {
|
||||
this.channels = channels;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据渠道类型获取对应的通知渠道
|
||||
*
|
||||
* @param type 渠道类型
|
||||
* @return 通知渠道实例
|
||||
*/
|
||||
public Optional<NoticeSendChannel> getChannel(String type) {
|
||||
return channels.stream().filter(channel -> channel.support(type)).findFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否支持指定的渠道类型
|
||||
*
|
||||
* @param type 渠道类型
|
||||
* @return 是否支持
|
||||
*/
|
||||
public boolean supports(String type) {
|
||||
return channels.stream().anyMatch(channel -> channel.support(type));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有支持的渠道类型
|
||||
*
|
||||
* @return 渠道类型列表
|
||||
*/
|
||||
public List<String> getSupportedTypes() {
|
||||
return List.of(
|
||||
"dingTalk", // 钉钉
|
||||
"email", // 邮箱
|
||||
"feishu", // 飞书
|
||||
"sms_ali", // 阿里云短信
|
||||
"sms_tencent", // 腾讯云短信
|
||||
"audio_ali", // 阿里云语音
|
||||
"audio_tencent" // 腾讯云语音
|
||||
);
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package cn.universal.manager.notice.service.channel;
|
||||
|
||||
import cn.universal.manager.notice.model.NoticeChannel;
|
||||
import java.util.Map;
|
||||
|
||||
public interface NoticeSendChannel {
|
||||
|
||||
boolean support(String type);
|
||||
|
||||
NoticeSendResult send(
|
||||
String content, String receivers, NoticeChannel config, Map<String, Object> params);
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
package cn.universal.manager.notice.service.channel;
|
||||
|
||||
public class NoticeSendResult {
|
||||
|
||||
private boolean success;
|
||||
private String receivers;
|
||||
private String content;
|
||||
private String errorMessage;
|
||||
|
||||
public NoticeSendResult() {}
|
||||
|
||||
public NoticeSendResult(boolean success, String receivers, String content, String errorMessage) {
|
||||
this.success = success;
|
||||
this.receivers = receivers;
|
||||
this.content = content;
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public void setSuccess(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public String getReceivers() {
|
||||
return receivers;
|
||||
}
|
||||
|
||||
public void setReceivers(String receivers) {
|
||||
this.receivers = receivers;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
public void setErrorMessage(String errorMessage) {
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private boolean success;
|
||||
private String receivers;
|
||||
private String content;
|
||||
private String errorMessage;
|
||||
|
||||
public Builder success(boolean success) {
|
||||
this.success = success;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder receivers(String receivers) {
|
||||
this.receivers = receivers;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder content(String content) {
|
||||
this.content = content;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder errorMessage(String errorMessage) {
|
||||
this.errorMessage = errorMessage;
|
||||
return this;
|
||||
}
|
||||
|
||||
public NoticeSendResult build() {
|
||||
return new NoticeSendResult(success, receivers, content, errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
package cn.universal.manager.notice.service.channel;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.aliyun.dysmsapi20170525.Client;
|
||||
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
|
||||
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
|
||||
import com.aliyun.teaopenapi.models.Config;
|
||||
import java.util.Map;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class SmsAliNoticeSendChannel extends AbstractNoticeSendChannel {
|
||||
|
||||
@Override
|
||||
public boolean support(String type) {
|
||||
return "sms_ali".equalsIgnoreCase(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoticeSendResult send(
|
||||
String content,
|
||||
String receivers,
|
||||
cn.universal.manager.notice.model.NoticeChannel config,
|
||||
Map<String, Object> params) {
|
||||
try {
|
||||
JSONObject configObj = parseConfig(config);
|
||||
if (!validateConfig(
|
||||
configObj, "accessKey", "secretKey", "signName", "templateCode", "receivers")) {
|
||||
String errMsg = "配置不完整";
|
||||
logSend("SmsAli", content, receivers, false, errMsg);
|
||||
return NoticeSendResult.builder()
|
||||
.success(false)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(errMsg)
|
||||
.build();
|
||||
}
|
||||
Config aliConfig =
|
||||
new Config()
|
||||
.setAccessKeyId(configObj.getStr("accessKey"))
|
||||
.setAccessKeySecret(configObj.getStr("secretKey"))
|
||||
.setEndpoint("dysmsapi.aliyuncs.com");
|
||||
Client client = new Client(aliConfig);
|
||||
JSONObject templateParam = new JSONObject();
|
||||
if (params != null) {
|
||||
params.forEach(templateParam::set);
|
||||
} else {
|
||||
templateParam.set("message", content);
|
||||
}
|
||||
SendSmsRequest request =
|
||||
new SendSmsRequest()
|
||||
.setPhoneNumbers(receivers)
|
||||
.setSignName(configObj.getStr("signName"))
|
||||
.setTemplateCode(configObj.getStr("templateCode"))
|
||||
.setTemplateParam(templateParam.toString());
|
||||
SendSmsResponse response = client.sendSms(request);
|
||||
if ("OK".equals(response.getBody().getCode())) {
|
||||
logSend("SmsAli", content, receivers, true, "发送成功");
|
||||
return NoticeSendResult.builder()
|
||||
.success(true)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(null)
|
||||
.build();
|
||||
} else {
|
||||
String errMsg = "阿里云返回错误: " + response.getBody().getMessage();
|
||||
logSend("SmsAli", content, receivers, false, errMsg);
|
||||
return NoticeSendResult.builder()
|
||||
.success(false)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(errMsg)
|
||||
.build();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String errMsg = "发送异常: " + e.getMessage();
|
||||
logSend("SmsAli", content, receivers, false, errMsg);
|
||||
logger.error("阿里云短信发送异常", e);
|
||||
return NoticeSendResult.builder()
|
||||
.success(false)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(errMsg)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
package cn.universal.manager.notice.service.channel;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.tencentcloudapi.common.Credential;
|
||||
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||
import com.tencentcloudapi.sms.v20210111.SmsClient;
|
||||
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
|
||||
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
|
||||
import java.util.Map;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class SmsTencentNoticeSendChannel extends AbstractNoticeSendChannel {
|
||||
|
||||
@Override
|
||||
public boolean support(String type) {
|
||||
return "sms_tencent".equalsIgnoreCase(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoticeSendResult send(
|
||||
String content,
|
||||
String receivers,
|
||||
cn.universal.manager.notice.model.NoticeChannel config,
|
||||
Map<String, Object> params) {
|
||||
try {
|
||||
JSONObject configObj = parseConfig(config);
|
||||
if (!validateConfig(
|
||||
configObj, "secretId", "secretKey", "signName", "templateCode", "receivers")) {
|
||||
String errMsg = "配置不完整";
|
||||
logSend("SmsTencent", content, receivers, false, errMsg);
|
||||
return NoticeSendResult.builder()
|
||||
.success(false)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(errMsg)
|
||||
.build();
|
||||
}
|
||||
Credential cred =
|
||||
new Credential(configObj.getStr("secretId"), configObj.getStr("secretKey"));
|
||||
SmsClient client = new SmsClient(cred, "ap-guangzhou");
|
||||
String[] templateParams;
|
||||
if (params != null && !params.isEmpty()) {
|
||||
templateParams = params.values().stream().map(Object::toString).toArray(String[]::new);
|
||||
} else {
|
||||
templateParams = new String[] {content};
|
||||
}
|
||||
SendSmsRequest request = new SendSmsRequest();
|
||||
request.setSmsSdkAppId("1400000000"); // 需要配置实际的SDK AppId
|
||||
request.setSignName(configObj.getStr("signName"));
|
||||
request.setTemplateId(configObj.getStr("templateCode"));
|
||||
request.setTemplateParamSet(templateParams);
|
||||
request.setPhoneNumberSet(new String[] {receivers});
|
||||
SendSmsResponse response = client.SendSms(request);
|
||||
if (response.getSendStatusSet() != null && response.getSendStatusSet().length > 0) {
|
||||
String status = response.getSendStatusSet()[0].getCode();
|
||||
if ("Ok".equals(status)) {
|
||||
logSend("SmsTencent", content, receivers, true, "发送成功");
|
||||
return NoticeSendResult.builder()
|
||||
.success(true)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(null)
|
||||
.build();
|
||||
} else {
|
||||
String errMsg = "腾讯云返回错误: " + response.getSendStatusSet()[0].getMessage();
|
||||
logSend("SmsTencent", content, receivers, false, errMsg);
|
||||
return NoticeSendResult.builder()
|
||||
.success(false)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(errMsg)
|
||||
.build();
|
||||
}
|
||||
} else {
|
||||
String errMsg = "腾讯云返回空响应";
|
||||
logSend("SmsTencent", content, receivers, false, errMsg);
|
||||
return NoticeSendResult.builder()
|
||||
.success(false)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(errMsg)
|
||||
.build();
|
||||
}
|
||||
} catch (TencentCloudSDKException e) {
|
||||
String errMsg = "腾讯云SDK异常: " + e.getMessage();
|
||||
logSend("SmsTencent", content, receivers, false, errMsg);
|
||||
logger.error("腾讯云短信发送异常", e);
|
||||
return NoticeSendResult.builder()
|
||||
.success(false)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(errMsg)
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
String errMsg = "发送异常: " + e.getMessage();
|
||||
logSend("SmsTencent", content, receivers, false, errMsg);
|
||||
logger.error("腾讯云短信发送异常", e);
|
||||
return NoticeSendResult.builder()
|
||||
.success(false)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(errMsg)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package cn.universal.manager.notice.service.channel;
|
||||
|
||||
import cn.universal.manager.notice.model.NoticeChannel;
|
||||
import java.util.Map;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class WeComNoticeSendChannel implements NoticeSendChannel {
|
||||
|
||||
@Override
|
||||
public boolean support(String type) {
|
||||
return "wecom".equalsIgnoreCase(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoticeSendResult send(
|
||||
String content, String receivers, NoticeChannel config, Map<String, Object> params) {
|
||||
// 解析config.getConfig()为webhook等
|
||||
// TODO: 发送企业微信消息
|
||||
System.out.println("[WeCom] receivers=" + receivers + ", content=" + content);
|
||||
return NoticeSendResult.builder()
|
||||
.success(true)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(null)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
package cn.universal.manager.notice.service.channel;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.Header;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.universal.manager.notice.model.NoticeChannel;
|
||||
import java.util.Map;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class WebhookNoticeSendChannel extends AbstractNoticeSendChannel {
|
||||
|
||||
@Override
|
||||
public boolean support(String type) {
|
||||
return "webhook".equalsIgnoreCase(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoticeSendResult send(
|
||||
String content, String receivers, NoticeChannel config, Map<String, Object> params) {
|
||||
if (StrUtil.isBlank(content)) {
|
||||
logSend("Webhook", content, receivers, false, "发送内容为空");
|
||||
return NoticeSendResult.builder()
|
||||
.success(false)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage("发送内容为空")
|
||||
.build();
|
||||
}
|
||||
JSONObject configObj = parseConfig(config);
|
||||
String webhookUrl = configObj.getStr("webhook");
|
||||
String authTokenKey = configObj.getStr("AuthTokenKey");
|
||||
String tokenValue = configObj.getStr("TokenValue");
|
||||
if (StrUtil.isBlank(webhookUrl)) {
|
||||
String errMsg = "Webhook地址未配置";
|
||||
logSend("Webhook", content, receivers, false, errMsg);
|
||||
return NoticeSendResult.builder()
|
||||
.success(false)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(errMsg)
|
||||
.build();
|
||||
}
|
||||
try {
|
||||
HttpRequest httpRequest = HttpUtil.createPost(webhookUrl);
|
||||
httpRequest.timeout(5000); // 默认5秒超时
|
||||
httpRequest.header(Header.CONTENT_TYPE, "application/json");
|
||||
// 自定义header
|
||||
if (StrUtil.isNotBlank(tokenValue)) {
|
||||
httpRequest.header(
|
||||
StrUtil.isBlank(authTokenKey) ? Header.AUTHORIZATION.getValue() : authTokenKey,
|
||||
tokenValue);
|
||||
}
|
||||
// 发送内容
|
||||
httpRequest.body(content);
|
||||
HttpResponse response = httpRequest.execute();
|
||||
String result = response.body();
|
||||
int status = response.getStatus();
|
||||
logger.warn(
|
||||
"[Webhook推送] url={}, status={}, body={}, result={}", webhookUrl, status, content, result);
|
||||
if (status >= 200 && status < 300) {
|
||||
logSend("Webhook", content, receivers, true, "发送成功");
|
||||
return NoticeSendResult.builder()
|
||||
.success(true)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(null)
|
||||
.build();
|
||||
} else {
|
||||
String errMsg = "Webhook响应码:" + status + ", response=" + result;
|
||||
logSend("Webhook", content, receivers, false, errMsg);
|
||||
return NoticeSendResult.builder()
|
||||
.success(false)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(errMsg)
|
||||
.build();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String errMsg = "Webhook发送异常: " + e.getMessage();
|
||||
logSend("Webhook", content, receivers, false, errMsg);
|
||||
return NoticeSendResult.builder()
|
||||
.success(false)
|
||||
.receivers(receivers)
|
||||
.content(content)
|
||||
.errorMessage(errMsg)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isJson(String str) {
|
||||
try {
|
||||
JSONUtil.parse(str);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
package cn.universal.manager.notice.service.impl;
|
||||
|
||||
import cn.universal.manager.notice.mapper.NoticeChannelMapper;
|
||||
import cn.universal.manager.notice.model.NoticeChannel;
|
||||
import cn.universal.manager.notice.service.NoticeChannelService;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import tk.mybatis.mapper.entity.Example;
|
||||
|
||||
@Service
|
||||
public class NoticeChannelServiceImpl implements NoticeChannelService {
|
||||
|
||||
@Autowired private NoticeChannelMapper noticeChannelMapper;
|
||||
|
||||
@Override
|
||||
public List<NoticeChannel> list() {
|
||||
return noticeChannelMapper.selectAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NoticeChannel> search(String name, String channelType, String status) {
|
||||
Example example = new Example(NoticeChannel.class);
|
||||
Example.Criteria criteria = example.createCriteria();
|
||||
|
||||
if (name != null && !name.trim().isEmpty()) {
|
||||
criteria.andLike("name", "%" + name + "%");
|
||||
}
|
||||
|
||||
if (channelType != null && !channelType.trim().isEmpty()) {
|
||||
criteria.andEqualTo("channelType", channelType);
|
||||
}
|
||||
|
||||
if (status != null && !status.trim().isEmpty()) {
|
||||
criteria.andEqualTo("status", status);
|
||||
}
|
||||
|
||||
example.orderBy("createTime").desc();
|
||||
return noticeChannelMapper.selectByExample(example);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(NoticeChannel channel) {
|
||||
Date now = new Date();
|
||||
if (channel.getId() == null) {
|
||||
// 新增
|
||||
channel.setCreateTime(now);
|
||||
channel.setUpdateTime(now);
|
||||
noticeChannelMapper.insert(channel);
|
||||
} else {
|
||||
// 更新
|
||||
channel.setUpdateTime(now);
|
||||
noticeChannelMapper.updateByPrimaryKeySelective(channel);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Long id) {
|
||||
noticeChannelMapper.deleteByPrimaryKey(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteBatch(List<Long> ids) {
|
||||
Example example = new Example(NoticeChannel.class);
|
||||
example.createCriteria().andIn("id", ids);
|
||||
noticeChannelMapper.deleteByExample(example);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoticeChannel getById(Long id) {
|
||||
return noticeChannelMapper.selectByPrimaryKey(id);
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package cn.universal.manager.notice.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.universal.manager.notice.mapper.NoticeSendRecordMapper;
|
||||
import cn.universal.manager.notice.model.NoticeSendRecord;
|
||||
import cn.universal.manager.notice.service.NoticeRecordService;
|
||||
import java.util.List;
|
||||
import org.springframework.stereotype.Service;
|
||||
import tk.mybatis.mapper.entity.Example;
|
||||
|
||||
@Service
|
||||
public class NoticeRecordServiceImpl implements NoticeRecordService {
|
||||
|
||||
private final NoticeSendRecordMapper recordMapper;
|
||||
|
||||
public NoticeRecordServiceImpl(NoticeSendRecordMapper recordMapper) {
|
||||
this.recordMapper = recordMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(NoticeSendRecord record) {
|
||||
record.setSendTime(new java.util.Date());
|
||||
recordMapper.insertSelective(record);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NoticeSendRecord> list() {
|
||||
return recordMapper.selectAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NoticeSendRecord> search(String keyword, String type, String status) {
|
||||
Example example = new Example(NoticeSendRecord.class);
|
||||
Example.Criteria c = example.createCriteria();
|
||||
if (StrUtil.isNotEmpty(keyword)) {
|
||||
c.andLike("receivers", "%" + keyword + "%");
|
||||
}
|
||||
if (StrUtil.isNotEmpty(type)) {
|
||||
c.andEqualTo("status", type);
|
||||
}
|
||||
if (StrUtil.isNotEmpty(status)) {
|
||||
c.andEqualTo("status", status);
|
||||
}
|
||||
return recordMapper.selectByExample(example);
|
||||
}
|
||||
}
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
package cn.universal.manager.notice.service.impl;
|
||||
|
||||
import cn.universal.manager.notice.model.NoticeChannel;
|
||||
import cn.universal.manager.notice.model.NoticeSendRecord;
|
||||
import cn.universal.manager.notice.model.NoticeSendRequest;
|
||||
import cn.universal.manager.notice.model.NoticeTemplate;
|
||||
import cn.universal.manager.notice.service.NoticeChannelService;
|
||||
import cn.universal.manager.notice.service.NoticeRecordService;
|
||||
import cn.universal.manager.notice.service.NoticeService;
|
||||
import cn.universal.manager.notice.service.NoticeTemplateService;
|
||||
import cn.universal.manager.notice.service.channel.NoticeSendChannel;
|
||||
import cn.universal.manager.notice.service.channel.NoticeSendResult;
|
||||
import cn.universal.manager.notice.util.TemplateUtil;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class NoticeServiceImpl implements NoticeService {
|
||||
|
||||
private final NoticeTemplateService templateService;
|
||||
private final NoticeRecordService recordService;
|
||||
private final NoticeChannelService noticeChannelService;
|
||||
private final List<NoticeSendChannel> channelList;
|
||||
|
||||
public NoticeServiceImpl(
|
||||
NoticeTemplateService templateService,
|
||||
NoticeRecordService recordService,
|
||||
NoticeChannelService noticeChannelService,
|
||||
List<NoticeSendChannel> channelList) {
|
||||
this.templateService = templateService;
|
||||
this.recordService = recordService;
|
||||
this.noticeChannelService = noticeChannelService;
|
||||
this.channelList = channelList;
|
||||
}
|
||||
|
||||
private String mergeReceivers(
|
||||
String templateReceivers, String requestReceivers, Map<String, Object> params) {
|
||||
String tpl = TemplateUtil.replaceParams(templateReceivers, params);
|
||||
String req = TemplateUtil.replaceParams(requestReceivers, params);
|
||||
if (!StringUtils.hasText(tpl)) {
|
||||
return req;
|
||||
}
|
||||
if (!StringUtils.hasText(req)) {
|
||||
return tpl;
|
||||
}
|
||||
Set<String> set = new LinkedHashSet<>();
|
||||
set.addAll(Arrays.asList(tpl.split(",")));
|
||||
set.addAll(Arrays.asList(req.split(",")));
|
||||
return String.join(",", set);
|
||||
}
|
||||
|
||||
private static class SendContext {
|
||||
|
||||
NoticeTemplate template;
|
||||
NoticeChannel channelConfig;
|
||||
NoticeSendChannel channel;
|
||||
String content;
|
||||
String mergedReceivers;
|
||||
}
|
||||
|
||||
private SendContext validateAndPrepare(NoticeSendRequest request) {
|
||||
if (request == null || request.getTemplateId() == null) {
|
||||
throw new IllegalArgumentException("模板ID不能为空");
|
||||
}
|
||||
NoticeTemplate template = templateService.getById(request.getTemplateId());
|
||||
if (template == null) {
|
||||
throw new IllegalArgumentException("通知模板不存在");
|
||||
}
|
||||
if (!StringUtils.hasText(template.getContent())) {
|
||||
throw new IllegalArgumentException("模板内容不能为空");
|
||||
}
|
||||
NoticeChannel channelConfig = noticeChannelService.getById(template.getChannelId());
|
||||
if (channelConfig == null) {
|
||||
throw new IllegalArgumentException("渠道配置不存在");
|
||||
}
|
||||
NoticeSendChannel channel =
|
||||
channelList.stream()
|
||||
.filter(c -> c.support(channelConfig.getChannelType()))
|
||||
.findFirst()
|
||||
.orElseThrow(
|
||||
() -> new IllegalArgumentException("不支持的通知类型:" + channelConfig.getChannelType()));
|
||||
String content = TemplateUtil.replaceParams(template.getContent(), request.getParams());
|
||||
String mergedReceivers =
|
||||
mergeReceivers(template.getReceivers(), request.getReceivers(), request.getParams());
|
||||
if (!StringUtils.hasText(mergedReceivers)) {
|
||||
// throw new IllegalArgumentException("收件人为空");
|
||||
log.debug("推送消息渠道={},收件人为空,部分不需要收件人", request.getTemplateId());
|
||||
}
|
||||
SendContext ctx = new SendContext();
|
||||
ctx.template = template;
|
||||
ctx.channelConfig = channelConfig;
|
||||
ctx.channel = channel;
|
||||
ctx.content = content;
|
||||
ctx.mergedReceivers = mergedReceivers;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
private NoticeSendRecord buildRecord(SendContext ctx, NoticeSendRequest request) {
|
||||
NoticeSendRecord record = new NoticeSendRecord();
|
||||
record.setTemplateId(ctx.template.getId());
|
||||
record.setConfigId(ctx.channelConfig.getId());
|
||||
record.setReceivers(ctx.mergedReceivers);
|
||||
record.setParams(request.getParams() != null ? request.getParams().toString() : null);
|
||||
record.setSendTime(new Date());
|
||||
return record;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(NoticeSendRequest request) {
|
||||
SendContext ctx;
|
||||
try {
|
||||
ctx = validateAndPrepare(request);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e.getMessage(), e);
|
||||
}
|
||||
NoticeSendRecord record = buildRecord(ctx, request);
|
||||
try {
|
||||
NoticeSendResult result =
|
||||
ctx.channel.send(
|
||||
ctx.content, ctx.mergedReceivers, ctx.channelConfig, request.getParams());
|
||||
record.setStatus(result.isSuccess() ? "SUCCESS" : "FAIL");
|
||||
record.setResult(result.getErrorMessage() == null ? "OK" : result.getErrorMessage());
|
||||
if (!result.isSuccess()) {
|
||||
throw new RuntimeException("消息推送失败: " + result.getErrorMessage());
|
||||
}
|
||||
} finally {
|
||||
recordService.save(record);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoticeSendResult sendR(NoticeSendRequest request) {
|
||||
SendContext ctx;
|
||||
try {
|
||||
ctx = validateAndPrepare(request);
|
||||
} catch (Exception e) {
|
||||
return NoticeSendResult.builder().success(false).errorMessage(e.getMessage()).build();
|
||||
}
|
||||
NoticeSendRecord record = buildRecord(ctx, request);
|
||||
NoticeSendResult result;
|
||||
try {
|
||||
result =
|
||||
ctx.channel.send(
|
||||
ctx.content, ctx.mergedReceivers, ctx.channelConfig, request.getParams());
|
||||
record.setStatus(result.isSuccess() ? "SUCCESS" : "FAIL");
|
||||
record.setResult(result.getErrorMessage() == null ? "OK" : result.getErrorMessage());
|
||||
} catch (Exception e) {
|
||||
record.setStatus("FAIL");
|
||||
record.setResult(e.getMessage());
|
||||
log.error("推送消息失败", e);
|
||||
result =
|
||||
NoticeSendResult.builder()
|
||||
.success(false)
|
||||
.errorMessage("消息推送失败:" + e.getMessage())
|
||||
.build();
|
||||
} finally {
|
||||
recordService.save(record);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
package cn.universal.manager.notice.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.universal.manager.notice.mapper.NoticeTemplateMapper;
|
||||
import cn.universal.manager.notice.model.NoticeChannel;
|
||||
import cn.universal.manager.notice.model.NoticeTemplate;
|
||||
import cn.universal.manager.notice.service.NoticeChannelService;
|
||||
import cn.universal.manager.notice.service.NoticeTemplateService;
|
||||
import cn.universal.manager.notice.service.channel.NoticeChannelFactory;
|
||||
import cn.universal.manager.notice.service.channel.NoticeSendChannel;
|
||||
import cn.universal.manager.notice.util.TemplateUtil;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.springframework.stereotype.Service;
|
||||
import tk.mybatis.mapper.entity.Example;
|
||||
|
||||
@Service
|
||||
public class NoticeTemplateServiceImpl implements NoticeTemplateService {
|
||||
|
||||
private final NoticeTemplateMapper templateMapper;
|
||||
private final NoticeChannelService noticeChannelService;
|
||||
private final NoticeChannelFactory channelFactory;
|
||||
|
||||
public NoticeTemplateServiceImpl(
|
||||
NoticeTemplateMapper templateMapper,
|
||||
NoticeChannelService noticeChannelService,
|
||||
NoticeChannelFactory channelFactory) {
|
||||
this.templateMapper = templateMapper;
|
||||
this.noticeChannelService = noticeChannelService;
|
||||
this.channelFactory = channelFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NoticeTemplate> list() {
|
||||
return templateMapper.selectAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(NoticeTemplate template) {
|
||||
Date now = new Date();
|
||||
if (template.getId() == null) {
|
||||
// 新增
|
||||
template.setCreateTime(now);
|
||||
template.setUpdateTime(now);
|
||||
templateMapper.insertSelective(template);
|
||||
} else {
|
||||
// 更新
|
||||
template.setUpdateTime(now);
|
||||
templateMapper.updateByPrimaryKeySelective(template);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(Long id) {
|
||||
templateMapper.deleteByPrimaryKey(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoticeTemplate getById(Long id) {
|
||||
return templateMapper.selectByPrimaryKey(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NoticeTemplate> search(String name, String channelType, String status) {
|
||||
Example example = new Example(NoticeTemplate.class);
|
||||
Example.Criteria c = example.createCriteria();
|
||||
if (StrUtil.isNotEmpty(name)) {
|
||||
c.andLike("name", "%" + name + "%");
|
||||
}
|
||||
if (StrUtil.isNotEmpty(channelType)) {
|
||||
c.andEqualTo("channelType", channelType);
|
||||
}
|
||||
if (StrUtil.isNotEmpty(status)) {
|
||||
c.andEqualTo("status", status);
|
||||
}
|
||||
example.orderBy("createTime").desc();
|
||||
return templateMapper.selectByExample(example);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteBatch(List<Long> ids) {
|
||||
Example example = new Example(NoticeTemplate.class);
|
||||
example.createCriteria().andIn("id", ids);
|
||||
templateMapper.deleteByExample(example);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableBatch(List<Long> ids) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Example example = new Example(NoticeTemplate.class);
|
||||
example.createCriteria().andIn("id", ids);
|
||||
NoticeTemplate update = new NoticeTemplate();
|
||||
update.setStatus("1"); // 启用
|
||||
templateMapper.updateByExampleSelective(update, example);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableBatch(List<Long> ids) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Example example = new Example(NoticeTemplate.class);
|
||||
example.createCriteria().andIn("id", ids);
|
||||
NoticeTemplate update = new NoticeTemplate();
|
||||
update.setStatus("0"); // 停用
|
||||
templateMapper.updateByExampleSelective(update, example);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testTemplate(Long templateId, String receivers, Object params) {
|
||||
// 1. 获取模板
|
||||
NoticeTemplate template = getById(templateId);
|
||||
if (template == null) {
|
||||
throw new IllegalArgumentException("模板不存在");
|
||||
}
|
||||
|
||||
// 2. 获取渠道配置
|
||||
NoticeChannel channelConfig = noticeChannelService.getById(template.getChannelId());
|
||||
if (channelConfig == null) {
|
||||
throw new IllegalArgumentException("渠道配置不存在");
|
||||
}
|
||||
|
||||
// 3. 替换参数
|
||||
Map<String, Object> paramMap = null;
|
||||
if (params instanceof Map) {
|
||||
paramMap = (Map<String, Object>) params;
|
||||
} else {
|
||||
paramMap = TemplateUtil.parseJson(TemplateUtil.toJson(params));
|
||||
}
|
||||
|
||||
String content = TemplateUtil.replaceParams(template.getContent(), paramMap);
|
||||
|
||||
// 4. 获取对应的通知渠道
|
||||
NoticeSendChannel channel =
|
||||
channelFactory
|
||||
.getChannel(template.getChannelType())
|
||||
.orElseThrow(
|
||||
() -> new IllegalArgumentException("不支持的渠道类型: " + template.getChannelType()));
|
||||
|
||||
// 5. 发送测试消息
|
||||
try {
|
||||
channel.send(content, receivers, channelConfig, paramMap);
|
||||
System.out.println(
|
||||
"✅ 测试发送成功 - 模板: " + template.getName() + ", 渠道: " + template.getChannelType());
|
||||
} catch (Exception e) {
|
||||
System.err.println(
|
||||
"❌ 测试发送失败 - 模板: " + template.getName() + ", 渠道: " + template.getChannelType());
|
||||
System.err.println("错误信息: " + e.getMessage());
|
||||
throw new RuntimeException("测试发送失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
package cn.universal.manager.notice.util;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
/** JSON脱敏工具类 用于检测和脱敏包含Secret关键字的字段 */
|
||||
public class JsonDesensitizationUtil {
|
||||
|
||||
private static final String SECRET_KEYWORD = "secret";
|
||||
private static final String MASK_VALUE = "******";
|
||||
|
||||
/**
|
||||
* 对JSON对象进行脱敏处理
|
||||
*
|
||||
* @param jsonString JSON字符串
|
||||
* @return 脱敏后的JSON对象
|
||||
*/
|
||||
public static JSONObject desensitize(String jsonString) {
|
||||
if (jsonString == null || jsonString.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
JSONObject jsonObject = JSONUtil.parseObj(jsonString);
|
||||
return desensitizeJsonObject(jsonObject);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 对JSONObject进行脱敏处理
|
||||
*
|
||||
* @param jsonObject JSON对象
|
||||
* @return 脱敏后的JSON对象
|
||||
*/
|
||||
public static JSONObject desensitizeJsonObject(JSONObject jsonObject) {
|
||||
if (jsonObject == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
JSONObject result = new JSONObject();
|
||||
Iterator<Map.Entry<String, Object>> iterator = jsonObject.entrySet().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<String, Object> entry = iterator.next();
|
||||
String key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
|
||||
// 检查key是否包含Secret关键字(忽略大小写)
|
||||
if (containsSecretKeyword(key)) {
|
||||
// 脱敏处理
|
||||
result.put(key, MASK_VALUE);
|
||||
} else if (value instanceof JSONObject) {
|
||||
// 递归处理嵌套的JSONObject
|
||||
result.put(key, desensitizeJsonObject((JSONObject) value));
|
||||
} else {
|
||||
// 直接复制其他值
|
||||
result.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查字符串是否包含Secret关键字(忽略大小写)
|
||||
*
|
||||
* @param text 要检查的字符串
|
||||
* @return 是否包含Secret关键字
|
||||
*/
|
||||
private static boolean containsSecretKeyword(String text) {
|
||||
if (text == null) {
|
||||
return false;
|
||||
}
|
||||
return text.toLowerCase().contains(SECRET_KEYWORD);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将Object转换为JSONObject并进行脱敏处理
|
||||
*
|
||||
* @param obj 要处理的对象
|
||||
* @return 脱敏后的JSONObject
|
||||
*/
|
||||
public static JSONObject desensitizeObject(Object obj) {
|
||||
if (obj == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
if (obj instanceof JSONObject) {
|
||||
return desensitizeJsonObject((JSONObject) obj);
|
||||
} else {
|
||||
// 先转换为JSON字符串,再解析为JSONObject
|
||||
String jsonString = JSONUtil.toJsonStr(obj);
|
||||
return desensitize(jsonString);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package cn.universal.manager.notice.util;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class TemplateUtil {
|
||||
|
||||
// 支持 #xxx 和 #{xxx} 两种格式(全部用普通字符串,不用字符串模板)
|
||||
private static final Pattern PARAM_PATTERN =
|
||||
Pattern.compile("#([a-zA-Z0-9_]+)|#\\{([a-zA-Z0-9_]+)\\}");
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
/** 替换模板中的参数,兼容 #xxx 和 #{xxx} 两种格式 */
|
||||
public static String replaceParams(String template, Map<String, Object> params) {
|
||||
if (template == null || params == null) {
|
||||
return template;
|
||||
}
|
||||
Matcher matcher = PARAM_PATTERN.matcher(template);
|
||||
StringBuffer result = new StringBuffer();
|
||||
while (matcher.find()) {
|
||||
String paramName = matcher.group(1) != null ? matcher.group(1) : matcher.group(2);
|
||||
Object value = params.get(paramName);
|
||||
String replacement = value != null ? value.toString() : "";
|
||||
matcher.appendReplacement(result, Matcher.quoteReplacement(replacement));
|
||||
}
|
||||
matcher.appendTail(result);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/** 解析JSON字符串为Map */
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Map<String, Object> parseJson(String json) {
|
||||
try {
|
||||
if (json == null || json.trim().isEmpty()) {
|
||||
return Map.of();
|
||||
}
|
||||
return objectMapper.readValue(json, Map.class);
|
||||
} catch (Exception e) {
|
||||
return Map.of();
|
||||
}
|
||||
}
|
||||
|
||||
/** 将对象转换为JSON字符串 */
|
||||
public static String toJson(Object obj) {
|
||||
try {
|
||||
return objectMapper.writeValueAsString(obj);
|
||||
} catch (Exception e) {
|
||||
return "{}";
|
||||
}
|
||||
}
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
// package cn.universal.manager.notice;
|
||||
//
|
||||
// import cn.universal.manager.notice.model.NoticeSendChannel;
|
||||
// import cn.universal.manager.notice.model.NoticeTemplate;
|
||||
// import cn.universal.manager.notice.service.NoticeChannelService;
|
||||
// import cn.universal.manager.notice.service.NoticeTemplateService;
|
||||
// import cn.universal.manager.notice.util.TemplateUtil;
|
||||
// import org.junit.jupiter.api.Test;
|
||||
// import org.springframework.beans.factory.annotation.Autowired;
|
||||
// import org.springframework.boot.test.context.SpringBootTest;
|
||||
//
|
||||
// import java.util.HashMap;
|
||||
// import java.util.List;
|
||||
// import java.util.Map;
|
||||
//
|
||||
// @SpringBootTest
|
||||
// public class NoticeTest {
|
||||
//
|
||||
// @Autowired
|
||||
// private NoticeChannelService noticeChannelService;
|
||||
//
|
||||
// @Autowired
|
||||
// private NoticeTemplateService noticeTemplateService;
|
||||
//
|
||||
// @Test
|
||||
// public void testChannelCRUD() {
|
||||
// // 测试渠道CRUD操作
|
||||
// NoticeSendChannel channel = new NoticeSendChannel();
|
||||
// channel.setName("测试钉钉机器人");
|
||||
// channel.setChannelType("dingTalk");
|
||||
// channel.setConfig("{\"webhook\":\"https://test.com\",\"secret\":\"test\"}");
|
||||
// channel.setStatus("1");
|
||||
// channel.setRemark("测试渠道");
|
||||
// channel.setCreator("test");
|
||||
//
|
||||
// // 保存
|
||||
// noticeChannelService.save(channel);
|
||||
// System.out.println("保存渠道成功,ID: " + channel.getId());
|
||||
//
|
||||
// // 查询
|
||||
// NoticeSendChannel saved = noticeChannelService.getById(channel.getId());
|
||||
// System.out.println("查询渠道: " + saved.getName());
|
||||
//
|
||||
// // 搜索
|
||||
// List<NoticeSendChannel> list = noticeChannelService.search("测试", "dingTalk", "1");
|
||||
// System.out.println("搜索到 " + list.size() + " 个渠道");
|
||||
//
|
||||
// // 删除
|
||||
// noticeChannelService.delete(channel.getId());
|
||||
// System.out.println("删除渠道成功");
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testTemplateCRUD() {
|
||||
// // 测试模板CRUD操作
|
||||
// NoticeTemplate template = new NoticeTemplate();
|
||||
// template.setName("测试告警模板");
|
||||
// template.setChannelType("dingTalk");
|
||||
// template.setChannelId(1L);
|
||||
// template.setContent("设备${deviceName}发生${alertLevel}级别告警:${alertMessage}");
|
||||
// template.setReceivers("[\"test_group\"]");
|
||||
// template.setStatus("1");
|
||||
// template.setRemark("测试模板");
|
||||
// template.setCreator("test");
|
||||
//
|
||||
// // 保存
|
||||
// noticeTemplateService.save(template);
|
||||
// System.out.println("保存模板成功,ID: " + template.getId());
|
||||
//
|
||||
// // 查询
|
||||
// NoticeTemplate saved = noticeTemplateService.getById(template.getId());
|
||||
// System.out.println("查询模板: " + saved.getName());
|
||||
//
|
||||
// // 搜索
|
||||
// List<NoticeTemplate> list = noticeTemplateService.search("测试", "dingTalk", "1");
|
||||
// System.out.println("搜索到 " + list.size() + " 个模板");
|
||||
//
|
||||
// // 删除
|
||||
// noticeTemplateService.delete(template.getId());
|
||||
// System.out.println("删除模板成功");
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testTemplateUtil() {
|
||||
// // 测试模板工具类
|
||||
// String template = "设备${deviceName}发生${alertLevel}级别告警:${alertMessage},时间:${alertTime}";
|
||||
//
|
||||
// Map<String, Object> params = new HashMap<>();
|
||||
// params.put("deviceName", "温度传感器001");
|
||||
// params.put("alertLevel", "严重");
|
||||
// params.put("alertMessage", "温度过高报警");
|
||||
// params.put("alertTime", "2024-01-15 14:30:25");
|
||||
//
|
||||
// String result = TemplateUtil.replaceParams(template, params);
|
||||
// System.out.println("模板替换结果: " + result);
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testTemplateTest() {
|
||||
// // 测试模板测试功能
|
||||
// Map<String, Object> params = new HashMap<>();
|
||||
// params.put("deviceName", "温度传感器001");
|
||||
// params.put("alertLevel", "严重");
|
||||
// params.put("alertMessage", "温度过高报警");
|
||||
// params.put("alertTime", "2024-01-15 14:30:25");
|
||||
//
|
||||
// noticeTemplateService.testTemplate(1L, "test_group", params);
|
||||
// }
|
||||
// }
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2025, IoT-Universal. All Rights Reserved.
|
||||
*
|
||||
* @Description: 七牛云存储实现
|
||||
*
|
||||
*/
|
||||
|
||||
package cn.universal.ossm.oss.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.universal.common.exception.IoTException;
|
||||
import cn.universal.ossm.oss.entity.UploadResult;
|
||||
import cn.universal.ossm.oss.properties.CloudStorageProperties;
|
||||
import cn.universal.ossm.oss.service.ICloudStorageService;
|
||||
import com.qiniu.storage.Configuration;
|
||||
import com.qiniu.storage.Region;
|
||||
import com.qiniu.storage.UploadManager;
|
||||
import com.qiniu.storage.model.DefaultPutRet;
|
||||
import com.qiniu.util.Auth;
|
||||
import com.qiniu.util.StringMap;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.Resource;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class QiniuCloudStorageServiceImpl implements ICloudStorageService {
|
||||
|
||||
@Resource private CloudStorageProperties properties;
|
||||
|
||||
private UploadManager uploadManager;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
CloudStorageProperties.QiniuProperties cfg = properties.getQiniu();
|
||||
Region region = Region.autoRegion();
|
||||
Configuration configuration = new Configuration(region);
|
||||
this.uploadManager = new UploadManager(configuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createBucket() {}
|
||||
|
||||
@Override
|
||||
public String getServiceType() {
|
||||
return "qiniu";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPath(String prefix, String suffix) {
|
||||
StringBuilder path = new StringBuilder();
|
||||
if (StrUtil.isNotBlank(prefix)) {
|
||||
path.append(prefix);
|
||||
}
|
||||
path.append(System.currentTimeMillis());
|
||||
if (StrUtil.isNotBlank(suffix)) {
|
||||
path.append(suffix);
|
||||
}
|
||||
return path.toString();
|
||||
}
|
||||
|
||||
private String getUpToken() {
|
||||
CloudStorageProperties.QiniuProperties cfg = properties.getQiniu();
|
||||
Auth auth = Auth.create(cfg.getAccessKey(), cfg.getSecretKey());
|
||||
StringMap putPolicy = new StringMap();
|
||||
return auth.uploadToken(cfg.getBucketName(), null, 3600, putPolicy);
|
||||
}
|
||||
|
||||
private String buildUrl(String key) {
|
||||
CloudStorageProperties.QiniuProperties cfg = properties.getQiniu();
|
||||
String domain = cfg.getDomain();
|
||||
if (Boolean.TRUE.equals(cfg.getIsHttps())) {
|
||||
domain = domain.replaceFirst("^http://", "https://");
|
||||
}
|
||||
if (!domain.startsWith("http")) {
|
||||
domain = (Boolean.TRUE.equals(cfg.getIsHttps()) ? "https://" : "http://") + domain;
|
||||
}
|
||||
return domain + "/" + key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UploadResult upload(byte[] data, String path, String contentType) {
|
||||
try {
|
||||
String token = getUpToken();
|
||||
String key = path;
|
||||
com.qiniu.http.Response response =
|
||||
uploadManager.put(new ByteArrayInputStream(data), key, token, null, contentType);
|
||||
if (!response.isOK()) {
|
||||
throw new IoTException("七牛上传失败:" + response.toString());
|
||||
}
|
||||
DefaultPutRet putRet = JSONUtil.toBean(response.bodyString(), DefaultPutRet.class);
|
||||
String url = buildUrl(putRet.key);
|
||||
return new UploadResult().setUrl(url).setFilename(putRet.key);
|
||||
} catch (Exception e) {
|
||||
throw new IoTException("七牛上传异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(String path) {
|
||||
// 可按需实现:调用 BucketManager 删除
|
||||
}
|
||||
|
||||
@Override
|
||||
public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) {
|
||||
String path = getPath(properties.getQiniu().getPrefix(), suffix);
|
||||
return upload(data, path, contentType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UploadResult upload(InputStream inputStream, String path, String contentType) {
|
||||
try {
|
||||
byte[] bytes = inputStream.readAllBytes();
|
||||
return upload(bytes, path, contentType);
|
||||
} catch (Exception e) {
|
||||
throw new IoTException("七牛上传异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UploadResult uploadSuffix(InputStream inputStream, String suffix, String contentType) {
|
||||
String path = getPath(properties.getQiniu().getPrefix(), suffix);
|
||||
return upload(inputStream, path, contentType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEndpointLink() {
|
||||
return properties.getQiniu().getDomain();
|
||||
}
|
||||
}
|
||||
+5
@@ -167,8 +167,11 @@ public class DefaultSecurityConfig {
|
||||
.permitAll()
|
||||
.requestMatchers("/emqx/**")
|
||||
.permitAll()
|
||||
.requestMatchers("/ct/aiot/**")
|
||||
.permitAll()
|
||||
// 测试接口
|
||||
.requestMatchers("/test/**")
|
||||
|
||||
.permitAll()
|
||||
.requestMatchers("/monitor/**")
|
||||
.permitAll()
|
||||
@@ -227,6 +230,8 @@ public class DefaultSecurityConfig {
|
||||
// 测试和监控点
|
||||
.requestMatchers("/test/**", "/monitor/**")
|
||||
.permitAll()
|
||||
.requestMatchers("/ct/aiot/**")
|
||||
.permitAll()
|
||||
// 前端相关
|
||||
.requestMatchers(
|
||||
"/js/**",
|
||||
|
||||
+27
-47
@@ -30,22 +30,17 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
public class CommonRequest {
|
||||
|
||||
/**
|
||||
* http请求超时时间
|
||||
*/
|
||||
/** http请求超时时间 */
|
||||
private static final Integer HTTP_TIME_OUT = 1200;
|
||||
|
||||
/**
|
||||
* URL状态信息
|
||||
*/
|
||||
/** URL状态信息 */
|
||||
public static class UrlStatus {
|
||||
|
||||
private int failureCount = 0;
|
||||
private long lastFailureTime = 0;
|
||||
private long nextAllowTime = 0;
|
||||
|
||||
public UrlStatus() {
|
||||
}
|
||||
public UrlStatus() {}
|
||||
|
||||
public int getFailureCount() {
|
||||
return failureCount;
|
||||
@@ -75,25 +70,19 @@ public class CommonRequest {
|
||||
private static String CACHE_NOTICE = "DNotice:";
|
||||
|
||||
// 存储URL状态信息,30分钟后过期
|
||||
private static Cache<String, UrlStatus> urlStatusCache = Caffeine.newBuilder()
|
||||
.expireAfterWrite(30, TimeUnit.MINUTES).maximumSize(256).build();
|
||||
private static Cache<String, UrlStatus> urlStatusCache =
|
||||
Caffeine.newBuilder().expireAfterWrite(30, TimeUnit.MINUTES).maximumSize(256).build();
|
||||
|
||||
/**
|
||||
* 分级阈值配置
|
||||
*/
|
||||
/** 分级阈值配置 */
|
||||
private static final int LEVEL_1_THRESHOLD = 3; // 轻微故障阈值
|
||||
|
||||
private static final int LEVEL_2_THRESHOLD = 6; // 中等故障阈值
|
||||
private static final int LEVEL_3_THRESHOLD = 10; // 严重故障阈值
|
||||
|
||||
/**
|
||||
* 基础延迟时间(秒)
|
||||
*/
|
||||
/** 基础延迟时间(秒) */
|
||||
private static final int BASE_DELAY_SECONDS = 30;
|
||||
|
||||
/**
|
||||
* 最大延迟时间(分钟)
|
||||
*/
|
||||
/** 最大延迟时间(分钟) */
|
||||
private static final int MAX_DELAY_MINUTES = 10;
|
||||
|
||||
private static ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
|
||||
@@ -115,8 +104,7 @@ public class CommonRequest {
|
||||
if (isUrlBlocked(url)) {
|
||||
UrlStatus status = urlStatusCache.getIfPresent(url);
|
||||
long remainingSeconds = (status.getNextAllowTime() - System.currentTimeMillis()) / 1000;
|
||||
log.warn("当前地址[{}]因连续失败{}次,暂时限制访问,还需等待{}秒", url,
|
||||
status.getFailureCount(), remainingSeconds);
|
||||
log.warn("当前地址[{}]因连续失败{}次,暂时限制访问,还需等待{}秒", url, status.getFailureCount(), remainingSeconds);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -124,7 +112,7 @@ public class CommonRequest {
|
||||
HttpRequest request = HttpUtil.createPost(url);
|
||||
request.timeout(HTTP_TIME_OUT);
|
||||
String timestamp = String.valueOf(System.currentTimeMillis());
|
||||
String signature = String.valueOf((timestamp + url).hashCode());
|
||||
String signature = MD5.create().digestHex16((timestamp + body));
|
||||
request.header("X-Timestamp", timestamp);
|
||||
request.header("X-Signature", signature);
|
||||
request.header(Header.CONTENT_TYPE, "application/json");
|
||||
@@ -146,9 +134,7 @@ public class CommonRequest {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查URL是否被阻止
|
||||
*/
|
||||
/** 检查URL是否被阻止 */
|
||||
private static boolean isUrlBlocked(String url) {
|
||||
UrlStatus status = urlStatusCache.getIfPresent(url);
|
||||
if (status == null) {
|
||||
@@ -159,9 +145,7 @@ public class CommonRequest {
|
||||
return currentTime < status.getNextAllowTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理请求成功
|
||||
*/
|
||||
/** 处理请求成功 */
|
||||
private static void handleSuccess(String url) {
|
||||
UrlStatus status = urlStatusCache.getIfPresent(url);
|
||||
if (status != null) {
|
||||
@@ -172,9 +156,7 @@ public class CommonRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理请求失败 - 智能退避策略
|
||||
*/
|
||||
/** 处理请求失败 - 智能退避策略 */
|
||||
private static void handleFailure(String url) {
|
||||
UrlStatus status = urlStatusCache.getIfPresent(url);
|
||||
if (status == null) {
|
||||
@@ -190,8 +172,12 @@ public class CommonRequest {
|
||||
status.setNextAllowTime(System.currentTimeMillis() + delayMillis);
|
||||
|
||||
String delayInfo = formatDelayInfo(delayMillis);
|
||||
log.warn("URL[{}]第{}次失败,采用{}策略,下次可访问时间:{}", url, failureCount,
|
||||
getStrategyLevel(failureCount), delayInfo);
|
||||
log.warn(
|
||||
"URL[{}]第{}次失败,采用{}策略,下次可访问时间:{}",
|
||||
url,
|
||||
failureCount,
|
||||
getStrategyLevel(failureCount),
|
||||
delayInfo);
|
||||
|
||||
// 严重故障时发送通知
|
||||
if (failureCount >= LEVEL_3_THRESHOLD) {
|
||||
@@ -199,9 +185,7 @@ public class CommonRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算延迟时间 - 指数退避算法
|
||||
*/
|
||||
/** 计算延迟时间 - 指数退避算法 */
|
||||
private static long calculateDelay(int failureCount) {
|
||||
if (failureCount <= 1) {
|
||||
return 0; // 首次失败不延迟
|
||||
@@ -226,9 +210,7 @@ public class CommonRequest {
|
||||
return delaySeconds * 1000; // 转换为毫秒
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取策略级别描述
|
||||
*/
|
||||
/** 获取策略级别描述 */
|
||||
private static String getStrategyLevel(int failureCount) {
|
||||
if (failureCount <= LEVEL_1_THRESHOLD) {
|
||||
return "轻微故障-线性退避";
|
||||
@@ -239,9 +221,7 @@ public class CommonRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化延迟信息
|
||||
*/
|
||||
/** 格式化延迟信息 */
|
||||
private static String formatDelayInfo(long delayMillis) {
|
||||
long seconds = delayMillis / 1000;
|
||||
if (seconds < 60) {
|
||||
@@ -257,16 +237,15 @@ public class CommonRequest {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送失败通知
|
||||
*/
|
||||
/** 发送失败通知 */
|
||||
private static void sendFailureNotification(String url, int failureCount) {
|
||||
String noticeKey = CACHE_NOTICE + url;
|
||||
UrlStatus noticeStatus = urlStatusCache.getIfPresent(noticeKey);
|
||||
|
||||
// 每小时最多发送一次通知
|
||||
if (noticeStatus == null || (System.currentTimeMillis() - noticeStatus.getLastFailureTime())
|
||||
> TimeUnit.HOURS.toMillis(1)) {
|
||||
if (noticeStatus == null
|
||||
|| (System.currentTimeMillis() - noticeStatus.getLastFailureTime())
|
||||
> TimeUnit.HOURS.toMillis(1)) {
|
||||
|
||||
log.error("严重故障警告:URL[{}]连续失败{}次,已进入长时间限制状态", url, failureCount);
|
||||
|
||||
@@ -276,6 +255,7 @@ public class CommonRequest {
|
||||
urlStatusCache.put(noticeKey, newNoticeStatus);
|
||||
|
||||
// TODO: 集成钉钉/企微等通知
|
||||
// DingTalkUtil.send("严重故障:地址 " + url + " 连续失败 " + failureCount + " 次");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -178,7 +178,7 @@ public abstract class IoTDownAdapter<T extends BaseDownRequest> {
|
||||
.createTime(System.currentTimeMillis() / 1000)
|
||||
.deviceName(downRequest.getData().getStr("deviceName", downRequest.getDeviceId()))
|
||||
.state(DeviceStatus.offline.getCode())
|
||||
.iotId(IdUtil.simpleUUID())
|
||||
.iotId(downRequest.getProductKey()+downRequest.getDeviceId())
|
||||
.application(downRequest.getApplicationId())
|
||||
.creatorId(downRequest.getAppUnionId())
|
||||
.productName(downRequest.getIoTProduct().getName())
|
||||
|
||||
+1
-2
@@ -17,8 +17,7 @@ import lombok.NoArgsConstructor;
|
||||
@Builder
|
||||
public class IoTCertificate implements Serializable {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
@Id private Long id;
|
||||
|
||||
@Column(name = "ssl_key")
|
||||
private String sslKey;
|
||||
|
||||
+8
-24
@@ -32,51 +32,35 @@ public class IoTDashboardStatistics implements Serializable {
|
||||
@KeySql(useGeneratedKeys = true)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 统计日期
|
||||
*/
|
||||
/** 统计日期 */
|
||||
@Column(name = "stat_date")
|
||||
private LocalDate statDate;
|
||||
|
||||
/**
|
||||
* 产品Key,NULL表示全产品
|
||||
*/
|
||||
/** 产品Key,NULL表示全产品 */
|
||||
@Column(name = "product_key")
|
||||
private String productKey;
|
||||
|
||||
/**
|
||||
* 推送渠道,NULL表示全渠道
|
||||
*/
|
||||
/** 推送渠道,NULL表示全渠道 */
|
||||
@Column(name = "channel")
|
||||
private String channel;
|
||||
|
||||
/**
|
||||
* 指标类型
|
||||
*/
|
||||
/** 指标类型 */
|
||||
@Column(name = "metric_type")
|
||||
private String metricType;
|
||||
|
||||
/**
|
||||
* 指标值
|
||||
*/
|
||||
/** 指标值 */
|
||||
@Column(name = "metric_value")
|
||||
private Long metricValue;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
/** 创建时间 */
|
||||
@Column(name = "create_time")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
/** 更新时间 */
|
||||
@Column(name = "update_time")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/**
|
||||
* 指标类型枚举
|
||||
*/
|
||||
/** 指标类型枚举 */
|
||||
public enum MetricType {
|
||||
DEVICE_TOTAL("device_total", "设备总数"),
|
||||
DEVICE_ONLINE("device_online", "在线设备数"),
|
||||
|
||||
+26
-75
@@ -33,90 +33,63 @@ import lombok.NoArgsConstructor;
|
||||
public class IoTDevice implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Id
|
||||
private Long id;
|
||||
@Id private Long id;
|
||||
|
||||
/**
|
||||
* 对外设备唯一标识符
|
||||
*/
|
||||
/** 对外设备唯一标识符 */
|
||||
@Column(name = "iot_id")
|
||||
private String iotId;
|
||||
|
||||
/**
|
||||
* 设备自身序号
|
||||
*/
|
||||
/** 设备自身序号 */
|
||||
@Excel(name = "设备序列号")
|
||||
@Column(name = "device_id")
|
||||
private String deviceId;
|
||||
|
||||
/**
|
||||
* 实例名称
|
||||
*/
|
||||
/** 实例名称 */
|
||||
// @Excel(name = "实例名称")
|
||||
@Column(name = "instance")
|
||||
private String instance;
|
||||
|
||||
/**
|
||||
* 归属应用
|
||||
*/
|
||||
/** 归属应用 */
|
||||
@Column(name = "application")
|
||||
private String application;
|
||||
|
||||
/**
|
||||
* 激活时间
|
||||
*/
|
||||
/** 激活时间 */
|
||||
@Column(name = "registry_time")
|
||||
private Integer registryTime;
|
||||
|
||||
/**
|
||||
* 最后上线时间
|
||||
*/
|
||||
/** 最后上线时间 */
|
||||
@Column(name = "online_time")
|
||||
private Long onlineTime;
|
||||
|
||||
/**
|
||||
* 第三方设备ID唯一标识符
|
||||
*/
|
||||
/** 第三方设备ID唯一标识符 */
|
||||
@Column(name = "ext_device_id")
|
||||
private String extDeviceId;
|
||||
|
||||
/**
|
||||
* 别名
|
||||
*/
|
||||
/** 别名 */
|
||||
@Column(name = "nick_name")
|
||||
private String nickName;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
/** 设备名称 */
|
||||
@Column(name = "product_name")
|
||||
private String productName;
|
||||
|
||||
private Long features;
|
||||
|
||||
/**
|
||||
* 网关产品ProductKey
|
||||
*/
|
||||
/** 网关产品ProductKey */
|
||||
@Excel(name = "网关产品ProductKey")
|
||||
@Column(name = "gw_product_key")
|
||||
private String gwProductKey;
|
||||
|
||||
/**
|
||||
* 设备密钥
|
||||
*/
|
||||
/** 设备密钥 */
|
||||
@Excel(name = "设备密钥")
|
||||
@Column(name = "device_secret")
|
||||
private String deviceSecret;
|
||||
|
||||
/**
|
||||
* 产品key
|
||||
*/
|
||||
/** 产品key */
|
||||
@Column(name = "product_key")
|
||||
private String productKey;
|
||||
|
||||
/**
|
||||
* 设备实例名称
|
||||
*/
|
||||
/** 设备实例名称 */
|
||||
@Excel(name = "设备名称")
|
||||
@Column(name = "device_name")
|
||||
private String deviceName;
|
||||
@@ -127,68 +100,46 @@ public class IoTDevice implements Serializable {
|
||||
@Column(name = "creator_name")
|
||||
private String creatorName;
|
||||
|
||||
/**
|
||||
* 0-离线,1-在线
|
||||
*/
|
||||
/** 0-离线,1-在线 */
|
||||
@Excel(name = "在线状态")
|
||||
private Boolean state;
|
||||
|
||||
/**
|
||||
* 说明
|
||||
*/
|
||||
/** 说明 */
|
||||
@Excel(name = "备注")
|
||||
private String detail;
|
||||
|
||||
@Column(name = "create_time")
|
||||
private Long createTime;
|
||||
|
||||
/**
|
||||
* 派生元数据,有的设备的属性,功能,事件可能会动态的添加
|
||||
*/
|
||||
/** 派生元数据,有的设备的属性,功能,事件可能会动态的添加 */
|
||||
@Column(name = "derive_metadata")
|
||||
private String deriveMetadata;
|
||||
|
||||
/**
|
||||
* 其他配置
|
||||
*/
|
||||
/** 其他配置 */
|
||||
@Column(name = "configuration")
|
||||
private String configuration;
|
||||
|
||||
/**
|
||||
* 区域ID
|
||||
*/
|
||||
/** 区域ID */
|
||||
private String areasId;
|
||||
|
||||
/**
|
||||
* 坐标
|
||||
*/
|
||||
/** 坐标 */
|
||||
// @Excel(name = "设备坐标")
|
||||
private String coordinate;
|
||||
|
||||
@Transient
|
||||
private String deviceNode;
|
||||
@Transient private String deviceNode;
|
||||
|
||||
/**
|
||||
* 纬度
|
||||
*/
|
||||
/** 纬度 */
|
||||
@Excel(name = "纬度")
|
||||
private transient String latitude;
|
||||
|
||||
/**
|
||||
* 经度
|
||||
*/
|
||||
/** 经度 */
|
||||
@Excel(name = "经度")
|
||||
private transient String longitude;
|
||||
|
||||
/**
|
||||
* 请求参数
|
||||
*/
|
||||
@Builder.Default
|
||||
private Map<String, Object> params = new HashMap<>();
|
||||
/** 请求参数 */
|
||||
@Builder.Default private Map<String, Object> params = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 接收额外参数
|
||||
*/
|
||||
/** 接收额外参数 */
|
||||
@Excel(name = "其他配置")
|
||||
@Builder.Default
|
||||
private Map<String, Object> otherParams = new HashMap<>();
|
||||
|
||||
+6
-18
@@ -20,34 +20,22 @@ import lombok.Data;
|
||||
@Builder
|
||||
public class IoTDeviceEvents implements Serializable {
|
||||
|
||||
/**
|
||||
* 事件标识
|
||||
*/
|
||||
/** 事件标识 */
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 事件名称
|
||||
*/
|
||||
/** 事件名称 */
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 事件级别
|
||||
*/
|
||||
/** 事件级别 */
|
||||
private String level;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
/** 描述 */
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 事件总数
|
||||
*/
|
||||
/** 事件总数 */
|
||||
private String qty;
|
||||
|
||||
/**
|
||||
* 最新事件上报时间
|
||||
*/
|
||||
/** 最新事件上报时间 */
|
||||
private String time;
|
||||
|
||||
// 是否设置存储策略
|
||||
|
||||
+6
-17
@@ -33,31 +33,20 @@ import lombok.NoArgsConstructor;
|
||||
@Builder
|
||||
public class IoTDeviceFenceRel implements Serializable {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
@Id private Long id;
|
||||
|
||||
/**
|
||||
* 围栏id
|
||||
*/
|
||||
/** 围栏id */
|
||||
private Long fenceId;
|
||||
|
||||
/**
|
||||
* 设备唯一标识符
|
||||
*/
|
||||
/** 设备唯一标识符 */
|
||||
private String iotId;
|
||||
|
||||
/**
|
||||
* 设备序列号
|
||||
*/
|
||||
/** 设备序列号 */
|
||||
private String deviceId;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
/** 创建人 */
|
||||
private String creatorId;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
/** 创建时间 */
|
||||
private Date createDate;
|
||||
}
|
||||
|
||||
+6
-18
@@ -20,33 +20,21 @@ import lombok.Data;
|
||||
@Builder
|
||||
public class IoTDeviceFunction implements Serializable {
|
||||
|
||||
/**
|
||||
* 功能标识
|
||||
*/
|
||||
/** 功能标识 */
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 功能名称
|
||||
*/
|
||||
/** 功能名称 */
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 是否是配置
|
||||
*/
|
||||
/** 是否是配置 */
|
||||
private boolean config;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
/** 描述 */
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 功能来源
|
||||
*/
|
||||
/** 功能来源 */
|
||||
private String source;
|
||||
|
||||
/**
|
||||
* 输入
|
||||
*/
|
||||
/** 输入 */
|
||||
private String inputs;
|
||||
}
|
||||
|
||||
+1
-3
@@ -55,8 +55,6 @@ public class IoTDeviceFunctionTask implements Serializable {
|
||||
private String command;
|
||||
private String commandData;
|
||||
|
||||
/**
|
||||
* 状态 0.待执行;1.已执行;2.正在执行
|
||||
*/
|
||||
/** 状态 0.待执行;1.已执行;2.正在执行 */
|
||||
private Integer status;
|
||||
}
|
||||
|
||||
+17
-50
@@ -42,86 +42,53 @@ public class IoTDeviceGeoFence implements Serializable {
|
||||
@KeySql(genId = SQenGenId.class)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 围栏名称
|
||||
*/
|
||||
/** 围栏名称 */
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 围栏状态 0.启用 1.停用
|
||||
*/
|
||||
/** 围栏状态 0.启用 1.停用 */
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 触发模式 in.进入 out.离开 all.进入&离开
|
||||
*/
|
||||
/** 触发模式 in.进入 out.离开 all.进入&离开 */
|
||||
private String touchWay;
|
||||
|
||||
/**
|
||||
* 范围
|
||||
*/
|
||||
/** 范围 */
|
||||
private String fence;
|
||||
|
||||
/**
|
||||
* 类型 circle.圆 polygon.多边形
|
||||
*/
|
||||
/** 类型 circle.圆 polygon.多边形 */
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 圆形中心点
|
||||
*/
|
||||
/** 圆形中心点 */
|
||||
private String point;
|
||||
|
||||
/**
|
||||
* 半径
|
||||
*/
|
||||
/** 半径 */
|
||||
private BigDecimal radius;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
/** 创建人 */
|
||||
private String creatorId;
|
||||
|
||||
/**
|
||||
* 周触发(天)
|
||||
*/
|
||||
/** 周触发(天) */
|
||||
private String weekTime;
|
||||
|
||||
/**
|
||||
* 天触发开始时间(时)
|
||||
*/
|
||||
/** 天触发开始时间(时) */
|
||||
private String beginTime;
|
||||
|
||||
/**
|
||||
* 天触发结束时间(时)
|
||||
*/
|
||||
/** 天触发结束时间(时) */
|
||||
private String endTime;
|
||||
|
||||
/**
|
||||
* 归属第三方应用
|
||||
*/
|
||||
/** 归属第三方应用 */
|
||||
private String creatorUser;
|
||||
|
||||
@Transient
|
||||
private List<String> queryUserList;
|
||||
@Transient private List<String> queryUserList;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
/** 创建时间 */
|
||||
private Date createDate;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
/** 更新时间 */
|
||||
private Date updateDate;
|
||||
|
||||
/**
|
||||
* 不触发时间
|
||||
*/
|
||||
/** 不触发时间 */
|
||||
private String noTriggerTime;
|
||||
|
||||
/**
|
||||
* 延迟时间 分钟
|
||||
*/
|
||||
/** 延迟时间 分钟 */
|
||||
private Integer delayTime;
|
||||
}
|
||||
|
||||
+12
-36
@@ -32,76 +32,52 @@ public class IoTDeviceGroup implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 分组ID,非自增
|
||||
*/
|
||||
/** 分组ID,非自增 */
|
||||
@Id
|
||||
@KeySql(genId = SQenGenId.class)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 分组名称
|
||||
*/
|
||||
/** 分组名称 */
|
||||
@Column(name = "group_name")
|
||||
private String groupName;
|
||||
|
||||
/**
|
||||
* 分组标识
|
||||
*/
|
||||
/** 分组标识 */
|
||||
@Column(name = "group_code")
|
||||
private String groupCode;
|
||||
|
||||
/**
|
||||
* 群组描述
|
||||
*/
|
||||
/** 群组描述 */
|
||||
@Column(name = "group_describe")
|
||||
private String groupDescribe;
|
||||
|
||||
/**
|
||||
* 父id
|
||||
*/
|
||||
/** 父id */
|
||||
@Column(name = "parent_id")
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 是否有子分组
|
||||
*/
|
||||
/** 是否有子分组 */
|
||||
@Column(name = "has_child")
|
||||
private Integer hasChild;
|
||||
|
||||
/**
|
||||
* 分组级别
|
||||
*/
|
||||
/** 分组级别 */
|
||||
@Column(name = "group_level")
|
||||
private Integer groupLevel;
|
||||
|
||||
/**
|
||||
* 激活设备数
|
||||
*/
|
||||
/** 激活设备数 */
|
||||
@Column(name = "relat_dev_count")
|
||||
private Integer relatDevCount;
|
||||
|
||||
/**
|
||||
* 关联设备树
|
||||
*/
|
||||
/** 关联设备树 */
|
||||
@Column(name = "active_dev_count")
|
||||
private Integer activeDevCount;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
/** 创建人 */
|
||||
@Column(name = "creator_id")
|
||||
private String creatorId;
|
||||
|
||||
/**
|
||||
* 实例编号
|
||||
*/
|
||||
/** 实例编号 */
|
||||
@Column(name = "instance")
|
||||
private String instance;
|
||||
|
||||
/**
|
||||
* 标签
|
||||
*/
|
||||
/** 标签 */
|
||||
@Column(name = "tag")
|
||||
private String tag;
|
||||
}
|
||||
|
||||
+14
-49
@@ -16,6 +16,7 @@ import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
@@ -28,83 +29,47 @@ import lombok.NoArgsConstructor;
|
||||
@Builder
|
||||
public class IoTDeviceLog implements Serializable {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
@Id private Long id;
|
||||
|
||||
/**
|
||||
* 唯一编码
|
||||
*/
|
||||
@Column(name = "iot_id")
|
||||
/** 唯一编码 */
|
||||
@Column(name = "iot_id", length = 128)
|
||||
private String iotId;
|
||||
|
||||
/**
|
||||
* 设备自身序号
|
||||
*/
|
||||
/** 设备自身序号 */
|
||||
@Column(name = "device_id")
|
||||
private String deviceId;
|
||||
|
||||
/**
|
||||
* 第三方设备ID唯一标识符
|
||||
*/
|
||||
// @Transient
|
||||
@Column(name = "ext_device_id")
|
||||
private String extDeviceId;
|
||||
|
||||
/**
|
||||
* 产品ID
|
||||
*/
|
||||
/** 产品ID */
|
||||
@Column(name = "product_key")
|
||||
private String productKey;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
/** 设备名称 */
|
||||
@Column(name = "device_name")
|
||||
private String deviceName;
|
||||
|
||||
/**
|
||||
* 消息类型
|
||||
*/
|
||||
/** 消息类型 */
|
||||
@Column(name = "message_type")
|
||||
private String messageType;
|
||||
|
||||
/**
|
||||
* 指令ID
|
||||
*/
|
||||
/** 指令ID */
|
||||
@Column(name = "command_id")
|
||||
private String commandId;
|
||||
|
||||
/**
|
||||
* 指令ID
|
||||
*/
|
||||
/** 指令ID */
|
||||
@Column(name = "command_status")
|
||||
private Integer commandStatus;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
@Column(name = "create_id")
|
||||
private String createId;
|
||||
|
||||
/**
|
||||
* 事件名称
|
||||
*/
|
||||
/** 事件名称 */
|
||||
private String event;
|
||||
|
||||
/**
|
||||
* 实例名称
|
||||
*/
|
||||
private String instance;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
/** 创建时间 */
|
||||
@Column(name = "create_time")
|
||||
private Long createTime;
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 内容
|
||||
*/
|
||||
/** 内容 */
|
||||
private String content;
|
||||
|
||||
private String point;
|
||||
|
||||
+12
-23
@@ -16,6 +16,7 @@ import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
@@ -28,38 +29,30 @@ import lombok.NoArgsConstructor;
|
||||
@Builder
|
||||
public class IoTDeviceLogMetadata implements Serializable {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
@Id private Long id;
|
||||
|
||||
@Column(name = "iot_id")
|
||||
private String iotId;
|
||||
|
||||
/**
|
||||
* 产品唯一标识
|
||||
*/
|
||||
/** 产品唯一标识 */
|
||||
@Column(name = "product_key")
|
||||
private String productKey;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
@Column(name = "device_name")
|
||||
/** 设备名称 */
|
||||
@Column(name = "device_name", length = 64)
|
||||
private String deviceName;
|
||||
|
||||
@Column(name = "device_id")
|
||||
@Column(name = "device_id", length = 64)
|
||||
private String deviceId;
|
||||
|
||||
/**
|
||||
* 消息类型
|
||||
*/
|
||||
/** 消息类型 */
|
||||
@Column(name = "message_type")
|
||||
private String messageType;
|
||||
|
||||
@Column(length = 32)
|
||||
private String event;
|
||||
|
||||
/**
|
||||
* 属性
|
||||
*/
|
||||
/** 属性 */
|
||||
private String property;
|
||||
|
||||
private String ext1;
|
||||
@@ -68,15 +61,11 @@ public class IoTDeviceLogMetadata implements Serializable {
|
||||
|
||||
private String ext3;
|
||||
|
||||
/**
|
||||
* 发生时间
|
||||
*/
|
||||
/** 发生时间 */
|
||||
@Column(name = "create_time")
|
||||
private Integer createTime;
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 其他
|
||||
*/
|
||||
/** 其他 */
|
||||
private String content;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
+8
-24
@@ -22,43 +22,27 @@ public class IoTDeviceProperties implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 属性标识
|
||||
*/
|
||||
/** 属性标识 */
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 属性名称
|
||||
*/
|
||||
/** 属性名称 */
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 数据类型
|
||||
*/
|
||||
/** 数据类型 */
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 属性值来源
|
||||
*/
|
||||
/** 属性值来源 */
|
||||
private String source;
|
||||
|
||||
/**
|
||||
* 单位
|
||||
*/
|
||||
/** 单位 */
|
||||
private String unit;
|
||||
|
||||
/**
|
||||
* 枚举键值
|
||||
*/
|
||||
/** 枚举键值 */
|
||||
private String elements;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
/** 描述 */
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 读写
|
||||
*/
|
||||
/** 读写 */
|
||||
private String mode;
|
||||
}
|
||||
|
||||
+1
-2
@@ -36,8 +36,7 @@ public class IoTDeviceProtocol implements Serializable {
|
||||
private String name;
|
||||
private String description;
|
||||
private Byte state;
|
||||
@Id
|
||||
private String id;
|
||||
@Id private String id;
|
||||
private String type;
|
||||
private String configuration;
|
||||
private String example;
|
||||
|
||||
+6
-17
@@ -29,36 +29,25 @@ import lombok.NoArgsConstructor;
|
||||
@Builder
|
||||
public class IoTDeviceRuleLog implements Serializable {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
@Id private Long id;
|
||||
|
||||
/**
|
||||
* 业务ID
|
||||
*/
|
||||
/** 业务ID */
|
||||
@Column(name = "c_id")
|
||||
private String cId;
|
||||
|
||||
/**
|
||||
* 业务名称
|
||||
*/
|
||||
/** 业务名称 */
|
||||
@Column(name = "c_name")
|
||||
private String cName;
|
||||
|
||||
/**
|
||||
* 执行状态
|
||||
*/
|
||||
/** 执行状态 */
|
||||
@Column(name = "c_status")
|
||||
private Byte cStatus;
|
||||
|
||||
/**
|
||||
* 1-场景联动,2-数据流转
|
||||
*/
|
||||
/** 1-场景联动,2-数据流转 */
|
||||
@Column(name = "c_type")
|
||||
private Byte cType;
|
||||
|
||||
/**
|
||||
* 条件
|
||||
*/
|
||||
/** 条件 */
|
||||
private String conditions;
|
||||
|
||||
@Column(name = "create_time")
|
||||
|
||||
+10
-29
@@ -29,60 +29,41 @@ import lombok.NoArgsConstructor;
|
||||
@Builder
|
||||
public class IoTDeviceShadow implements Serializable {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
@Id private Long id;
|
||||
|
||||
/**
|
||||
* 本平台设备唯一标识符
|
||||
*/
|
||||
/** 本平台设备唯一标识符 */
|
||||
@Column(name = "iot_id")
|
||||
private String iotId;
|
||||
|
||||
/**
|
||||
* 产品KEY
|
||||
*/
|
||||
/** 产品KEY */
|
||||
@Column(name = "product_key")
|
||||
private String productKey;
|
||||
|
||||
/**
|
||||
* 设备自身序号
|
||||
*/
|
||||
/** 设备自身序号 */
|
||||
@Column(name = "device_id")
|
||||
private String deviceId;
|
||||
|
||||
/**
|
||||
* 第三方平台设备ID唯一标识符
|
||||
*/
|
||||
/** 第三方平台设备ID唯一标识符 */
|
||||
@Column(name = "ext_device_id")
|
||||
private String extDeviceId;
|
||||
|
||||
/**
|
||||
* 注册时间
|
||||
*/
|
||||
/** 注册时间 */
|
||||
@Column(name = "active_time")
|
||||
private Date activeTime;
|
||||
|
||||
/**
|
||||
* 激活时间
|
||||
*/
|
||||
/** 激活时间 */
|
||||
@Column(name = "online_time")
|
||||
private Date onlineTime;
|
||||
|
||||
/**
|
||||
* 最后通信时间
|
||||
*/
|
||||
/** 最后通信时间 */
|
||||
@Column(name = "last_time")
|
||||
private Date lastTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
/** 更新时间 */
|
||||
@Column(name = "update_date")
|
||||
private Date updateDate;
|
||||
|
||||
/**
|
||||
* 影子数据
|
||||
*/
|
||||
/** 影子数据 */
|
||||
private String metadata;
|
||||
|
||||
@Column(name = "`instance`")
|
||||
|
||||
+12
-35
@@ -30,70 +30,47 @@ import lombok.NoArgsConstructor;
|
||||
@Builder
|
||||
public class IoTDeviceSubscribe implements Serializable {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
@Id private Long id;
|
||||
|
||||
/**
|
||||
* 消息类别:属性(PROPERTIES),指令(REPLY),事件(EVENT),上下线(EVENT:online,offline),所有
|
||||
*/
|
||||
/** 消息类别:属性(PROPERTIES),指令(REPLY),事件(EVENT),上下线(EVENT:online,offline),所有 */
|
||||
@Column(name = "msg_type")
|
||||
private String msgType;
|
||||
|
||||
/**
|
||||
* 订阅级别:设备级,产品级
|
||||
*/
|
||||
/** 订阅级别:设备级,产品级 */
|
||||
@Column(name = "sub_type")
|
||||
private String subType;
|
||||
|
||||
/**
|
||||
* 设备deviceId
|
||||
*/
|
||||
/** 设备deviceId */
|
||||
@Column(name = "device_id")
|
||||
private String deviceId;
|
||||
|
||||
/**
|
||||
* 产品ID或者设备唯一标识
|
||||
*/
|
||||
/** 产品ID或者设备唯一标识 */
|
||||
@Column(name = "product_key")
|
||||
private String productKey;
|
||||
|
||||
/**
|
||||
* 产品ID或者设备唯一标识
|
||||
*/
|
||||
/** 产品ID或者设备唯一标识 */
|
||||
@Column(name = "iot_id")
|
||||
private String iotId;
|
||||
|
||||
/**
|
||||
* 订阅地址
|
||||
*/
|
||||
/** 订阅地址 */
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* 主题
|
||||
*/
|
||||
/** 主题 */
|
||||
private String topic;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
/** 创建时间 */
|
||||
@Column(name = "create_date")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createDate;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
/** 创建人 */
|
||||
private String creater;
|
||||
|
||||
/**
|
||||
* 实例编号(应用标识)
|
||||
*/
|
||||
/** 实例编号(应用标识) */
|
||||
@Column(name = "`instance`")
|
||||
private String instance;
|
||||
|
||||
/**
|
||||
* 是否启用
|
||||
*/
|
||||
/** 是否启用 */
|
||||
private Boolean enabled;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
+3
-8
@@ -28,18 +28,13 @@ import lombok.NoArgsConstructor;
|
||||
@Builder
|
||||
public class IoTDeviceTags implements Serializable {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
@Id private Long id;
|
||||
|
||||
/**
|
||||
* 设备deviceId
|
||||
*/
|
||||
/** 设备deviceId */
|
||||
@Column(name = "device_id")
|
||||
private String deviceId;
|
||||
|
||||
/**
|
||||
* 产品ID或者设备唯一标识
|
||||
*/
|
||||
/** 产品ID或者设备唯一标识 */
|
||||
@Column(name = "product_key")
|
||||
private String productKey;
|
||||
|
||||
|
||||
+29
-80
@@ -12,6 +12,7 @@
|
||||
|
||||
package cn.universal.persistence.entity;
|
||||
|
||||
import cn.universal.persistence.annotation.SensitiveField;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
@@ -31,155 +32,103 @@ public class IoTProduct implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@Id
|
||||
private Long id;
|
||||
/** 主键ID */
|
||||
@Id private Long id;
|
||||
|
||||
/**
|
||||
* 产品编号
|
||||
*/
|
||||
/** 产品编号 */
|
||||
@Column(name = "product_id")
|
||||
private String productId;
|
||||
|
||||
/**
|
||||
* 产品标签
|
||||
*/
|
||||
/** 产品标签 */
|
||||
@Column(name = "tags")
|
||||
private String tags;
|
||||
|
||||
/**
|
||||
* 产品KEY
|
||||
*/
|
||||
/** 产品KEY */
|
||||
@Column(name = "product_key")
|
||||
private String productKey;
|
||||
|
||||
/**
|
||||
* 产品密钥(1型1密)
|
||||
*/
|
||||
/** 产品密钥(1型1密) */
|
||||
@Column(name = "product_secret")
|
||||
@SensitiveField(showPrefix = 3, showSuffix = 3)
|
||||
private String productSecret;
|
||||
|
||||
/**
|
||||
* 第三方平台:lvzhou,ctwing,onenet,alibaba,baidu
|
||||
*/
|
||||
/** 第三方平台:lvzhou,ctwing,onenet,alibaba,baidu */
|
||||
@Column(name = "third_platform")
|
||||
private String thirdPlatform;
|
||||
|
||||
/**
|
||||
* 第三方平台配置信息
|
||||
*/
|
||||
/** 第三方平台配置信息 */
|
||||
@Column(name = "third_configuration")
|
||||
private String thirdConfiguration;
|
||||
|
||||
/**
|
||||
* 厂商编号
|
||||
*/
|
||||
/** 厂商编号 */
|
||||
@Column(name = "company_no")
|
||||
private String companyNo;
|
||||
|
||||
/**
|
||||
* 分类ID
|
||||
*/
|
||||
/** 分类ID */
|
||||
@Column(name = "classified_id")
|
||||
private String classifiedId;
|
||||
|
||||
/**
|
||||
* 网络组件:关联network表
|
||||
*/
|
||||
/** 网络组件:关联network表 */
|
||||
@Column(name = "network_union_id")
|
||||
private String networkUnionId;
|
||||
|
||||
/**
|
||||
* 设备类型: 网关,设备
|
||||
*/
|
||||
/** 设备类型: 网关,设备 */
|
||||
@Column(name = "device_node")
|
||||
private String deviceNode;
|
||||
|
||||
/**
|
||||
* 所属项目
|
||||
*/
|
||||
/** 所属项目 */
|
||||
@Column(name = "gw_product_key")
|
||||
private String gwProductKey;
|
||||
|
||||
/**
|
||||
* 分类名称
|
||||
*/
|
||||
/** 分类名称 */
|
||||
@Column(name = "classified_name")
|
||||
private String classifiedName;
|
||||
|
||||
/**
|
||||
* 消息协议:
|
||||
*/
|
||||
/** 消息协议: */
|
||||
@Column(name = "message_protocol")
|
||||
private String messageProtocol;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
/** 名称 */
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 创建者id
|
||||
*/
|
||||
/** 创建者id */
|
||||
@Column(name = "creator_id")
|
||||
private String creatorId;
|
||||
|
||||
/**
|
||||
* 产品状态
|
||||
*/
|
||||
/** 产品状态 */
|
||||
private Byte state;
|
||||
|
||||
/**
|
||||
* 说明
|
||||
*/
|
||||
/** 说明 */
|
||||
@Column(name = "`describe`")
|
||||
private String describe;
|
||||
|
||||
/**
|
||||
* 数据存储策略
|
||||
*/
|
||||
/** 数据存储策略 */
|
||||
@Column(name = "store_policy")
|
||||
private String storePolicy;
|
||||
|
||||
/**
|
||||
* 传输协议: MQTT,COAP,UDP
|
||||
*/
|
||||
/** 传输协议: MQTT,COAP,UDP */
|
||||
@Column(name = "transport_protocol")
|
||||
private String transportProtocol;
|
||||
|
||||
/**
|
||||
* 图片地址
|
||||
*/
|
||||
/** 图片地址 */
|
||||
@Column(name = "photo_url")
|
||||
private String photoUrl;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
/** 创建时间 */
|
||||
@Column(name = "create_time")
|
||||
private Long createTime;
|
||||
|
||||
/**
|
||||
* 协议配置
|
||||
*/
|
||||
/** 协议配置 */
|
||||
private String configuration;
|
||||
|
||||
/**
|
||||
* 数据存储策略配置
|
||||
*/
|
||||
/** 数据存储策略配置 */
|
||||
@Column(name = "store_policy_configuration")
|
||||
private String storePolicyConfiguration;
|
||||
|
||||
/**
|
||||
* 物模型
|
||||
*/
|
||||
/** 物模型 */
|
||||
private String metadata;
|
||||
|
||||
/**
|
||||
* 第三方平台产品下发信息
|
||||
*/
|
||||
/** 第三方平台产品下发信息 */
|
||||
private String thirdDownRequest;
|
||||
|
||||
@Column(name = "update_time")
|
||||
|
||||
+9
-27
@@ -28,57 +28,39 @@ public class IoTProductSort implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
/** id */
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 父id
|
||||
*/
|
||||
/** 父id */
|
||||
@Excel(name = "父id")
|
||||
private String parentId;
|
||||
|
||||
/**
|
||||
* 是否有子节点
|
||||
*/
|
||||
/** 是否有子节点 */
|
||||
@Excel(name = "是否有子节点")
|
||||
private Integer hasChild;
|
||||
|
||||
/**
|
||||
* 标识
|
||||
*/
|
||||
/** 标识 */
|
||||
@Excel(name = "标识")
|
||||
private String identification;
|
||||
|
||||
/**
|
||||
* 分类名称
|
||||
*/
|
||||
/** 分类名称 */
|
||||
@Excel(name = "分类名称")
|
||||
private String classifiedName;
|
||||
|
||||
/**
|
||||
* 说明
|
||||
*/
|
||||
/** 说明 */
|
||||
@Excel(name = "说明")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
/** 创建时间 */
|
||||
@Excel(name = "创建时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
/** 创建者 */
|
||||
@Excel(name = "创建者")
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 子分类
|
||||
*/
|
||||
/** 子分类 */
|
||||
private List<IoTProductSort> children = new ArrayList<IoTProductSort>();
|
||||
|
||||
public List<IoTProductSort> getChildren() {
|
||||
|
||||
+23
-67
@@ -40,109 +40,76 @@ import lombok.NoArgsConstructor;
|
||||
public class IoTUser implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Id
|
||||
private Long id;
|
||||
@Id private Long id;
|
||||
|
||||
/**
|
||||
* 归属组织机构
|
||||
*/
|
||||
/** 归属组织机构 */
|
||||
@Column(name = "org_id")
|
||||
@Excel(name = "归属组织机构")
|
||||
private Long orgId;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
/** 用户名 */
|
||||
@Excel(name = "用户名")
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
/** 密码 */
|
||||
@JsonIgnore
|
||||
@Excel(name = "密码")
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 别名
|
||||
*/
|
||||
/** 别名 */
|
||||
@Excel(name = "别名")
|
||||
private String alias;
|
||||
|
||||
/**
|
||||
* 用户唯一标识
|
||||
*/
|
||||
/** 用户唯一标识 */
|
||||
@Excel(name = "用户唯一标识")
|
||||
@Column(name = "union_id")
|
||||
private String unionId;
|
||||
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
/** 邮箱 */
|
||||
@Excel(name = "邮箱")
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 密码加盐
|
||||
*/
|
||||
/** 密码加盐 */
|
||||
@Excel(name = "密码加盐")
|
||||
private String salt;
|
||||
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
/** 手机号 */
|
||||
@Excel(name = "手机号")
|
||||
private String mobile;
|
||||
|
||||
/**
|
||||
* 账号状态(0正常,1停用)
|
||||
*/
|
||||
/** 账号状态(0正常,1停用) */
|
||||
@Excel(name = "账号状态(0正常,1停用")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
/** 头像 */
|
||||
@Excel(name = "头像")
|
||||
private String avatar;
|
||||
|
||||
/**
|
||||
* 上级用户唯一id
|
||||
*/
|
||||
/** 上级用户唯一id */
|
||||
@Excel(name = "上级用户唯一id")
|
||||
private String parentUnionId;
|
||||
|
||||
/**
|
||||
* 账号身份 0.超级管理员 1.普通用户 2.子用户
|
||||
*/
|
||||
/** 账号身份 0.超级管理员 1.普通用户 2.子用户 */
|
||||
@Excel(name = "账号身份 0.超级管理员 1.普通用户 2.子用户")
|
||||
private Integer identity;
|
||||
|
||||
/**
|
||||
* 登录IP
|
||||
*/
|
||||
/** 登录IP */
|
||||
@Column(name = "login_ip")
|
||||
@Excel(name = "登录IP")
|
||||
private String loginIp;
|
||||
|
||||
/**
|
||||
* 登录时间
|
||||
*/
|
||||
/** 登录时间 */
|
||||
@Column(name = "login_date")
|
||||
@Excel(name = "登录时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date loginDate;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
/** 创建者 */
|
||||
@Column(name = "create_by")
|
||||
@Excel(name = "创建者")
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
/** 创建时间 */
|
||||
@Column(name = "create_date")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Excel(name = "创建时间")
|
||||
@@ -157,22 +124,16 @@ public class IoTUser implements Serializable {
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date updateDate;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
/** 备注 */
|
||||
@Excel(name = "备注")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 接入数
|
||||
*/
|
||||
/** 接入数 */
|
||||
@Column(name = "license")
|
||||
@Excel(name = "接入数")
|
||||
private Integer license;
|
||||
|
||||
/**
|
||||
* 接入数
|
||||
*/
|
||||
/** 接入数 */
|
||||
@Column(name = "license_total_amount")
|
||||
@Excel(name = "接入数总额度")
|
||||
private Integer licenseTotalAmount;
|
||||
@@ -183,16 +144,11 @@ public class IoTUser implements Serializable {
|
||||
@Excel(name = "注册来源")
|
||||
private String registerFrom;
|
||||
|
||||
/**
|
||||
* 0-正常,1-删除
|
||||
*/
|
||||
/** 0-正常,1-删除 */
|
||||
private Integer deleted;
|
||||
|
||||
/**
|
||||
* 请求参数
|
||||
*/
|
||||
@Builder.Default
|
||||
private Map<String, Object> params = new HashMap<>();
|
||||
/** 请求参数 */
|
||||
@Builder.Default private Map<String, Object> params = new HashMap<>();
|
||||
|
||||
public IoTUser(Long userId) {
|
||||
this.id = userId;
|
||||
|
||||
+8
-24
@@ -40,57 +40,41 @@ public class IoTUserApplication implements Serializable {
|
||||
@Excel(name = "用户唯一标识")
|
||||
private String unionId;
|
||||
|
||||
/**
|
||||
* 调用凭证APPID
|
||||
*/
|
||||
/** 调用凭证APPID */
|
||||
@Column(name = "app_id")
|
||||
@Excel(name = "调用凭证APPID")
|
||||
private String appId;
|
||||
|
||||
/**
|
||||
* MQ上行主题,英文逗号分隔
|
||||
*/
|
||||
/** MQ上行主题,英文逗号分隔 */
|
||||
@Column(name = "up_topic")
|
||||
@Excel(name = "MQ上行主题")
|
||||
private String upTopic;
|
||||
|
||||
/**
|
||||
* MQ下行主题,英文逗号分隔
|
||||
*/
|
||||
/** MQ下行主题,英文逗号分隔 */
|
||||
@Column(name = "down_topic")
|
||||
@Excel(name = "MQ下行主题")
|
||||
private String downTopic;
|
||||
|
||||
/**
|
||||
* 调用密钥
|
||||
*/
|
||||
/** 调用密钥 */
|
||||
@Column(name = "app_secret")
|
||||
@Excel(name = "调用密钥")
|
||||
private String appSecret;
|
||||
|
||||
/**
|
||||
* 授权结束时间
|
||||
*/
|
||||
/** 授权结束时间 */
|
||||
@Column(name = "valid_end_date")
|
||||
@Excel(name = "授权结束时间")
|
||||
private Date validEndDate;
|
||||
|
||||
/**
|
||||
* 授权范围
|
||||
*/
|
||||
/** 授权范围 */
|
||||
@Excel(name = "授权范围")
|
||||
private String scope;
|
||||
|
||||
/**
|
||||
* 0-正常,1-停用
|
||||
*/
|
||||
/** 0-正常,1-停用 */
|
||||
@Column(name = "app_status")
|
||||
@Excel(name = "应用状态 0-正常,1-停用")
|
||||
private Integer appStatus;
|
||||
|
||||
/**
|
||||
* 0-正常,1-删除
|
||||
*/
|
||||
/** 0-正常,1-删除 */
|
||||
@Excel(name = "是否删除 0正常 1删除")
|
||||
private Integer deleted;
|
||||
|
||||
|
||||
+7
-20
@@ -29,17 +29,12 @@ import lombok.NoArgsConstructor;
|
||||
@Builder
|
||||
public class Network implements Serializable {
|
||||
|
||||
@Id
|
||||
private Integer id;
|
||||
@Id private Integer id;
|
||||
|
||||
/**
|
||||
* TCP_CLIENT,MQTT_CLIENT,HTTP_CLIENT,WEB_SOCKET_CLIENT
|
||||
*/
|
||||
/** TCP_CLIENT,MQTT_CLIENT,HTTP_CLIENT,WEB_SOCKET_CLIENT */
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 唯一标识
|
||||
*/
|
||||
/** 唯一标识 */
|
||||
@Column(name = "product_key")
|
||||
private String productKey;
|
||||
|
||||
@@ -48,27 +43,19 @@ public class Network implements Serializable {
|
||||
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 详细描述
|
||||
*/
|
||||
/** 详细描述 */
|
||||
private String description;
|
||||
|
||||
@Column(name = "create_date")
|
||||
private Date createDate;
|
||||
|
||||
/**
|
||||
* enable,disable
|
||||
*/
|
||||
/** enable,disable */
|
||||
private Boolean state;
|
||||
|
||||
/**
|
||||
* 配置内容
|
||||
*/
|
||||
/** 配置内容 */
|
||||
private String configuration;
|
||||
|
||||
/**
|
||||
* 创建用户
|
||||
*/
|
||||
/** 创建用户 */
|
||||
@Column(name = "create_user")
|
||||
private String createUser;
|
||||
|
||||
|
||||
+13
-35
@@ -32,22 +32,16 @@ import lombok.experimental.Accessors;
|
||||
@Accessors(chain = true)
|
||||
public class OAuth2ClientDetails implements Serializable {
|
||||
|
||||
/**
|
||||
* 客户端标识
|
||||
*/
|
||||
/** 客户端标识 */
|
||||
@Id
|
||||
@Column(name = "client_id")
|
||||
private String clientId;
|
||||
|
||||
/**
|
||||
* 资源标识
|
||||
*/
|
||||
/** 资源标识 */
|
||||
@Column(name = "resource_ids")
|
||||
private String resourceIds;
|
||||
|
||||
/**
|
||||
* 客户端秘钥
|
||||
*/
|
||||
/** 客户端秘钥 */
|
||||
@Column(name = "client_secret")
|
||||
private String clientSecret;
|
||||
|
||||
@@ -60,50 +54,34 @@ public class OAuth2ClientDetails implements Serializable {
|
||||
@Column(name = "Authorized_grant_types")
|
||||
private String AuthorizedGrantTypes;
|
||||
|
||||
/**
|
||||
* 授权成功后回调URL
|
||||
*/
|
||||
/** 授权成功后回调URL */
|
||||
@Column(name = "web_server_redirect_uri")
|
||||
private String webServerRedirectUri;
|
||||
|
||||
private String Authorities;
|
||||
|
||||
/**
|
||||
* 访问令牌的有效时间
|
||||
*/
|
||||
/** 访问令牌的有效时间 */
|
||||
@Column(name = "access_token_validity")
|
||||
private Integer accessTokenValidity;
|
||||
|
||||
/**
|
||||
* 刷新令牌的有效时间
|
||||
*/
|
||||
/** 刷新令牌的有效时间 */
|
||||
@Column(name = "refresh_token_validity")
|
||||
private Integer refreshTokenValidity;
|
||||
|
||||
/**
|
||||
* 额外的信息,备用
|
||||
*/
|
||||
/** 额外的信息,备用 */
|
||||
@Column(name = "additional_information")
|
||||
private String additionalInformation;
|
||||
|
||||
/**
|
||||
* 自动批准标识:0代表不显示授权页面 1显示授权页面
|
||||
*/
|
||||
/** 自动批准标识:0代表不显示授权页面 1显示授权页面 */
|
||||
private String autoapprove;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
/** 用户名 */
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
/** 密码 */
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 唯一标识
|
||||
*/
|
||||
/** 唯一标识 */
|
||||
@Column(name = "iot_union_id")
|
||||
private String iotUnionId;
|
||||
|
||||
@@ -182,7 +160,7 @@ public class OAuth2ClientDetails implements Serializable {
|
||||
* client_credentials:客户端模式
|
||||
*
|
||||
* @return Authorized_grant_types - 授权类型 Authorization_code:授权码模式 refresh_token:刷新token
|
||||
* password:密码模式 implicit:隐私授权模式 client_credentials:客户端模式
|
||||
* password:密码模式 implicit:隐私授权模式 client_credentials:客户端模式
|
||||
*/
|
||||
public String getAuthorizedGrantTypes() {
|
||||
return AuthorizedGrantTypes;
|
||||
@@ -193,7 +171,7 @@ public class OAuth2ClientDetails implements Serializable {
|
||||
* client_credentials:客户端模式
|
||||
*
|
||||
* @param AuthorizedGrantTypes 授权类型 Authorization_code:授权码模式 refresh_token:刷新token password:密码模式
|
||||
* implicit:隐私授权模式 client_credentials:客户端模式
|
||||
* implicit:隐私授权模式 client_credentials:客户端模式
|
||||
*/
|
||||
public void setAuthorizedGrantTypes(String AuthorizedGrantTypes) {
|
||||
this.AuthorizedGrantTypes = AuthorizedGrantTypes;
|
||||
|
||||
+10
-30
@@ -39,75 +39,55 @@ public class RuleModel implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
/** 主键ID */
|
||||
@Id
|
||||
@KeySql(genId = SQenGenId.class)
|
||||
@Schema(description = "主键ID")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 规则名称
|
||||
*/
|
||||
/** 规则名称 */
|
||||
@Schema(description = "规则名称")
|
||||
@Column(name = "rule_name")
|
||||
private String ruleName;
|
||||
|
||||
/**
|
||||
* 数据级别
|
||||
*/
|
||||
/** 数据级别 */
|
||||
@Schema(description = "数据级别")
|
||||
@Column(name = "data_level")
|
||||
private String dataLevel;
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
/** 描述 */
|
||||
@Schema(description = "描述")
|
||||
@Column(name = "description")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
/** 状态 */
|
||||
@Schema(description = "状态")
|
||||
@Column(name = "status")
|
||||
private String status;
|
||||
|
||||
;
|
||||
|
||||
/**
|
||||
* 产品KEY
|
||||
*/
|
||||
/** 产品KEY */
|
||||
@Schema(description = "产品KEY")
|
||||
@Column(name = "product_key")
|
||||
private String productKey;
|
||||
|
||||
/**
|
||||
* 规则配置
|
||||
*/
|
||||
/** 规则配置 */
|
||||
@Schema(description = "规则配置")
|
||||
@Column(name = "config")
|
||||
private String config;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
/** 创建人 */
|
||||
@Schema(description = "创建人")
|
||||
@Column(name = "creator_id")
|
||||
private String creatorId;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
/** 创建时间 */
|
||||
@Schema(description = "创建时间")
|
||||
@Column(name = "create_time")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
/** 创建时间 */
|
||||
@Schema(description = "创建时间")
|
||||
@Column(name = "update_time")
|
||||
private Date updateTime;
|
||||
|
||||
+4
-12
@@ -37,28 +37,20 @@ public class RuleModelInstance implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
/** 主键ID */
|
||||
@Id
|
||||
@KeySql(genId = SQenGenId.class)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 模型id
|
||||
*/
|
||||
/** 模型id */
|
||||
@Column(name = "model_id")
|
||||
private Long modelId;
|
||||
|
||||
/**
|
||||
* 关联类型
|
||||
*/
|
||||
/** 关联类型 */
|
||||
@Column(name = "relation_type")
|
||||
private String relationType;
|
||||
|
||||
/**
|
||||
* 关联id
|
||||
*/
|
||||
/** 关联id */
|
||||
@Column(name = "relation_id")
|
||||
private String relationId;
|
||||
}
|
||||
|
||||
+12
-36
@@ -40,87 +40,63 @@ public class RulegoChain implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
/** 主键ID */
|
||||
@Id
|
||||
@KeySql(genId = SQenGenId.class)
|
||||
@Schema(description = "主键ID")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* rulego规则链ID
|
||||
*/
|
||||
/** rulego规则链ID */
|
||||
@Schema(description = "rulego规则链ID")
|
||||
@Column(name = "rulego_id")
|
||||
private String rulegoId;
|
||||
|
||||
/**
|
||||
* 规则链名称
|
||||
*/
|
||||
/** 规则链名称 */
|
||||
@Schema(description = "规则链名称")
|
||||
@Column(name = "chain_name")
|
||||
private String chainName;
|
||||
|
||||
/**
|
||||
* 规则链描述
|
||||
*/
|
||||
/** 规则链描述 */
|
||||
@Schema(description = "规则链描述")
|
||||
@Column(name = "description")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 创建人unionId
|
||||
*/
|
||||
/** 创建人unionId */
|
||||
@Schema(description = "创建人unionId")
|
||||
@Column(name = "creator_id")
|
||||
private String creatorId;
|
||||
|
||||
/**
|
||||
* 创建人姓名
|
||||
*/
|
||||
/** 创建人姓名 */
|
||||
@Schema(description = "创建人姓名")
|
||||
@Column(name = "creator_name")
|
||||
private String creatorName;
|
||||
|
||||
/**
|
||||
* 状态:draft-草稿,deployed-已部署,stopped-已停止
|
||||
*/
|
||||
/** 状态:draft-草稿,deployed-已部署,stopped-已停止 */
|
||||
@Schema(description = "状态")
|
||||
@Column(name = "status")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 规则链DSL内容(JSON格式)
|
||||
*/
|
||||
/** 规则链DSL内容(JSON格式) */
|
||||
@Schema(description = "规则链DSL内容")
|
||||
@Column(name = "dsl_content")
|
||||
private String dslContent;
|
||||
|
||||
/**
|
||||
* 最后同步时间
|
||||
*/
|
||||
/** 最后同步时间 */
|
||||
@Schema(description = "最后同步时间")
|
||||
@Column(name = "last_sync_time")
|
||||
private Date lastSyncTime;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
/** 创建时间 */
|
||||
@Schema(description = "创建时间")
|
||||
@Column(name = "create_time")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
/** 更新时间 */
|
||||
@Schema(description = "更新时间")
|
||||
@Column(name = "update_time")
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 是否删除:0-未删除,1-已删除
|
||||
*/
|
||||
/** 是否删除:0-未删除,1-已删除 */
|
||||
@Schema(description = "是否删除")
|
||||
@Column(name = "deleted")
|
||||
private Integer deleted;
|
||||
|
||||
+10
-30
@@ -40,73 +40,53 @@ public class RulegoChainLog implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
/** 主键ID */
|
||||
@Id
|
||||
@KeySql(genId = SQenGenId.class)
|
||||
@Schema(description = "主键ID")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* rulego规则链ID
|
||||
*/
|
||||
/** rulego规则链ID */
|
||||
@Schema(description = "rulego规则链ID")
|
||||
@Column(name = "rulego_id")
|
||||
private String rulegoId;
|
||||
|
||||
/**
|
||||
* 规则链名称
|
||||
*/
|
||||
/** 规则链名称 */
|
||||
@Schema(description = "规则链名称")
|
||||
@Column(name = "chain_name")
|
||||
private String chainName;
|
||||
|
||||
/**
|
||||
* 执行ID
|
||||
*/
|
||||
/** 执行ID */
|
||||
@Schema(description = "执行ID")
|
||||
@Column(name = "execution_id")
|
||||
private String executionId;
|
||||
|
||||
/**
|
||||
* 输入数据
|
||||
*/
|
||||
/** 输入数据 */
|
||||
@Schema(description = "输入数据")
|
||||
@Column(name = "input_data")
|
||||
private String inputData;
|
||||
|
||||
/**
|
||||
* 输出数据
|
||||
*/
|
||||
/** 输出数据 */
|
||||
@Schema(description = "输出数据")
|
||||
@Column(name = "output_data")
|
||||
private String outputData;
|
||||
|
||||
/**
|
||||
* 执行状态:success-成功,failed-失败
|
||||
*/
|
||||
/** 执行状态:success-成功,failed-失败 */
|
||||
@Schema(description = "执行状态")
|
||||
@Column(name = "execution_status")
|
||||
private String executionStatus;
|
||||
|
||||
/**
|
||||
* 错误信息
|
||||
*/
|
||||
/** 错误信息 */
|
||||
@Schema(description = "错误信息")
|
||||
@Column(name = "error_message")
|
||||
private String errorMessage;
|
||||
|
||||
/**
|
||||
* 执行耗时(毫秒)
|
||||
*/
|
||||
/** 执行耗时(毫秒) */
|
||||
@Schema(description = "执行耗时")
|
||||
@Column(name = "execution_time")
|
||||
private Long executionTime;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
/** 创建时间 */
|
||||
@Schema(description = "创建时间")
|
||||
@Column(name = "create_time")
|
||||
private Date createTime;
|
||||
|
||||
+8
-23
@@ -36,54 +36,39 @@ public class SceneLinkage extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
@Id private Long id;
|
||||
|
||||
/**
|
||||
* 场景名称
|
||||
*/
|
||||
/** 场景名称 */
|
||||
@Excel(name = "场景名称")
|
||||
@Column(name = "scene_name")
|
||||
private String sceneName;
|
||||
|
||||
/**
|
||||
* 触发条件 all.全部 one.任意一个
|
||||
*/
|
||||
/** 触发条件 all.全部 one.任意一个 */
|
||||
@Excel(name = "触发条件 all.全部 one.任意一个")
|
||||
@Column(name = "touch")
|
||||
private String touch;
|
||||
|
||||
/**
|
||||
* 触发条件
|
||||
*/
|
||||
/** 触发条件 */
|
||||
@Excel(name = "触发条件")
|
||||
@Column(name = "trigger_condition")
|
||||
private String triggerCondition;
|
||||
|
||||
/**
|
||||
* 执行动作
|
||||
*/
|
||||
/** 执行动作 */
|
||||
@Excel(name = "执行动作")
|
||||
@Column(name = "exec_action")
|
||||
private String execAction;
|
||||
|
||||
/**
|
||||
* 沉默周期
|
||||
*/
|
||||
/** 沉默周期 */
|
||||
@Excel(name = "沉默周期")
|
||||
@Column(name = "sleep_cycle")
|
||||
private Integer sleepCycle;
|
||||
|
||||
/**
|
||||
* 0启用 1停用
|
||||
*/
|
||||
/** 0启用 1停用 */
|
||||
@Excel(name = "0启用 1停用")
|
||||
@Column(name = "status")
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 设备id
|
||||
*/
|
||||
/** 设备id */
|
||||
@Excel(name = "设备id")
|
||||
@Column(name = "dev_id")
|
||||
private String devId;
|
||||
|
||||
+7
-20
@@ -28,36 +28,23 @@ import lombok.NoArgsConstructor;
|
||||
public class SupportMapAreas implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Id
|
||||
private String id;
|
||||
@Id private String id;
|
||||
|
||||
/**
|
||||
* 父id
|
||||
*/
|
||||
/** 父id */
|
||||
private String pid;
|
||||
|
||||
/**
|
||||
* 地址
|
||||
*/
|
||||
/** 地址 */
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 详细地址
|
||||
*/
|
||||
/** 详细地址 */
|
||||
private String fullName;
|
||||
|
||||
/**
|
||||
* 深度
|
||||
*/
|
||||
/** 深度 */
|
||||
private String deep;
|
||||
|
||||
/**
|
||||
* 核心点坐标
|
||||
*/
|
||||
/** 核心点坐标 */
|
||||
private String location;
|
||||
|
||||
/**
|
||||
* 范围坐标
|
||||
*/
|
||||
/** 范围坐标 */
|
||||
private String polygon;
|
||||
}
|
||||
|
||||
+12
-35
@@ -25,9 +25,7 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 系统访问记录表 sys_logininfor @Author ruoyi
|
||||
*/
|
||||
/** 系统访问记录表 sys_logininfor @Author ruoyi */
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
@@ -35,65 +33,44 @@ public class SysLogininfor implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
/** ID */
|
||||
@Excel(name = "序号", cellType = ColumnType.NUMERIC)
|
||||
@Id
|
||||
private Long infoId;
|
||||
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
/** 用户账号 */
|
||||
@Excel(name = "用户账号")
|
||||
private String userName;
|
||||
|
||||
/**
|
||||
* 登录状态 0成功 1失败
|
||||
*/
|
||||
/** 登录状态 0成功 1失败 */
|
||||
@Excel(name = "登录状态", readConverterExp = "0=成功,1=失败")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 登录IP地址
|
||||
*/
|
||||
/** 登录IP地址 */
|
||||
@Excel(name = "登录地址")
|
||||
private String ipaddr;
|
||||
|
||||
/**
|
||||
* 登录地点
|
||||
*/
|
||||
/** 登录地点 */
|
||||
@Excel(name = "登录地点")
|
||||
private String loginLocation;
|
||||
|
||||
/**
|
||||
* 浏览器类型
|
||||
*/
|
||||
/** 浏览器类型 */
|
||||
@Excel(name = "浏览器")
|
||||
private String browser;
|
||||
|
||||
/**
|
||||
* 操作系统
|
||||
*/
|
||||
/** 操作系统 */
|
||||
@Excel(name = "操作系统")
|
||||
private String os;
|
||||
|
||||
/**
|
||||
* 提示消息
|
||||
*/
|
||||
/** 提示消息 */
|
||||
@Excel(name = "提示消息")
|
||||
private String msg;
|
||||
|
||||
/**
|
||||
* 访问时间
|
||||
*/
|
||||
/** 访问时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Excel(name = "访问时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date loginTime;
|
||||
|
||||
/**
|
||||
* 请求参数
|
||||
*/
|
||||
@Transient
|
||||
private Map<String, Object> params = new HashMap<>();
|
||||
/** 请求参数 */
|
||||
@Transient private Map<String, Object> params = new HashMap<>();
|
||||
}
|
||||
|
||||
+21
-61
@@ -25,9 +25,7 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 操作日志记录表 oper_log @Author ruoyi
|
||||
*/
|
||||
/** 操作日志记录表 oper_log @Author ruoyi */
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
@@ -35,113 +33,75 @@ public class SysOperLog implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 日志主键
|
||||
*/
|
||||
/** 日志主键 */
|
||||
@Excel(name = "操作序号", cellType = ColumnType.NUMERIC)
|
||||
@Id
|
||||
private Long operId;
|
||||
|
||||
/**
|
||||
* 操作模块
|
||||
*/
|
||||
/** 操作模块 */
|
||||
@Excel(name = "操作模块")
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* 业务类型(0其它 1新增 2修改 3删除)
|
||||
*/
|
||||
/** 业务类型(0其它 1新增 2修改 3删除) */
|
||||
@Excel(name = "业务类型", readConverterExp = "0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据")
|
||||
private Integer businessType;
|
||||
|
||||
/**
|
||||
* 业务类型数组
|
||||
*/
|
||||
@Transient
|
||||
private Integer[] businessTypes;
|
||||
/** 业务类型数组 */
|
||||
@Transient private Integer[] businessTypes;
|
||||
|
||||
/**
|
||||
* 请求方法
|
||||
*/
|
||||
/** 请求方法 */
|
||||
@Excel(name = "请求方法")
|
||||
private String method;
|
||||
|
||||
/**
|
||||
* 请求方式
|
||||
*/
|
||||
/** 请求方式 */
|
||||
@Excel(name = "请求方式")
|
||||
private String requestMethod;
|
||||
|
||||
/**
|
||||
* 操作类别(0其它 1后台用户 2手机端用户)
|
||||
*/
|
||||
/** 操作类别(0其它 1后台用户 2手机端用户) */
|
||||
@Excel(name = "操作类别", readConverterExp = "0=其它,1=后台用户,2=手机端用户")
|
||||
private Integer operatorType;
|
||||
|
||||
/**
|
||||
* 操作人员
|
||||
*/
|
||||
/** 操作人员 */
|
||||
@Excel(name = "操作人员")
|
||||
private String operName;
|
||||
|
||||
/**
|
||||
* 部门名称
|
||||
*/
|
||||
/** 部门名称 */
|
||||
@Excel(name = "部门名称")
|
||||
private String deptName;
|
||||
|
||||
/**
|
||||
* 请求url
|
||||
*/
|
||||
/** 请求url */
|
||||
@Excel(name = "请求地址")
|
||||
private String operUrl;
|
||||
|
||||
/**
|
||||
* 操作地址
|
||||
*/
|
||||
/** 操作地址 */
|
||||
@Excel(name = "操作地址")
|
||||
private String operIp;
|
||||
|
||||
/**
|
||||
* 操作地点
|
||||
*/
|
||||
/** 操作地点 */
|
||||
@Excel(name = "操作地点")
|
||||
private String operLocation;
|
||||
|
||||
/**
|
||||
* 请求参数
|
||||
*/
|
||||
/** 请求参数 */
|
||||
@Excel(name = "请求参数")
|
||||
private String operParam;
|
||||
|
||||
/**
|
||||
* 返回参数
|
||||
*/
|
||||
/** 返回参数 */
|
||||
@Excel(name = "返回参数")
|
||||
private String jsonResult;
|
||||
|
||||
/**
|
||||
* 操作状态(0正常 1异常)
|
||||
*/
|
||||
/** 操作状态(0正常 1异常) */
|
||||
@Excel(name = "状态", readConverterExp = "0=正常,1=异常")
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 错误消息
|
||||
*/
|
||||
/** 错误消息 */
|
||||
@Excel(name = "错误消息")
|
||||
private String errorMsg;
|
||||
|
||||
/**
|
||||
* 操作时间
|
||||
*/
|
||||
/** 操作时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Excel(name = "操作时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date operTime;
|
||||
|
||||
/**
|
||||
* 请求参数
|
||||
*/
|
||||
@Transient
|
||||
private Map<String, Object> params = new HashMap<>();
|
||||
/** 请求参数 */
|
||||
@Transient private Map<String, Object> params = new HashMap<>();
|
||||
}
|
||||
|
||||
+13
-38
@@ -25,9 +25,7 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 参数配置表 sys_config @Author ruoyi
|
||||
*/
|
||||
/** 参数配置表 sys_config @Author ruoyi */
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
@@ -38,70 +36,47 @@ public class SysConfig {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 参数主键
|
||||
*/
|
||||
@Id
|
||||
private Long configId;
|
||||
/** 参数主键 */
|
||||
@Id private Long configId;
|
||||
|
||||
/**
|
||||
* 参数名称
|
||||
*/
|
||||
/** 参数名称 */
|
||||
@Column(name = "config_name")
|
||||
private String configName;
|
||||
|
||||
/**
|
||||
* 参数键名
|
||||
*/
|
||||
/** 参数键名 */
|
||||
@Column(name = "config_key")
|
||||
private String configKey;
|
||||
|
||||
/**
|
||||
* 参数键值
|
||||
*/
|
||||
/** 参数键值 */
|
||||
@Column(name = "config_value")
|
||||
private String configValue;
|
||||
|
||||
/**
|
||||
* 系统内置(Y是 N否)
|
||||
*/
|
||||
/** 系统内置(Y是 N否) */
|
||||
@Column(name = "config_type")
|
||||
private String configType;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
/** 创建者 */
|
||||
@Column(name = "create_by")
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
/** 创建时间 */
|
||||
@Column(name = "create_time")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
/** 更新者 */
|
||||
@Column(name = "update_by")
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
/** 更新时间 */
|
||||
@Column(name = "update_time")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 请求参数
|
||||
*/
|
||||
/** 请求参数 */
|
||||
// @TableField(exist = false)
|
||||
private Map<String, Object> params = new HashMap<>();
|
||||
}
|
||||
|
||||
+17
-50
@@ -29,9 +29,7 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 字典数据表 sys_dict_data @Author ruoyi
|
||||
*/
|
||||
/** 字典数据表 sys_dict_data @Author ruoyi */
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
@@ -42,111 +40,80 @@ public class SysDictData implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 字典编码
|
||||
*/
|
||||
/** 字典编码 */
|
||||
// @Excel(name = "字典编码", cellType = Excel.ColumnType.NUMERIC)
|
||||
@Id
|
||||
private Long dictCode;
|
||||
@Id private Long dictCode;
|
||||
|
||||
/**
|
||||
* 字典排序
|
||||
*/
|
||||
/** 字典排序 */
|
||||
// @Excel(name = "字典排序", cellType = Excel.ColumnType.NUMERIC)
|
||||
@Column(name = "dict_sort")
|
||||
private Long dictSort;
|
||||
|
||||
/**
|
||||
* 字典标签
|
||||
*/
|
||||
/** 字典标签 */
|
||||
// @Excel(name = "字典标签")
|
||||
@NotBlank(message = "字典标签不能为空")
|
||||
@Size(min = 0, max = 100, message = "字典标签长度不能超过100个字符")
|
||||
@Column(name = "dict_label")
|
||||
private String dictLabel;
|
||||
|
||||
/**
|
||||
* 字典键值
|
||||
*/
|
||||
/** 字典键值 */
|
||||
// @Excel(name = "字典键值")
|
||||
@NotBlank(message = "字典键值不能为空")
|
||||
@Column(name = "dict_value")
|
||||
@Size(min = 0, max = 100, message = "字典键值长度不能超过100个字符")
|
||||
private String dictValue;
|
||||
|
||||
/**
|
||||
* 字典类型
|
||||
*/
|
||||
/** 字典类型 */
|
||||
// @Excel(name = "字典类型")
|
||||
@NotBlank(message = "字典类型不能为空")
|
||||
@Column(name = "dict_type")
|
||||
@Size(min = 0, max = 100, message = "字典类型长度不能超过100个字符")
|
||||
private String dictType;
|
||||
|
||||
/**
|
||||
* 样式属性(其他样式扩展)
|
||||
*/
|
||||
/** 样式属性(其他样式扩展) */
|
||||
@Size(min = 0, max = 100, message = "样式属性长度不能超过100个字符")
|
||||
@Column(name = "css_class")
|
||||
private String cssClass;
|
||||
|
||||
/**
|
||||
* 表格字典样式
|
||||
*/
|
||||
/** 表格字典样式 */
|
||||
@Column(name = "list_class")
|
||||
private String listClass;
|
||||
|
||||
/**
|
||||
* 是否默认(Y是 N否)
|
||||
*/
|
||||
/** 是否默认(Y是 N否) */
|
||||
// @Excel(name = "是否默认", readConverterExp = "Y=是,N=否")
|
||||
@Column(name = "is_default")
|
||||
private String isDefault;
|
||||
|
||||
/**
|
||||
* 状态(0正常 1停用)
|
||||
*/
|
||||
/** 状态(0正常 1停用) */
|
||||
// @Excel(name = "状态", readConverterExp = "0=正常,1=停用")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
/** 创建者 */
|
||||
// @TableField(fill = FieldFill.INSERT)
|
||||
@Column(name = "create_by")
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
/** 创建时间 */
|
||||
// @TableField(fill = FieldFill.INSERT)
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Column(name = "create_time")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
/** 更新者 */
|
||||
// @TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
@Column(name = "update_by")
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
/** 更新时间 */
|
||||
// @TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Column(name = "update_time")
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 请求参数
|
||||
*/
|
||||
/** 请求参数 */
|
||||
// @TableField(exist = false)
|
||||
private Map<String, Object> params = new HashMap<>();
|
||||
|
||||
|
||||
+12
-35
@@ -26,9 +26,7 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 字典类型表 sys_dict_type @Author ruoyi
|
||||
*/
|
||||
/** 字典类型表 sys_dict_type @Author ruoyi */
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
@@ -37,76 +35,55 @@ public class SysDictType implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 字典主键
|
||||
*/
|
||||
/** 字典主键 */
|
||||
// @Excel(name = "字典主键", cellType = Excel.ColumnType.NUMERIC)
|
||||
// @TableId(value = "dict_id", type = IdType.AUTO)
|
||||
@Id
|
||||
private Long dictId;
|
||||
@Id private Long dictId;
|
||||
|
||||
/**
|
||||
* 字典名称
|
||||
*/
|
||||
/** 字典名称 */
|
||||
// @Excel(name = "字典名称")
|
||||
@NotBlank(message = "字典名称不能为空")
|
||||
@Size(min = 0, max = 100, message = "字典类型名称长度不能超过100个字符")
|
||||
@Column(name = "dict_name")
|
||||
private String dictName;
|
||||
|
||||
/**
|
||||
* 字典类型
|
||||
*/
|
||||
/** 字典类型 */
|
||||
// @Excel(name = "字典类型")
|
||||
@NotBlank(message = "字典类型不能为空")
|
||||
@Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符")
|
||||
@Column(name = "dict_type")
|
||||
private String dictType;
|
||||
|
||||
/**
|
||||
* 状态(0正常 1停用)
|
||||
*/
|
||||
/** 状态(0正常 1停用) */
|
||||
// @Excel(name = "状态", readConverterExp = "0=正常,1=停用")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
/** 创建者 */
|
||||
// @TableField(fill = FieldFill.INSERT)
|
||||
@Column(name = "create_by")
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
/** 创建时间 */
|
||||
// @TableField(fill = FieldFill.INSERT)
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Column(name = "create_time")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
/** 更新者 */
|
||||
// @TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
@Column(name = "update_by")
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
/** 更新时间 */
|
||||
// @TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Column(name = "update_time")
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 请求参数
|
||||
*/
|
||||
/** 请求参数 */
|
||||
// @TableField(exist = false)
|
||||
private Map<String, Object> params = new HashMap<>();
|
||||
}
|
||||
|
||||
+24
-69
@@ -28,9 +28,7 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 菜单权限表 sys_menu @Author ruoyi
|
||||
*/
|
||||
/** 菜单权限表 sys_menu @Author ruoyi */
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@@ -41,15 +39,10 @@ public class SysMenu implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 菜单ID
|
||||
*/
|
||||
@Id
|
||||
private Long menuId;
|
||||
/** 菜单ID */
|
||||
@Id private Long menuId;
|
||||
|
||||
/**
|
||||
* 菜单名称
|
||||
*/
|
||||
/** 菜单名称 */
|
||||
@Column(name = "menu_name")
|
||||
private String menuName;
|
||||
|
||||
@@ -57,106 +50,68 @@ public class SysMenu implements Serializable {
|
||||
// @Column(name = "parent_name")
|
||||
// private String parentName;
|
||||
|
||||
/**
|
||||
* 父菜单ID
|
||||
*/
|
||||
/** 父菜单ID */
|
||||
@Column(name = "parent_id")
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 显示顺序
|
||||
*/
|
||||
/** 显示顺序 */
|
||||
@Column(name = "order_num")
|
||||
private String orderNum;
|
||||
|
||||
/**
|
||||
* 路由地址
|
||||
*/
|
||||
/** 路由地址 */
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* 组件路径
|
||||
*/
|
||||
/** 组件路径 */
|
||||
private String component;
|
||||
|
||||
/**
|
||||
* 是否为外链(0是 1否)
|
||||
*/
|
||||
/** 是否为外链(0是 1否) */
|
||||
@Column(name = "is_frame")
|
||||
private String isFrame;
|
||||
|
||||
/**
|
||||
* 是否缓存(0缓存 1不缓存)
|
||||
*/
|
||||
/** 是否缓存(0缓存 1不缓存) */
|
||||
@Column(name = "is_cache")
|
||||
private String isCache;
|
||||
|
||||
/**
|
||||
* 类型(M目录 C菜单 F按钮)
|
||||
*/
|
||||
/** 类型(M目录 C菜单 F按钮) */
|
||||
@Column(name = "menu_type")
|
||||
private String menuType;
|
||||
|
||||
/**
|
||||
* 显示状态(0显示 1隐藏)
|
||||
*/
|
||||
/** 显示状态(0显示 1隐藏) */
|
||||
private String visible;
|
||||
|
||||
/**
|
||||
* 菜单状态(0显示 1隐藏)
|
||||
*/
|
||||
/** 菜单状态(0显示 1隐藏) */
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 权限字符串
|
||||
*/
|
||||
/** 权限字符串 */
|
||||
private String perms;
|
||||
|
||||
/**
|
||||
* 菜单图标
|
||||
*/
|
||||
/** 菜单图标 */
|
||||
private String icon;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
/** 创建者 */
|
||||
@Column(name = "create_by")
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
/** 创建时间 */
|
||||
@Column(name = "create_time")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
/** 更新者 */
|
||||
@Column(name = "update_by")
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
/** 更新时间 */
|
||||
@Column(name = "update_time")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 请求参数
|
||||
*/
|
||||
@Builder.Default
|
||||
private Map<String, Object> params = new HashMap<>();
|
||||
/** 请求参数 */
|
||||
@Builder.Default private Map<String, Object> params = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 子菜单
|
||||
*/
|
||||
@Builder.Default
|
||||
private List<SysMenu> children = new ArrayList<SysMenu>();
|
||||
/** 子菜单 */
|
||||
@Builder.Default private List<SysMenu> children = new ArrayList<SysMenu>();
|
||||
}
|
||||
|
||||
+20
-58
@@ -27,9 +27,7 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 角色表 sys_role @Author ruoyi
|
||||
*/
|
||||
/** 角色表 sys_role @Author ruoyi */
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
@@ -40,104 +38,68 @@ public class SysRole implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 角色ID
|
||||
*/
|
||||
@Id
|
||||
private Long roleId;
|
||||
/** 角色ID */
|
||||
@Id private Long roleId;
|
||||
|
||||
/**
|
||||
* 角色名称
|
||||
*/
|
||||
/** 角色名称 */
|
||||
@Excel(name = "角色名称")
|
||||
@Column(name = "role_name")
|
||||
private String roleName;
|
||||
|
||||
/**
|
||||
* 角色权限
|
||||
*/
|
||||
/** 角色权限 */
|
||||
@Column(name = "role_key")
|
||||
private String roleKey;
|
||||
|
||||
/**
|
||||
* 角色排序
|
||||
*/
|
||||
/** 角色排序 */
|
||||
@Column(name = "role_sort")
|
||||
private String roleSort;
|
||||
|
||||
/**
|
||||
* 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限)
|
||||
*/
|
||||
/** 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) */
|
||||
@Column(name = "data_scope")
|
||||
private String dataScope;
|
||||
|
||||
/**
|
||||
* 菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示)
|
||||
*/
|
||||
/** 菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示) */
|
||||
@Column(name = "menu_check_strictly")
|
||||
private Boolean menuCheckStrictly;
|
||||
|
||||
/**
|
||||
* 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 )
|
||||
*/
|
||||
/** 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 ) */
|
||||
@Column(name = "dept_check_strictly")
|
||||
private Boolean deptCheckStrictly;
|
||||
|
||||
/**
|
||||
* 角色状态(0正常 1停用)
|
||||
*/
|
||||
/** 角色状态(0正常 1停用) */
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
/** 创建者 */
|
||||
@Column(name = "create_by")
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
/** 创建时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Column(name = "create_time")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
/** 更新者 */
|
||||
@Column(name = "update_by")
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
/** 更新时间 */
|
||||
@Column(name = "update_time")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 请求参数
|
||||
*/
|
||||
@Builder.Default
|
||||
private Map<String, Object> params = new HashMap<>();
|
||||
/** 请求参数 */
|
||||
@Builder.Default private Map<String, Object> params = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 用户是否存在此角色标识 默认不存在
|
||||
*/
|
||||
/** 用户是否存在此角色标识 默认不存在 */
|
||||
private boolean flag = false;
|
||||
|
||||
/**
|
||||
* 菜单组
|
||||
*/
|
||||
/** 菜单组 */
|
||||
private Long[] menuIds;
|
||||
|
||||
/**
|
||||
* 部门组(数据权限)
|
||||
*/
|
||||
/** 部门组(数据权限) */
|
||||
|
||||
// private Long[] deptIds;
|
||||
public SysRole(Long roleId) {
|
||||
|
||||
+4
-11
@@ -21,9 +21,7 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 角色和菜单关联 sys_role_menu @Author ruoyi
|
||||
*/
|
||||
/** 角色和菜单关联 sys_role_menu @Author ruoyi */
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
@@ -33,16 +31,11 @@ import lombok.experimental.Accessors;
|
||||
public class SysRoleMenu implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Id
|
||||
private Long uuid;
|
||||
@Id private Long uuid;
|
||||
|
||||
/**
|
||||
* 角色ID
|
||||
*/
|
||||
/** 角色ID */
|
||||
private Long roleId;
|
||||
|
||||
/**
|
||||
* 菜单ID
|
||||
*/
|
||||
/** 菜单ID */
|
||||
private Long menuId;
|
||||
}
|
||||
|
||||
+4
-11
@@ -21,9 +21,7 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 用户和角色关联 sys_user_role @Author ruoyi
|
||||
*/
|
||||
/** 用户和角色关联 sys_user_role @Author ruoyi */
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@@ -33,16 +31,11 @@ import lombok.experimental.Accessors;
|
||||
public class SysUserRole implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
@Id
|
||||
private Long uuid;
|
||||
@Id private Long uuid;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
/** 用户ID */
|
||||
private String unionId;
|
||||
|
||||
/**
|
||||
* 角色ID
|
||||
*/
|
||||
/** 角色ID */
|
||||
private Long roleId;
|
||||
}
|
||||
|
||||
+4
-12
@@ -20,9 +20,7 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* Treeselect树结构实体类 @Author ruoyi
|
||||
*/
|
||||
/** Treeselect树结构实体类 @Author ruoyi */
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
@@ -30,19 +28,13 @@ public class TreeSelect implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 节点ID
|
||||
*/
|
||||
/** 节点ID */
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 节点名称
|
||||
*/
|
||||
/** 节点名称 */
|
||||
private String label;
|
||||
|
||||
/**
|
||||
* 子节点
|
||||
*/
|
||||
/** 子节点 */
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private List<TreeSelect> children;
|
||||
|
||||
|
||||
+5
-15
@@ -17,32 +17,22 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 路由显示信息 @Author ruoyi
|
||||
*/
|
||||
/** 路由显示信息 @Author ruoyi */
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
public class MetaVo {
|
||||
|
||||
/**
|
||||
* 设置该路由在侧边栏和面包屑中展示的名字
|
||||
*/
|
||||
/** 设置该路由在侧边栏和面包屑中展示的名字 */
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* 设置该路由的图标,对应路径src/assets/icons/svg
|
||||
*/
|
||||
/** 设置该路由的图标,对应路径src/assets/icons/svg */
|
||||
private String icon;
|
||||
|
||||
/**
|
||||
* 设置为true,则不会被 <keep-alive>缓存
|
||||
*/
|
||||
/** 设置为true,则不会被 <keep-alive>缓存 */
|
||||
private boolean noCache;
|
||||
|
||||
/**
|
||||
* 内链地址(http(s)://开头)
|
||||
*/
|
||||
/** 内链地址(http(s)://开头) */
|
||||
private String link;
|
||||
|
||||
public MetaVo(String title, String icon) {
|
||||
|
||||
+9
-27
@@ -18,52 +18,34 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 路由配置信息 @Author ruoyi
|
||||
*/
|
||||
/** 路由配置信息 @Author ruoyi */
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
public class RouterVo {
|
||||
|
||||
/**
|
||||
* 路由名字
|
||||
*/
|
||||
/** 路由名字 */
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 路由地址
|
||||
*/
|
||||
/** 路由地址 */
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* 是否隐藏路由,当设置 true 的时候该路由不会再侧边栏出现
|
||||
*/
|
||||
/** 是否隐藏路由,当设置 true 的时候该路由不会再侧边栏出现 */
|
||||
private boolean hidden;
|
||||
|
||||
/**
|
||||
* 重定向地址,当设置 noRedirect 的时候该路由在面包屑导航中不可被点击
|
||||
*/
|
||||
/** 重定向地址,当设置 noRedirect 的时候该路由在面包屑导航中不可被点击 */
|
||||
private String redirect;
|
||||
|
||||
/**
|
||||
* 组件地址
|
||||
*/
|
||||
/** 组件地址 */
|
||||
private String component;
|
||||
|
||||
/**
|
||||
* 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面
|
||||
*/
|
||||
/** 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面 */
|
||||
private Boolean alwaysShow;
|
||||
|
||||
/**
|
||||
* 其他元素
|
||||
*/
|
||||
/** 其他元素 */
|
||||
private MetaVo meta;
|
||||
|
||||
/**
|
||||
* 子路由
|
||||
*/
|
||||
/** 子路由 */
|
||||
private List<RouterVo> children;
|
||||
}
|
||||
|
||||
+18
-54
@@ -21,9 +21,7 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 字典数据表 sys_dict_data @Author ruoyi
|
||||
*/
|
||||
/** 字典数据表 sys_dict_data @Author ruoyi */
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@@ -31,89 +29,55 @@ public class SysDictDataVo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 字典编码
|
||||
*/
|
||||
/** 字典编码 */
|
||||
private Long dictCode;
|
||||
|
||||
/**
|
||||
* 字典排序
|
||||
*/
|
||||
/** 字典排序 */
|
||||
private Long dictSort;
|
||||
|
||||
/**
|
||||
* 字典标签
|
||||
*/
|
||||
/** 字典标签 */
|
||||
private String dictLabel;
|
||||
|
||||
/**
|
||||
* 字典键值
|
||||
*/
|
||||
/** 字典键值 */
|
||||
private String dictValue;
|
||||
|
||||
/**
|
||||
* 字典类型
|
||||
*/
|
||||
/** 字典类型 */
|
||||
private String dictType;
|
||||
|
||||
/**
|
||||
* 样式属性(其他样式扩展)
|
||||
*/
|
||||
/** 样式属性(其他样式扩展) */
|
||||
private String cssClass;
|
||||
|
||||
/**
|
||||
* 表格字典样式
|
||||
*/
|
||||
/** 表格字典样式 */
|
||||
private String listClass;
|
||||
|
||||
/**
|
||||
* 是否默认(Y是 N否)
|
||||
*/
|
||||
/** 是否默认(Y是 N否) */
|
||||
private String isDefault;
|
||||
|
||||
/**
|
||||
* 状态(0正常 1停用)
|
||||
*/
|
||||
/** 状态(0正常 1停用) */
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 创建者
|
||||
*/
|
||||
/** 创建者 */
|
||||
private String createBy;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
/** 创建时间 */
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
/** 更新者 */
|
||||
private String updateBy;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
/** 更新时间 */
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
/** 开始时间 */
|
||||
private String startTime;
|
||||
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
/** 结束时间 */
|
||||
private String endTime;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 请求参数
|
||||
*/
|
||||
/** 请求参数 */
|
||||
// @TableField(exist = false)
|
||||
private Map<String, Object> params = new HashMap<>();
|
||||
|
||||
|
||||
+1
-3
@@ -19,9 +19,7 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 字典类型group分组 @Author ruoyi
|
||||
*/
|
||||
/** 字典类型group分组 @Author ruoyi */
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
|
||||
+29
-77
@@ -30,116 +30,76 @@ public class IoTDeviceBO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 对外设备唯一标识符
|
||||
*/
|
||||
/** 对外设备唯一标识符 */
|
||||
private String iotId;
|
||||
|
||||
/**
|
||||
* Lora密钥
|
||||
*/
|
||||
/** Lora密钥 */
|
||||
private String secretKey;
|
||||
|
||||
/**
|
||||
* 归属应用
|
||||
*/
|
||||
/** 归属应用 */
|
||||
private String application;
|
||||
|
||||
/**
|
||||
* 激活时间
|
||||
*/
|
||||
/** 激活时间 */
|
||||
private Integer registryTime;
|
||||
|
||||
/**
|
||||
* 最后上线时间
|
||||
*/
|
||||
/** 最后上线时间 */
|
||||
private Long onlineTime;
|
||||
|
||||
/**
|
||||
* 设备自身序号
|
||||
*/
|
||||
/** 设备自身序号 */
|
||||
private String deviceId;
|
||||
|
||||
/**
|
||||
* 第三方设备ID唯一标识符
|
||||
*/
|
||||
/** 第三方设备ID唯一标识符 */
|
||||
private String extDeviceId;
|
||||
|
||||
/**
|
||||
* 别名
|
||||
*/
|
||||
/** 别名 */
|
||||
private String nickName;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
/** 设备名称 */
|
||||
private String productName;
|
||||
|
||||
private Long features;
|
||||
|
||||
/**
|
||||
* 网关产品ProductKey
|
||||
*/
|
||||
/** 网关产品ProductKey */
|
||||
private String gwProductKey;
|
||||
|
||||
/**
|
||||
* 设备密钥
|
||||
*/
|
||||
private String gwDeviceId;
|
||||
|
||||
/** 设备密钥 */
|
||||
private String deviceSecret;
|
||||
|
||||
/**
|
||||
* 产品key
|
||||
*/
|
||||
/** 产品key */
|
||||
private String productKey;
|
||||
|
||||
/**
|
||||
* 设备实例名称
|
||||
*/
|
||||
/** 设备实例名称 */
|
||||
private String deviceName;
|
||||
|
||||
private String creatorId;
|
||||
private String creatorName;
|
||||
|
||||
/**
|
||||
* 0-离线,1-在线
|
||||
*/
|
||||
/** 0-离线,1-在线 */
|
||||
private Boolean state;
|
||||
|
||||
/**
|
||||
* 说明
|
||||
*/
|
||||
/** 说明 */
|
||||
private String detail;
|
||||
|
||||
private Long createTime;
|
||||
|
||||
/**
|
||||
* 派生元数据,有的设备的属性,功能,事件可能会动态的添加
|
||||
*/
|
||||
/** 派生元数据,有的设备的属性,功能,事件可能会动态的添加 */
|
||||
private String deriveMetadata;
|
||||
|
||||
/**
|
||||
* 其他配置
|
||||
*/
|
||||
/** 其他配置 */
|
||||
private String configuration;
|
||||
|
||||
/**
|
||||
* 设备坐标
|
||||
*/
|
||||
/** 设备坐标 */
|
||||
private String coordinate;
|
||||
|
||||
/**
|
||||
* 区域ID
|
||||
*/
|
||||
/** 区域ID */
|
||||
private String areasId;
|
||||
|
||||
/**
|
||||
* 纬度
|
||||
*/
|
||||
/** 纬度 */
|
||||
private String latitude;
|
||||
|
||||
/**
|
||||
* 经度
|
||||
*/
|
||||
/** 经度 */
|
||||
private String longitude;
|
||||
|
||||
private String fenceId;
|
||||
@@ -148,24 +108,16 @@ public class IoTDeviceBO implements Serializable {
|
||||
|
||||
// private String parentUnionId;
|
||||
|
||||
/**
|
||||
* 请求参数
|
||||
*/
|
||||
@Builder.Default
|
||||
private Map<String, Object> params = new HashMap<>();
|
||||
/** 请求参数 */
|
||||
@Builder.Default private Map<String, Object> params = new HashMap<>();
|
||||
|
||||
private Boolean hasProtocol;
|
||||
|
||||
/**
|
||||
* 接收额外参数
|
||||
*/
|
||||
@Builder.Default
|
||||
private Map<String, Object> otherParams = new HashMap<>();
|
||||
/** 接收额外参数 */
|
||||
@Builder.Default private Map<String, Object> otherParams = new HashMap<>();
|
||||
|
||||
private List<String> devGroupName;
|
||||
|
||||
/**
|
||||
* 所属父设备名称
|
||||
*/
|
||||
private String parentName;
|
||||
/** 所属父设备信息 */
|
||||
private String gwDeviceInfo;
|
||||
}
|
||||
|
||||
+2
-5
@@ -48,9 +48,6 @@ public class IoTDeviceFunctionTaskBO {
|
||||
private Boolean chooseAll;
|
||||
private List<String> extParam;
|
||||
|
||||
/**
|
||||
* 请求参数
|
||||
*/
|
||||
@Transient
|
||||
private Map<String, Object> params = new HashMap<>();
|
||||
/** 请求参数 */
|
||||
@Transient private Map<String, Object> params = new HashMap<>();
|
||||
}
|
||||
|
||||
+7
-21
@@ -17,9 +17,7 @@ import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
/** */
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@@ -28,34 +26,22 @@ public class IoTDeviceGroupBO {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 分组ID,非自增
|
||||
*/
|
||||
/** 分组ID,非自增 */
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 设备id
|
||||
*/
|
||||
/** 设备id */
|
||||
private String[] devIds;
|
||||
|
||||
/**
|
||||
* 分组名称
|
||||
*/
|
||||
/** 分组名称 */
|
||||
private String groupName;
|
||||
|
||||
/**
|
||||
* 分组标识
|
||||
*/
|
||||
/** 分组标识 */
|
||||
private String groupCode;
|
||||
|
||||
/**
|
||||
* 群组描述
|
||||
*/
|
||||
/** 群组描述 */
|
||||
private String groupDescribe;
|
||||
|
||||
/**
|
||||
* 父id
|
||||
*/
|
||||
/** 父id */
|
||||
private Long parentId;
|
||||
// //账号父id
|
||||
// private String parentUnionId;
|
||||
|
||||
+17
-50
@@ -29,84 +29,51 @@ public class IoTDeviceLogBO extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 日志ID,非自增
|
||||
*/
|
||||
/** 日志ID,非自增 */
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 设备编码
|
||||
*/
|
||||
/** 设备编码 */
|
||||
private String iotId;
|
||||
|
||||
/**
|
||||
* 设备序列号
|
||||
*/
|
||||
/** 设备序列号 */
|
||||
private String deviceId;
|
||||
|
||||
/**
|
||||
* 第三方设备ID唯一标识符
|
||||
*/
|
||||
@Transient
|
||||
private String extDeviceId;
|
||||
/** 第三方设备ID唯一标识符 */
|
||||
@Transient private String extDeviceId;
|
||||
|
||||
/**
|
||||
* 产品ID
|
||||
*/
|
||||
/** 产品ID */
|
||||
private String productKey;
|
||||
|
||||
/**
|
||||
* 设备名称
|
||||
*/
|
||||
/** 设备名称 */
|
||||
private String deviceName;
|
||||
|
||||
/**
|
||||
* 消息类型
|
||||
*/
|
||||
/** 消息类型 */
|
||||
private String messageType;
|
||||
|
||||
/**
|
||||
* 公司名称
|
||||
*/
|
||||
/** 公司名称 */
|
||||
private String companyNo;
|
||||
|
||||
/**
|
||||
* 协议名称
|
||||
*/
|
||||
/** 协议名称 */
|
||||
private String protocol;
|
||||
|
||||
/**
|
||||
* 节点类型
|
||||
*/
|
||||
/** 节点类型 */
|
||||
private String deviceNode;
|
||||
|
||||
/**
|
||||
* 设备分类编号
|
||||
*/
|
||||
/** 设备分类编号 */
|
||||
private String classifiedId;
|
||||
|
||||
/**
|
||||
* 组织ID
|
||||
*/
|
||||
/** 组织ID */
|
||||
private String orgId;
|
||||
|
||||
/**
|
||||
* 事件名称
|
||||
*/
|
||||
/** 事件名称 */
|
||||
private String event;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
/** 创建人 */
|
||||
private String createId;
|
||||
|
||||
/**
|
||||
* 经纬度
|
||||
*/
|
||||
/** 经纬度 */
|
||||
private String point;
|
||||
|
||||
/**
|
||||
* 内容
|
||||
*/
|
||||
/** 内容 */
|
||||
private String content;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user