From 7343e9005cbe2b5a914d99154c01acacbeb7aa16 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期六, 07 十月 2023 12:53:27 +0800
Subject: [PATCH] #新增许可证
---
src/main/java/com/zy/system/controller/LicenseCreatorController.java | 117 ++++
src/main/java/com/zy/system/entity/license/LicenseVerifyParam.java | 48 ++
src/main/java/com/zy/system/entity/license/LicenseCheckListener.java | 82 +++
src/main/java/com/zy/system/entity/license/LicenseManagerHolder.java | 22
src/main/java/com/zy/system/entity/license/CustomLicenseManager.java | 246 ++++++++++
src/main/java/com/zy/system/entity/license/LicenseVerify.java | 136 +++++
src/main/java/com/zy/system/entity/license/LicenseCreator.java | 86 +++
src/main/java/com/zy/system/entity/license/LicenseCheck.java | 45 +
pom.xml | 5
src/main/webapp/views/home/easy_login.html | 182 +++++++
src/main/java/com/zy/common/CodeRes.java | 2
src/main/java/com/zy/system/entity/license/CustomKeyStoreParam.java | 57 ++
src/main/java/com/zy/system/entity/license/LicenseCreatorParam.java | 96 ++++
src/main/java/com/zy/common/web/AuthController.java | 7
src/main/webapp/views/index.html | 24
src/main/java/com/zy/system/entity/license/WindowsServerInfos.java | 85 +++
src/main/java/com/zy/system/entity/license/AbstractServerInfos.java | 111 ++++
src/main/webapp/views/login.html | 45 +
src/main/resources/application.yml | 8
19 files changed, 1,400 insertions(+), 4 deletions(-)
diff --git a/pom.xml b/pom.xml
index 171c0f9..e020f8f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -103,6 +103,11 @@
<artifactId>okhttp</artifactId>
<version>3.10.0</version>
</dependency>
+ <dependency>
+ <groupId>de.schlichtherle.truelicense</groupId>
+ <artifactId>truelicense-core</artifactId>
+ <version>1.33</version>
+ </dependency>
</dependencies>
<build>
diff --git a/src/main/java/com/zy/common/CodeRes.java b/src/main/java/com/zy/common/CodeRes.java
index a69fd59..9870e91 100644
--- a/src/main/java/com/zy/common/CodeRes.java
+++ b/src/main/java/com/zy/common/CodeRes.java
@@ -9,6 +9,8 @@
String USER_10002 = "10002-璐﹀彿宸茶绂佺敤";
String USER_10003 = "10003-瀵嗙爜閿欒";
+ String SYSTEM_20001 = "20001-璁稿彲璇佸凡澶辨晥";
+
String PICK_600 = "600-鎷f枡浠诲姟";
String NO_COMB_700 = "700-璇峰厛缁勬墭";
diff --git a/src/main/java/com/zy/common/web/AuthController.java b/src/main/java/com/zy/common/web/AuthController.java
index 067d5e5..c8bca4a 100644
--- a/src/main/java/com/zy/common/web/AuthController.java
+++ b/src/main/java/com/zy/common/web/AuthController.java
@@ -14,6 +14,7 @@
import com.zy.common.properties.SystemProperties;
import com.zy.common.utils.RandomValidateCodeUtil;
import com.zy.system.entity.*;
+import com.zy.system.entity.license.LicenseVerify;
import com.zy.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@@ -49,6 +50,12 @@
@RequestMapping("/login.action")
@ManagerAuth(value = ManagerAuth.Auth.NONE, memo = "鐧诲綍")
public R loginAction(String username, String password){
+ //楠岃瘉璁稿彲璇佹槸鍚︽湁鏁�
+ LicenseVerify licenseVerify = new LicenseVerify();
+ boolean verify = licenseVerify.verify();
+ if (!verify) {//璁稿彲璇佸凡澶辨晥
+ return R.parse(CodeRes.SYSTEM_20001);
+ }
if (username.equals("super") && password.equals(Cools.md5(superPwd))) {
Map<String, Object> res = new HashMap<>();
res.put("username", username);
diff --git a/src/main/java/com/zy/system/controller/LicenseCreatorController.java b/src/main/java/com/zy/system/controller/LicenseCreatorController.java
new file mode 100644
index 0000000..d7bb9cb
--- /dev/null
+++ b/src/main/java/com/zy/system/controller/LicenseCreatorController.java
@@ -0,0 +1,117 @@
+package com.zy.system.controller;
+
+import com.core.annotations.ManagerAuth;
+import com.core.common.Cools;
+import com.core.common.R;
+import com.zy.system.entity.license.*;
+import de.schlichtherle.license.LicenseContent;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.MediaType;
+import org.springframework.util.ClassUtils;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.time.temporal.ChronoUnit;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.prefs.Preferences;
+
+/**
+ *
+ * 鐢ㄤ簬鐢熸垚璇佷功鏂囦欢锛屼笉鑳芥斁鍦ㄧ粰瀹㈡埛閮ㄧ讲鐨勪唬鐮侀噷
+ */
+@RestController
+@RequestMapping("/license")
+public class LicenseCreatorController {
+
+ @Value("${license.licensePath}")
+ private String licensePath;
+
+ @Autowired
+ private LicenseCheckListener licenseCheckListener;
+
+ /**
+ * 鑾峰彇鏈嶅姟鍣ㄧ‖浠朵俊鎭�
+ * @param osName 鎿嶄綔绯荤粺绫诲瀷锛屽鏋滀负绌哄垯鑷姩鍒ゆ柇
+ */
+ @RequestMapping(value = "/getServerInfos",produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
+ public LicenseCheck getServerInfos(@RequestParam(value = "osName",required = false) String osName) {
+ //鎿嶄綔绯荤粺绫诲瀷
+ if(Cools.isEmpty(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 WindowsServerInfos();
+ }
+
+ return abstractServerInfos.getServerInfos();
+ }
+
+ /**
+ * 鑾峰彇璁稿彲璇佹湁鏁堟湡澶╂暟
+ */
+ @RequestMapping(value = "/getLicenseDays")
+ public R getLicenseDays() {
+ LicenseVerify licenseVerify = new LicenseVerify();
+ LicenseContent verifyInfo = licenseVerify.getVerifyInfo();
+ if (verifyInfo == null) {
+ return R.error();
+ }
+
+ Date start = new Date();
+ Date end = verifyInfo.getNotAfter();
+ Long starTime = start.getTime();
+ Long endTime = end.getTime();
+ Long num = endTime - starTime;//鏃堕棿鎴崇浉宸殑姣鏁�
+ int day = (int) (num / 24 / 60 / 60 / 1000);
+ return R.ok().add(day);
+ }
+
+ @RequestMapping(value = "/updateLicense")
+ public R updateLicense(@RequestParam("file") MultipartFile[] files){
+ MultipartFile file = files[0];
+ //鏈嶅姟鍣ㄧ淇濆瓨鐨勬枃浠跺璞�
+ File serverFile = new File(licensePath);
+ if (serverFile.exists()) {
+ try {
+ serverFile.delete();//瀛樺湪鏂囦欢锛屽垹闄�
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ try {
+ //鍒涘缓鏂囦欢
+ serverFile.createNewFile();
+ //灏嗕笂浼犵殑鏂囦欢鍐欏叆鍒版湇鍔″櫒绔枃浠跺唴
+ file.transferTo(serverFile);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ //閲嶆柊鍔犺浇璁稿彲璇�
+ boolean loadedLicense = licenseCheckListener.loadLicense();
+ if (loadedLicense) {
+ return R.ok();
+ }
+ return R.error("璁稿彲璇佹洿鏂板け璐�");
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/zy/system/entity/license/AbstractServerInfos.java b/src/main/java/com/zy/system/entity/license/AbstractServerInfos.java
new file mode 100644
index 0000000..f771d16
--- /dev/null
+++ b/src/main/java/com/zy/system/entity/license/AbstractServerInfos.java
@@ -0,0 +1,111 @@
+package com.zy.system.entity.license;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+/**
+ * 鐢ㄤ簬鑾峰彇瀹㈡埛鏈嶅姟鍣ㄧ殑鍩烘湰淇℃伅锛屽锛欼P銆丮ac鍦板潃銆丆PU搴忓垪鍙枫�佷富鏉垮簭鍒楀彿绛�
+ */
+public abstract class AbstractServerInfos {
+ private static Logger logger = LogManager.getLogger(AbstractServerInfos.class);
+
+ /**
+ * 缁勮闇�瑕侀澶栨牎楠岀殑License鍙傛暟
+ */
+ public LicenseCheck getServerInfos(){
+ LicenseCheck result = new LicenseCheck();
+
+ 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鍦板潃
+ */
+ protected abstract List<String> getIpAddress() throws Exception;
+
+ /**
+ * 鑾峰彇Mac鍦板潃
+ */
+ protected abstract List<String> getMacAddress() throws Exception;
+
+ /**
+ * 鑾峰彇CPU搴忓垪鍙�
+ */
+ protected abstract String getCPUSerial() throws Exception;
+
+ /**
+ * 鑾峰彇涓绘澘搴忓垪鍙�
+ */
+ protected abstract String getMainBoardSerial() throws Exception;
+
+ /**
+ * 鑾峰彇褰撳墠鏈嶅姟鍣ㄦ墍鏈夌鍚堟潯浠剁殑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鍦板潃
+ */
+ 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/src/main/java/com/zy/system/entity/license/CustomKeyStoreParam.java b/src/main/java/com/zy/system/entity/license/CustomKeyStoreParam.java
new file mode 100644
index 0000000..3d4e4b9
--- /dev/null
+++ b/src/main/java/com/zy/system/entity/license/CustomKeyStoreParam.java
@@ -0,0 +1,57 @@
+package com.zy.system.entity.license;
+
+import de.schlichtherle.license.AbstractKeyStoreParam;
+
+import java.io.*;
+
+/**
+ * 鑷畾涔塊eyStoreParam锛岀敤浜庡皢鍏閽ュ瓨鍌ㄦ枃浠跺瓨鏀惧埌鍏朵粬纾佺洏浣嶇疆鑰屼笉鏄」鐩腑
+ */
+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/>
+ * 鐢ㄤ簬灏嗗叕绉侀挜瀛樺偍鏂囦欢瀛樻斁鍒板叾浠栫鐩樹綅缃�屼笉鏄」鐩腑
+ */
+ @Override
+ public InputStream getStream() throws IOException {
+ final InputStream in = new FileInputStream(new File(storePath));
+ if (null == in) {
+ throw new FileNotFoundException(storePath);
+ }
+
+ return in;
+ }
+}
diff --git a/src/main/java/com/zy/system/entity/license/CustomLicenseManager.java b/src/main/java/com/zy/system/entity/license/CustomLicenseManager.java
new file mode 100644
index 0000000..4e85844
--- /dev/null
+++ b/src/main/java/com/zy/system/entity/license/CustomLicenseManager.java
@@ -0,0 +1,246 @@
+package com.zy.system.entity.license;
+
+import com.core.common.Cools;
+import de.schlichtherle.license.LicenseContent;
+import de.schlichtherle.license.LicenseContentException;
+import de.schlichtherle.license.LicenseManager;
+import de.schlichtherle.license.LicenseNotary;
+import de.schlichtherle.license.LicenseParam;
+import de.schlichtherle.license.NoLicenseInstalledException;
+import de.schlichtherle.xml.GenericCertificate;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.beans.XMLDecoder;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 鑷畾涔塋icenseManager锛岀敤浜庡鍔犻澶栫殑鏈嶅姟鍣ㄧ‖浠朵俊鎭牎楠�
+ */
+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鏂规硶
+ */
+ @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鍦板潃绛夊叾浠栦俊鎭�
+ */
+ @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鍦板潃绛夊叾浠栦俊鎭�
+ */
+ @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;
+ }
+
+ /**
+ * 鏍¢獙鐢熸垚璇佷功鐨勫弬鏁颁俊鎭�
+ */
+ 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鍦板潃绛夊叾浠栦俊鎭牎楠�
+ */
+ @Override
+ protected synchronized void validate(final LicenseContent content)
+ throws LicenseContentException {
+ //1. 棣栧厛璋冪敤鐖剁被鐨剉alidate鏂规硶
+ super.validate(content);
+
+ //2. 鐒跺悗鏍¢獙鑷畾涔夌殑License鍙傛暟
+ //License涓彲琚厑璁哥殑鍙傛暟淇℃伅
+ LicenseCheck expectedCheckModel = (LicenseCheck) content.getExtra();
+ //褰撳墠鏈嶅姟鍣ㄧ湡瀹炵殑鍙傛暟淇℃伅
+ LicenseCheck 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
+ */
+ 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鍙傛暟
+ */
+ private LicenseCheck 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 WindowsServerInfos();
+ }
+
+ return abstractServerInfos.getServerInfos();
+ }
+
+ /**
+ * 鏍¢獙褰撳墠鏈嶅姟鍣ㄧ殑IP/Mac鍦板潃鏄惁鍦ㄥ彲琚厑璁哥殑IP鑼冨洿鍐�<br/>
+ * 濡傛灉瀛樺湪IP鍦ㄥ彲琚厑璁哥殑IP/Mac鍦板潃鑼冨洿鍐咃紝鍒欒繑鍥瀟rue
+ */
+ 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绛夛級搴忓垪鍙锋槸鍚﹀湪鍙厑璁歌寖鍥村唴
+ */
+ private boolean checkSerial(String expectedSerial,String serverSerial){
+ if(!Cools.isEmpty(expectedSerial)){
+ if(!Cools.isEmpty(serverSerial)){
+ if(expectedSerial.equals(serverSerial)){
+ return true;
+ }
+ }
+ return false;
+ }else{
+ return true;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/zy/system/entity/license/LicenseCheck.java b/src/main/java/com/zy/system/entity/license/LicenseCheck.java
new file mode 100644
index 0000000..660f818
--- /dev/null
+++ b/src/main/java/com/zy/system/entity/license/LicenseCheck.java
@@ -0,0 +1,45 @@
+package com.zy.system.entity.license;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 鑷畾涔夐渶瑕佹牎楠岀殑License鍙傛暟
+ */
+@Data
+public class LicenseCheck implements Serializable {
+
+ private static final long serialVersionUID = 8600137500316662317L;
+ /**
+ * 鍙鍏佽鐨処P鍦板潃
+ */
+ private List<String> ipAddress;
+
+ /**
+ * 鍙鍏佽鐨凪AC鍦板潃
+ */
+ private List<String> macAddress;
+
+ /**
+ * 鍙鍏佽鐨凜PU搴忓垪鍙�
+ */
+ private String cpuSerial;
+
+ /**
+ * 鍙鍏佽鐨勪富鏉垮簭鍒楀彿
+ */
+ private String mainBoardSerial;
+
+ @Override
+ public String toString() {
+ return "LicenseCheckModel{" +
+ "ipAddress=" + ipAddress +
+ ", macAddress=" + macAddress +
+ ", cpuSerial='" + cpuSerial + '\'' +
+ ", mainBoardSerial='" + mainBoardSerial + '\'' +
+ '}';
+ }
+
+}
diff --git a/src/main/java/com/zy/system/entity/license/LicenseCheckListener.java b/src/main/java/com/zy/system/entity/license/LicenseCheckListener.java
new file mode 100644
index 0000000..139b49d
--- /dev/null
+++ b/src/main/java/com/zy/system/entity/license/LicenseCheckListener.java
@@ -0,0 +1,82 @@
+package com.zy.system.entity.license;
+
+import com.core.common.Cools;
+import de.schlichtherle.license.LicenseContent;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+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;
+
+/**
+ * 鍦ㄩ」鐩惎鍔ㄦ椂瀹夎璇佷功
+ */
+@Component
+public class LicenseCheckListener implements ApplicationListener<ContextRefreshedEvent> {
+ private static Logger logger = LogManager.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){
+ loadLicense();
+ }
+ }
+
+ //鍔犺浇璇佷功
+ public boolean loadLicense() {
+ if(!Cools.isEmpty(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();
+ //瀹夎璇佷功
+ LicenseContent install = licenseVerify.install(param);
+
+ logger.info("++++++++ 璁稿彲璇佸姞杞界粨鏉� ++++++++");
+
+ return install != null;
+ }
+
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/zy/system/entity/license/LicenseCreator.java b/src/main/java/com/zy/system/entity/license/LicenseCreator.java
new file mode 100644
index 0000000..01f2ad1
--- /dev/null
+++ b/src/main/java/com/zy/system/entity/license/LicenseCreator.java
@@ -0,0 +1,86 @@
+package com.zy.system.entity.license;
+
+import de.schlichtherle.license.*;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import javax.security.auth.x500.X500Principal;
+import java.io.File;
+import java.text.MessageFormat;
+import java.util.prefs.Preferences;
+
+/**
+ * License鐢熸垚绫�
+ */
+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璇佷功
+ */
+ 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;
+ }
+ }
+
+ /**
+ * 鍒濆鍖栬瘉涔︾敓鎴愬弬鏁�
+ */
+ 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枃淇℃伅
+ */
+ 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.getLicenseCheck());
+
+ return licenseContent;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/zy/system/entity/license/LicenseCreatorParam.java b/src/main/java/com/zy/system/entity/license/LicenseCreatorParam.java
new file mode 100644
index 0000000..5a3915d
--- /dev/null
+++ b/src/main/java/com/zy/system/entity/license/LicenseCreatorParam.java
@@ -0,0 +1,96 @@
+package com.zy.system.entity.license;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * License鐢熸垚绫婚渶瑕佺殑鍙傛暟
+ */
+@Data
+public class LicenseCreatorParam implements Serializable {
+
+ private static final long serialVersionUID = -7793154252684580872L;
+ /**
+ * 璇佷功subject
+ */
+ private String subject;
+
+ /**
+ * 瀵嗛挜鍒О
+ */
+ private String privateAlias;
+
+ /**
+ * 瀵嗛挜瀵嗙爜锛堥渶瑕佸Ε鍠勪繚绠★紝涓嶈兘璁╀娇鐢ㄨ�呯煡閬擄級
+ */
+ private String keyPass;
+
+ /**
+ * 璁块棶绉橀挜搴撶殑瀵嗙爜
+ */
+ private String storePass;
+
+ /**
+ * 璇佷功鐢熸垚璺緞
+ */
+ private String licensePath;
+
+ /**
+ * 瀵嗛挜搴撳瓨鍌ㄨ矾寰�
+ */
+ private String privateKeysStorePath;
+
+ /**
+ * 璇佷功鐢熸晥鏃堕棿
+ */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date issuedTime = new Date();
+
+ /**
+ * 璇佷功澶辨晥鏃堕棿
+ */
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date expiryTime;
+
+ /**
+ * 鐢ㄦ埛绫诲瀷
+ */
+ private String consumerType = "user";
+
+ /**
+ * 鐢ㄦ埛鏁伴噺
+ */
+ private Integer consumerAmount = 1;
+
+ /**
+ * 鎻忚堪淇℃伅
+ */
+ private String description = "";
+
+ /**
+ * 棰濆鐨勬湇鍔″櫒纭欢鏍¢獙淇℃伅
+ */
+ private LicenseCheck licenseCheck;
+
+ @Override
+ public String toString() {
+ return "LicenseCreatorParam{" +
+ "subject='" + subject + '\'' +
+ ", privateAlias='" + privateAlias + '\'' +
+ ", keyPass='" + keyPass + '\'' +
+ ", storePass='" + storePass + '\'' +
+ ", licensePath='" + licensePath + '\'' +
+ ", privateKeysStorePath='" + privateKeysStorePath + '\'' +
+ ", issuedTime=" + issuedTime +
+ ", expiryTime=" + expiryTime +
+ ", consumerType='" + consumerType + '\'' +
+ ", consumerAmount=" + consumerAmount +
+ ", description='" + description + '\'' +
+ ", licenseCheck=" + licenseCheck +
+ '}';
+ }
+
+}
diff --git a/src/main/java/com/zy/system/entity/license/LicenseManagerHolder.java b/src/main/java/com/zy/system/entity/license/LicenseManagerHolder.java
new file mode 100644
index 0000000..64c6f39
--- /dev/null
+++ b/src/main/java/com/zy/system/entity/license/LicenseManagerHolder.java
@@ -0,0 +1,22 @@
+package com.zy.system.entity.license;
+
+import de.schlichtherle.license.LicenseManager;
+import de.schlichtherle.license.LicenseParam;
+
+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/src/main/java/com/zy/system/entity/license/LicenseVerify.java b/src/main/java/com/zy/system/entity/license/LicenseVerify.java
new file mode 100644
index 0000000..9f91d36
--- /dev/null
+++ b/src/main/java/com/zy/system/entity/license/LicenseVerify.java
@@ -0,0 +1,136 @@
+package com.zy.system.entity.license;
+
+import de.schlichtherle.license.*;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.io.File;
+import java.text.DateFormat;
+import java.text.MessageFormat;
+import java.text.SimpleDateFormat;
+import java.util.prefs.Preferences;
+
+/**
+ * License鏍¢獙绫�
+ */
+public class LicenseVerify {
+ private static Logger logger = LogManager.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璇佷功
+ */
+ public boolean verify(){
+ LicenseManager licenseManager = LicenseManagerHolder.getInstance(null);
+ DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+ if (!updateSystemTime()) {
+ //鏃堕棿鏇存柊澶辫触锛岀郴缁熸椂闂磋鏇存敼
+ return false;
+ }
+
+ //2. 鏍¢獙璇佷功
+ try {
+ LicenseContent licenseContent = licenseManager.verify();
+// System.out.println(licenseContent.getSubject());
+
+ logger.info(MessageFormat.format("璁稿彲璇佹牎楠岄�氳繃锛岃鍙瘉鏈夋晥鏈燂細{0} - {1}",format.format(licenseContent.getNotBefore()),format.format(licenseContent.getNotAfter())));
+ return true;
+ }catch (Exception e){
+ logger.error("璁稿彲璇佹牎楠屽け璐ワ紒",e);
+ return false;
+ }
+ }
+
+ /**
+ * 鏍¢獙License璇佷功骞惰幏鍙栬瘉涔︿俊鎭�
+ */
+ public LicenseContent getVerifyInfo(){
+ LicenseManager licenseManager = LicenseManagerHolder.getInstance(null);
+
+ if (!updateSystemTime()) {
+ //鏃堕棿鏇存柊澶辫触锛岀郴缁熸椂闂磋鏇存敼
+ return null;
+ }
+
+ //鏍¢獙璇佷功
+ try {
+ LicenseContent licenseContent = licenseManager.verify();
+ return licenseContent;
+ }catch (Exception e){
+ logger.error("璁稿彲璇佹牎楠屽け璐ワ紒",e);
+ return null;
+ }
+ }
+
+ /**
+ * 鍒濆鍖栬瘉涔︾敓鎴愬弬鏁�
+ * @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);
+ }
+
+ /**
+ * 鏇存柊鏃堕棿鍒版敞鍐岃〃涓�
+ */
+ private boolean updateSystemTime() {
+ // 鑾峰彇鐢ㄦ埛鏍硅妭鐐�
+ Preferences userRoot = Preferences.userRoot();
+ // 鑾峰彇鎸囧畾璺緞涓嬬殑鑺傜偣
+ Preferences node = userRoot.node("/zhongyang");
+ String key = "time";
+ // 璇诲彇娉ㄥ唽琛�
+ String value = node.get(key, null);
+ if (value != null) {
+ long originTime = Long.parseLong(value);
+ long now = System.currentTimeMillis();
+ long diff = now - originTime;//鐜板湪鏃堕棿 - 婧愭椂闂� = 鏃堕棿宸�
+ if (diff > 0) {
+ //鏃堕棿宸ぇ浜�0鎵嶅厑璁告洿鏂版敞鍐岃〃鏃堕棿
+ node.put(key, String.valueOf(System.currentTimeMillis()));
+ return true;
+ }
+ }else {
+ // 鍐欏叆娉ㄥ唽琛�
+ node.put(key, String.valueOf(System.currentTimeMillis()));
+ return true;
+ }
+ return false;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/zy/system/entity/license/LicenseVerifyParam.java b/src/main/java/com/zy/system/entity/license/LicenseVerifyParam.java
new file mode 100644
index 0000000..33806e5
--- /dev/null
+++ b/src/main/java/com/zy/system/entity/license/LicenseVerifyParam.java
@@ -0,0 +1,48 @@
+package com.zy.system.entity.license;
+
+import lombok.Data;
+
+/**
+ * 鏍¢獙绛惧悕鏂囦欢
+ */
+@Data
+public class LicenseVerifyParam {
+
+ /**
+ * 璇佷功subject
+ */
+ private String subject;
+
+ /**
+ * 鍏挜鍒О
+ */
+ private String publicAlias;
+
+ /**
+ * 璁块棶鍏挜搴撶殑瀵嗙爜
+ */
+ private String storePass;
+
+ /**
+ * 璇佷功鐢熸垚璺緞
+ */
+ private String licensePath;
+
+ /**
+ * 瀵嗛挜搴撳瓨鍌ㄨ矾寰�
+ */
+ private String publicKeysStorePath;
+
+ public LicenseVerifyParam() {
+
+ }
+
+ public LicenseVerifyParam(String subject, String publicAlias, String storePass, String licensePath, String publicKeysStorePath) {
+ this.subject = subject;
+ this.publicAlias = publicAlias;
+ this.storePass = storePass;
+ this.licensePath = licensePath;
+ this.publicKeysStorePath = publicKeysStorePath;
+ }
+
+}
diff --git a/src/main/java/com/zy/system/entity/license/WindowsServerInfos.java b/src/main/java/com/zy/system/entity/license/WindowsServerInfos.java
new file mode 100644
index 0000000..c575e6d
--- /dev/null
+++ b/src/main/java/com/zy/system/entity/license/WindowsServerInfos.java
@@ -0,0 +1,85 @@
+package com.zy.system.entity.license;
+
+import java.net.InetAddress;
+import java.util.List;
+import java.util.Scanner;
+import java.util.stream.Collectors;
+
+/**
+ * 鐢ㄤ簬鑾峰彇瀹㈡埛Windows鏈嶅姟鍣ㄧ殑鍩烘湰淇℃伅
+ */
+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/src/main/resources/application.yml b/src/main/resources/application.yml
index e482094..6eea873 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -42,6 +42,14 @@
swagger:
enable: false
+#License鐩稿叧閰嶇疆
+license:
+ subject: tzskasrs
+ publicAlias: publicCert
+ storePass: public_zhongyang_123456789
+ licensePath: D:/license/license.lic
+ publicKeysStorePath: D:/license/publicCerts.keystore
+
# 涓嬩綅鏈洪厤缃�
wcs-slave:
# 鍙屾繁
diff --git a/src/main/webapp/views/home/easy_login.html b/src/main/webapp/views/home/easy_login.html
new file mode 100644
index 0000000..2b79fdc
--- /dev/null
+++ b/src/main/webapp/views/home/easy_login.html
@@ -0,0 +1,182 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <title>娴欐睙涓壃 鈹� login of zoneyung wms</title>
+ <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1">
+ <meta name="description" content="study of Instancing with three.js">
+ <meta name="keywords" content="undefined, Yoichi Kobayashi, WebGL, three.js">
+ <meta name="theme-color" content="#111111">
+ <meta name="msapplication-TileImage" content="/sketch-threejs/img/common/ms_tileimage.png">
+ <meta name="msapplication-TileColor" content="#111111">
+ <link rel="stylesheet" href="../static/css/font/font-awesome-4.7.0/css/font-awesome.css">
+ <link rel="stylesheet" href="../static/css/main.min.css">
+ <link rel="stylesheet" href="../static/css/login.css">
+ <style>
+ #sidebar{
+ /*瀹氫綅*/
+ position: absolute;
+ top: 50%;
+ right: 1%;
+ transform: translateY(-50%);
+ width: 20%;
+ height: 95%;
+ /*鐗规晥*/
+ background: rgba(255,255,255,0.6);
+ border-radius: 5px;
+ color: #ffffff;
+ z-index: 99;
+ box-shadow: 3px 3px 6px 3px rgba(0, 0, 0, .3);
+ }
+
+ .login-contain {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ }
+ .login-box {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 100%;
+ text-align: center;
+ }
+
+ </style>
+ </head>
+ <body>
+ <!-- 渚ц竟鏍� -->
+ <div id="sidebar">
+ <div class="login-contain">
+ <div class="login-box">
+ <img src="../static/image/logo.png" alt="" style="width: 80%">
+<!-- <span class="login100-form-title p-t-20 p-b-45">涓壃绔嬪簱</span>-->
+<!-- <span class="login100-form-title p-t-20 p-b-45" style="margin: 15px 0;color: #868686;font-size: 24px">WMS</span>-->
+ <div class="wrap-input100 validate-input m-b-10" data-validate="璇疯緭鍏ョ敤鎴峰悕">
+ <input id="username" class="input100" type="text" name="username" placeholder="username" autocomplete="off">
+ <span class="focus-input100"></span>
+ <span class="symbol-input100">
+ <i class="fa fa-user"></i>
+ </span>
+ </div>
+ <div class="wrap-input100 validate-input m-b-10" data-validate="璇疯緭鍏ュ瘑鐮�">
+ <input id="password" class="input100" type="password" name="pass" placeholder="password">
+ <span class="focus-input100"></span>
+ <span class="symbol-input100">
+ <i class="fa fa-lock"></i>
+ </span>
+ </div>
+ <div class="container-login100-form-btn p-t-10">
+ <button class="login100-form-btn login-btn">Login</button>
+ </div>
+ <div class="container-login100-form-btn p-t-10" style="display: none;margin-top: 50px;" id="updateLicense">
+ <form enctype="multipart/form-data" style="display: none;">
+ <input id="license" type="file" name="file" >
+ </form>
+ <button class="login100-form-btn" id="submitLicense">鏇存柊璁稿彲璇�</button>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <script type="text/javascript" src="../../static/js/tools/main.min.js"></script>
+ <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script>
+ <script type="text/javascript" src="../../static/js/tools/md5.js"></script>
+ <script type="text/javascript" src="../../static/layer/layer.js"></script>
+ <script type="text/javascript" src="../../static/js/common.js"></script>
+ <script>
+ // remember pwd
+ $(function () {
+ var oldUserName = localStorage.getItem('oldUserName');
+ var oldPass = localStorage.getItem('oldPass');
+ if(oldUserName){
+ $('#username').val(oldUserName);
+ }
+ if(oldPass){
+ $('#password').val(oldPass);
+ }
+ })
+
+ window.onload = function(){document.getElementById("username").focus();}
+
+ $(document).on('click','.login-btn', function () {
+ let username = $("#username").val();
+ if (username === "") {
+ layer.tips('璇疯緭鍏ョ櫥褰曡处鍙�', '#username', {tips: [4, '#ff0000']});
+ return;
+ }
+ let password = $("#password").val();
+ if (password === "") {
+ layer.tips('璇疯緭鍏ュ瘑鐮�', '#password', {tips: [4, '#ff0000']});
+ return;
+ }
+ $.ajax({
+ url: baseUrl+"/login.action",
+ data: {
+ username: username,
+ password: hex_md5(password)
+ },
+ method: 'POST',
+ success: function (res) {
+ if (res.code === 200){
+ localStorage.setItem("token", res.data.token);
+ localStorage.setItem("username", res.data.username);
+ window.location.href = "../index.html";
+ } else if (res.code === 10001) {
+ layer.tips(res.msg, '#username', {tips: [4, '#ff0000']});
+ } else if (res.code === 10002) {
+ layer.tips(res.msg, '#username', {tips: [4, '#ff0000']});
+ } else if (res.code === 10003) {
+ layer.tips(res.msg, '#password', {tips: [4, '#ff0000']});
+ } else if (res.code == 20001) {
+ layer.tips(res.msg, '.login-btn', {tips: [3, '#ff0000']});
+ $("#updateLicense").show()
+ } else {
+ layer.tips(res.msg, '.login-btn', {tips: [3, '#ff0000']});
+ }
+ }
+ });
+ });
+
+ $('body').keydown(function () {
+ if (event.keyCode === 13) {
+ $(".login-btn").click();
+ }
+ });
+
+ //鏇存柊璁稿彲璇�
+ $("#submitLicense").on("click",() => {
+ $("#license").click()
+ })
+
+ //涓婁紶骞舵洿鏂拌鍙瘉
+ $("#license").on("change",(evt) => {
+ var files = evt.target.files;
+ let formData = new FormData();
+ formData.append("file", files[0])
+ $.ajax({
+ url: baseUrl+"/license/updateLicense",
+ headers: {'token': localStorage.getItem('token')},
+ data: formData,
+ method: 'POST',
+ cache: false,
+ processData: false,
+ contentType: false,
+ success: function (res) {
+ if (res.code == 200) {
+ layer.msg('鏇存柊鎴愬姛', {time: 1000}, () => {
+ parent.location.reload()
+ });
+ }else{
+ layer.msg(res.msg,{time:2000},() => {
+ parent.location.reload()
+ })
+ }
+ }
+ })
+ })
+ </script>
+ </body>
+</html>
diff --git a/src/main/webapp/views/index.html b/src/main/webapp/views/index.html
index 6d576f4..872d1aa 100644
--- a/src/main/webapp/views/index.html
+++ b/src/main/webapp/views/index.html
@@ -40,8 +40,11 @@
</li>
</ul>
<ul class="layui-nav layui-layout-right">
- <li class="layui-nav-item" lay-unselect>
- <a ew-event="note" title="渚跨"><i class="layui-icon layui-icon-note"></i></a>
+<!-- <li class="layui-nav-item" lay-unselect>-->
+<!-- <a ew-event="note" title="渚跨"><i class="layui-icon layui-icon-note"></i></a>-->
+<!-- </li>-->
+ <li class="layui-nav-item" lay-unselect id="licenseShow" style="display: none;user-select: none;">
+ <div style="color: red;">璁稿彲璇佹湁鏁堟湡锛�<span id="licenseDays">29</span>澶�</div>
</li>
<li class="layui-nav-item layui-hide-xs" lay-unselect>
<a ew-event="fullScreen" title="鍏ㄥ睆"><i class="layui-icon layui-icon-screen-full"></i></a>
@@ -139,6 +142,23 @@
}
});
+ $.ajax({
+ url: baseUrl + "/license/getLicenseDays",
+ headers: {'token': localStorage.getItem('token')},
+ method: 'POST',
+ success: function (res) {
+ if (res.code == 200) {
+ let days = res.data
+ if (days <= 30) {
+ $("#licenseShow").show()
+ $("#licenseDays").html(days)
+ }
+ }else {
+ top.location.href = baseUrl + "/login";
+ }
+ }
+ });
+
// 榛樿鍔犺浇涓婚〉
index.loadHome({
menuPath: baseUrl+'/views/home/navigation.html',
diff --git a/src/main/webapp/views/login.html b/src/main/webapp/views/login.html
index 2a45e5c..a0652d4 100644
--- a/src/main/webapp/views/login.html
+++ b/src/main/webapp/views/login.html
@@ -67,8 +67,8 @@
<div class="login-contain">
<div class="login-box">
<img src="../static/image/logo.png" alt="" style="width: 80%">
- <span class="login100-form-title p-t-20 p-b-45">涓壃绔嬪簱</span>
- <span class="login100-form-title p-t-20 p-b-45" style="margin: 15px 0;color: #868686;font-size: 24px">WMS</span>
+<!-- <span class="login100-form-title p-t-20 p-b-45">涓壃绔嬪簱</span>-->
+<!-- <span class="login100-form-title p-t-20 p-b-45" style="margin: 15px 0;color: #868686;font-size: 24px">WMS</span>-->
<div class="wrap-input100 validate-input m-b-10" data-validate="璇疯緭鍏ョ敤鎴峰悕">
<input id="username" class="input100" type="text" name="username" placeholder="username" autocomplete="off">
<span class="focus-input100"></span>
@@ -85,6 +85,12 @@
</div>
<div class="container-login100-form-btn p-t-10">
<button class="login100-form-btn login-btn">Login</button>
+ </div>
+ <div class="container-login100-form-btn p-t-10" style="display: none;margin-top: 50px;" id="updateLicense">
+ <form enctype="multipart/form-data" style="display: none;">
+ <input id="license" type="file" name="file" >
+ </form>
+ <button class="login100-form-btn" id="submitLicense">鏇存柊璁稿彲璇�</button>
</div>
</div>
</div>
@@ -139,6 +145,9 @@
layer.tips(res.msg, '#username', {tips: [4, '#ff0000']});
} else if (res.code === 10003) {
layer.tips(res.msg, '#password', {tips: [4, '#ff0000']});
+ } else if (res.code == 20001) {
+ layer.tips(res.msg, '.login-btn', {tips: [3, '#ff0000']});
+ $("#updateLicense").show()
} else {
layer.tips(res.msg, '.login-btn', {tips: [3, '#ff0000']});
}
@@ -151,6 +160,38 @@
$(".login-btn").click();
}
});
+
+ //鏇存柊璁稿彲璇�
+ $("#submitLicense").on("click",() => {
+ $("#license").click()
+ })
+
+ //涓婁紶骞舵洿鏂拌鍙瘉
+ $("#license").on("change",(evt) => {
+ var files = evt.target.files;
+ let formData = new FormData();
+ formData.append("file", files[0])
+ $.ajax({
+ url: baseUrl+"/license/updateLicense",
+ headers: {'token': localStorage.getItem('token')},
+ data: formData,
+ method: 'POST',
+ cache: false,
+ processData: false,
+ contentType: false,
+ success: function (res) {
+ if (res.code == 200) {
+ layer.msg('鏇存柊鎴愬姛', {time: 1000}, () => {
+ parent.location.reload()
+ });
+ }else{
+ layer.msg(res.msg,{time:2000},() => {
+ parent.location.reload()
+ })
+ }
+ }
+ })
+ })
</script>
</body>
</html>
--
Gitblit v1.9.1