From ff61738813a553bfbf8f4f1fec6e001e3c8e4415 Mon Sep 17 00:00:00 2001 From: whycq <10027870+whycq@user.noreply.gitee.com> Date: 星期三, 18 十月 2023 15:13:22 +0800 Subject: [PATCH] # 移植台州三凯许可证 --- src/main/java/com/zy/system/controller/LicenseCreatorController.java | 112 ++++++++++++++ src/main/java/com/zy/system/entity/license/LicenseCheckListener.java | 94 +++++++++++ src/main/java/com/zy/common/CodeRes.java | 2 src/main/java/com/zy/common/web/AuthController.java | 7 src/main/resources/publicCerts.keystore | 0 src/main/webapp/views/index.html | 20 ++ pom.xml | 5 src/main/resources/license.lic | 0 src/main/webapp/views/login.html | 41 +++++ src/main/resources/application.yml | 11 + src/main/webapp/views/home/easy_login.html | 182 ++++++++++++++++++++++ 11 files changed, 473 insertions(+), 1 deletions(-) diff --git a/pom.xml b/pom.xml index 925f6ef..06a10cf 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 3249778..23d9266 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 EXIST_500 = "500-宸ヤ綔妗�/搴撳瓨鏉$爜鏁版嵁宸插瓨鍦�"; 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 b4a55a8..f260726 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; @@ -50,6 +51,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..0aafb3b --- /dev/null +++ b/src/main/java/com/zy/system/controller/LicenseCreatorController.java @@ -0,0 +1,112 @@ +package com.zy.system.controller; + +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.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.util.Date; + +/** + * + * 鐢ㄤ簬鐢熸垚璇佷功鏂囦欢锛屼笉鑳芥斁鍦ㄧ粰瀹㈡埛閮ㄧ讲鐨勪唬鐮侀噷 + */ +@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]; + + String licensePathFileName = this.getClass().getClassLoader().getResource(licensePath).getPath(); + File licensePathFile = new File(licensePathFileName); + //鏈嶅姟鍣ㄧ淇濆瓨鐨勬枃浠跺璞� + File serverFile = new File(licensePathFile.getPath()); + 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/LicenseCheckListener.java b/src/main/java/com/zy/system/entity/license/LicenseCheckListener.java new file mode 100644 index 0000000..1659df2 --- /dev/null +++ b/src/main/java/com/zy/system/entity/license/LicenseCheckListener.java @@ -0,0 +1,94 @@ +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; + +import java.io.File; + +/** + * 鍦ㄩ」鐩惎鍔ㄦ椂瀹夎璇佷功 + */ +@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("++++++++ 寮�濮嬪姞杞借鍙瘉 ++++++++"); + + try { + String publicKeysStoreFileName = this.getClass().getClassLoader().getResource(publicKeysStorePath).getPath(); + File publicKeysStoreFile = new File(publicKeysStoreFileName); + + String licensePathFileName = this.getClass().getClassLoader().getResource(licensePath).getPath(); + File licensePathFile = new File(licensePathFileName); + + LicenseVerifyParam param = new LicenseVerifyParam(); + param.setSubject(subject); + param.setPublicAlias(publicAlias); + param.setStorePass(storePass); + param.setLicensePath(licensePathFile.getPath()); + param.setPublicKeysStorePath(publicKeysStoreFile.getPath()); + + LicenseVerify licenseVerify = new LicenseVerify(); + //瀹夎璇佷功 + LicenseContent install = licenseVerify.install(param); + + logger.info("++++++++ 璁稿彲璇佸姞杞界粨鏉� ++++++++"); + + return install != null; + } catch (Exception e) { + return false; + } + } + + return false; + } +} \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 472609e..bf29db8 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -53,4 +53,13 @@ #erp erp: - enable: false \ No newline at end of file + enable: false + + +#License鐩稿叧閰嶇疆 +license: + subject: pswms + publicAlias: publicCert + storePass: public_zhongyang_123456789 + licensePath: license.lic + publicKeysStorePath: publicCerts.keystore \ No newline at end of file diff --git a/src/main/resources/license.lic b/src/main/resources/license.lic new file mode 100644 index 0000000..311b8c9 --- /dev/null +++ b/src/main/resources/license.lic Binary files differ diff --git a/src/main/resources/publicCerts.keystore b/src/main/resources/publicCerts.keystore new file mode 100644 index 0000000..382a874 --- /dev/null +++ b/src/main/resources/publicCerts.keystore Binary files differ 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 60a5625..e3ce393 100644 --- a/src/main/webapp/views/index.html +++ b/src/main/webapp/views/index.html @@ -41,6 +41,9 @@ </li> </ul> <ul class="layui-nav layui-layout-right"> + <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" lay-unselect> <a ew-event="note" title="渚跨"><i class="layui-icon layui-icon-note"></i></a> </li> @@ -140,6 +143,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 dba7bf1..b4c209b 100644 --- a/src/main/webapp/views/login.html +++ b/src/main/webapp/views/login.html @@ -87,6 +87,12 @@ <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> @@ -140,6 +146,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']}); } @@ -152,6 +161,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