From d603739c0320f355cfc3152865918729fea790de Mon Sep 17 00:00:00 2001
From: Lius <Lius2225@163.com>
Date: 星期一, 04 十一月 2024 09:45:43 +0800
Subject: [PATCH] license

---
 lxzn-boot-base-core/src/main/java/org/jeecg/config/license/LicenseManagerHolder.java                      |   28 
 lxzn-module-system/lxzn-system-start/src/main/resources/application-dev.yml                               |   22 
 lxzn-boot-base-core/src/main/java/org/jeecg/config/license/entity/LicenseCheckModel.java                  |   62 +
 lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/EquipmentWorkLineServiceImpl.java        |   26 
 lxzn-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java                                 |    1 
 lxzn-boot-base-core/src/main/java/org/jeecg/config/LicenseConfig.java                                     |   32 +
 lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IEquipmentXYZService.java                     |    5 
 lxzn-boot-base-core/src/main/java/org/jeecg/config/license/LicenseVerify.java                             |   87 ++
 lxzn-boot-base-core/src/main/java/org/jeecg/config/license/LicenseCheckListener.java                      |   77 ++
 lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/EquipmentWorklineMapper.xml                |   76 ++
 lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/EquipmentXYZServiceImpl.java             |    8 
 lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/dto/CurrentElectricDto.java                           |   27 
 lxzn-boot-base-core/src/main/java/org/jeecg/config/license/entity/LicenseVerifyParam.java                 |   67 ++
 lxzn-boot-base-core/src/main/java/org/jeecg/config/license/LicenseCheckInterceptor.java                   |   84 ++
 lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/EquipmentXYZMapper.xml                     |   18 
 lxzn-boot-base-core/src/main/java/org/jeecg/config/license/entity/CustomLicenseManager.java               |  270 ++++++++
 lxzn-boot-base-core/pom.xml                                                                               |    6 
 lxzn-module-mdc/src/main/java/org/jeecg/modules/screen/service/impl/MdcLargeScreenServiceImpl.java        |    4 
 lxzn-boot-base-core/src/main/java/org/jeecg/config/license/LinuxServerInfos.java                          |   89 ++
 lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/EquipmentXYZMapper.java                        |    5 
 lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcOeeInfoServiceImpl.java               |   20 
 lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/job/StatisticalSpindleJob.java                        |   70 +
 lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/EquipmentWorklineMapper.java                   |   14 
 lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/config/license/LicenseCreatorParam.java        |  155 ++++
 lxzn-boot-base-core/src/main/java/org/jeecg/config/license/AbstractServerInfos.java                       |  129 ++++
 lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IEquipmentWorkLineService.java                |   46 +
 lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/job/StatisticalElectricJob.java                       |   97 +-
 lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/base/controller/LicenseController.java |   96 +++
 lxzn-boot-base-core/src/main/java/org/jeecg/config/license/WindowsServerInfos.java                        |   88 ++
 lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/config/license/LicenseCreator.java             |   98 +++
 lxzn-boot-base-core/src/main/java/org/jeecg/config/license/CustomKeyStoreParam.java                       |   63 +
 31 files changed, 1,774 insertions(+), 96 deletions(-)

diff --git a/lxzn-boot-base-core/pom.xml b/lxzn-boot-base-core/pom.xml
index 47d636f..ac7bcf6 100644
--- a/lxzn-boot-base-core/pom.xml
+++ b/lxzn-boot-base-core/pom.xml
@@ -226,6 +226,12 @@
 			<groupId>com.fasterxml.jackson.module</groupId>
 			<artifactId>jackson-module-kotlin</artifactId>
 		</dependency>
+		<!--鐢熸垚license-->
+		<dependency>
+			<groupId>de.schlichtherle.truelicense</groupId>
+			<artifactId>truelicense-core</artifactId>
+			<version>1.33</version>
+		</dependency>
 	</dependencies>
 
 </project>
