From 82daef08b9db31e01a8d5fbd1731d30cd7ba7a9c Mon Sep 17 00:00:00 2001
From: liriming <1343021927@qq.com>
Date: 星期二, 25 二月 2025 10:55:22 +0800
Subject: [PATCH] ansteel

---
 /dev/null                                                                                        |  103 ------
 ansteel-biz/src/main/java/com/iailab/module/ansteel/config/FeignTokenInterceptor.java            |   43 ++
 ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/config/QueuePredictFinishConfig.java      |   36 ++
 ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/consumer/ModelAlarmConsumer.java          |  165 +++++++++++
 ansteel-biz/src/main/java/com/iailab/module/ansteel/util/SpringContextUtils.java                 |   47 +++
 ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/consumer/ModelPredictFinishConsumer.java  |  117 +++++++
 ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/config/QueueModelAlarmConfig.java         |   38 ++
 ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/common/constant/CommonConstant.java       |   26 +
 ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/consumer/ModelPredictFinish2Consumer.java |  150 ++++++++++
 ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/package-info.java                         |    1 
 ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/common/constant/RoutingConstant.java      |   12 
 ansteel-biz/src/main/java/com/iailab/module/ansteel/util/token/IailabClient.java                 |  145 +++++++++
 12 files changed, 780 insertions(+), 103 deletions(-)

diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/client/OAuth2Client.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/client/OAuth2Client.java
deleted file mode 100644
index 3eb5dd8..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/client/OAuth2Client.java
+++ /dev/null
@@ -1,157 +0,0 @@
-package com.iailab.module.ansteel.client;
-
-import com.iailab.framework.common.pojo.CommonResult;
-import com.iailab.module.ansteel.client.dto.oauth2.OAuth2AccessTokenRespDTO;
-import com.iailab.module.ansteel.client.dto.oauth2.OAuth2CheckTokenRespDTO;
-import org.springframework.core.ParameterizedTypeReference;
-import org.springframework.http.*;
-import org.springframework.stereotype.Component;
-import org.springframework.util.Assert;
-import org.springframework.util.Base64Utils;
-import org.springframework.util.LinkedMultiValueMap;
-import org.springframework.util.MultiValueMap;
-import org.springframework.web.client.RestTemplate;
-
-import java.nio.charset.StandardCharsets;
-
-/**
- * OAuth 2.0 客户端
- *
- * 对应调用 OAuth2OpenController 接口
- */
-@Component
-public class OAuth2Client {
-
-    private static final String BASE_URL = "http://127.0.0.1:48080/admin-api/system/oauth2";
-
-    /**
-     * 租户编号
-     *
-     * 默认使用 1;如果使用别的租户,可以调整
-     */
-    public static final Long TENANT_ID = 1L;
-
-    private static final String CLIENT_ID = "ansteel";
-    private static final String CLIENT_SECRET = "ansteel111111111111111";
-
-
-//    @Resource // 可优化,注册一个 RestTemplate Bean,然后注入
-    private final RestTemplate restTemplate = new RestTemplate();
-
-    /**
-     * 使用 code 授权码,获得访问令牌
-     *
-     * @param code        授权码
-     * @param redirectUri 重定向 URI
-     * @return 访问令牌
-     */
-    public CommonResult<OAuth2AccessTokenRespDTO> postAccessToken(String code, String redirectUri) {
-        // 1.1 构建请求头
-        HttpHeaders headers = new HttpHeaders();
-        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
-        headers.set("tenant-id", TENANT_ID.toString());
-        addClientHeader(headers);
-        // 1.2 构建请求参数
-        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
-        body.add("grant_type", "authorization_code");
-        body.add("code", code);
-        body.add("redirect_uri", redirectUri);
-//        body.add("state", ""); // 选填;填了会校验
-
-        // 2. 执行请求
-        ResponseEntity<CommonResult<OAuth2AccessTokenRespDTO>> exchange = restTemplate.exchange(
-                BASE_URL + "/token",
-                HttpMethod.POST,
-                new HttpEntity<>(body, headers),
-                new ParameterizedTypeReference<CommonResult<OAuth2AccessTokenRespDTO>>() {}); // 解决 CommonResult 的泛型丢失
-        Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功");
-        return exchange.getBody();
-    }
-
-    /**
-     * 校验访问令牌,并返回它的基本信息
-     *
-     * @param token 访问令牌
-     * @return 访问令牌的基本信息
-     */
-    public CommonResult<OAuth2CheckTokenRespDTO> checkToken(String token) {
-        // 1.1 构建请求头
-        HttpHeaders headers = new HttpHeaders();
-        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
-        headers.set("tenant-id", TENANT_ID.toString());
-        addClientHeader(headers);
-        // 1.2 构建请求参数
-        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
-        body.add("token", token);
-
-        // 2. 执行请求
-        ResponseEntity<CommonResult<OAuth2CheckTokenRespDTO>> exchange = restTemplate.exchange(
-                BASE_URL + "/check-token",
-                HttpMethod.POST,
-                new HttpEntity<>(body, headers),
-                new ParameterizedTypeReference<CommonResult<OAuth2CheckTokenRespDTO>>() {}); // 解决 CommonResult 的泛型丢失
-        Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功");
-        return exchange.getBody();
-    }
-
-    /**
-     * 使用刷新令牌,获得(刷新)访问令牌
-     *
-     * @param refreshToken 刷新令牌
-     * @return 访问令牌
-     */
-    public CommonResult<OAuth2AccessTokenRespDTO> refreshToken(String refreshToken) {
-        // 1.1 构建请求头
-        HttpHeaders headers = new HttpHeaders();
-        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
-        headers.set("tenant-id", TENANT_ID.toString());
-        addClientHeader(headers);
-        // 1.2 构建请求参数
-        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
-        body.add("grant_type", "refresh_token");
-        body.add("refresh_token", refreshToken);
-
-        // 2. 执行请求
-        ResponseEntity<CommonResult<OAuth2AccessTokenRespDTO>> exchange = restTemplate.exchange(
-                BASE_URL + "/token",
-                HttpMethod.POST,
-                new HttpEntity<>(body, headers),
-                new ParameterizedTypeReference<CommonResult<OAuth2AccessTokenRespDTO>>() {}); // 解决 CommonResult 的泛型丢失
-        Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功");
-        return exchange.getBody();
-    }
-
-    /**
-     * 删除访问令牌
-     *
-     * @param token 访问令牌
-     * @return 成功
-     */
-    public CommonResult<Boolean> revokeToken(String token) {
-        // 1.1 构建请求头
-        HttpHeaders headers = new HttpHeaders();
-        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
-        headers.set("tenant-id", TENANT_ID.toString());
-        addClientHeader(headers);
-        // 1.2 构建请求参数
-        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
-        body.add("token", token);
-
-        // 2. 执行请求
-        ResponseEntity<CommonResult<Boolean>> exchange = restTemplate.exchange(
-                BASE_URL + "/token",
-                HttpMethod.DELETE,
-                new HttpEntity<>(body, headers),
-                new ParameterizedTypeReference<CommonResult<Boolean>>() {}); // 解决 CommonResult 的泛型丢失
-        Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功");
-        return exchange.getBody();
-    }
-
-    private static void addClientHeader(HttpHeaders headers) {
-        // client 拼接,需要 BASE64 编码
-        String client = CLIENT_ID + ":" + CLIENT_SECRET;
-        client = Base64Utils.encodeToString(client.getBytes(StandardCharsets.UTF_8));
-        headers.add("Authorization", "Basic " + client);
-    }
-
-}
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/client/UserClient.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/client/UserClient.java
deleted file mode 100644
index 4052b97..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/client/UserClient.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package com.iailab.module.ansteel.client;
-
-import com.iailab.framework.common.pojo.CommonResult;
-import com.iailab.framework.security.core.LoginUser;
-import com.iailab.module.ansteel.client.dto.user.UserInfoRespDTO;
-import com.iailab.module.ansteel.client.dto.user.UserUpdateReqDTO;
-import org.springframework.core.ParameterizedTypeReference;
-import org.springframework.http.*;
-import org.springframework.stereotype.Component;
-import org.springframework.util.Assert;
-import org.springframework.util.LinkedMultiValueMap;
-import org.springframework.util.MultiValueMap;
-import org.springframework.web.client.RestTemplate;
-
-import static com.iailab.framework.security.core.util.SecurityFrameworkUtils.getLoginUser;
-
-/**
- * 用户 User 信息的客户端
- *
- * 对应调用 OAuth2UserController 接口
- */
-@Component
-public class UserClient {
-
-    private static final String BASE_URL = "http://127.0.0.1:48080/admin-api/system/oauth2/user";
-
-    //    @Resource // 可优化,注册一个 RestTemplate Bean,然后注入
-    private final RestTemplate restTemplate = new RestTemplate();
-
-    public CommonResult<UserInfoRespDTO> getUser() {
-        // 1.1 构建请求头
-        HttpHeaders headers = new HttpHeaders();
-        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
-        headers.set("tenant-id", OAuth2Client.TENANT_ID.toString());
-        addTokenHeader(headers);
-        // 1.2 构建请求参数
-        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
-
-        // 2. 执行请求
-        ResponseEntity<CommonResult<UserInfoRespDTO>> exchange = restTemplate.exchange(
-                BASE_URL + "/get",
-                HttpMethod.GET,
-                new HttpEntity<>(body, headers),
-                new ParameterizedTypeReference<CommonResult<UserInfoRespDTO>>() {}); // 解决 CommonResult 的泛型丢失
-        Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功");
-        return exchange.getBody();
-    }
-
-    public CommonResult<Boolean> updateUser(UserUpdateReqDTO updateReqDTO) {
-        // 1.1 构建请求头
-        HttpHeaders headers = new HttpHeaders();
-        headers.setContentType(MediaType.APPLICATION_JSON);
-        headers.set("tenant-id", OAuth2Client.TENANT_ID.toString());
-        addTokenHeader(headers);
-        // 1.2 构建请求参数
-        // 使用 updateReqDTO 即可
-
-        // 2. 执行请求
-        ResponseEntity<CommonResult<Boolean>> exchange = restTemplate.exchange(
-                BASE_URL + "/update",
-                HttpMethod.PUT,
-                new HttpEntity<>(updateReqDTO, headers),
-                new ParameterizedTypeReference<CommonResult<Boolean>>() {}); // 解决 CommonResult 的泛型丢失
-        Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功");
-        return exchange.getBody();
-    }
-
-
-    private static void addTokenHeader(HttpHeaders headers) {
-        LoginUser loginUser = getLoginUser();
-        Assert.notNull(loginUser, "登录用户不能为空");
-        headers.add("Authorization", "Bearer " + loginUser.getAccessToken());
-    }
-}
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/client/dto/oauth2/OAuth2AccessTokenRespDTO.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/client/dto/oauth2/OAuth2AccessTokenRespDTO.java
deleted file mode 100644
index d3e49da..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/client/dto/oauth2/OAuth2AccessTokenRespDTO.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.iailab.module.ansteel.client.dto.oauth2;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-/**
- * 访问令牌 Response DTO
- */
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-public class OAuth2AccessTokenRespDTO {
-
-    /**
-     * 访问令牌
-     */
-    private String accessToken;
-
-    /**
-     * 刷新令牌
-     */
-    private String refreshToken;
-
-    /**
-     * 令牌类型
-     */
-    private String tokenType;
-
-    /**
-     * 过期时间;单位:秒
-     */
-    private Long expiresTime;
-
-    /**
-     * 授权范围;如果多个授权范围,使用空格分隔
-     */
-    private String scope;
-
-}
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/client/dto/oauth2/OAuth2CheckTokenRespDTO.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/client/dto/oauth2/OAuth2CheckTokenRespDTO.java
deleted file mode 100644
index df7b699..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/client/dto/oauth2/OAuth2CheckTokenRespDTO.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.iailab.module.ansteel.client.dto.oauth2;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.util.List;
-
-/**
- * 校验令牌 Response DTO
- *
- * @author 芋道源码
- */
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-public class OAuth2CheckTokenRespDTO {
-
-    /**
-     * 用户编号
-     */
-    @JsonProperty("user_id")
-    private Long userId;
-    /**
-     * 用户类型
-     */
-    @JsonProperty("user_type")
-    private Integer userType;
-    /**
-     * 租户编号
-     */
-    @JsonProperty("tenant_id")
-    private Long tenantId;
-
-    /**
-     * 客户端编号
-     */
-    @JsonProperty("client_id")
-    private String clientId;
-    /**
-     * 授权范围
-     */
-    private List<String> scopes;
-
-    /**
-     * 访问令牌
-     */
-    @JsonProperty("access_token")
-    private String accessToken;
-
-    /**
-     * 过期时间
-     *
-     * 时间戳 / 1000,即单位:秒
-     */
-    private Long exp;
-
-}
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/client/dto/user/UserInfoRespDTO.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/client/dto/user/UserInfoRespDTO.java
deleted file mode 100644
index c72767f..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/client/dto/user/UserInfoRespDTO.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package com.iailab.module.ansteel.client.dto.user;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.util.List;
-
-/**
- * 获得用户基本信息 Response dto
- */
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-public class UserInfoRespDTO {
-
-    /**
-     * 用户编号
-     */
-    private Long id;
-
-    /**
-     * 用户账号
-     */
-    private String username;
-
-    /**
-     * 用户昵称
-     */
-    private String nickname;
-
-    /**
-     * 用户邮箱
-     */
-    private String email;
-    /**
-     * 手机号码
-     */
-    private String mobile;
-
-    /**
-     * 用户性别
-     */
-    private Integer sex;
-
-    /**
-     * 用户头像
-     */
-    private String avatar;
-
-    /**
-     * 所在部门
-     */
-    private Dept dept;
-
-    /**
-     * 所属岗位数组
-     */
-    private List<Post> posts;
-
-    /**
-     * 部门
-     */
-    @Data
-    public static class Dept {
-
-        /**
-         * 部门编号
-         */
-        private Long id;
-
-        /**
-         * 部门名称
-         */
-        private String name;
-
-    }
-
-    /**
-     * 岗位
-     */
-    @Data
-    public static class Post {
-
-        /**
-         * 岗位编号
-         */
-        private Long id;
-
-        /**
-         * 岗位名称
-         */
-        private String name;
-
-    }
-
-}
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/client/dto/user/UserUpdateReqDTO.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/client/dto/user/UserUpdateReqDTO.java
deleted file mode 100644
index 99c16bd..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/client/dto/user/UserUpdateReqDTO.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.iailab.module.ansteel.client.dto.user;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-/**
- * 更新用户基本信息 Request DTO
- */
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-public class UserUpdateReqDTO {
-
-    /**
-     * 用户昵称
-     */
-    private String nickname;
-
-    /**
-     * 用户邮箱
-     */
-    private String email;
-
-    /**
-     * 手机号码
-     */
-    private String mobile;
-
-    /**
-     * 用户性别
-     */
-    private Integer sex;
-
-}
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/config/FeignTokenInterceptor.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/config/FeignTokenInterceptor.java
new file mode 100644
index 0000000..8761dae
--- /dev/null
+++ b/ansteel-biz/src/main/java/com/iailab/module/ansteel/config/FeignTokenInterceptor.java
@@ -0,0 +1,43 @@
+package com.iailab.module.ansteel.config;
+
+import com.iailab.module.shasteel.util.token.IailabClient;
+import feign.RequestInterceptor;
+import feign.RequestTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpHeaders;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+@Configuration
+public class FeignTokenInterceptor implements RequestInterceptor {
+
+    @Autowired
+    private IailabClient iailabClient;
+
+    @Override
+    public void apply(RequestTemplate requestTemplate) {
+        // 从当前请求上下文中获取Token
+        String token = getTokenFromCurrentRequest();
+
+        if (token == null) {
+            // 如果没有获取到Token,从system-server中获取token
+            token = iailabClient.getToken();
+            if (token!= null) {
+                requestTemplate.header(HttpHeaders.AUTHORIZATION, token);
+            }
+            Long tenantId = iailabClient.getTenantId();
+            if (tenantId != null) {
+                requestTemplate.header("tenant-id", String.valueOf(tenantId));
+            }
+        }
+    }
+
+    private String getTokenFromCurrentRequest() {
+        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        if (attributes!= null) {
+            return attributes.getRequest().getHeader(HttpHeaders.AUTHORIZATION);
+        }
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/admin/auth/AuthController.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/admin/auth/AuthController.java
deleted file mode 100644
index 8743685..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/admin/auth/AuthController.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package com.iailab.module.ansteel.controller.admin.auth;
-
-import cn.hutool.core.util.StrUtil;
-import com.iailab.framework.common.pojo.CommonResult;
-import com.iailab.module.ansteel.client.OAuth2Client;
-import com.iailab.module.ansteel.client.dto.oauth2.OAuth2AccessTokenRespDTO;
-import com.iailab.module.ansteel.util.SecurityUtils;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-import javax.annotation.Resource;
-import javax.annotation.security.PermitAll;
-import javax.servlet.http.HttpServletRequest;
-
-@RestController
-@RequestMapping("/ansteel/auth")
-public class AuthController {
-
-    @Resource
-    private OAuth2Client oauth2Client;
-
-    /**
-     * 使用 code 访问令牌,获得访问令牌
-     *
-     * @param code 授权码
-     * @param redirectUri 重定向 URI
-     * @return 访问令牌;注意,实际项目中,最好创建对应的 ResponseVO 类,只返回必要的字段
-     */
-    @PostMapping("/loginBycode")
-    @PermitAll
-    public CommonResult<OAuth2AccessTokenRespDTO> loginByCode(@RequestParam("code") String code,
-                                                              @RequestParam("redirectUri") String redirectUri) {
-        return oauth2Client.postAccessToken(code, redirectUri);
-    }
-
-    /**
-     * 使用刷新令牌,获得(刷新)访问令牌
-     *
-     * @param refreshToken 刷新令牌
-     * @return 访问令牌;注意,实际项目中,最好创建对应的 ResponseVO 类,只返回必要的字段
-     */
-    @PostMapping("/refresh-token")
-    public CommonResult<OAuth2AccessTokenRespDTO> refreshToken(@RequestParam("refreshToken") String refreshToken) {
-        return oauth2Client.refreshToken(refreshToken);
-    }
-
-    /**
-     * 退出登录
-     *
-     * @param request 请求
-     * @return 成功
-     */
-    @PostMapping("/logout")
-    public CommonResult<Boolean> logout(HttpServletRequest request) {
-        String token = SecurityUtils.obtainAuthorization(request, "Authorization");
-        if (StrUtil.isNotBlank(token)) {
-            return oauth2Client.revokeToken(token);
-        }
-        // 返回成功
-        return new CommonResult<>();
-    }
-
-}
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/admin/demo/DemoController.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/admin/demo/DemoController.java
deleted file mode 100644
index 1fee7d7..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/admin/demo/DemoController.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package com.iailab.module.ansteel.controller.admin.demo;
-
-import com.iailab.framework.apilog.core.annotation.ApiAccessLog;
-import com.iailab.framework.common.pojo.CommonResult;
-import com.iailab.framework.common.pojo.PageParam;
-import com.iailab.framework.common.pojo.PageResult;
-import com.iailab.framework.common.util.object.BeanUtils;
-import com.iailab.framework.excel.core.util.ExcelUtils;
-import com.iailab.module.ansteel.controller.admin.demo.vo.DemoPageReqVO;
-import com.iailab.module.ansteel.controller.admin.demo.vo.DemoRespVO;
-import com.iailab.module.ansteel.controller.admin.demo.vo.DemoSaveReqVO;
-import com.iailab.module.ansteel.dal.dataobject.demo.DemoDO;
-import com.iailab.module.ansteel.service.demo.DemoService;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.web.bind.annotation.*;
-
-import javax.annotation.Resource;
-import javax.servlet.http.HttpServletResponse;
-import javax.validation.Valid;
-import java.io.IOException;
-import java.util.List;
-
-import static com.iailab.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
-import static com.iailab.framework.common.pojo.CommonResult.success;
-
-@Tag(name = "管理后台 - 演示管理")
-@RestController
-@RequestMapping("/ansteel/demo")
-public class DemoController {
-
-    @Resource
-    private DemoService demoService;
-
-    @PostMapping("/create")
-    @Operation(summary = "创建演示")
-    @PreAuthorize("@ss.hasPermission('ansteel:demo:create')")
-    public CommonResult<Long> createDemo(@Valid @RequestBody DemoSaveReqVO createReqVO) {
-        return success(demoService.create(createReqVO));
-    }
-
-    @PutMapping("/update")
-    @Operation(summary = "更新演示")
-    @PreAuthorize("@ss.hasPermission('ansteel:demo:update')")
-    public CommonResult<Boolean> updateDemo(@Valid @RequestBody DemoSaveReqVO updateReqVO) {
-        demoService.update(updateReqVO);
-        return success(true);
-    }
-
-    @DeleteMapping("/delete")
-    @Operation(summary = "删除演示")
-    @Parameter(name = "id", description = "ID", required = true, example = "1024")
-    @PreAuthorize("@ss.hasPermission('ansteel:demo:delete')")
-    public CommonResult<Boolean> deleteDemo(@RequestParam("id") Long id) {
-        demoService.delete(id);
-        return success(true);
-    }
-
-    @GetMapping("/get")
-    @Operation(summary = "获得演示")
-    @Parameter(name = "id", description = "ID", required = true, example = "1024")
-    @PreAuthorize("@ss.hasPermission('ansteel:demo:query')")
-    public CommonResult<DemoRespVO> getDemo(@RequestParam("id") Long id) {
-        DemoDO data = demoService.getInfo(id);
-        return success(BeanUtils.toBean(data, DemoRespVO.class));
-    }
-
-    @GetMapping("/page")
-    @Operation(summary = "获得分页")
-    @PreAuthorize("@ss.hasPermission('ansteel:demo:query')")
-    public CommonResult<PageResult<DemoRespVO>> getDemoPage(@Valid DemoPageReqVO pageVO) {
-        PageResult<DemoDO> pageResult = demoService.getPage(pageVO);
-        return success(BeanUtils.toBean(pageResult, DemoRespVO.class));
-    }
-
-    @GetMapping("/export-excel")
-    @Operation(summary = "导出 Excel")
-    @PreAuthorize("@ss.hasPermission('system:demo:export')")
-    @ApiAccessLog(operateType = EXPORT)
-    public void exportDemoExcel(@Valid DemoPageReqVO exportReqVO,
-                                  HttpServletResponse response) throws IOException {
-        exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
-        List<DemoDO> list = demoService.getPage(exportReqVO).getList();
-        // 导出 Excel
-        ExcelUtils.write(response, "租户.xls", "数据", DemoRespVO.class,
-                BeanUtils.toBean(list, DemoRespVO.class));
-    }
-}
\ No newline at end of file
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/admin/demo/vo/DemoPageReqVO.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/admin/demo/vo/DemoPageReqVO.java
deleted file mode 100644
index d5a5630..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/admin/demo/vo/DemoPageReqVO.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.iailab.module.ansteel.controller.admin.demo.vo;
-
-import com.iailab.framework.common.pojo.PageParam;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-
-/**
- * @author PanZhibao
- * @Description
- * @createTime 2024年08月17日
- */
-@Schema(description = "管理后台 - 演示分页 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class DemoPageReqVO extends PageParam {
-
-    private String code;
-
-    private String name;
-}
\ No newline at end of file
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/admin/demo/vo/DemoRespVO.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/admin/demo/vo/DemoRespVO.java
deleted file mode 100644
index 23c0e13..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/admin/demo/vo/DemoRespVO.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.iailab.module.ansteel.controller.admin.demo.vo;
-
-import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
-import com.alibaba.excel.annotation.ExcelProperty;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import java.time.LocalDateTime;
-
-/**
- * @author PanZhibao
- * @Description
- * @createTime 2024年08月18日
- */
-@Schema(description = "管理后台 - 演示 Response VO")
-@Data
-@ExcelIgnoreUnannotated
-public class DemoRespVO {
-
-    @Schema(description = "演示编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
-    @ExcelProperty("演示编号")
-    private Long id;
-
-    @Schema(description = "演示编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "演示编号")
-    @ExcelProperty("演示编号")
-    private String code;
-
-    @Schema(description = "演示名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "演示名称")
-    @ExcelProperty("演示名称")
-    private String name;
-
-    @Schema(description = "演示图标", requiredMode = Schema.RequiredMode.REQUIRED, example = "演示图标")
-    @ExcelProperty("演示图标")
-    private String icon;
-
-    @Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "排序")
-    @ExcelProperty("排序")
-    private Integer orderNum;
-
-    @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "状态")
-    @ExcelProperty("状态")
-    private Integer status;
-
-    @Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "备注")
-    @ExcelProperty("备注")
-    private String remark;
-
-    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
-    @ExcelProperty("创建时间")
-    private LocalDateTime createTime;
-
-    @Schema(description = "演示菜单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "演示菜单ID")
-    private Long appMenuId;
-
-    /**
-     * 演示类型(1-系统菜单, 2-演示菜单)
-     */
-    private Integer appType;
-}
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/admin/demo/vo/DemoSaveReqVO.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/admin/demo/vo/DemoSaveReqVO.java
deleted file mode 100644
index e9f4ad9..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/admin/demo/vo/DemoSaveReqVO.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.iailab.module.ansteel.controller.admin.demo.vo;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import javax.validation.constraints.NotNull;
-
-/**
- * @author PanZhibao
- * @Description
- * @createTime 2024年08月17日
- */
-@Schema(description = "管理后台 - 演示创建/修改 Request VO")
-@Data
-public class DemoSaveReqVO {
-
-    @Schema(description = "ID")
-    private Long id;
-
-    @Schema(description = "演示编号", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotNull(message = "演示编号不能为空")
-    private String code;
-
-    @Schema(description = "演示名称", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotNull(message = "演示名称不能为空")
-    private String name;
-
-    @Schema(description = "演示图标", example = "")
-    private String icon;
-
-    @Schema(description = "排序", example = "")
-    private Integer orderNum;
-
-    @Schema(description = "状态", example = "")
-    private Integer status;
-
-    @Schema(description = "备注", example = "")
-    private String remark;
-}
\ No newline at end of file
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/admin/package-info.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/admin/package-info.java
deleted file mode 100644
index b0c56a6..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/admin/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package com.iailab.module.ansteel.controller.admin;
\ No newline at end of file
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/app/ip/AppAreaController.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/app/ip/AppAreaController.java
deleted file mode 100644
index 1110ccf..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/app/ip/AppAreaController.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.iailab.module.ansteel.controller.app.ip;
-
-import cn.hutool.core.lang.Assert;
-import com.iailab.framework.common.pojo.CommonResult;
-import com.iailab.framework.common.util.object.BeanUtils;
-import com.iailab.framework.ip.core.Area;
-import com.iailab.framework.ip.core.utils.AreaUtils;
-import com.iailab.module.ansteel.controller.app.ip.vo.AppAreaNodeRespVO;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.util.List;
-
-import static com.iailab.framework.common.pojo.CommonResult.success;
-
-@Tag(name = "用户 App - 地区")
-@RestController
-@RequestMapping("/system/area")
-@Validated
-public class AppAreaController {
-
-    @GetMapping("/tree")
-    @Operation(summary = "获得地区树")
-    public CommonResult<List<AppAreaNodeRespVO>> getAreaTree() {
-        Area area = AreaUtils.getArea(Area.ID_CHINA);
-        Assert.notNull(area, "获取不到中国");
-        return success(BeanUtils.toBean(area.getChildren(), AppAreaNodeRespVO.class));
-    }
-
-}
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/app/ip/vo/AppAreaNodeRespVO.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/app/ip/vo/AppAreaNodeRespVO.java
deleted file mode 100644
index 6f9f38a..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/app/ip/vo/AppAreaNodeRespVO.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.iailab.module.ansteel.controller.app.ip.vo;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import java.util.List;
-
-@Schema(description = "用户 App - 地区节点 Response VO")
-@Data
-public class AppAreaNodeRespVO {
-
-    @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "110000")
-    private Integer id;
-
-    @Schema(description = "名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "北京")
-    private String name;
-
-    /**
-     * 子节点
-     */
-    private List<AppAreaNodeRespVO> children;
-
-}
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/app/package-info.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/app/package-info.java
deleted file mode 100644
index a5016b5..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/app/package-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- * 占位,避免 package 无法提交到 Git 仓库
- */
-package com.iailab.module.ansteel.controller.app;
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/package-info.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/package-info.java
deleted file mode 100644
index c1c4695..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/controller/package-info.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * 提供 RESTful API 给前端:
- * 1. admin 包:提供给管理后台 iailab-ui-admin 前端项目
- * 2. app 包:提供给用户 APP iailab-ui-app 前端项目,它的 Controller 和 VO 都要添加 App 前缀,用于和管理后台进行区分
- */
-package com.iailab.module.ansteel.controller;
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/dal/dataobject/demo/DemoDO.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/dal/dataobject/demo/DemoDO.java
deleted file mode 100644
index f87c2a0..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/dal/dataobject/demo/DemoDO.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package com.iailab.module.ansteel.dal.dataobject.demo;
-
-import com.baomidou.mybatisplus.annotation.KeySequence;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import com.iailab.framework.tenant.core.db.TenantBaseDO;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-
-/**
- * 演示表
- *
- * @author Houzhongjian
- * @Description
- * @createTime 2024年09月05日
- */
-@TableName("demo")
-@KeySequence("demo_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
-@Data
-@EqualsAndHashCode(callSuper = true)
-public class DemoDO extends TenantBaseDO {
-
-    public static final Long PARENT_ID_ROOT = 0L;
-
-    /**
-     * ID
-     */
-    @TableId
-    private Long id;
-
-    /**
-     * 编号
-     */
-    private String code;
-
-    /**
-     * 名称
-     */
-    private String name;
-
-
-    /**
-     * 图标
-     */
-    private String icon;
-
-    /**
-     * 排序
-     */
-    private Integer orderNum;
-
-    /**
-     * 状态
-     */
-    private Integer status;
-
-    /**
-     * 备注
-     */
-    private String remark;
-
-}
\ No newline at end of file
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/dal/dataobject/package-info.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/dal/dataobject/package-info.java
deleted file mode 100644
index 0c422f6..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/dal/dataobject/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package com.iailab.module.ansteel.dal.dataobject;
\ No newline at end of file
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/dal/mysql/demo/DemoMapper.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/dal/mysql/demo/DemoMapper.java
deleted file mode 100644
index db9de4f..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/dal/mysql/demo/DemoMapper.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.iailab.module.ansteel.dal.mysql.demo;
-
-import com.iailab.framework.common.pojo.PageResult;
-import com.iailab.framework.mybatis.core.mapper.BaseMapperX;
-import com.iailab.framework.mybatis.core.query.LambdaQueryWrapperX;
-import com.iailab.module.ansteel.controller.admin.demo.vo.DemoPageReqVO;
-import com.iailab.module.ansteel.dal.dataobject.demo.DemoDO;
-import org.apache.ibatis.annotations.Mapper;
-
-/**
- * @author Houzhongjian
- * @Description
- * @createTime 2024年09月05日
- */
-@Mapper
-public interface DemoMapper extends BaseMapperX<DemoDO> {
-
-    default PageResult<DemoDO> selectPage(DemoPageReqVO reqVO) {
-        return selectPage(reqVO, new LambdaQueryWrapperX<DemoDO>()
-                .likeIfPresent(DemoDO::getCode, reqVO.getCode())
-                .likeIfPresent(DemoDO::getName, reqVO.getName())
-                .orderByDesc(DemoDO::getId));
-    }
-}
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/dal/mysql/package-info.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/dal/mysql/package-info.java
deleted file mode 100644
index b3b1949..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/dal/mysql/package-info.java
+++ /dev/null
@@ -1,9 +0,0 @@
-/**
- * DAL = Data Access Layer 数据访问层
- * 1. data object:数据对象
- * 2. redis:Redis 的 CRUD 操作
- * 3. mysql:MySQL 的 CRUD 操作
- *
- * 其中,MySQL 的表以 system_ 作为前缀
- */
-package com.iailab.module.ansteel.dal.mysql;
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/common/constant/CommonConstant.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/common/constant/CommonConstant.java
new file mode 100644
index 0000000..67376ce
--- /dev/null
+++ b/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/common/constant/CommonConstant.java
@@ -0,0 +1,26 @@
+package com.iailab.module.ansteel.mq.common.constant;
+
+
+/**
+ * @Description: 通用常量
+ */
+public interface CommonConstant {
+
+    //压缩空气调度方案code
+    String COMPRESSOR_CODE = "Air";
+
+    //蒸汽调度方案code
+    String STEAM_CODE = "sha01";
+
+    //氧气班平衡计划方案code
+    String OXYGEN_ONE_CODE = "oxygen01";
+
+    //氧气系统优化调度决策方案code
+    String OXYGEN_TWO_CODE = "oxygen02";
+
+    //超上限
+    String EXCEEDING_UPPER_LIMIT = "UpperLimit";
+
+    //超下限
+    String EXCEEDING_LOWER_LIMIT = "LowerLimit";
+}
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/common/constant/RoutingConstant.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/common/constant/RoutingConstant.java
new file mode 100644
index 0000000..2fbd6ab
--- /dev/null
+++ b/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/common/constant/RoutingConstant.java
@@ -0,0 +1,12 @@
+package com.iailab.module.ansteel.mq.common.constant;
+
+public interface RoutingConstant {
+
+    String EXCHANGE = "FastShasteel";
+
+    // 预测模型完成路由
+    String Iailab_Model_PredictFinish = "Iailab.Model.PredictFinish";
+
+    //预警消息路由
+    String Iailab_Model_Alarm = "Iailab.Model.Alarm";
+}
\ No newline at end of file
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/config/QueueModelAlarmConfig.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/config/QueueModelAlarmConfig.java
new file mode 100644
index 0000000..037a125
--- /dev/null
+++ b/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/config/QueueModelAlarmConfig.java
@@ -0,0 +1,38 @@
+package com.iailab.module.ansteel.mq.config;
+
+import com.iailab.module.shasteel.mq.common.constant.RoutingConstant;
+import org.springframework.amqp.core.Binding;
+import org.springframework.amqp.core.BindingBuilder;
+import org.springframework.amqp.core.Queue;
+import org.springframework.amqp.core.TopicExchange;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 绑定队列
+ *
+ * @author lirm
+ * @Description
+ * @createTime 2024年11月27日
+ */
+@Configuration
+public class QueueModelAlarmConfig {
+    // 队列名称
+    public final static String QUEUE_NAME = "IaiabFastShateel.Model.Alarm";
+
+    @Bean
+    public Queue alarmQueue() {
+        return new Queue(QUEUE_NAME);
+    }
+
+    @Bean
+    TopicExchange alarmExchange() {
+        return new TopicExchange(RoutingConstant.EXCHANGE);
+    }
+
+    // 注意通配符*和#的用法
+    @Bean
+    Binding bindingExchangeMessageAlarm() {
+        return BindingBuilder.bind(alarmQueue()).to(alarmExchange()).with(RoutingConstant.Iailab_Model_Alarm);
+    }
+}
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/config/QueuePredictFinishConfig.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/config/QueuePredictFinishConfig.java
new file mode 100644
index 0000000..03fbb0d
--- /dev/null
+++ b/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/config/QueuePredictFinishConfig.java
@@ -0,0 +1,36 @@
+package com.iailab.module.ansteel.mq.config;
+
+import com.iailab.module.shasteel.mq.common.constant.RoutingConstant;
+import org.springframework.amqp.core.Binding;
+import org.springframework.amqp.core.BindingBuilder;
+import org.springframework.amqp.core.Queue;
+import org.springframework.amqp.core.TopicExchange;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author lirm
+ * @Description
+ * @createTime 2024年11月27日
+ */
+@Configuration
+public class QueuePredictFinishConfig {
+    // 队列名称
+    public final static String QUEUE_NAME = "IaiabFastShateel.Model.PredictFinish";
+
+    @Bean
+    public Queue predictFinishQueue() {
+        return new Queue(QueuePredictFinishConfig.QUEUE_NAME);
+    }
+
+    @Bean
+    TopicExchange predictFinishExchange() {
+        return new TopicExchange(RoutingConstant.EXCHANGE);
+    }
+
+    // 注意通配符*和#的用法
+    @Bean
+    Binding bindingExchangeMessagePF() {
+        return BindingBuilder.bind(predictFinishQueue()).to(predictFinishExchange()).with(RoutingConstant.Iailab_Model_PredictFinish);
+    }
+}
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/consumer/ModelAlarmConsumer.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/consumer/ModelAlarmConsumer.java
new file mode 100644
index 0000000..871d7cb
--- /dev/null
+++ b/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/consumer/ModelAlarmConsumer.java
@@ -0,0 +1,165 @@
+package com.iailab.module.ansteel.mq.consumer;
+
+import com.alibaba.fastjson.JSONObject;
+import com.iailab.framework.common.util.date.DateUtils;
+import com.iailab.module.model.api.mcs.McsApi;
+import com.iailab.module.model.api.mcs.dto.AlarmMessageRespDTO;
+import com.iailab.module.model.api.mcs.dto.ScheduleSuggestRespDTO;
+import com.iailab.module.model.api.mcs.dto.StScheduleSchemeDTO;
+import com.iailab.module.model.api.mdk.MdkApi;
+import com.iailab.module.model.api.mdk.dto.MdkScheduleReqDTO;
+import com.iailab.module.model.api.mdk.dto.MdkScheduleRespDTO;
+import com.iailab.module.model.enums.ScheduleTriggerMethodEnum;
+import com.iailab.module.shasteel.mq.common.constant.CommonConstant;
+import com.iailab.module.shasteel.mq.config.QueueModelAlarmConfig;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.core.Message;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * 监听报警信息
+ *
+ * @author PanZhibao
+ * @Description
+ * @createTime 2024年12月11日
+ */
+@Slf4j
+@Component
+public class ModelAlarmConsumer {
+
+    @Resource
+    private McsApi mcsApi;
+
+    @Resource
+    private MdkApi mdkApi;
+
+    /**
+     * 事件标识
+     */
+    private final String EVENT_FLAG = "GasAlarm";
+
+    /**
+     * 监听报警信息,执行调度
+     *
+     * @param message
+     */
+    @RabbitListener(queues = QueueModelAlarmConfig.QUEUE_NAME)
+    public void listen(Message message) {
+        String routingKey = message.getMessageProperties().getReceivedRoutingKey();
+        log.info("routingKey:" + routingKey);
+        String messageBody = new String(message.getBody());
+        log.info("messageBody:" + messageBody);
+        JSONObject messageJson = JSONObject.parseObject(messageBody);
+        if (CollectionUtils.isEmpty(messageJson)) {
+            return;
+        }
+        // 查找需要执行的调度方案
+        List<StScheduleSchemeDTO> scheduleSchemeList = mcsApi.listScheduleScheme(ScheduleTriggerMethodEnum.EVENT.getCode(), routingKey);
+        for(StScheduleSchemeDTO stScheduleSchemeDTO : scheduleSchemeList){
+            MdkScheduleReqDTO mdkScheduleReqDTO = new MdkScheduleReqDTO();
+            mdkScheduleReqDTO.setScheduleCode(stScheduleSchemeDTO.getCode());
+            mdkScheduleReqDTO.setScheduleTime(stScheduleSchemeDTO.getScheduleTime());
+            MdkScheduleRespDTO mdkScheduleRespDTO = mdkApi.doSchedule(mdkScheduleReqDTO);//执行调度方案
+            if(mdkScheduleRespDTO == null){
+                return;
+            }
+            AlarmMessageRespDTO alarmRespDTO = (AlarmMessageRespDTO)messageJson.get("AlarmMessageRespDTO");
+            alarmRespDTO.setId(UUID.randomUUID().toString());
+            alarmRespDTO.setAlarmTime(DateUtils.parse(messageJson.get("predictTime").toString(), DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
+            mcsApi.createAlarmMessage(alarmRespDTO);
+            Map<String, Object> result = mdkScheduleRespDTO.getResult();
+            switch (mdkScheduleRespDTO.getScheduleCode()) {
+                case CommonConstant.OXYGEN_ONE_CODE://氧气班平衡计划方案
+                    if(!result.containsKey("faAdvice") || !result.containsKey("yingDiAdvice") || !result.containsKey("yingZhongAdvice")
+                            || !result.containsKey("hongAdvice") || !result.containsKey("RunAdvice")){
+                        return;
+                    }
+                    for (String key : result.keySet()) {
+                        if ("faAdvice".equals(key) && !"".equals(result.get("faAdvice").toString())) {
+                            ScheduleSuggestRespDTO suggestRespDTO = new ScheduleSuggestRespDTO();
+                            suggestRespDTO.setId(UUID.randomUUID().toString());
+                            suggestRespDTO.setScheduleObj(stScheduleSchemeDTO.getScheduleObj());
+                            suggestRespDTO.setContent(result.get("faAdvice").toString());//法夜空建议送出量建议
+                            suggestRespDTO.setSchemeId(stScheduleSchemeDTO.getId());
+                            mcsApi.createScheduleSuggest(suggestRespDTO);
+                        }else if ("yingDiAdvice".equals(key) && !"".equals(result.get("yingDiAdvice").toString())) {
+                            ScheduleSuggestRespDTO suggestRespDTO = new ScheduleSuggestRespDTO();
+                            suggestRespDTO.setId(UUID.randomUUID().toString());
+                            suggestRespDTO.setScheduleObj(stScheduleSchemeDTO.getScheduleObj());
+                            suggestRespDTO.setContent(result.get("yingDiAdvice").toString());//盈德低压建议送出量建议
+                            suggestRespDTO.setSchemeId(stScheduleSchemeDTO.getId());
+                            mcsApi.createScheduleSuggest(suggestRespDTO);
+                        }else if ("yingZhongAdvice".equals(key) && !"".equals(result.get("yingZhongAdvice").toString())) {
+                            ScheduleSuggestRespDTO suggestRespDTO = new ScheduleSuggestRespDTO();
+                            suggestRespDTO.setId(UUID.randomUUID().toString());
+                            suggestRespDTO.setScheduleObj(stScheduleSchemeDTO.getScheduleObj());
+                            suggestRespDTO.setContent(result.get("yingZhongAdvice").toString());//盈德中压建议送出量建议
+                            suggestRespDTO.setSchemeId(stScheduleSchemeDTO.getId());
+                            mcsApi.createScheduleSuggest(suggestRespDTO);
+                        }else if ("hongAdvice".equals(key) && !"".equals(result.get("hongAdvice").toString())) {
+                            ScheduleSuggestRespDTO suggestRespDTO = new ScheduleSuggestRespDTO();
+                            suggestRespDTO.setId(UUID.randomUUID().toString());
+                            suggestRespDTO.setScheduleObj(stScheduleSchemeDTO.getScheduleObj());
+                            suggestRespDTO.setContent(result.get("hongAdvice").toString());//宏昌建议送出量建议
+                            suggestRespDTO.setSchemeId(stScheduleSchemeDTO.getId());
+                            mcsApi.createScheduleSuggest(suggestRespDTO);
+                        }else if ("RunAdvice".equals(key) && !"".equals(result.get("RunAdvice").toString())) {
+                            ScheduleSuggestRespDTO suggestRespDTO = new ScheduleSuggestRespDTO();
+                            suggestRespDTO.setId(UUID.randomUUID().toString());
+                            suggestRespDTO.setScheduleObj(stScheduleSchemeDTO.getScheduleObj());
+                            suggestRespDTO.setContent(result.get("RunAdvice").toString());//润忠建议送出量建议
+                            suggestRespDTO.setSchemeId(stScheduleSchemeDTO.getId());
+                            mcsApi.createScheduleSuggest(suggestRespDTO);
+                        }
+                    }
+                    break;
+                case CommonConstant.OXYGEN_TWO_CODE://氧气系统优化调度决策方案
+                    if(!result.containsKey("yingdiAdvice") || !result.containsKey("faAdvice") || !result.containsKey("hongAdvice")
+                            || !result.containsKey("RunAdvice")){
+                        return;
+                    }
+                    for (String key : result.keySet()) {
+                        if ("yingdiAdvice".equals(key) && !"".equals(result.get("yingdiAdvice").toString())) {
+                            ScheduleSuggestRespDTO suggestRespDTO = new ScheduleSuggestRespDTO();
+                            suggestRespDTO.setId(UUID.randomUUID().toString());
+                            suggestRespDTO.setScheduleObj(stScheduleSchemeDTO.getScheduleObj());
+                            suggestRespDTO.setContent(result.get("yingdiAdvice").toString());//盈德中压建议调整量建议
+                            suggestRespDTO.setSchemeId(stScheduleSchemeDTO.getId());
+                            mcsApi.createScheduleSuggest(suggestRespDTO);
+                        }else if ("faAdvice".equals(key) && !"".equals(result.get("faAdvice").toString())) {
+                            ScheduleSuggestRespDTO suggestRespDTO = new ScheduleSuggestRespDTO();
+                            suggestRespDTO.setId(UUID.randomUUID().toString());
+                            suggestRespDTO.setScheduleObj(stScheduleSchemeDTO.getScheduleObj());
+                            suggestRespDTO.setContent(result.get("faAdvice").toString());//法夜空建议调整量建议
+                            suggestRespDTO.setSchemeId(stScheduleSchemeDTO.getId());
+                            mcsApi.createScheduleSuggest(suggestRespDTO);
+                        }else if ("hongAdvice".equals(key) && !"".equals(result.get("hongAdvice").toString())) {
+                            ScheduleSuggestRespDTO suggestRespDTO = new ScheduleSuggestRespDTO();
+                            suggestRespDTO.setId(UUID.randomUUID().toString());
+                            suggestRespDTO.setScheduleObj(stScheduleSchemeDTO.getScheduleObj());
+                            suggestRespDTO.setContent(result.get("hongAdvice").toString());//宏昌建议调整量建议
+                            suggestRespDTO.setSchemeId(stScheduleSchemeDTO.getId());
+                            mcsApi.createScheduleSuggest(suggestRespDTO);
+                        }else if ("RunAdvice".equals(key) && !"".equals(result.get("RunAdvice").toString())) {
+                            ScheduleSuggestRespDTO suggestRespDTO = new ScheduleSuggestRespDTO();
+                            suggestRespDTO.setId(UUID.randomUUID().toString());
+                            suggestRespDTO.setScheduleObj(stScheduleSchemeDTO.getScheduleObj());
+                            suggestRespDTO.setContent(result.get("RunAdvice").toString());//润忠建议调整量建议
+                            suggestRespDTO.setSchemeId(stScheduleSchemeDTO.getId());
+                            mcsApi.createScheduleSuggest(suggestRespDTO);
+                        }
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/consumer/ModelPredictFinish2Consumer.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/consumer/ModelPredictFinish2Consumer.java
new file mode 100644
index 0000000..c1dac4f
--- /dev/null
+++ b/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/consumer/ModelPredictFinish2Consumer.java
@@ -0,0 +1,150 @@
+package com.iailab.module.ansteel.mq.consumer;
+
+import com.alibaba.fastjson.JSONObject;
+import com.iailab.framework.common.util.date.DateUtils;
+import com.iailab.module.model.api.mcs.McsApi;
+import com.iailab.module.model.api.mcs.dto.AlarmMessageRespDTO;
+import com.iailab.module.model.api.mcs.dto.ScheduleSuggestRespDTO;
+import com.iailab.module.model.api.mcs.dto.StScheduleSchemeDTO;
+import com.iailab.module.model.api.mdk.MdkApi;
+import com.iailab.module.model.api.mdk.dto.MdkScheduleReqDTO;
+import com.iailab.module.model.api.mdk.dto.MdkScheduleRespDTO;
+import com.iailab.module.model.enums.ScheduleTriggerMethodEnum;
+import com.iailab.module.shasteel.mq.common.constant.CommonConstant;
+import com.iailab.module.shasteel.mq.config.QueuePredictFinishConfig;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.core.Message;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * 监听报警信息
+ *
+ * @author PanZhibao
+ * @Description
+ * @createTime 2024年12月11日
+ */
+@Slf4j
+@Component
+public class ModelPredictFinish2Consumer {
+
+    @Resource
+    private McsApi mcsApi;
+
+    @Resource
+    private MdkApi mdkApi;
+
+    /**
+     * 监听预测完成,执行调度
+     *
+     * @param message
+     */
+    @RabbitListener(queues = QueuePredictFinishConfig.QUEUE_NAME)
+    public void listen(Message message) {
+        String routingKey = message.getMessageProperties().getReceivedRoutingKey();
+        log.info("routingKey:" + routingKey);
+        String messageBody = new String(message.getBody());
+        log.info("messageBody:" + messageBody);
+        JSONObject messageJson = JSONObject.parseObject(messageBody);
+        if (CollectionUtils.isEmpty(messageJson)) {
+            return;
+        }
+        // 查找需要执行的调度方案
+        List<StScheduleSchemeDTO> scheduleSchemeList = mcsApi.listScheduleScheme(ScheduleTriggerMethodEnum.EVENT.getCode(), routingKey);
+        for(StScheduleSchemeDTO stScheduleSchemeDTO : scheduleSchemeList){
+            MdkScheduleReqDTO mdkScheduleReqDTO = new MdkScheduleReqDTO();
+            mdkScheduleReqDTO.setScheduleCode(stScheduleSchemeDTO.getCode());
+            mdkScheduleReqDTO.setScheduleTime(stScheduleSchemeDTO.getScheduleTime());
+            MdkScheduleRespDTO mdkScheduleRespDTO = mdkApi.doSchedule(mdkScheduleReqDTO);//执行调度方案
+            if(mdkScheduleRespDTO == null){
+                return;
+            }
+            Map<String, Object> result = mdkScheduleRespDTO.getResult();
+            switch (mdkScheduleRespDTO.getScheduleCode()) {
+                case CommonConstant.COMPRESSOR_CODE://压缩空气调度方案
+                    if(!result.containsKey("pressureWarning") || !result.containsKey("dispatchStart") || !result.containsKey("dispatchEnd")){
+                        return;
+                    }
+                    for (String key : result.keySet()) {
+                        if("pressureWarning".equals(key) && !"".equals(result.get("pressureWarning").toString())){
+                            AlarmMessageRespDTO alarmRespDTO = new AlarmMessageRespDTO();
+                            alarmRespDTO.setId(UUID.randomUUID().toString());
+                            alarmRespDTO.setContent(result.get("pressureWarning").toString());//压力预警信息
+                            alarmRespDTO.setAlarmTime(DateUtils.parse(messageJson.get("predictTime").toString(), DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
+                            mcsApi.createAlarmMessage(alarmRespDTO);
+                        }else if("dispatchStart".equals(key) && !"".equals(result.get("dispatchStart").toString())){
+                            ScheduleSuggestRespDTO suggestRespDTO = new ScheduleSuggestRespDTO();
+                            suggestRespDTO.setId(UUID.randomUUID().toString());
+                            suggestRespDTO.setScheduleObj(stScheduleSchemeDTO.getScheduleObj());
+                            suggestRespDTO.setContent(result.get("dispatchStart").toString());//空压机启动调度建议
+                            suggestRespDTO.setSchemeId(stScheduleSchemeDTO.getId());
+                            mcsApi.createScheduleSuggest(suggestRespDTO);
+                        }else if("dispatchEnd".equals(key) && !"".equals(result.get("dispatchEnd").toString())){
+                            ScheduleSuggestRespDTO suggestRespDTO = new ScheduleSuggestRespDTO();
+                            suggestRespDTO.setId(UUID.randomUUID().toString());
+                            suggestRespDTO.setScheduleObj(stScheduleSchemeDTO.getScheduleObj());
+                            suggestRespDTO.setContent(result.get("dispatchClose").toString());//空压机关停调度建议
+                            suggestRespDTO.setSchemeId(stScheduleSchemeDTO.getId());
+                            mcsApi.createScheduleSuggest(suggestRespDTO);
+                        }
+                    }
+                    break;
+                case CommonConstant.STEAM_CODE://蒸汽调度方案
+                    if(!result.containsKey("daxinWarning") || !result.containsKey("jinfengWarning") || !result.containsKey("zhuanlu1Warning")
+                            || !result.containsKey("zhuanlu2Warning") || !result.containsKey("jinfengAdvice") || !result.containsKey("daxinAdvice")){
+                        return;
+                    }
+                    for (String key : result.keySet()) {
+                        if ("daxinWarning".equals(key) && !"".equals(result.get("daxinWarning").toString())) {
+                            AlarmMessageRespDTO alarmRespDTO = new AlarmMessageRespDTO();
+                            alarmRespDTO.setId(UUID.randomUUID().toString());
+                            alarmRespDTO.setContent(result.get("daxinWarning").toString());//大新预警
+                            alarmRespDTO.setAlarmTime(DateUtils.parse(messageJson.get("predictTime").toString(), DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
+                            mcsApi.createAlarmMessage(alarmRespDTO);
+                        }else if ("jinfengWarning".equals(key) && !"".equals(result.get("jinfengWarning").toString())) {
+                            AlarmMessageRespDTO alarmRespDTO = new AlarmMessageRespDTO();
+                            alarmRespDTO.setId(UUID.randomUUID().toString());
+                            alarmRespDTO.setContent(result.get("jinfengWarning").toString());//锦丰预警
+                            alarmRespDTO.setAlarmTime(DateUtils.parse(messageJson.get("predictTime").toString(), DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
+                            mcsApi.createAlarmMessage(alarmRespDTO);
+                        }else if ("zhuanlu1Warning".equals(key) && !"".equals(result.get("zhuanlu1Warning").toString())) {
+                            AlarmMessageRespDTO alarmRespDTO = new AlarmMessageRespDTO();
+                            alarmRespDTO.setId(UUID.randomUUID().toString());
+                            alarmRespDTO.setContent(result.get("zhuanlu1Warning").toString());//转炉一预警
+                            alarmRespDTO.setAlarmTime(DateUtils.parse(messageJson.get("predictTime").toString(), DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
+                            mcsApi.createAlarmMessage(alarmRespDTO);
+                        }else if ("zhuanlu2Warning".equals(key) && !"".equals(result.get("zhuanlu2Warning").toString())) {
+                            AlarmMessageRespDTO alarmRespDTO = new AlarmMessageRespDTO();
+                            alarmRespDTO.setId(UUID.randomUUID().toString());
+                            alarmRespDTO.setContent(result.get("zhuanlu2Warning").toString());//转炉二预警
+                            alarmRespDTO.setAlarmTime(DateUtils.parse(messageJson.get("predictTime").toString(), DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
+                            mcsApi.createAlarmMessage(alarmRespDTO);
+                        }else if ("jinfengAdvice".equals(key) && !"".equals(result.get("jinfengAdvice").toString())) {
+                            ScheduleSuggestRespDTO suggestRespDTO = new ScheduleSuggestRespDTO();
+                            suggestRespDTO.setId(UUID.randomUUID().toString());
+                            suggestRespDTO.setScheduleObj(stScheduleSchemeDTO.getScheduleObj());
+                            suggestRespDTO.setContent(result.get("jinfengAdvice").toString());//锦丰调度建议
+                            suggestRespDTO.setSchemeId(stScheduleSchemeDTO.getId());
+                            mcsApi.createScheduleSuggest(suggestRespDTO);
+                        }else if ("daxinAdvice".equals(key) && !"".equals(result.get("daxinAdvice").toString())) {
+                            ScheduleSuggestRespDTO suggestRespDTO = new ScheduleSuggestRespDTO();
+                            suggestRespDTO.setId(UUID.randomUUID().toString());
+                            suggestRespDTO.setScheduleObj(stScheduleSchemeDTO.getScheduleObj());
+                            suggestRespDTO.setContent(result.get("daxinAdvice").toString());//大新调度建议
+                            suggestRespDTO.setSchemeId(stScheduleSchemeDTO.getId());
+                            mcsApi.createScheduleSuggest(suggestRespDTO);
+                        }
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/consumer/ModelPredictFinishConsumer.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/consumer/ModelPredictFinishConsumer.java
new file mode 100644
index 0000000..a614a12
--- /dev/null
+++ b/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/consumer/ModelPredictFinishConsumer.java
@@ -0,0 +1,117 @@
+package com.iailab.module.ansteel.mq.consumer;
+
+import com.alibaba.fastjson.JSONObject;
+import com.iailab.framework.common.util.date.DateUtils;
+import com.iailab.module.model.api.mcs.McsApi;
+import com.iailab.module.model.api.mcs.dto.AlarmConfigRespDTO;
+import com.iailab.module.model.api.mcs.dto.AlarmMessageRespDTO;
+import com.iailab.module.model.api.mcs.dto.PreDataJsonReqVO;
+import com.iailab.module.shasteel.mq.common.constant.CommonConstant;
+import com.iailab.module.shasteel.mq.common.constant.RoutingConstant;
+import com.iailab.module.shasteel.mq.config.QueuePredictFinishConfig;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.core.Message;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 监听预测完成
+ *
+ * @author PanZhibao
+ * @Description
+ * @createTime 2024年12月11日
+ */
+@Slf4j
+@Component
+public class ModelPredictFinishConsumer {
+
+    @Resource
+    private McsApi mcsApi;
+
+    @Resource
+    private RabbitTemplate rabbitTemplate;
+
+    /**
+     * 监听预测完成,产生预警消息
+     *
+     * @param message
+     */
+    @RabbitListener(queues = QueuePredictFinishConfig.QUEUE_NAME)
+    public void listen(Message message) {
+        try {
+            String routingKey = message.getMessageProperties().getReceivedRoutingKey();
+            log.info("routingKey:" + routingKey);
+            String messageBody = new String(message.getBody());
+            log.info("messageBody:" + messageBody);
+            JSONObject messageJson = JSONObject.parseObject(messageBody);
+            if (CollectionUtils.isEmpty(messageJson)) {
+                return;
+            }
+            List<AlarmConfigRespDTO> configList = mcsApi.listAlarmConfig(new HashMap<String, Object>());
+            if (CollectionUtils.isEmpty(configList)) {
+                return;
+            }
+            List<String> outputIdList = new ArrayList<>();
+            configList.forEach(item -> {
+                outputIdList.add(item.getOutId());
+            });
+            configList.forEach(item -> {
+                PreDataJsonReqVO reqVO = new PreDataJsonReqVO();
+                reqVO.setPredictTime(DateUtils.parse(messageJson.get("predictTime").toString(), DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
+                reqVO.setOutputIdList(outputIdList);
+                Map<String, List<Object[]>> preData = mcsApi.getPreDataCur(reqVO);
+                if (CollectionUtils.isEmpty(preData)) {
+                    return;
+                }
+                List<Object[]> result = preData.get(item.getOutId());
+                int toIndex = result.size();
+                if (toIndex <= 0) {
+                    return;
+                }
+                int fromIndex = result.size() - item.getCompLength();
+                List<Object[]> predictList = result.subList(fromIndex, toIndex);
+                for (Object[] data : predictList) {
+                    BigDecimal dataValue = new BigDecimal(Double.parseDouble(data[1].toString())).setScale(2, BigDecimal.ROUND_HALF_UP);
+                    if (!(dataValue.compareTo(item.getLowerLimit()) >= 0 && dataValue.compareTo(item.getUpperLimit()) <= 0)) {
+                        AlarmMessageRespDTO alarmMessage = new AlarmMessageRespDTO();
+                        alarmMessage.setConfigId(item.getId());
+                        if (dataValue.compareTo(item.getLowerLimit()) < 0) {
+                            alarmMessage.setAlarmType(CommonConstant.EXCEEDING_LOWER_LIMIT);//超下限
+                        } else if (dataValue.compareTo(item.getUpperLimit()) > 0) {
+                            alarmMessage.setAlarmType(CommonConstant.EXCEEDING_UPPER_LIMIT);//超上限
+                        }
+                        alarmMessage.setAlarmTime(DateUtils.parse(data[0].toString(), DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND));
+                        StringBuffer sb = new StringBuffer();
+                        sb.append(data[0]);
+                        sb.append(" ");
+                        sb.append(item.getAlarmObj());
+                        if ("1".equals(alarmMessage.getAlarmType())) {
+                            sb.append(CommonConstant.EXCEEDING_LOWER_LIMIT);
+                        } else if ("2".equals(alarmMessage.getAlarmType())) {
+                            sb.append(CommonConstant.EXCEEDING_UPPER_LIMIT);
+                        }
+                        sb.append(dataValue);
+                        sb.append(item.getUnit());
+                        alarmMessage.setContent(sb.toString());
+                        System.out.println("预警消息=" + alarmMessage);
+                        rabbitTemplate.convertAndSend(RoutingConstant.EXCHANGE, RoutingConstant.Iailab_Model_Alarm, alarmMessage);
+                        break;
+                    }
+                }
+                System.out.println(preData);
+            });
+        } catch (Exception e) {
+            return;
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/package-info.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/package-info.java
new file mode 100644
index 0000000..5d3bcf2
--- /dev/null
+++ b/ansteel-biz/src/main/java/com/iailab/module/ansteel/mq/package-info.java
@@ -0,0 +1 @@
+package com.iailab.module.ansteel.mq;
\ No newline at end of file
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/service/demo/DemoService.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/service/demo/DemoService.java
deleted file mode 100644
index e88d6d0..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/service/demo/DemoService.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.iailab.module.ansteel.service.demo;
-
-import com.iailab.framework.common.pojo.PageResult;
-import com.iailab.module.ansteel.controller.admin.demo.vo.DemoPageReqVO;
-import com.iailab.module.ansteel.controller.admin.demo.vo.DemoSaveReqVO;
-import com.iailab.module.ansteel.dal.dataobject.demo.DemoDO;
-
-/**
- * @author PanZhibao
- * @Description
- * @createTime 2024年08月17日
- */
-public interface DemoService {
-
-    Long create(DemoSaveReqVO createReqVO);
-
-    Long update(DemoSaveReqVO createReqVO);
-
-    void delete(Long id);
-
-    DemoDO getInfo(Long id);
-
-    PageResult<DemoDO> getPage(DemoPageReqVO pageReqVO);
-}
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/service/demo/DemoServiceImpl.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/service/demo/DemoServiceImpl.java
deleted file mode 100644
index 2ef8664..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/service/demo/DemoServiceImpl.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package com.iailab.module.ansteel.service.demo;
-
-import com.iailab.framework.common.pojo.PageResult;
-import com.iailab.framework.common.util.object.BeanUtils;
-import com.iailab.module.ansteel.controller.admin.demo.vo.DemoPageReqVO;
-import com.iailab.module.ansteel.controller.admin.demo.vo.DemoSaveReqVO;
-import com.iailab.module.ansteel.dal.dataobject.demo.DemoDO;
-import com.iailab.module.ansteel.dal.mysql.demo.DemoMapper;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-
-import javax.annotation.Resource;
-
-/**
- * @author PanZhibao
- * @Description
- * @createTime 2024年08月17日
- */
-@Service
-@Slf4j
-public class DemoServiceImpl implements DemoService {
-
-    @Resource
-    private DemoMapper demoMapper;
-
-
-    @Override
-    public Long create(DemoSaveReqVO createReqVO) {
-        DemoDO demo = BeanUtils.toBean(createReqVO, DemoDO.class);
-        demoMapper.insert(demo);
-        return demo.getId();
-    }
-
-    @Override
-    public Long update(DemoSaveReqVO createReqVO) {
-        DemoDO demo = BeanUtils.toBean(createReqVO, DemoDO.class);
-        demoMapper.updateById(demo);
-        return demo.getId();
-    }
-
-    @Override
-    public void delete(Long id) {
-        demoMapper.deleteById(id);
-    }
-
-    @Override
-    public DemoDO getInfo(Long id) {
-        return demoMapper.selectById(id);
-    }
-
-    @Override
-    public PageResult<DemoDO> getPage(DemoPageReqVO pageReqVO) {
-        return demoMapper.selectPage(pageReqVO);
-    }
-
-}
\ No newline at end of file
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/service/package-info.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/service/package-info.java
deleted file mode 100644
index fcafaab..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/service/package-info.java
+++ /dev/null
@@ -1 +0,0 @@
-package com.iailab.module.ansteel.service;
\ No newline at end of file
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/util/SecurityUtils.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/util/SecurityUtils.java
deleted file mode 100644
index f238f36..0000000
--- a/ansteel-biz/src/main/java/com/iailab/module/ansteel/util/SecurityUtils.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package com.iailab.module.ansteel.util;
-
-import com.iailab.framework.security.core.LoginUser;
-import org.springframework.lang.Nullable;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContext;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
-import org.springframework.util.StringUtils;
-
-import javax.servlet.http.HttpServletRequest;
-import java.util.Collections;
-
-/**
- * 安全服务工具类
- *
- * @author 芋道源码
- */
-public class SecurityUtils {
-
-    public static final String AUTHORIZATION_BEARER = "Bearer";
-
-    private SecurityUtils() {}
-
-    /**
-     * 从请求中,获得认证 Token
-     *
-     * @param request 请求
-     * @param header 认证 Token 对应的 Header 名字
-     * @return 认证 Token
-     */
-    public static String obtainAuthorization(HttpServletRequest request, String header) {
-        String authorization = request.getHeader(header);
-        if (!StringUtils.hasText(authorization)) {
-            return null;
-        }
-        int index = authorization.indexOf(AUTHORIZATION_BEARER + " ");
-        if (index == -1) { // 未找到
-            return null;
-        }
-        return authorization.substring(index + 7).trim();
-    }
-
-    /**
-     * 获得当前认证信息
-     *
-     * @return 认证信息
-     */
-    public static Authentication getAuthentication() {
-        SecurityContext context = SecurityContextHolder.getContext();
-        if (context == null) {
-            return null;
-        }
-        return context.getAuthentication();
-    }
-
-    /**
-     * 获取当前用户
-     *
-     * @return 当前用户
-     */
-    @Nullable
-    public static LoginUser getLoginUser() {
-        Authentication authentication = getAuthentication();
-        if (authentication == null) {
-            return null;
-        }
-        return authentication.getPrincipal() instanceof LoginUser ? (LoginUser) authentication.getPrincipal() : null;
-    }
-
-    /**
-     * 获得当前用户的编号,从上下文中
-     *
-     * @return 用户编号
-     */
-    @Nullable
-    public static Long getLoginUserId() {
-        LoginUser loginUser = getLoginUser();
-        return loginUser != null ? loginUser.getId() : null;
-    }
-
-    /**
-     * 设置当前用户
-     *
-     * @param loginUser 登录用户
-     * @param request 请求
-     */
-    public static void setLoginUser(LoginUser loginUser, HttpServletRequest request) {
-        // 创建 Authentication,并设置到上下文
-        Authentication authentication = buildAuthentication(loginUser, request);
-        SecurityContextHolder.getContext().setAuthentication(authentication);
-    }
-
-    private static Authentication buildAuthentication(LoginUser loginUser, HttpServletRequest request) {
-        // 创建 UsernamePasswordAuthenticationToken 对象
-        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
-                loginUser, null, Collections.emptyList());
-        authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
-        return authenticationToken;
-    }
-
-}
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/util/SpringContextUtils.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/util/SpringContextUtils.java
new file mode 100644
index 0000000..90969d4
--- /dev/null
+++ b/ansteel-biz/src/main/java/com/iailab/module/ansteel/util/SpringContextUtils.java
@@ -0,0 +1,47 @@
+package com.iailab.module.ansteel.util;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+/**
+ * Spring Context 工具类
+ * 
+ * @author Mark sunlightcs@gmail.com
+ */
+@Component
+public class SpringContextUtils implements ApplicationContextAware {
+	public static ApplicationContext applicationContext; 
+
+	@Override
+	public void setApplicationContext(ApplicationContext applicationContext)
+			throws BeansException {
+		SpringContextUtils.applicationContext = applicationContext;
+	}
+
+	public static Object getBean(String name) {
+		return applicationContext.getBean(name);
+	}
+
+	public static <T> T getBean(Class<T> requiredType) {
+		return applicationContext.getBean(requiredType);
+	}
+
+	public static <T> T getBean(String name, Class<T> requiredType) {
+		return applicationContext.getBean(name, requiredType);
+	}
+
+	public static boolean containsBean(String name) {
+		return applicationContext.containsBean(name);
+	}
+
+	public static boolean isSingleton(String name) {
+		return applicationContext.isSingleton(name);
+	}
+
+	public static Class<? extends Object> getType(String name) {
+		return applicationContext.getType(name);
+	}
+
+}
\ No newline at end of file
diff --git a/ansteel-biz/src/main/java/com/iailab/module/ansteel/util/token/IailabClient.java b/ansteel-biz/src/main/java/com/iailab/module/ansteel/util/token/IailabClient.java
new file mode 100644
index 0000000..974c1cd
--- /dev/null
+++ b/ansteel-biz/src/main/java/com/iailab/module/ansteel/util/token/IailabClient.java
@@ -0,0 +1,145 @@
+package com.iailab.module.ansteel.util.token;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+import org.springframework.util.Assert;
+import org.springframework.util.Base64Utils;
+import org.springframework.util.ObjectUtils;
+import org.springframework.web.client.RestTemplate;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+
+/**
+ * @author PanZhibao
+ * @Description
+ * @createTime 2024年11月21日
+ */
+@Slf4j
+@Component
+public class IailabClient {
+
+    /**
+     * 平台地址
+     */
+    @Value("${iailab.token.base-url}")
+    private String BASE_URL;
+
+    /**
+     * 租户编号
+     */
+    @Value("${iailab.token.tenant-id}")
+    private String TENANT_ID;
+
+    /**
+     * 客户端信息
+     */
+    @Value("${iailab.token.client-id}")
+    private String CLIENT_ID;
+    @Value("${iailab.token.client-secret}")
+    private String CLIENT_SECRET;
+    @Value("${iailab.token.username}")
+    private String USERNAME;
+    @Value("${iailab.token.password}")
+    private String PASSWORD;
+    private static final String GRAND_TYPE = "password";
+    private static final String SCOPE = "user.read user.write";
+
+
+    private static final RestTemplate restTemplate = new RestTemplate();
+
+    // 鉴权token
+    private String accessToken;
+    // 刷新token
+    private String refreshToken;
+    // 鉴权token过期时间
+    private Long expireTime;
+
+    /**
+     * 用户名密码方式获取平台token
+     */
+    private synchronized void authenticate() {
+        log.info("获取平台token");
+        // 1.1 构建请求头
+        HttpHeaders headers = new HttpHeaders();
+        addClientHeader(headers);
+        // 1.2 构建authenticate请求URL
+        String authenticateUrl = BASE_URL + "/oauth2/token?"
+                // 密码模式的参数
+                + "grant_type=" + GRAND_TYPE
+                + "&username=" + USERNAME
+                + "&password=" + PASSWORD
+                + "&scope=" + SCOPE;
+        // 2. 执行请求
+        ResponseEntity<Map<String, Object>> exchange = restTemplate.exchange(
+                authenticateUrl,
+                HttpMethod.POST,
+                new org.springframework.http.HttpEntity<>(headers),
+                new ParameterizedTypeReference<Map<String, Object>>() {
+                });
+        Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功");
+        log.info(exchange.toString());
+        Map<String, Object> authMap = exchange.getBody();
+        accessToken = authMap.get("access_token").toString();
+        refreshToken = authMap.get("refresh_token").toString();
+        expireTime = Long.valueOf(authMap.get("expires_time").toString());
+    }
+
+    private synchronized void refreshToken() {
+        log.info("刷新token");
+        // 1.1 构建请求头
+        HttpHeaders headers = new HttpHeaders();
+        addClientHeader(headers);
+        // 1.2 构建authenticate请求URL
+        String authenticateUrl = BASE_URL + "/system/auth/client-refresh-token?refreshToken=" + refreshToken
+                + "&clientId=" + CLIENT_ID;
+        // 2. 执行请求
+        ResponseEntity<Map<String, Object>> exchange = restTemplate.exchange(
+                authenticateUrl,
+                HttpMethod.POST,
+                new org.springframework.http.HttpEntity<>(headers),
+                new ParameterizedTypeReference<Map<String, Object>>() {
+                });
+        Assert.isTrue(exchange.getStatusCode().is2xxSuccessful(), "响应必须是 200 成功");
+        Map<String, Object> authMap = exchange.getBody();
+        //刷新token过期,重新获取token
+        if (!ObjectUtils.isEmpty(authMap.get("code"))) {
+            Integer code = Integer.valueOf(authMap.get("code").toString());
+            if (code == 401) {
+                authenticate();
+            }
+        } else {
+            accessToken = authMap.get("access_token").toString();
+            expireTime = Long.valueOf(authMap.get("expires_time").toString());
+        }
+    }
+
+    private void addClientHeader(HttpHeaders headers) {
+        // client 拼接,需要 BASE64 编码
+        String client = CLIENT_ID + ":" + CLIENT_SECRET;
+        client = Base64Utils.encodeToString(client.getBytes(StandardCharsets.UTF_8));
+        headers.add("Authorization", "Basic " + client);
+        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+        headers.set("tenant-id", getTenantId().toString());
+    }
+
+    public String getToken() {
+        //第一次请求或者token过期,需要重新获取token
+        if(ObjectUtils.isEmpty(accessToken)) {
+            authenticate();
+        } else if (expireTime < System.currentTimeMillis() / 1000) {
+            refreshToken();
+        }
+        
+        return accessToken;
+    }
+    public Long getTenantId() {
+        return Long.valueOf(TENANT_ID);
+    }
+}
\ No newline at end of file

--
Gitblit v1.9.3