\ No newline at end of file
diff --git a/lxzn-boot-base-core/src/main/java/org/jeecg/config/LicenseConfig.java b/lxzn-boot-base-core/src/main/java/org/jeecg/config/LicenseConfig.java
new file mode 100644
index 0000000..cf2998b
--- /dev/null
+++ b/lxzn-boot-base-core/src/main/java/org/jeecg/config/LicenseConfig.java
@@ -0,0 +1,32 @@
+package org.jeecg.config;
+
+import org.jeecg.config.license.LicenseCheckInterceptor;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import javax.annotation.Resource;
+
+/**
+ * @Author: lius
+ * @Description: License鎷︽埅鍣ㄩ厤缃�
+ * @DateTime: 17:55 2024/11/2
+ */
+@Configuration
+public class LicenseConfig implements WebMvcConfigurer {
+
+    @Resource
+    private LicenseCheckInterceptor licenseCheckInterceptor;
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+
+        //娣诲姞瑕佹嫤鎴殑url
+        registry.addInterceptor(licenseCheckInterceptor)
+                // 鎷︽埅鐨勮矾寰�
+                .addPathPatterns("/**")
+                // 鏀捐鐨勮矾寰�
+                .excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**", "/doc.html")//swagger
+                .excludePathPatterns("/base/license/**");//鐢熸垚license鍜岃幏鍙栨湇鍔″櫒纭欢淇℃伅
+    }
+}
diff --git a/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/AbstractServerInfos.java b/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/AbstractServerInfos.java
new file mode 100644
index 0000000..bf12f27
--- /dev/null
+++ b/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/AbstractServerInfos.java
@@ -0,0 +1,129 @@
+package org.jeecg.config.license;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.jeecg.config.license.entity.LicenseCheckModel;
+
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+/**
+ * @Author: lius
+ * @ClassName AbstractServerInfos
+ * @date 2024/11/2 16:00
+ */
+
+public abstract class AbstractServerInfos {
+
+    private static Logger logger = LogManager.getLogger(AbstractServerInfos.class);
+
+    /**
+     * 缁勮闇�瑕侀澶栨牎楠岀殑License鍙傛暟
+     *
+     * @return entity.vo.LicenseCheckModel
+     */
+    public LicenseCheckModel getServerInfos() {
+        LicenseCheckModel result = new LicenseCheckModel();
+
+        try {
+            result.setIpAddress(this.getIpAddress());
+            result.setMacAddress(this.getMacAddress());
+            result.setCpuSerial(this.getCPUSerial());
+            result.setMainBoardSerial(this.getMainBoardSerial());
+        } catch (Exception e) {
+            logger.error("鑾峰彇鏈嶅姟鍣ㄧ‖浠朵俊鎭け璐�", e);
+        }
+
+        return result;
+    }
+
+    /**
+     * 鑾峰彇IP鍦板潃
+     *
+     * @return java.util.List<java.lang.String>
+     */
+    protected abstract List<String> getIpAddress() throws Exception;
+
+    /**
+     * 鑾峰彇Mac鍦板潃
+     *
+     * @return java.util.List<java.lang.String>
+     */
+    protected abstract List<String> getMacAddress() throws Exception;
+
+    /**
+     * 鑾峰彇CPU搴忓垪鍙�
+     *
+     * @return java.lang.String
+     */
+    protected abstract String getCPUSerial() throws Exception;
+
+    /**
+     * 鑾峰彇涓绘澘搴忓垪鍙�
+     *
+     * @return java.lang.String
+     */
+    protected abstract String getMainBoardSerial() throws Exception;
+
+    /**
+     * 鑾峰彇褰撳墠鏈嶅姟鍣ㄦ墍鏈夌鍚堟潯浠剁殑InetAddress
+     *
+     * @return java.util.List<java.net.InetAddress>
+     */
+    protected List<InetAddress> getLocalAllInetAddress() throws Exception {
+        List<InetAddress> result = new ArrayList<>(4);
+
+        // 閬嶅巻鎵�鏈夌殑缃戠粶鎺ュ彛
+        for (Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces(); networkInterfaces.hasMoreElements(); ) {
+            NetworkInterface iface = (NetworkInterface) networkInterfaces.nextElement();
+            // 鍦ㄦ墍鏈夌殑鎺ュ彛涓嬪啀閬嶅巻IP
+            for (Enumeration inetAddresses = iface.getInetAddresses(); inetAddresses.hasMoreElements(); ) {
+                InetAddress inetAddr = (InetAddress) inetAddresses.nextElement();
+
+                //鎺掗櫎LoopbackAddress銆丼iteLocalAddress銆丩inkLocalAddress銆丮ulticastAddress绫诲瀷鐨処P鍦板潃
+                if (!inetAddr.isLoopbackAddress() /*&& !inetAddr.isSiteLocalAddress()*/
+                        && !inetAddr.isLinkLocalAddress() && !inetAddr.isMulticastAddress()) {
+                    result.add(inetAddr);
+                }
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * 鑾峰彇鏌愪釜缃戠粶鎺ュ彛鐨凪ac鍦板潃
+     *
+     * @return void
+     */
+    protected String getMacByInetAddress(InetAddress inetAddr) {
+        try {
+            byte[] mac = NetworkInterface.getByInetAddress(inetAddr).getHardwareAddress();
+            StringBuffer stringBuffer = new StringBuffer();
+
+            for (int i = 0; i < mac.length; i++) {
+                if (i != 0) {
+                    stringBuffer.append("-");
+                }
+
+                //灏嗗崄鍏繘鍒禸yte杞寲涓哄瓧绗︿覆
+                String temp = Integer.toHexString(mac[i] & 0xff);
+                if (temp.length() == 1) {
+                    stringBuffer.append("0" + temp);
+                } else {
+                    stringBuffer.append(temp);
+                }
+            }
+
+            return stringBuffer.toString().toUpperCase();
+        } catch (SocketException e) {
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/CustomKeyStoreParam.java b/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/CustomKeyStoreParam.java
new file mode 100644
index 0000000..a5e1cfc
--- /dev/null
+++ b/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/CustomKeyStoreParam.java
@@ -0,0 +1,63 @@
+package org.jeecg.config.license;
+
+import de.schlichtherle.license.AbstractKeyStoreParam;
+
+import java.io.*;
+
+/**
+ * @Author: lius
+ * @ClassName CustomKeyStoreParam
+ * @date 2024/11/2 16:00
+ */
+
+public class CustomKeyStoreParam extends AbstractKeyStoreParam {
+
+    /**
+     * 鍏挜/绉侀挜鍦ㄧ鐩樹笂鐨勫瓨鍌ㄨ矾寰�
+     */
+    private String storePath;
+    private String alias;
+    private String storePwd;
+    private String keyPwd;
+
+    public CustomKeyStoreParam(Class clazz, String resource, String alias, String storePwd, String keyPwd) {
+        super(clazz, resource);
+        this.storePath = resource;
+        this.alias = alias;
+        this.storePwd = storePwd;
+        this.keyPwd = keyPwd;
+    }
+
+
+    @Override
+    public String getAlias() {
+        return alias;
+    }
+
+    @Override
+    public String getStorePwd() {
+        return storePwd;
+    }
+
+    @Override
+    public String getKeyPwd() {
+        return keyPwd;
+    }
+
+    /**
+     * 澶嶅啓de.schlichtherle.license.AbstractKeyStoreParam鐨刧etStream()鏂规硶<br/>
+     * 鐢ㄤ簬灏嗗叕绉侀挜瀛樺偍鏂囦欢瀛樻斁鍒板叾浠栫鐩樹綅缃�屼笉鏄」鐩腑
+     *
+     * @param
+     * @return java.io.InputStream
+     */
+    @Override
+    public InputStream getStream() throws IOException {
+        final InputStream in = new FileInputStream(new File(storePath));
+        if (null == in) {
+            throw new FileNotFoundException(storePath);
+        }
+
+        return in;
+    }
+}
\ No newline at end of file
diff --git a/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/LicenseCheckInterceptor.java b/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/LicenseCheckInterceptor.java
new file mode 100644
index 0000000..659112a
--- /dev/null
+++ b/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/LicenseCheckInterceptor.java
@@ -0,0 +1,84 @@
+package org.jeecg.config.license;
+
+import com.alibaba.fastjson.JSON;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.lang.Nullable;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+* @Author: lius
+* @Description: 浣跨敤鎷︽埅鍣ㄦ嫤鎴姹傦紝楠岃瘉璇佷功鐨勫彲鐢ㄦ��
+* @DateTime: 2024/11/2 16:00
+*/
+@Component
+public class LicenseCheckInterceptor implements HandlerInterceptor {
+
+    private static Logger log = LoggerFactory.getLogger(LicenseCheckListener.class);
+
+    /**
+     * 杩涘叆controller灞備箣鍓嶆嫤鎴姹�
+     * @param request
+     * @param response
+     * @param handler
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+        log.info("杩涘叆鎷︽埅鍣紝楠岃瘉璇佷功鍙娇鐢ㄦ��");
+        LicenseVerify licenseVerify = new LicenseVerify();
+
+        //鏍¢獙璇佷功鏄惁鏈夋晥
+        boolean verifyResult = licenseVerify.verify();
+
+        if(verifyResult){
+            log.info("楠岃瘉鎴愬姛锛岃瘉涔﹀彲鐢�");
+            return true;
+        }else{
+            log.info("楠岃瘉澶辫触锛岃瘉涔︽棤鏁�");
+            response.setContentType("application/json;charset=utf-8");
+            Map<String,String> result = new HashMap<>(1);
+            result.put("result","鎮ㄧ殑璇佷功鏃犳晥锛岃鏍告煡鏈嶅姟鍣ㄦ槸鍚﹀彇寰楁巿鏉冩垨閲嶆柊鐢宠璇佷功锛�");
+
+            response.getWriter().write(JSON.toJSONString(result));
+
+            return false;
+        }
+    }
+
+    /**
+     * 澶勭悊璇锋眰瀹屾垚鍚庤鍥炬覆鏌撲箣鍓嶇殑澶勭悊鎿嶄綔
+     * @param request
+     * @param response
+     * @param handler
+     * @param modelAndView
+     * @throws Exception
+     */
+    @Override
+    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
+//        log.info("澶勭悊璇锋眰瀹屾垚鍚庤鍥炬覆鏌撲箣鍓嶇殑澶勭悊鎿嶄綔");
+    }
+
+    /**
+     * 瑙嗗浘娓叉煋涔嬪悗鐨勬搷浣�
+     * @param request
+     * @param response
+     * @param handler
+     * @param ex
+     * @throws Exception
+     */
+    @Override
+    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
+//        log.info("瑙嗗浘娓叉煋涔嬪悗鐨勬搷浣�");
+    }
+
+}
diff --git a/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/LicenseCheckListener.java b/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/LicenseCheckListener.java
new file mode 100644
index 0000000..caa8043
--- /dev/null
+++ b/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/LicenseCheckListener.java
@@ -0,0 +1,77 @@
+package org.jeecg.config.license;
+
+import org.apache.commons.lang3.StringUtils;
+import org.jeecg.config.license.entity.LicenseVerifyParam;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.stereotype.Component;
+
+/**
+ * @Author: lius
+ * @ClassName LicenseCheckListener
+ * @date 2024/11/2 16:00
+ */
+
+@Component
+public class LicenseCheckListener implements ApplicationListener<ContextRefreshedEvent> {
+
+    private static Logger logger = LoggerFactory.getLogger(LicenseCheckListener.class);
+
+    /**
+     * 璇佷功subject
+     */
+    @Value("${license.subject}")
+    private String subject;
+
+    /**
+     * 鍏挜鍒О
+     */
+    @Value("${license.publicAlias}")
+    private String publicAlias;
+
+    /**
+     * 璁块棶鍏挜搴撶殑瀵嗙爜
+     */
+    @Value("${license.storePass}")
+    private String storePass;
+
+    /**
+     * 璇佷功鐢熸垚璺緞
+     */
+    @Value("${license.licensePath}")
+    private String licensePath;
+
+    /**
+     * 瀵嗛挜搴撳瓨鍌ㄨ矾寰�
+     */
+    @Value("${license.publicKeysStorePath}")
+    private String publicKeysStorePath;
+
+    @Override
+    public void onApplicationEvent(ContextRefreshedEvent event) {
+        //root application context 娌℃湁parent
+        ApplicationContext context = event.getApplicationContext().getParent();
+        if (context == null) {
+            if (StringUtils.isNotBlank(licensePath)) {
+                logger.info("++++++++ 寮�濮嬪畨瑁呰瘉涔� ++++++++");
+
+                LicenseVerifyParam param = new LicenseVerifyParam();
+                param.setSubject(subject);
+                param.setPublicAlias(publicAlias);
+                param.setStorePass(storePass);
+                param.setLicensePath(licensePath);
+                param.setPublicKeysStorePath(publicKeysStorePath);
+
+                LicenseVerify licenseVerify = new LicenseVerify();
+                //瀹夎璇佷功
+                licenseVerify.install(param);
+
+                logger.info("++++++++ 璇佷功瀹夎缁撴潫 ++++++++");
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/LicenseManagerHolder.java b/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/LicenseManagerHolder.java
new file mode 100644
index 0000000..d16f05a
--- /dev/null
+++ b/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/LicenseManagerHolder.java
@@ -0,0 +1,28 @@
+package org.jeecg.config.license;
+
+import de.schlichtherle.license.LicenseManager;
+import de.schlichtherle.license.LicenseParam;
+import org.jeecg.config.license.entity.CustomLicenseManager;
+
+/**
+ * @Author: lius
+ * @ClassName LicenseManagerHolder
+ * @date 2024/11/2 16:00
+ */
+
+public class LicenseManagerHolder {
+
+    private static volatile LicenseManager LICENSE_MANAGER;
+
+    public static LicenseManager getInstance(LicenseParam param){
+        if(LICENSE_MANAGER == null){
+            synchronized (LicenseManagerHolder.class){
+                if(LICENSE_MANAGER == null){
+                    LICENSE_MANAGER = new CustomLicenseManager(param);
+                }
+            }
+        }
+
+        return LICENSE_MANAGER;
+    }
+}
\ No newline at end of file
diff --git a/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/LicenseVerify.java b/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/LicenseVerify.java
new file mode 100644
index 0000000..5f24e03
--- /dev/null
+++ b/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/LicenseVerify.java
@@ -0,0 +1,87 @@
+package org.jeecg.config.license;
+
+import de.schlichtherle.license.*;
+import org.jeecg.config.license.entity.LicenseVerifyParam;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.text.DateFormat;
+import java.text.MessageFormat;
+import java.text.SimpleDateFormat;
+import java.util.prefs.Preferences;
+
+/**
+ * @Author: lius
+ * @ClassName LicenseVerify
+ * @Description 瀹夎鎺堟潈璇佷功
+ * @date 2024/11/2 16:00
+ */
+
+public class LicenseVerify {
+
+    private static final Logger logger = LoggerFactory.getLogger(LicenseVerify.class);
+
+    /**
+     * 瀹夎License璇佷功
+     */
+    public synchronized LicenseContent install(LicenseVerifyParam param){
+        LicenseContent result = null;
+        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+        //1. 瀹夎璇佷功
+        try{
+            LicenseManager licenseManager = LicenseManagerHolder.getInstance(initLicenseParam(param));
+            licenseManager.uninstall();
+
+            result = licenseManager.install(new File(param.getLicensePath()));
+            logger.info(MessageFormat.format("璇佷功瀹夎鎴愬姛锛岃瘉涔︽湁鏁堟湡锛歿0} - {1}",format.format(result.getNotBefore()),format.format(result.getNotAfter())));
+        }catch (Exception e){
+            logger.error("璇佷功瀹夎澶辫触锛�",e);
+        }
+
+        return result;
+    }
+
+    /**
+     * 鏍¢獙License璇佷功
+     * @return boolean
+     */
+    public boolean verify(){
+        LicenseManager licenseManager = LicenseManagerHolder.getInstance(null);
+        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+        //2. 鏍¢獙璇佷功
+        try {
+            LicenseContent licenseContent = licenseManager.verify();
+
+            logger.info(MessageFormat.format("璇佷功鏍¢獙閫氳繃锛岃瘉涔︽湁鏁堟湡锛歿0} - {1}",format.format(licenseContent.getNotBefore()),format.format(licenseContent.getNotAfter())));
+            return true;
+        }catch (Exception e){
+            logger.error("璇佷功鏍¢獙澶辫触锛�",e);
+            return false;
+        }
+    }
+
+    /**
+     * 鍒濆鍖栬瘉涔︾敓鎴愬弬鏁�
+     * @param param License鏍¢獙绫婚渶瑕佺殑鍙傛暟
+     * @return de.schlichtherle.license.LicenseParam
+     */
+    private LicenseParam initLicenseParam(LicenseVerifyParam param){
+        Preferences preferences = Preferences.userNodeForPackage(LicenseVerify.class);
+
+        CipherParam cipherParam = new DefaultCipherParam(param.getStorePass());
+
+        KeyStoreParam publicStoreParam = new CustomKeyStoreParam(LicenseVerify.class
+                ,param.getPublicKeysStorePath()
+                ,param.getPublicAlias()
+                ,param.getStorePass()
+                ,null);
+
+        return new DefaultLicenseParam(param.getSubject()
+                ,preferences
+                ,publicStoreParam
+                ,cipherParam);
+    }
+}
\ No newline at end of file
diff --git a/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/LinuxServerInfos.java b/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/LinuxServerInfos.java
new file mode 100644
index 0000000..24d5ede
--- /dev/null
+++ b/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/LinuxServerInfos.java
@@ -0,0 +1,89 @@
+package org.jeecg.config.license;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.InetAddress;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @Author: lius
+ * @ClassName LinuxServerInfos
+ * @date 2024/11/2 16:00
+ */
+
+public class LinuxServerInfos extends AbstractServerInfos{
+
+    @Override
+    protected List<String> getIpAddress() throws Exception {
+        List<String> result = null;
+
+        //鑾峰彇鎵�鏈夌綉缁滄帴鍙�
+        List<InetAddress> inetAddresses = getLocalAllInetAddress();
+
+        if(inetAddresses != null && inetAddresses.size() > 0){
+            result = inetAddresses.stream().map(InetAddress::getHostAddress).distinct().map(String::toLowerCase).collect(Collectors.toList());
+        }
+
+        return result;
+    }
+
+    @Override
+    protected List<String> getMacAddress() throws Exception {
+        List<String> result = null;
+
+        //1. 鑾峰彇鎵�鏈夌綉缁滄帴鍙�
+        List<InetAddress> inetAddresses = getLocalAllInetAddress();
+
+        if(inetAddresses != null && inetAddresses.size() > 0){
+            //2. 鑾峰彇鎵�鏈夌綉缁滄帴鍙g殑Mac鍦板潃
+            result = inetAddresses.stream().map(this::getMacByInetAddress).distinct().collect(Collectors.toList());
+        }
+
+        return result;
+    }
+
+    @Override
+    protected String getCPUSerial() throws Exception {
+        //搴忓垪鍙�
+        String serialNumber = "";
+
+        //浣跨敤dmidecode鍛戒护鑾峰彇CPU搴忓垪鍙�
+        String[] shell = {"/bin/bash","-c","dmidecode -t processor | grep 'ID' | awk -F ':' '{print $2}' | head -n 1"};
+        Process process = Runtime.getRuntime().exec(shell);
+        process.getOutputStream().close();
+
+        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
+
+        String line = reader.readLine().trim();
+        if(StringUtils.isNotBlank(line)){
+            serialNumber = line;
+        }
+
+        reader.close();
+        return serialNumber;
+    }
+
+    @Override
+    protected String getMainBoardSerial() throws Exception {
+        //搴忓垪鍙�
+        String serialNumber = "";
+
+        //浣跨敤dmidecode鍛戒护鑾峰彇涓绘澘搴忓垪鍙�
+        String[] shell = {"/bin/bash","-c","dmidecode | grep 'Serial Number' | awk -F ':' '{print $2}' | head -n 1"};
+        Process process = Runtime.getRuntime().exec(shell);
+        process.getOutputStream().close();
+
+        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
+
+        String line = reader.readLine().trim();
+        if(StringUtils.isNotBlank(line)){
+            serialNumber = line;
+        }
+
+        reader.close();
+        return serialNumber;
+    }
+}
\ No newline at end of file
diff --git a/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/WindowsServerInfos.java b/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/WindowsServerInfos.java
new file mode 100644
index 0000000..46b0211
--- /dev/null
+++ b/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/WindowsServerInfos.java
@@ -0,0 +1,88 @@
+package org.jeecg.config.license;
+
+import java.net.InetAddress;
+import java.util.List;
+import java.util.Scanner;
+import java.util.stream.Collectors;
+
+/**
+ * @Author: lius
+ * @ClassName WindowsServerInfos
+ * @date 2024/11/2 16:00
+ */
+
+public class WindowsServerInfos extends AbstractServerInfos{
+
+        @Override
+        protected List<String> getIpAddress() throws Exception {
+            List<String> result = null;
+
+            //鑾峰彇鎵�鏈夌綉缁滄帴鍙�
+            List<InetAddress> inetAddresses = getLocalAllInetAddress();
+
+            if(inetAddresses != null && inetAddresses.size() > 0){
+                result = inetAddresses.stream().map(InetAddress::getHostAddress).distinct().map(String::toLowerCase).collect(Collectors.toList());
+            }
+
+            return result;
+        }
+
+        @Override
+        protected List<String> getMacAddress() throws Exception {
+            List<String> result = null;
+
+            //1. 鑾峰彇鎵�鏈夌綉缁滄帴鍙�
+            List<InetAddress> inetAddresses = getLocalAllInetAddress();
+
+            if(inetAddresses != null && inetAddresses.size() > 0){
+                //2. 鑾峰彇鎵�鏈夌綉缁滄帴鍙g殑Mac鍦板潃
+                result = inetAddresses.stream().map(this::getMacByInetAddress).distinct().collect(Collectors.toList());
+            }
+
+            return result;
+        }
+
+        @Override
+        protected String getCPUSerial() throws Exception {
+            //搴忓垪鍙�
+            String serialNumber = "";
+
+            //浣跨敤WMIC鑾峰彇CPU搴忓垪鍙�
+            Process process = Runtime.getRuntime().exec("wmic cpu get processorid");
+            process.getOutputStream().close();
+            Scanner scanner = new Scanner(process.getInputStream());
+
+            if(scanner.hasNext()){
+                scanner.next();
+            }
+
+            if(scanner.hasNext()){
+                serialNumber = scanner.next().trim();
+            }
+
+            scanner.close();
+            return serialNumber;
+        }
+
+        @Override
+        protected String getMainBoardSerial() throws Exception {
+            //搴忓垪鍙�
+            String serialNumber = "";
+
+            //浣跨敤WMIC鑾峰彇涓绘澘搴忓垪鍙�
+            Process process = Runtime.getRuntime().exec("wmic baseboard get serialnumber");
+            process.getOutputStream().close();
+            Scanner scanner = new Scanner(process.getInputStream());
+
+            if(scanner.hasNext()){
+                scanner.next();
+            }
+
+            if(scanner.hasNext()){
+                serialNumber = scanner.next().trim();
+            }
+
+            scanner.close();
+            return serialNumber;
+        }
+}
\ No newline at end of file
diff --git a/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/entity/CustomLicenseManager.java b/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/entity/CustomLicenseManager.java
new file mode 100644
index 0000000..d999ed2
--- /dev/null
+++ b/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/entity/CustomLicenseManager.java
@@ -0,0 +1,270 @@
+package org.jeecg.config.license.entity;
+
+import de.schlichtherle.license.*;
+import de.schlichtherle.xml.GenericCertificate;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.jeecg.config.license.AbstractServerInfos;
+import org.jeecg.config.license.LinuxServerInfos;
+import org.jeecg.config.license.WindowsServerInfos;
+
+import java.beans.XMLDecoder;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @Author: lius
+ * @ClassName CustomLicenseManager
+ * @date 2024/11/2 16:00
+ */
+
+public class CustomLicenseManager extends LicenseManager {
+
+    private static Logger logger = LogManager.getLogger(CustomLicenseManager.class);
+
+    //XML缂栫爜
+    private static final String XML_CHARSET = "UTF-8";
+    //榛樿BUFSIZE
+    private static final int DEFAULT_BUFSIZE = 8 * 1024;
+
+    public CustomLicenseManager() {
+
+    }
+
+    public CustomLicenseManager(LicenseParam param) {
+        super(param);
+    }
+
+    /**
+     * 澶嶅啓create鏂规硶
+     *
+     * @param
+     * @return byte[]
+     */
+    @Override
+    protected synchronized byte[] create(
+            LicenseContent content,
+            LicenseNotary notary)
+            throws Exception {
+        initialize(content);
+        this.validateCreate(content);
+        final GenericCertificate certificate = notary.sign(content);
+        return getPrivacyGuard().cert2key(certificate);
+    }
+
+    /**
+     * 澶嶅啓install鏂规硶锛屽叾涓璿alidate鏂规硶璋冪敤鏈被涓殑validate鏂规硶锛屾牎楠孖P鍦板潃銆丮ac鍦板潃绛夊叾浠栦俊鎭�
+     *
+     * @param
+     * @return de.schlichtherle.license.LicenseContent
+     */
+    @Override
+    protected synchronized LicenseContent install(
+            final byte[] key,
+            final LicenseNotary notary)
+            throws Exception {
+        final GenericCertificate certificate = getPrivacyGuard().key2cert(key);
+
+        notary.verify(certificate);
+        final LicenseContent content = (LicenseContent) this.load(certificate.getEncoded());
+        this.validate(content);
+        setLicenseKey(key);
+        setCertificate(certificate);
+
+        return content;
+    }
+
+    /**
+     * 澶嶅啓verify鏂规硶锛岃皟鐢ㄦ湰绫讳腑鐨剉alidate鏂规硶锛屾牎楠孖P鍦板潃銆丮ac鍦板潃绛夊叾浠栦俊鎭�
+     *
+     * @param
+     * @return de.schlichtherle.license.LicenseContent
+     */
+    @Override
+    protected synchronized LicenseContent verify(final LicenseNotary notary)
+            throws Exception {
+        GenericCertificate certificate = getCertificate();
+
+        // Load license key from preferences,
+        final byte[] key = getLicenseKey();
+        if (null == key) {
+            throw new NoLicenseInstalledException(getLicenseParam().getSubject());
+        }
+
+        certificate = getPrivacyGuard().key2cert(key);
+        notary.verify(certificate);
+        final LicenseContent content = (LicenseContent) this.load(certificate.getEncoded());
+        this.validate(content);
+        setCertificate(certificate);
+
+        return content;
+    }
+
+    /**
+     * 鏍¢獙鐢熸垚璇佷功鐨勫弬鏁颁俊鎭�
+     *
+     * @param content 璇佷功姝f枃
+     */
+    protected synchronized void validateCreate(final LicenseContent content)
+            throws LicenseContentException {
+        final LicenseParam param = getLicenseParam();
+
+        final Date now = new Date();
+        final Date notBefore = content.getNotBefore();
+        final Date notAfter = content.getNotAfter();
+        if (null != notAfter && now.after(notAfter)) {
+            throw new LicenseContentException("璇佷功澶辨晥鏃堕棿涓嶈兘鏃╀簬褰撳墠鏃堕棿");
+        }
+        if (null != notBefore && null != notAfter && notAfter.before(notBefore)) {
+            throw new LicenseContentException("璇佷功鐢熸晥鏃堕棿涓嶈兘鏅氫簬璇佷功澶辨晥鏃堕棿");
+        }
+        final String consumerType = content.getConsumerType();
+        if (null == consumerType) {
+            throw new LicenseContentException("鐢ㄦ埛绫诲瀷涓嶈兘涓虹┖");
+        }
+    }
+
+
+    /**
+     * 澶嶅啓validate鏂规硶锛屽鍔營P鍦板潃銆丮ac鍦板潃绛夊叾浠栦俊鎭牎楠�
+     *
+     * @param content LicenseContent
+     */
+    @Override
+    protected synchronized void validate(final LicenseContent content)
+            throws LicenseContentException {
+        //1. 棣栧厛璋冪敤鐖剁被鐨剉alidate鏂规硶
+        super.validate(content);
+
+        //2. 鐒跺悗鏍¢獙鑷畾涔夌殑License鍙傛暟
+        //License涓彲琚厑璁哥殑鍙傛暟淇℃伅
+        LicenseCheckModel expectedCheckModel = (LicenseCheckModel) content.getExtra();
+        //褰撳墠鏈嶅姟鍣ㄧ湡瀹炵殑鍙傛暟淇℃伅
+        LicenseCheckModel serverCheckModel = getServerInfos();
+
+        if (expectedCheckModel != null && serverCheckModel != null) {
+            //鏍¢獙IP鍦板潃
+            if (!checkIpAddress(expectedCheckModel.getIpAddress(), serverCheckModel.getIpAddress())) {
+                throw new LicenseContentException("褰撳墠鏈嶅姟鍣ㄧ殑IP娌″湪鎺堟潈鑼冨洿鍐�");
+            }
+
+            //鏍¢獙Mac鍦板潃
+            if (!checkIpAddress(expectedCheckModel.getMacAddress(), serverCheckModel.getMacAddress())) {
+                throw new LicenseContentException("褰撳墠鏈嶅姟鍣ㄧ殑Mac鍦板潃娌″湪鎺堟潈鑼冨洿鍐�");
+            }
+
+            //鏍¢獙涓绘澘搴忓垪鍙�
+            if (!checkSerial(expectedCheckModel.getMainBoardSerial(), serverCheckModel.getMainBoardSerial())) {
+                throw new LicenseContentException("褰撳墠鏈嶅姟鍣ㄧ殑涓绘澘搴忓垪鍙锋病鍦ㄦ巿鏉冭寖鍥村唴");
+            }
+
+            //鏍¢獙CPU搴忓垪鍙�
+            if (!checkSerial(expectedCheckModel.getCpuSerial(), serverCheckModel.getCpuSerial())) {
+                throw new LicenseContentException("褰撳墠鏈嶅姟鍣ㄧ殑CPU搴忓垪鍙锋病鍦ㄦ巿鏉冭寖鍥村唴");
+            }
+        } else {
+            throw new LicenseContentException("涓嶈兘鑾峰彇鏈嶅姟鍣ㄧ‖浠朵俊鎭�");
+        }
+    }
+
+
+    /**
+     * 閲嶅啓XMLDecoder瑙f瀽XML
+     *
+     * @param encoded XML绫诲瀷瀛楃涓�
+     * @return java.lang.Object
+     */
+    private Object load(String encoded) {
+        BufferedInputStream inputStream = null;
+        XMLDecoder decoder = null;
+        try {
+            inputStream = new BufferedInputStream(new ByteArrayInputStream(encoded.getBytes(XML_CHARSET)));
+
+            decoder = new XMLDecoder(new BufferedInputStream(inputStream, DEFAULT_BUFSIZE), null, null);
+
+            return decoder.readObject();
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (decoder != null) {
+                    decoder.close();
+                }
+                if (inputStream != null) {
+                    inputStream.close();
+                }
+            } catch (Exception e) {
+                logger.error("XMLDecoder瑙f瀽XML澶辫触", e);
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * 鑾峰彇褰撳墠鏈嶅姟鍣ㄩ渶瑕侀澶栨牎楠岀殑License鍙傛暟
+     *
+     * @return demo.LicenseCheckModel
+     */
+    private LicenseCheckModel getServerInfos() {
+        //鎿嶄綔绯荤粺绫诲瀷
+        String osName = System.getProperty("os.name").toLowerCase();
+        AbstractServerInfos abstractServerInfos = null;
+
+        //鏍规嵁涓嶅悓鎿嶄綔绯荤粺绫诲瀷閫夋嫨涓嶅悓鐨勬暟鎹幏鍙栨柟娉�
+        if (osName.startsWith("windows")) {
+            abstractServerInfos = new WindowsServerInfos();
+        } else if (osName.startsWith("linux")) {
+            abstractServerInfos = new LinuxServerInfos();
+        } else {//鍏朵粬鏈嶅姟鍣ㄧ被鍨�
+            abstractServerInfos = new LinuxServerInfos();
+        }
+
+        return abstractServerInfos.getServerInfos();
+    }
+
+    /**
+     * 鏍¢獙褰撳墠鏈嶅姟鍣ㄧ殑IP/Mac鍦板潃鏄惁鍦ㄥ彲琚厑璁哥殑IP鑼冨洿鍐�<br/>
+     * 濡傛灉瀛樺湪IP鍦ㄥ彲琚厑璁哥殑IP/Mac鍦板潃鑼冨洿鍐咃紝鍒欒繑鍥瀟rue
+     *
+     * @return boolean
+     */
+    private boolean checkIpAddress(List<String> expectedList, List<String> serverList) {
+        if (expectedList != null && expectedList.size() > 0) {
+            if (serverList != null && serverList.size() > 0) {
+                for (String expected : expectedList) {
+                    if (serverList.contains(expected.trim())) {
+                        return true;
+                    }
+                }
+            }
+
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * 鏍¢獙褰撳墠鏈嶅姟鍣ㄧ‖浠讹紙涓绘澘銆丆PU绛夛級搴忓垪鍙锋槸鍚﹀湪鍙厑璁歌寖鍥村唴
+     *
+     * @return boolean
+     */
+    private boolean checkSerial(String expectedSerial, String serverSerial) {
+        if (StringUtils.isNotBlank(expectedSerial)) {
+            if (StringUtils.isNotBlank(serverSerial)) {
+                if (expectedSerial.equals(serverSerial)) {
+                    return true;
+                }
+            }
+
+            return false;
+        } else {
+            return true;
+        }
+    }
+}
\ No newline at end of file
diff --git a/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/entity/LicenseCheckModel.java b/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/entity/LicenseCheckModel.java
new file mode 100644
index 0000000..b984bb0
--- /dev/null
+++ b/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/entity/LicenseCheckModel.java
@@ -0,0 +1,62 @@
+package org.jeecg.config.license.entity;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @Author: lius
+ * @ClassName LicenseCheckModel
+ * @date 2024/11/2 16:00
+ */
+@ApiModel("璁惧淇℃伅瀹炰綋绫�")
+public class LicenseCheckModel implements Serializable {
+
+    private static final long serialVersionUID = -2314678441082223148L;
+
+    @ApiModelProperty("鍙鍏佽鐨処P鍦板潃")
+    private List<String> ipAddress;
+
+    @ApiModelProperty("鍙鍏佽鐨凪AC鍦板潃")
+    private List<String> macAddress;
+
+    @ApiModelProperty("鍙鍏佽鐨凜PU搴忓垪鍙�")
+    private String cpuSerial;
+
+    @ApiModelProperty("鍙鍏佽鐨勪富鏉垮簭鍒楀彿")
+    private String mainBoardSerial;
+
+    public List<String> getIpAddress() {
+        return ipAddress;
+    }
+
+    public void setIpAddress(List<String> ipAddress) {
+        this.ipAddress = ipAddress;
+    }
+
+    public List<String> getMacAddress() {
+        return macAddress;
+    }
+
+    public void setMacAddress(List<String> macAddress) {
+        this.macAddress = macAddress;
+    }
+
+    public String getCpuSerial() {
+        return cpuSerial;
+    }
+
+    public void setCpuSerial(String cpuSerial) {
+        this.cpuSerial = cpuSerial;
+    }
+
+    public String getMainBoardSerial() {
+        return mainBoardSerial;
+    }
+
+    public void setMainBoardSerial(String mainBoardSerial) {
+        this.mainBoardSerial = mainBoardSerial;
+    }
+}
\ No newline at end of file
diff --git a/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/entity/LicenseVerifyParam.java b/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/entity/LicenseVerifyParam.java
new file mode 100644
index 0000000..7f9e465
--- /dev/null
+++ b/lxzn-boot-base-core/src/main/java/org/jeecg/config/license/entity/LicenseVerifyParam.java
@@ -0,0 +1,67 @@
+package org.jeecg.config.license.entity;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @Author: lius
+ * @ClassName LicenseVerifyParam
+ * @date 2024/11/2 16:00
+ */
+
+public class LicenseVerifyParam {
+
+    @ApiModelProperty("璇佷功subject")
+    private String subject;
+
+    @ApiModelProperty("鍏挜鍒О")
+    private String publicAlias;
+
+    @ApiModelProperty("璁块棶鍏挜搴撶殑瀵嗙爜")
+    private String storePass;
+
+    @ApiModelProperty("璇佷功鐢熸垚璺緞")
+    private String licensePath;
+
+    @ApiModelProperty("瀵嗛挜搴撳瓨鍌ㄨ矾寰�")
+    private String publicKeysStorePath;
+
+    public String getSubject() {
+        return subject;
+    }
+
+    public void setSubject(String subject) {
+        this.subject = subject;
+    }
+
+    public String getPublicAlias() {
+        return publicAlias;
+    }
+
+    public void setPublicAlias(String publicAlias) {
+        this.publicAlias = publicAlias;
+    }
+
+    public String getStorePass() {
+        return storePass;
+    }
+
+    public void setStorePass(String storePass) {
+        this.storePass = storePass;
+    }
+
+    public String getLicensePath() {
+        return licensePath;
+    }
+
+    public void setLicensePath(String licensePath) {
+        this.licensePath = licensePath;
+    }
+
+    public String getPublicKeysStorePath() {
+        return publicKeysStorePath;
+    }
+
+    public void setPublicKeysStorePath(String publicKeysStorePath) {
+        this.publicKeysStorePath = publicKeysStorePath;
+    }
+}
\ No newline at end of file
diff --git a/lxzn-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java b/lxzn-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java
index 5aeb5ce..a3f35c6 100644
--- a/lxzn-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java
+++ b/lxzn-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java
@@ -98,6 +98,7 @@
         filterChainDefinitionMap.put("/sys/getLoginQrcode/**", "anon"); //鐧诲綍浜岀淮鐮�
         filterChainDefinitionMap.put("/sys/getQrcodeToken/**", "anon"); //鐩戝惉鎵爜
         filterChainDefinitionMap.put("/sys/checkAuth", "anon"); //鎺堟潈鎺ュ彛鎺掗櫎
+        filterChainDefinitionMap.put("/base/license/**", "anon"); //鐢熸垚license鍜岃幏鍙栨湇鍔″櫒纭欢淇℃伅
 
 
         filterChainDefinitionMap.put("/", "anon");
diff --git a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/dto/CurrentElectricDto.java b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/dto/CurrentElectricDto.java
new file mode 100644
index 0000000..caf4be2
--- /dev/null
+++ b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/dto/CurrentElectricDto.java
@@ -0,0 +1,27 @@
+package org.jeecg.modules.mdc.dto;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * @author Lius
+ * @date 2024/11/1 15:00
+ */
+@Data
+public class CurrentElectricDto {
+    /**
+     * 閲囬泦鏃堕棿
+     */
+    private Date collectTime;
+    /**
+     * 璁惧缂栧彿
+     */
+    private String equipmentID;
+    /**
+     * dao瑙f瀽鏁版嵁浣跨敤
+     */
+    private String currentValue;
+
+
+}
diff --git a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/job/StatisticalElectricJob.java b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/job/StatisticalElectricJob.java
index 9a13173..5a8ea8c 100644
--- a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/job/StatisticalElectricJob.java
+++ b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/job/StatisticalElectricJob.java
@@ -3,7 +3,7 @@
 import lombok.extern.slf4j.Slf4j;
 import org.jeecg.common.constant.CommonConstant;
 import org.jeecg.common.system.vo.DictModel;
-import org.jeecg.modules.mdc.dto.CurrentElectricHistoryDto;
+import org.jeecg.modules.mdc.dto.CurrentElectricDto;
 import org.jeecg.modules.mdc.dto.EquipmentMachiningHistoryDto;
 import org.jeecg.modules.mdc.dto.MachineXYZHistoryDto;
 import org.jeecg.modules.mdc.entity.Equipment;
@@ -54,13 +54,10 @@
     private IEquipmentElectricStatisticalService equipmentElectricStatisticalService;
 
     @Resource
-    private ICurrentXYZHistoryService currentXYZHistoryService;
+    private IEquipmentWorkLineService equipmentWorkLineService;
 
     @Resource
-    private IMachineXYZHistoryService machineXYZHistoryService;
-
-    @Resource
-    private IEquipmentMachiningHistoryService equipmentMachiningHistoryService;
+    private IEquipmentXYZService equipmentXYZService;
 
     @Override
     public void execute(JobExecutionContext context) throws JobExecutionException {
@@ -81,50 +78,54 @@
                 List<DictModel> dictList = sysDictService.queryEnableDictItemsByCode(CommonConstant.AXIS_TYPE);
                 if (dictList != null && !dictList.isEmpty()) {
                     for (Equipment equipment : equipmentList) {
-                        Date lastDate = equipmentElectricStatisticalService.getMaxDate(equipment.getEquipmentid());
-                        if (lastDate == null) {
-                            Date minCollectTime = currentXYZHistoryService.getMinDate(equipment.getEquipmentid());
-                            if (minCollectTime == null) {
-                                continue;
-                            }
-                            initDate = DateUtils.removeTime(minCollectTime);
-                        }
-                        for (DictModel dictModel : dictList) {
-                            electricStatistical = new EquipmentElectricStatistical();
-                            Integer axisType = Integer.parseInt(dictModel.getValue());
-                            CurrentElectricHistoryDto currentElectricHistoryDto = currentXYZHistoryService.getMaxElectric(equipment.getEquipmentid(), axisType, initDate, DateUtils.plusTime(initDate, 1));
-                            if (currentElectricHistoryDto == null || currentElectricHistoryDto.getEquipmentID() == null || currentElectricHistoryDto.getCollectTime() == null) {
-                                initDate = DateUtils.plusTime(initDate, 1);
-                                continue;
-                            }
-                            electricStatistical.setAxistype(axisType);
-                            electricStatistical.setEquipmentid(equipment.getEquipmentid());
-                            electricStatistical.setEquipmentname(equipment.getEquipmentname());
-                            electricStatistical.setElectrictime(currentElectricHistoryDto.getCollectTime());
-                            electricStatistical.setElectricvalue(currentElectricHistoryDto.getCurrentValue());
-                            electricStatistical.setCreatedate(initDate);
-                            EquipmentMachiningHistoryDto machiningHistoryDto = equipmentMachiningHistoryService.getNearTimeSpindleLoad(equipment.getEquipmentid(), initDate, DateUtils.plusTime(initDate, 1), currentElectricHistoryDto.getCollectTime());
-                            if (machiningHistoryDto != null) {
-                                electricStatistical.setSpindlespeed(machiningHistoryDto.getSpindleSpeed());
-                                electricStatistical.setSpindleload(machiningHistoryDto.getSpindleLoad());
-                                electricStatistical.setSpindletime(machiningHistoryDto.getCollectTime());
-                            }
-                            MachineXYZHistoryDto machineXYZHistoryDto = machineXYZHistoryService.getNearAxisType(equipment.getEquipmentid(), initDate, DateUtils.plusTime(initDate, 1), currentElectricHistoryDto.getCollectTime());
-                            if (machineXYZHistoryDto != null) {
-                                electricStatistical.setAxistime(machineXYZHistoryDto.getCollectTime());
-                                if (axisType == 1) {
-                                    electricStatistical.setAxisvalue(machineXYZHistoryDto.getXMachine());
-                                } else if (axisType == 2) {
-                                    electricStatistical.setAxisvalue(machineXYZHistoryDto.getYMachine());
-                                } else if (axisType == 3) {
-                                    electricStatistical.setAxisvalue(machineXYZHistoryDto.getZMachine());
-                                } else if (axisType == 4) {
-                                    electricStatistical.setAxisvalue(machineXYZHistoryDto.getAMachine());
-                                } else if (axisType == 5) {
-                                    electricStatistical.setAxisvalue(machineXYZHistoryDto.getBMachine());
+                        if (equipment.getDrivetype().equals("SIEMENSOpcUa")) {
+                            String saveTableName = equipment.getSavetablename();
+                            Date lastDate = equipmentElectricStatisticalService.getMaxDate(equipment.getEquipmentid());
+                            if (lastDate == null) {
+                                Date minCollectTime = equipmentWorkLineService.getMinDate(saveTableName);
+                                if (minCollectTime == null) {
+                                    continue;
                                 }
+                                initDate = DateUtils.removeTime(minCollectTime);
+                            } else {
+                                initDate = DateUtils.plusTime(lastDate, 1);
                             }
-                            resultList.add(electricStatistical);
+                            for (DictModel dictModel : dictList) {
+                                electricStatistical = new EquipmentElectricStatistical();
+                                Integer axisType = Integer.parseInt(dictModel.getValue());
+                                CurrentElectricDto currentElectricDto = equipmentWorkLineService.getMaxElectric(saveTableName, axisType, initDate, DateUtils.plusTime(initDate, 1));
+                                if (currentElectricDto == null) {
+                                    continue;
+                                }
+                                electricStatistical.setAxistype(axisType);
+                                electricStatistical.setEquipmentid(equipment.getEquipmentid());
+                                electricStatistical.setEquipmentname(equipment.getEquipmentname());
+                                electricStatistical.setElectrictime(currentElectricDto.getCollectTime());
+                                electricStatistical.setElectricvalue(currentElectricDto.getCurrentValue());
+                                electricStatistical.setCreatedate(initDate);
+                                EquipmentMachiningHistoryDto machiningHistoryDto = equipmentWorkLineService.getNearTimeSpindleLoad(saveTableName, initDate, DateUtils.plusTime(initDate, 1), currentElectricDto.getCollectTime());
+                                if (machiningHistoryDto != null) {
+                                    electricStatistical.setSpindlespeed(machiningHistoryDto.getSpindleSpeed());
+                                    electricStatistical.setSpindleload(machiningHistoryDto.getSpindleLoad());
+                                    electricStatistical.setSpindletime(machiningHistoryDto.getCollectTime());
+                                }
+                                MachineXYZHistoryDto machineXYZHistoryDto = equipmentXYZService.getNearAxisType(equipment.getEquipmentid(), initDate, DateUtils.plusTime(initDate, 1), currentElectricDto.getCollectTime());
+                                if (machineXYZHistoryDto != null) {
+                                    electricStatistical.setAxistime(machineXYZHistoryDto.getCollectTime());
+                                    if (axisType == 1) {
+                                        electricStatistical.setAxisvalue(machineXYZHistoryDto.getXMachine());
+                                    } else if (axisType == 2) {
+                                        electricStatistical.setAxisvalue(machineXYZHistoryDto.getYMachine());
+                                    } else if (axisType == 3) {
+                                        electricStatistical.setAxisvalue(machineXYZHistoryDto.getZMachine());
+                                    } else if (axisType == 4) {
+                                        electricStatistical.setAxisvalue(machineXYZHistoryDto.getAMachine());
+                                    } else if (axisType == 5) {
+                                        electricStatistical.setAxisvalue(machineXYZHistoryDto.getBMachine());
+                                    }
+                                }
+                                resultList.add(electricStatistical);
+                            }
                         }
                     }
                 }
diff --git a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/job/StatisticalSpindleJob.java b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/job/StatisticalSpindleJob.java
index c345bef..bbb7e33 100644
--- a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/job/StatisticalSpindleJob.java
+++ b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/job/StatisticalSpindleJob.java
@@ -5,10 +5,7 @@
 import org.jeecg.modules.mdc.dto.MachineXYZHistoryDto;
 import org.jeecg.modules.mdc.entity.Equipment;
 import org.jeecg.modules.mdc.entity.EquipmentSpindleStatistical;
-import org.jeecg.modules.mdc.service.IEquipmentMachiningHistoryService;
-import org.jeecg.modules.mdc.service.IEquipmentService;
-import org.jeecg.modules.mdc.service.IEquipmentSpindleStatisticalService;
-import org.jeecg.modules.mdc.service.IMachineXYZHistoryService;
+import org.jeecg.modules.mdc.service.*;
 import org.jeecg.modules.mdc.util.DateUtils;
 import org.jeecg.modules.mdc.util.ThrowableUtil;
 import org.jeecg.modules.quartz.entity.QuartzJob;
@@ -55,6 +52,12 @@
     @Resource
     private IMachineXYZHistoryService machineXYZHistoryService;
 
+    @Resource
+    private IEquipmentWorkLineService equipmentWorkLineService;
+
+    @Resource
+    private IEquipmentXYZService equipmentXYZService;
+
     @Override
     public void execute(JobExecutionContext context) throws JobExecutionException {
         SysQuartzLog quartzLog = new SysQuartzLog();
@@ -72,36 +75,41 @@
                 EquipmentSpindleStatistical spindleStatistical;
                 List<EquipmentSpindleStatistical> resultList = new ArrayList<>();
                 for (Equipment equipment : equipmentList) {
-                    Date lastDate = equipmentSpindleStatisticalService.getMaxDate(equipment.getEquipmentid());
-                    if (lastDate == null) {
-                        Date minCollectTime = equipmentMachiningHistoryService.getMinDate(equipment.getEquipmentid());
-                        if (minCollectTime == null) {
+                    if (!equipment.getDrivetype().equals("CurrentState")) {
+                        String saveTableName = equipment.getSavetablename();
+                        Date lastDate = equipmentSpindleStatisticalService.getMaxDate(equipment.getEquipmentid());
+                        if (lastDate == null) {
+                            Date minCollectTime = equipmentWorkLineService.getMinDate(saveTableName);
+                            if (minCollectTime == null) {
+                                continue;
+                            }
+                            initDate = DateUtils.removeTime(minCollectTime);
+                        } else {
+                            initDate = DateUtils.plusTime(lastDate, 1);
+                        }
+
+                        spindleStatistical = new EquipmentSpindleStatistical();
+                        EquipmentMachiningHistoryDto machiningHistoryDto = equipmentWorkLineService.getMaxSpindleLoad(saveTableName, initDate, DateUtils.plusTime(initDate, 1));
+                        if(machiningHistoryDto == null || machiningHistoryDto.getEquipmentID() == null || machiningHistoryDto.getCollectTime() == null) {
                             continue;
                         }
-                        initDate = DateUtils.removeTime(minCollectTime);
+                        spindleStatistical.setCreatedate(initDate);
+                        spindleStatistical.setSpindlespeed(machiningHistoryDto.getSpindleSpeed());
+                        spindleStatistical.setEquipmentid(equipment.getEquipmentid());
+                        spindleStatistical.setEquipmentname(equipment.getEquipmentname());
+                        spindleStatistical.setSpindleload(machiningHistoryDto.getSpindleLoad());
+                        spindleStatistical.setSpindletime(machiningHistoryDto.getCollectTime());
+                        MachineXYZHistoryDto machineXYZHistoryDto = equipmentXYZService.getNearAxisType(equipment.getEquipmentid(), initDate, DateUtils.plusTime(initDate, 1), machiningHistoryDto.getCollectTime());
+                        if(machineXYZHistoryDto != null) {
+                            spindleStatistical.setAxistime(machineXYZHistoryDto.getCollectTime());
+                            spindleStatistical.setAxisx(machineXYZHistoryDto.getXMachine());
+                            spindleStatistical.setAxisy(machineXYZHistoryDto.getYMachine());
+                            spindleStatistical.setAxisz(machineXYZHistoryDto.getZMachine());
+                            spindleStatistical.setAxisa(machineXYZHistoryDto.getAMachine());
+                            spindleStatistical.setAxisb(machineXYZHistoryDto.getBMachine());
+                        }
+                        resultList.add(spindleStatistical);
                     }
-
-                    spindleStatistical = new EquipmentSpindleStatistical();
-                    EquipmentMachiningHistoryDto machiningHistoryDto = equipmentMachiningHistoryService.getMaxSpindleLoad(equipment.getEquipmentid(), initDate, DateUtils.plusTime(initDate, 1));
-                    if(machiningHistoryDto == null || machiningHistoryDto.getEquipmentID() == null || machiningHistoryDto.getCollectTime() == null) {
-                        continue;
-                    }
-                    spindleStatistical.setCreatedate(initDate);
-                    spindleStatistical.setSpindlespeed(machiningHistoryDto.getSpindleSpeed());
-                    spindleStatistical.setEquipmentid(equipment.getEquipmentid());
-                    spindleStatistical.setEquipmentname(equipment.getEquipmentname());
-                    spindleStatistical.setSpindleload(machiningHistoryDto.getSpindleLoad());
-                    spindleStatistical.setSpindletime(machiningHistoryDto.getCollectTime());
-                    MachineXYZHistoryDto machineXYZHistoryDto = machineXYZHistoryService.getNearAxisType(equipment.getEquipmentid(), initDate, DateUtils.plusTime(initDate, 1), machiningHistoryDto.getCollectTime());
-                    if(machineXYZHistoryDto != null) {
-                        spindleStatistical.setAxistime(machineXYZHistoryDto.getCollectTime());
-                        spindleStatistical.setAxisx(machineXYZHistoryDto.getXMachine());
-                        spindleStatistical.setAxisy(machineXYZHistoryDto.getYMachine());
-                        spindleStatistical.setAxisz(machineXYZHistoryDto.getZMachine());
-                        spindleStatistical.setAxisa(machineXYZHistoryDto.getAMachine());
-                        spindleStatistical.setAxisb(machineXYZHistoryDto.getBMachine());
-                    }
-                    resultList.add(spindleStatistical);
                 }
                 if (!resultList.isEmpty()) {
                     equipmentSpindleStatisticalService.saveBatch(resultList);
diff --git a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/EquipmentWorklineMapper.java b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/EquipmentWorklineMapper.java
index 1c766c3..8d17881 100644
--- a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/EquipmentWorklineMapper.java
+++ b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/EquipmentWorklineMapper.java
@@ -4,7 +4,9 @@
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
+import org.jeecg.modules.mdc.dto.CurrentElectricDto;
 import org.jeecg.modules.mdc.dto.EquipmentMachingDto;
+import org.jeecg.modules.mdc.dto.EquipmentMachiningHistoryDto;
 import org.jeecg.modules.mdc.dto.MdcEquipmentDto;
 import org.springframework.stereotype.Repository;
 
@@ -52,4 +54,16 @@
 
     @InterceptorIgnore(tenantLine = "1")
     Map<String, Object> getDataList(@Param("tableName") String saveTableName);
+
+    @InterceptorIgnore(tenantLine = "1")
+    Date getMinDate(@Param("tableName") String saveTableName);
+
+    @InterceptorIgnore(tenantLine = "1")
+    CurrentElectricDto getMaxElectric(@Param("tableName") String saveTableName, @Param("axisType") Integer axisType, @Param("startDate") Date startDate, @Param("endDate") Date endDate);
+
+    @InterceptorIgnore(tenantLine = "1")
+    EquipmentMachiningHistoryDto getNearTimeSpindleLoad(@Param("tableName") String tableName, @Param("startDate")Date startDate, @Param("endDate")Date endDate, @Param("nearDate")Date nearDate);
+
+    @InterceptorIgnore(tenantLine = "1")
+    EquipmentMachiningHistoryDto getMaxSpindleLoad(@Param("tableName") String tableName, @Param("startDate")Date startDate, @Param("endDate")Date endDate);
 }
diff --git a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/EquipmentXYZMapper.java b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/EquipmentXYZMapper.java
index fb4a4eb..45aa172 100644
--- a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/EquipmentXYZMapper.java
+++ b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/EquipmentXYZMapper.java
@@ -2,7 +2,10 @@
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import org.apache.ibatis.annotations.Param;
+import org.jeecg.modules.mdc.dto.MachineXYZHistoryDto;
 import org.jeecg.modules.mdc.entity.EquipmentXYZ;
+
+import java.util.Date;
 
 /**
  * @author: LiuS
@@ -11,4 +14,6 @@
 public interface EquipmentXYZMapper extends BaseMapper<EquipmentXYZ> {
 
     EquipmentXYZ findByEquipmentId(@Param("equipmentId") String equipmentId);
+
+    MachineXYZHistoryDto getNearAxisType(@Param("equipmentId") String equipmentId, @Param("startDate") Date startDate, @Param("endDate") Date endDate, @Param("nearDate") Date nearDate);
 }
diff --git a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/EquipmentWorklineMapper.xml b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/EquipmentWorklineMapper.xml
index 27b64c4..0703ef0 100644
--- a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/EquipmentWorklineMapper.xml
+++ b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/EquipmentWorklineMapper.xml
@@ -25,4 +25,80 @@
     <select id="getDataList" resultType="java.util.Map">
         select top 1 [${tableName}].* from [${tableName}] order by CollectTime  desc
     </select>
+
+    <select id="getMinDate" resultType="java.util.Date">
+        SELECT TOP 1 CollectTime from [${tableName}] ORDER BY CollectTime ASC
+    </select>
+
+    <select id="getMaxElectric" resultType="org.jeecg.modules.mdc.dto.CurrentElectricDto">
+        SELECT TOP 1
+        <if test="axisType != null and axisType != '' and axisType == 1">
+            ABS( actualCurrentX ) currentValue,
+            EquipmentID,
+            CollectTime
+        </if>
+        <if test="axisType != null and axisType != '' and axisType == 2">
+            ABS( actualCurrentY ) currentValue,
+            EquipmentID,
+            CollectTime
+        </if>
+        <if test="axisType != null and axisType != '' and axisType == 3">
+            ABS( actualCurrentZ ) currentValue,
+            EquipmentID,
+            CollectTime
+        </if>
+        <if test="axisType != null and axisType != '' and axisType == 4">
+            ABS( actualCurrentA ) currentValue,
+            EquipmentID,
+            CollectTime
+        </if>
+        <if test="axisType != null and axisType != '' and axisType == 5">
+            ABS( actualCurrentB ) currentValue,
+            EquipmentID,
+            CollectTime
+        </if>
+        FROM
+            [${tableName}]
+        WHERE
+        <if test="axisType != null and axisType != '' and axisType == 1">
+            ABS( actualCurrentX ) = ( SELECT MAX ( ABS( actualCurrentX ) ) currentValue FROM [${tableName}] WHERE CollectTime BETWEEN #{startDate} AND #{endDate} )
+        </if>
+        <if test="axisType != null and axisType != '' and axisType == 2">
+            ABS( actualCurrentY ) = ( SELECT MAX ( ABS( actualCurrentY ) ) currentValue FROM [${tableName}] WHERE CollectTime BETWEEN #{startDate} AND #{endDate} )
+        </if>
+        <if test="axisType != null and axisType != '' and axisType == 3">
+            ABS( actualCurrentZ ) = ( SELECT MAX ( ABS( actualCurrentZ ) ) currentValue FROM [${tableName}] WHERE CollectTime BETWEEN #{startDate} AND #{endDate} )
+        </if>
+        <if test="axisType != null and axisType != '' and axisType == 4">
+            ABS( actualCurrentA ) = ( SELECT MAX ( ABS( actualCurrentA ) ) currentValue FROM [${tableName}] WHERE CollectTime BETWEEN #{startDate} AND #{endDate} )
+        </if>
+        <if test="axisType != null and axisType != '' and axisType == 5">
+            ABS( actualCurrentB ) = ( SELECT MAX ( ABS( actualCurrentB ) ) currentValue FROM [${tableName}] WHERE CollectTime BETWEEN #{startDate} AND #{endDate} )
+        </if>
+    </select>
+
+    <select id="getNearTimeSpindleLoad" resultType="org.jeecg.modules.mdc.dto.EquipmentMachiningHistoryDto">
+        SELECT TOP 1
+            CollectTime collectTime,
+            spindleload,
+            spindlespeed
+        FROM
+            [${tableName}]
+        WHERE
+            CollectTime BETWEEN #{startDate} AND #{endDate}
+        ORDER BY
+            ABS( DATEDIFF( SECOND, CollectTime, #{nearDate} ) )
+    </select>
+
+    <select id="getMaxSpindleLoad" resultType="org.jeecg.modules.mdc.dto.EquipmentMachiningHistoryDto">
+        SELECT TOP 1
+            CollectTime collectTime,
+            EquipmentID equipmentID,
+            spindleload spindleLoad,
+            spindlespeed spindleSpeed
+        FROM
+            [${tableName}]
+        WHERE
+            ABS( spindleload ) = ( SELECT MAX ( ABS( spindleload ) ) spindleload FROM [${tableName}] WHERE CollectTime BETWEEN #{startDate} AND #{endDate} )
+    </select>
 </mapper>
diff --git a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/EquipmentXYZMapper.xml b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/EquipmentXYZMapper.xml
index a570cae..a7ae619 100644
--- a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/EquipmentXYZMapper.xml
+++ b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/mapper/xml/EquipmentXYZMapper.xml
@@ -12,4 +12,22 @@
         ORDER BY
             CollectTime DESC
     </select>
+
+    <select id="getNearAxisType" resultType="org.jeecg.modules.mdc.dto.MachineXYZHistoryDto">
+        SELECT TOP 1
+            CollectTime collectTime,
+            EquipmentID equipmentID,
+            Xmachine xMachine,
+            Ymachine yMachine,
+            Zmachine zMachine,
+            Amachine aMachine,
+            Bmachine bMachine
+        FROM
+            EquipmentXYZ
+        WHERE
+            EquipmentID = #{equipmentId}
+          AND CollectTime BETWEEN #{startDate} AND #{endDate}
+        ORDER BY
+            ABS( DATEDIFF( SECOND, CollectTime, #{nearDate} ) )
+    </select>
 </mapper>
\ No newline at end of file
diff --git a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IEquipmentWorkLineService.java b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IEquipmentWorkLineService.java
index 076e641..b9bfd79 100644
--- a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IEquipmentWorkLineService.java
+++ b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IEquipmentWorkLineService.java
@@ -1,6 +1,8 @@
 package org.jeecg.modules.mdc.service;
 
+import org.jeecg.modules.mdc.dto.CurrentElectricDto;
 import org.jeecg.modules.mdc.dto.EquipmentMachingDto;
+import org.jeecg.modules.mdc.dto.EquipmentMachiningHistoryDto;
 import org.jeecg.modules.mdc.dto.MdcEquipmentDto;
 
 import java.util.Date;
@@ -34,6 +36,7 @@
 
     /**
      * 鏌ユ壘娉曞叞鍏嬭澶囪繍琛岀殑绋嬪簭鍙�
+     *
      * @param drivetype
      * @param equipmentid
      * @param startTime
@@ -44,6 +47,7 @@
 
     /**
      * 鏌ヨ娉曟媺鍏嬭澶囧姞宸ュ伐浠跺紑濮嬫椂闂�
+     *
      * @param saveTableName
      * @param productCount
      * @return
@@ -52,6 +56,7 @@
 
     /**
      * 鏌ヨ娉曟媺鍏嬭澶囧姞宸ュ伐浠剁粨鏉熸椂闂�
+     *
      * @param saveTableName
      * @param productCount
      * @return
@@ -60,8 +65,49 @@
 
     /**
      * 鑾峰彇璁惧杩愯鏁版嵁
+     *
      * @param saveTableName
      * @return
      */
     Map<String, Object> getDataList(String saveTableName);
+
+    /**
+     * 鏌ヨ鍗曡〃绗竴鏉℃暟鎹椂闂�
+     *
+     * @param saveTableName
+     * @return
+     */
+    Date getMinDate(String saveTableName);
+
+    /**
+     * 鏌ヨ杞存渶澶х數娴�
+     *
+     * @param saveTableName
+     * @param axisType
+     * @param startDate
+     * @param endDate
+     * @return
+     */
+    CurrentElectricDto getMaxElectric(String saveTableName, Integer axisType, Date startDate, Date endDate);
+
+    /**
+     * 鏌ヨ鏃堕棿鐐规渶杩戠殑涓�鏉℃暟鎹�
+     *
+     * @param tableName
+     * @param startDate
+     * @param endDate
+     * @param nearDate
+     * @return
+     */
+    EquipmentMachiningHistoryDto getNearTimeSpindleLoad(String tableName, Date startDate, Date endDate, Date nearDate);
+
+    /**
+     * 鏌ヨ鏈�澶т富杞磋礋杞�
+     *
+     * @param tableName
+     * @param startDate
+     * @param endDate
+     * @return
+     */
+    EquipmentMachiningHistoryDto getMaxSpindleLoad(String tableName, Date startDate, Date endDate);
 }
diff --git a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IEquipmentXYZService.java b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IEquipmentXYZService.java
index b229d5c..c9e274b 100644
--- a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IEquipmentXYZService.java
+++ b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/IEquipmentXYZService.java
@@ -1,7 +1,10 @@
 package org.jeecg.modules.mdc.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import org.jeecg.modules.mdc.dto.MachineXYZHistoryDto;
 import org.jeecg.modules.mdc.entity.EquipmentXYZ;
+
+import java.util.Date;
 
 /**
  * @author: LiuS
@@ -11,4 +14,6 @@
     EquipmentXYZ getByEquipmentId(String equipmentId);
 
     EquipmentXYZ findByEquipmentId(String equipmentId);
+
+    MachineXYZHistoryDto getNearAxisType(String equipmentId, Date startDate, Date endDate, Date nearDate);
 }
diff --git a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/EquipmentWorkLineServiceImpl.java b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/EquipmentWorkLineServiceImpl.java
index c0b336d..4619cc4 100644
--- a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/EquipmentWorkLineServiceImpl.java
+++ b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/EquipmentWorkLineServiceImpl.java
@@ -1,6 +1,8 @@
 package org.jeecg.modules.mdc.service.impl;
 
+import org.jeecg.modules.mdc.dto.CurrentElectricDto;
 import org.jeecg.modules.mdc.dto.EquipmentMachingDto;
+import org.jeecg.modules.mdc.dto.EquipmentMachiningHistoryDto;
 import org.jeecg.modules.mdc.dto.MdcEquipmentDto;
 import org.jeecg.modules.mdc.mapper.EquipmentWorklineMapper;
 import org.jeecg.modules.mdc.service.IEquipmentWorkLineService;
@@ -86,6 +88,30 @@
         }
     }
 
+    @Override
+    public Date getMinDate(String saveTableName) {
+        try {
+            return equipmentWorkLineMapper.getMinDate(saveTableName);
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    @Override
+    public CurrentElectricDto getMaxElectric(String saveTableName, Integer axisType, Date startDate, Date endDate) {
+        return equipmentWorkLineMapper.getMaxElectric(saveTableName, axisType, startDate, endDate);
+    }
+
+    @Override
+    public EquipmentMachiningHistoryDto getNearTimeSpindleLoad(String tableName, Date startDate, Date endDate, Date nearDate) {
+        return equipmentWorkLineMapper.getNearTimeSpindleLoad(tableName, startDate, endDate, nearDate);
+    }
+
+    @Override
+    public EquipmentMachiningHistoryDto getMaxSpindleLoad(String tableName, Date startDate, Date endDate) {
+        return equipmentWorkLineMapper.getMaxSpindleLoad(tableName, startDate, endDate);
+    }
+
     private List<EquipmentMachingDto> convertData(List<Map<String, Object>> list) {
         SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
         List<EquipmentMachingDto> dto = new ArrayList<>();
diff --git a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/EquipmentXYZServiceImpl.java b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/EquipmentXYZServiceImpl.java
index 364cc6c..dddadc5 100644
--- a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/EquipmentXYZServiceImpl.java
+++ b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/EquipmentXYZServiceImpl.java
@@ -2,10 +2,13 @@
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.jeecg.modules.mdc.dto.MachineXYZHistoryDto;
 import org.jeecg.modules.mdc.entity.EquipmentXYZ;
 import org.jeecg.modules.mdc.mapper.EquipmentXYZMapper;
 import org.jeecg.modules.mdc.service.IEquipmentXYZService;
 import org.springframework.stereotype.Service;
+
+import java.util.Date;
 
 /**
  * @author: LiuS
@@ -22,4 +25,9 @@
     public EquipmentXYZ findByEquipmentId(String equipmentId) {
         return this.baseMapper.findByEquipmentId(equipmentId);
     }
+
+    @Override
+    public MachineXYZHistoryDto getNearAxisType(String equipmentId, Date startDate, Date endDate, Date nearDate) {
+        return this.baseMapper.getNearAxisType(equipmentId, startDate, endDate, nearDate);
+    }
 }
diff --git a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcOeeInfoServiceImpl.java b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcOeeInfoServiceImpl.java
index feb3306..b611f47 100644
--- a/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcOeeInfoServiceImpl.java
+++ b/lxzn-module-mdc/src/main/java/org/jeecg/modules/mdc/service/impl/MdcOeeInfoServiceImpl.java
@@ -105,6 +105,9 @@
             }
             queryWrapper.orderByAsc(MdcEquipment::getEquipmentName);
             List<MdcEquipment> equipmentList = mdcEquipmentService.list(queryWrapper);
+
+            vo.setStartTime(DateUtils.format(DateUtils.toDate(vo.getStartTime(), DateUtils.STRDATE), DateUtils.STR_DATE));
+            vo.setEndTime(DateUtils.format(DateUtils.toDate(vo.getEndTime(), DateUtils.STRDATE), DateUtils.STR_DATE));
             //鏌ヨoee鏁版嵁
             List<MdcOeeInfo> oeeList = this.baseMapper.oeeList(vo);
             //鏁版嵁澶勭悊
@@ -134,7 +137,7 @@
                     BigDecimal oeeRate = BigDecimal.ZERO;
                     if (!mdcOeeInfoList.isEmpty()) {
                         BigDecimal count = mdcOeeInfoList.stream().map(MdcOeeInfo::getOeeRate).reduce(BigDecimal.ZERO, BigDecimal::add);
-                        oeeRate = count.divide(new BigDecimal(mdcOeeInfoList.size()), 2, RoundingMode.HALF_UP);
+                        oeeRate = count.divide(new BigDecimal(mdcOeeInfoList.size()), 4, RoundingMode.HALF_UP);
                         mdcOeeResultDto.setOeeRate(oeeRate);
                     }
                     long rate = oeeRate.multiply(new BigDecimal("100")).longValue();
@@ -190,8 +193,8 @@
                     .eq(MdcProductDayschedule::getEquipmentId, equipment.getEquipmentid()));
             if (productDayScheduleList != null && !productDayScheduleList.isEmpty()) {
                 MdcProductDayschedule mdcProductDayschedule;
-                MdcOeeInfo mdcOeeInfo = new MdcOeeInfo();
                 for (MdcShiftSub mdcShiftSub : mdcShiftSubList) {
+                    MdcOeeInfo mdcOeeInfo = new MdcOeeInfo();
                     String id = mdcShiftSub.getId();
                     if (productDayScheduleList.stream().anyMatch(productDayschedule -> productDayschedule.getOrderId().substring(8, 10).equals(id))) {
                         mdcOeeInfo.setEquipmentId(equipment.getEquipmentid());
@@ -241,11 +244,13 @@
                             continue;
                         }
                         mdcOeeInfo.setScheduleNum(mdcComponentInfo.getScheduleNum());
-
-                        BigDecimal oeeRate = mdcOeeInfo.getProcessLong().multiply(new BigDecimal(mdcOeeInfo.getPlanNum())).multiply(new BigDecimal(mdcOeeInfo.getQualityNum()))
-                                        .divide(mdcEquipmentStatisticalShiftInfo.getTotalLong(), 2, RoundingMode.HALF_UP)
-                                        .divide(new BigDecimal(mdcOeeInfo.getScheduleNum()), 2, RoundingMode.HALF_UP)
-                                        .divide(new BigDecimal(mdcOeeInfo.getCompleteNum()), 2, RoundingMode.HALF_UP);
+                        BigDecimal oeeRate = BigDecimal.ZERO;
+                        if (!mdcOeeInfo.getCompleteNum().equals(0)) {
+                            oeeRate = mdcOeeInfo.getProcessLong().multiply(new BigDecimal(mdcOeeInfo.getPlanNum())).multiply(new BigDecimal(mdcOeeInfo.getQualityNum()))
+                                    .divide(mdcEquipmentStatisticalShiftInfo.getTotalLong(), 4, RoundingMode.HALF_UP)
+                                    .divide(new BigDecimal(mdcOeeInfo.getScheduleNum()), 4, RoundingMode.HALF_UP)
+                                    .divide(new BigDecimal(mdcOeeInfo.getCompleteNum()), 4, RoundingMode.HALF_UP);
+                        }
                         mdcOeeInfo.setOeeRate(oeeRate);
                         result.add(mdcOeeInfo);
                     }
@@ -256,5 +261,4 @@
             this.saveBatch(result);
         }
     }
-
 }
diff --git a/lxzn-module-mdc/src/main/java/org/jeecg/modules/screen/service/impl/MdcLargeScreenServiceImpl.java b/lxzn-module-mdc/src/main/java/org/jeecg/modules/screen/service/impl/MdcLargeScreenServiceImpl.java
index 3890456..9bb45c8 100644
--- a/lxzn-module-mdc/src/main/java/org/jeecg/modules/screen/service/impl/MdcLargeScreenServiceImpl.java
+++ b/lxzn-module-mdc/src/main/java/org/jeecg/modules/screen/service/impl/MdcLargeScreenServiceImpl.java
@@ -125,7 +125,7 @@
                 equipmentRateDto.setEquipmentName(mdcEfficiencyDto.getEquipmentName());
                 equipmentRateDto.setOpenRate(mdcEfficiencyDto.getOpenRate().multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP));
                 equipmentRateDto.setUtilizationRate(mdcEfficiencyDto.getUtilizationRate().multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP));
-                if (!equipmentRateDto.getOpenRate().equals(BigDecimal.ZERO) || !equipmentRateDto.getUtilizationRate().equals(BigDecimal.ZERO)) {
+                if (!(equipmentRateDto.getOpenRate().compareTo(BigDecimal.ZERO) == 0) && !(equipmentRateDto.getUtilizationRate().compareTo(BigDecimal.ZERO) == 0)) {
                     result.add(equipmentRateDto);
                 }
             }
@@ -149,7 +149,7 @@
                 meu.setDate(new StringBuilder(mdcEfficiencyDto.getTheDate().substring(4, 8)).insert(2, "-").toString());
                 BigDecimal equipmentCount = mdcLargeScreenMapper.findEquipmentCount(yesterday);
                 meu.setUtilizationRate(mdcEfficiencyDto.getProcessLong().divide(equipmentCount.multiply(new BigDecimal("86400")), 4, RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP));
-                if (!meu.getUtilizationRate().equals(BigDecimal.ZERO)) {
+                if (!(meu.getUtilizationRate().compareTo(BigDecimal.ZERO) == 0)) {
                     result.add(meu);
                 }
             }
diff --git a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/config/license/LicenseCreator.java b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/config/license/LicenseCreator.java
new file mode 100644
index 0000000..97e4e11
--- /dev/null
+++ b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/config/license/LicenseCreator.java
@@ -0,0 +1,98 @@
+package org.jeecg.config.license;
+
+import de.schlichtherle.license.*;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.jeecg.config.license.entity.CustomLicenseManager;
+
+import javax.security.auth.x500.X500Principal;
+import java.io.File;
+import java.text.MessageFormat;
+import java.util.prefs.Preferences;
+
+/**
+ * @Author: ljh
+ * @ClassName LicenseCreator
+ * @Description TODO
+ * @date 2022/12/9 11:14
+ * @Version 1.0
+ */
+
+public class LicenseCreator {
+
+    private static Logger logger = LogManager.getLogger(LicenseCreator.class);
+    private final static X500Principal DEFAULT_HOLDER_AND_ISSUER = new X500Principal("CN=localhost, OU=localhost, O=localhost, L=SH, ST=SH, C=CN");
+    private LicenseCreatorParam param;
+
+    public LicenseCreator(LicenseCreatorParam param) {
+        this.param = param;
+    }
+
+    /**
+     * 鐢熸垚License璇佷功
+     *
+     * @return boolean
+     */
+    public boolean generateLicense() {
+        try {
+            LicenseManager licenseManager = new CustomLicenseManager(initLicenseParam());
+            LicenseContent licenseContent = initLicenseContent();
+
+            licenseManager.store(licenseContent, new File(param.getLicensePath()));
+
+            return true;
+        } catch (Exception e) {
+            logger.error(MessageFormat.format("璇佷功鐢熸垚澶辫触锛歿0}", param), e);
+            return false;
+        }
+    }
+
+    /**
+     * 鍒濆鍖栬瘉涔︾敓鎴愬弬鏁�
+     *
+     * @return de.schlichtherle.license.LicenseParam
+     */
+    private LicenseParam initLicenseParam() {
+        Preferences preferences = Preferences.userNodeForPackage(LicenseCreator.class);
+
+        //璁剧疆瀵硅瘉涔﹀唴瀹瑰姞瀵嗙殑绉橀挜
+        CipherParam cipherParam = new DefaultCipherParam(param.getStorePass());
+
+        KeyStoreParam privateStoreParam = new CustomKeyStoreParam(LicenseCreator.class
+                , param.getPrivateKeysStorePath()
+                , param.getPrivateAlias()
+                , param.getStorePass()
+                , param.getKeyPass());
+
+        LicenseParam licenseParam = new DefaultLicenseParam(param.getSubject()
+                , preferences
+                , privateStoreParam
+                , cipherParam);
+
+        return licenseParam;
+    }
+
+    /**
+     * 璁剧疆璇佷功鐢熸垚姝f枃淇℃伅
+     *
+     * @return de.schlichtherle.license.LicenseContent
+     */
+    private LicenseContent initLicenseContent() {
+        LicenseContent licenseContent = new LicenseContent();
+        licenseContent.setHolder(DEFAULT_HOLDER_AND_ISSUER);
+        licenseContent.setIssuer(DEFAULT_HOLDER_AND_ISSUER);
+
+        licenseContent.setSubject(param.getSubject());
+        licenseContent.setIssued(param.getIssuedTime());
+        licenseContent.setNotBefore(param.getIssuedTime());
+        licenseContent.setNotAfter(param.getExpiryTime());
+        licenseContent.setConsumerType(param.getConsumerType());
+        licenseContent.setConsumerAmount(param.getConsumerAmount());
+        licenseContent.setInfo(param.getDescription());
+
+        //鎵╁睍鏍¢獙鏈嶅姟鍣ㄧ‖浠朵俊鎭�
+        licenseContent.setExtra(param.getLicenseCheckModel());
+
+        return licenseContent;
+    }
+}
\ No newline at end of file
diff --git a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/config/license/LicenseCreatorParam.java b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/config/license/LicenseCreatorParam.java
new file mode 100644
index 0000000..80c842a
--- /dev/null
+++ b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/config/license/LicenseCreatorParam.java
@@ -0,0 +1,155 @@
+package org.jeecg.config.license;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.jeecg.config.license.entity.LicenseCheckModel;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @Author: lius
+ * @ClassName LicenseCreatorParam
+ * @date 2024/11/2 17:02
+ */
+@ApiModel("鐢熸垚璇佷功瀹炰綋绫�")
+public class LicenseCreatorParam implements Serializable {
+
+    private static final long serialVersionUID = 2832129012982731724L;
+
+    @ApiModelProperty("璇佷功subject")
+    private String subject;
+
+    @ApiModelProperty("瀵嗛挜鍒О")
+    private String privateAlias;
+
+    @ApiModelProperty("瀵嗛挜瀵嗙爜")
+    private String keyPass;
+
+    @ApiModelProperty("璁块棶绉橀挜搴撶殑瀵嗙爜")
+    private String storePass;
+
+    @ApiModelProperty("璇佷功鐢熸垚璺緞")
+    private String licensePath;
+
+    @ApiModelProperty("瀵嗛挜搴撳瓨鍌ㄨ矾寰�")
+    private String privateKeysStorePath;
+
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @ApiModelProperty("璇佷功鐢熸晥鏃堕棿")
+    private Date issuedTime = new Date();
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    @ApiModelProperty("璇佷功澶辨晥鏃堕棿")
+    private Date expiryTime;
+
+    @ApiModelProperty("鐢ㄦ埛绫诲瀷")
+    private String consumerType = "user";
+
+    @ApiModelProperty("鐢ㄦ埛鏁伴噺")
+    private Integer consumerAmount = 1;
+
+    @ApiModelProperty("鎻忚堪淇℃伅")
+    private String description = "";
+
+    @ApiModelProperty("棰濆鐨勬湇鍔″櫒纭欢鏍¢獙淇℃伅")
+    private LicenseCheckModel licenseCheckModel;
+
+    public String getSubject() {
+        return subject;
+    }
+
+    public void setSubject(String subject) {
+        this.subject = subject;
+    }
+
+    public String getPrivateAlias() {
+        return privateAlias;
+    }
+
+    public void setPrivateAlias(String privateAlias) {
+        this.privateAlias = privateAlias;
+    }
+
+    public String getKeyPass() {
+        return keyPass;
+    }
+
+    public void setKeyPass(String keyPass) {
+        this.keyPass = keyPass;
+    }
+
+    public String getStorePass() {
+        return storePass;
+    }
+
+    public void setStorePass(String storePass) {
+        this.storePass = storePass;
+    }
+
+    public String getLicensePath() {
+        return licensePath;
+    }
+
+    public void setLicensePath(String licensePath) {
+        this.licensePath = licensePath;
+    }
+
+    public String getPrivateKeysStorePath() {
+        return privateKeysStorePath;
+    }
+
+    public void setPrivateKeysStorePath(String privateKeysStorePath) {
+        this.privateKeysStorePath = privateKeysStorePath;
+    }
+
+    public Date getIssuedTime() {
+        return issuedTime;
+    }
+
+    public void setIssuedTime(Date issuedTime) {
+        this.issuedTime = issuedTime;
+    }
+
+    public Date getExpiryTime() {
+        return expiryTime;
+    }
+
+    public void setExpiryTime(Date expiryTime) {
+        this.expiryTime = expiryTime;
+    }
+
+    public String getConsumerType() {
+        return consumerType;
+    }
+
+    public void setConsumerType(String consumerType) {
+        this.consumerType = consumerType;
+    }
+
+    public Integer getConsumerAmount() {
+        return consumerAmount;
+    }
+
+    public void setConsumerAmount(Integer consumerAmount) {
+        this.consumerAmount = consumerAmount;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public LicenseCheckModel getLicenseCheckModel() {
+        return licenseCheckModel;
+    }
+
+    public void setLicenseCheckModel(LicenseCheckModel licenseCheckModel) {
+        this.licenseCheckModel = licenseCheckModel;
+    }
+}
\ No newline at end of file
diff --git a/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/base/controller/LicenseController.java b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/base/controller/LicenseController.java
new file mode 100644
index 0000000..622234c
--- /dev/null
+++ b/lxzn-module-system/lxzn-system-biz/src/main/java/org/jeecg/modules/base/controller/LicenseController.java
@@ -0,0 +1,96 @@
+package org.jeecg.modules.base.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.config.license.*;
+import org.jeecg.config.license.entity.LicenseCheckModel;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @Author: lius
+ * @ClassName LicenseController
+ * @date 2024/11/2 17:35
+ */
+@Slf4j
+@Api(tags = "license璇佷功")
+@RestController
+@RequestMapping("/base/license")
+public class LicenseController {
+
+    /**
+     * 璇佷功鐢熸垚璺緞
+     */
+    @Value("${license.licensePath}")
+    private String licensePath;
+
+    /**
+    * @Author: lius
+    * @Description: 鑾峰彇鏈嶅姟鍣ㄧ‖浠朵俊鎭�
+    * @DateTime: 17:35 2024/11/2
+    * @Params:  osName 绯荤粺绫诲瀷 windows鎴杔inux
+    * @Return
+    */
+    @AutoLog(value = "鑾峰彇鏈嶅姟鍣ㄧ‖浠朵俊鎭�")
+    @ApiOperation("鑾峰彇鏈嶅姟鍣ㄧ‖浠朵俊鎭�")
+    @GetMapping("/getServerInfos/{osName}")
+    public LicenseCheckModel getServerInfos(@PathVariable String osName) {
+        //鎿嶄綔绯荤粺绫诲瀷
+        if (StringUtils.isBlank(osName)) {
+            osName = System.getProperty("os.name");
+        }
+        osName = osName.toLowerCase();
+
+        AbstractServerInfos abstractServerInfos = null;
+
+        //鏍规嵁涓嶅悓鎿嶄綔绯荤粺绫诲瀷閫夋嫨涓嶅悓鐨勬暟鎹幏鍙栨柟娉�
+        if (osName.startsWith("windows")) {
+            abstractServerInfos = new WindowsServerInfos();
+        } else if (osName.startsWith("linux")) {
+            abstractServerInfos = new LinuxServerInfos();
+        } else {//鍏朵粬鏈嶅姟鍣ㄧ被鍨�
+            abstractServerInfos = new LinuxServerInfos();
+        }
+
+        return abstractServerInfos.getServerInfos();
+    }
+
+    /**
+    * @Author: lius
+    * @Description: 鐢熸垚璇佷功
+    * @DateTime: 17:35 2024/11/2
+    */
+    @AutoLog(value = "鐢熸垚璇佷功")
+    @ApiOperation("鐢熸垚璇佷功")
+    @PostMapping("/generateLicense")
+    public Map<String, Object> generateLicense(@RequestBody LicenseCreatorParam param) {
+        Map<String, Object> resultMap = new HashMap<>(2);
+
+        if (StringUtils.isBlank(param.getLicensePath())) {
+            param.setLicensePath(licensePath);
+        }
+
+        LicenseCreator licenseCreator = new LicenseCreator(param);
+        boolean result = licenseCreator.generateLicense();
+
+        if (result) {
+            resultMap.put("result", "ok");
+            resultMap.put("msg", param);
+        } else {
+            resultMap.put("result", "error");
+            resultMap.put("msg", "璇佷功鏂囦欢鐢熸垚澶辫触锛�");
+        }
+
+        return resultMap;
+    }
+
+
+
+
+}
\ No newline at end of file
diff --git a/lxzn-module-system/lxzn-system-start/src/main/resources/application-dev.yml b/lxzn-module-system/lxzn-system-start/src/main/resources/application-dev.yml
index b3e5fb3..4dca823 100644
--- a/lxzn-module-system/lxzn-system-start/src/main/resources/application-dev.yml
+++ b/lxzn-module-system/lxzn-system-start/src/main/resources/application-dev.yml
@@ -126,15 +126,16 @@
         connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
       datasource:
         master:
-          url: jdbc:sqlserver://192.168.124.118:1433;databasename=LXZN_TEST_YITUO
+          url: jdbc:sqlserver://localhost:1433;databasename=LXZN_MDC_YITUO
+#          url: jdbc:sqlserver://192.168.124.118:1433;databasename=LXZN_TEST_YITUO
           username: sa
           password: 123
           driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
-        mesSoAdb:
-          url: jdbc:sqlserver://192.168.124.118:1433;databasename=SOADB
-          username: sa
-          password: 123
-          driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
+#        mesSoAdb:
+#          url: jdbc:sqlserver://192.168.124.118:1433;databasename=SOADB
+#          username: sa
+#          password: 123
+#          driverClassName: com.microsoft.sqlserver.jdbc.SQLServerDriver
   #redis 閰嶇疆
   redis:
     database: 0
@@ -295,4 +296,11 @@
   url: http://localhost:8081/services/EquipmentService?wsdl
   namespace: http://service.server.webservice.example.com
   statusMethod: equipmentStatus
-  rateMethod: equipmentRate
\ No newline at end of file
+  rateMethod: equipmentRate
+license:
+  subject: license_lyyt
+  publicAlias: publicCert
+  storePass: lxzn1688
+  licensePath: F:/license/license.lic
+  publicKeysStorePath: F:/license/publicCerts.keystore
+  uploadPath: F:/LicenseDemo/
\ No newline at end of file

--
Gitblit v1.9.3