From bcfa42da27aa99ac2673892499b697cc415dcaa7 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期日, 29 三月 2026 17:59:13 +0800
Subject: [PATCH] #
---
src/main/webapp/static/js/login/login.js | 176 ++++++++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 145 insertions(+), 31 deletions(-)
diff --git a/src/main/webapp/static/js/login/login.js b/src/main/webapp/static/js/login/login.js
index 6365e4c..2fb1a1b 100644
--- a/src/main/webapp/static/js/login/login.js
+++ b/src/main/webapp/static/js/login/login.js
@@ -11,6 +11,7 @@
localeOptions: [],
currentLocale: "zh-CN",
loginLoading: false,
+ passkeyLoading: false,
mfaLoading: false,
toolsDialogVisible: false,
textDialogVisible: false,
@@ -69,19 +70,50 @@
var localeTick = this.localeTick;
void localeTick;
if (window.WCS_I18N && typeof window.WCS_I18N.t === "function") {
- return window.WCS_I18N.t(key);
+ var translated = window.WCS_I18N.t(key);
+ if (translated && translated !== key) {
+ return translated;
+ }
}
return fallback || key;
+ },
+ refreshRuleMessages: function () {
+ var vm = this;
+ vm.loginRules = {
+ mobile: [
+ { required: true, message: vm.text("login.validation.usernameRequired", "璇疯緭鍏ヨ处鍙�"), trigger: "blur" }
+ ],
+ password: [
+ { required: true, message: vm.text("login.validation.passwordRequired", "璇疯緭鍏ュ瘑鐮�"), trigger: "blur" }
+ ]
+ };
+ vm.mfaRules = {
+ code: [
+ { required: true, message: vm.text("login.validation.mfaRequired", "璇疯緭鍏�6浣嶉獙璇佺爜"), trigger: "blur" },
+ {
+ validator: function (rule, value, callback) {
+ if (!/^\d{6}$/.test(String(value || "").trim())) {
+ callback(new Error(vm.text("login.validation.mfaInvalid", "璇疯緭鍏�6浣嶆暟瀛楅獙璇佺爜")));
+ return;
+ }
+ callback();
+ },
+ trigger: "blur"
+ }
+ ]
+ };
},
initLanguageSwitch: function () {
var vm = this;
if (!window.WCS_I18N || typeof window.WCS_I18N.onReady !== "function") {
+ vm.refreshRuleMessages();
return;
}
window.WCS_I18N.onReady(function (i18n) {
vm.localeOptions = i18n.getLocaleOptions();
vm.currentLocale = i18n.getLocale();
document.title = i18n.t("login.title");
+ vm.refreshRuleMessages();
vm.localeTick++;
});
},
@@ -121,6 +153,33 @@
return true;
});
},
+ handlePasskeyLogin: function () {
+ var vm = this;
+ if (!window.WCS_WEBAUTHN || !window.WCS_WEBAUTHN.isSupported()) {
+ vm.$message.error(vm.resolvePasskeyErrorMessage({ message: window.isSecureContext ? "not-supported" : "secure-context" }, "login.error.passkeyOptionsFailed", "鑾峰彇閫氳瀵嗛挜鐧诲綍鍙傛暟澶辫触"));
+ return;
+ }
+ vm.passkeyLoading = true;
+ ajaxJson({
+ url: baseUrl + "/login/passkey/options.action",
+ data: {
+ mobile: vm.loginForm.mobile
+ },
+ method: "POST",
+ success: function (res) {
+ if (Number(res.code) !== 200) {
+ vm.passkeyLoading = false;
+ vm.$message.error(res.msg || vm.text("login.error.passkeyOptionsFailed", "鑾峰彇閫氳瀵嗛挜鐧诲綍鍙傛暟澶辫触"));
+ return;
+ }
+ vm.executePasskeyLogin(res.data || {});
+ },
+ error: function () {
+ vm.passkeyLoading = false;
+ vm.$message.error(vm.text("login.error.passkeyOptionsFailed", "鑾峰彇閫氳瀵嗛挜鐧诲綍鍙傛暟澶辫触"));
+ }
+ });
+ },
submitLogin: function () {
var vm = this;
vm.loginLoading = true;
@@ -138,13 +197,13 @@
vm.openMfaDialog(payload);
return;
}
- vm.finishLogin(payload);
- return;
- }
- vm.$message.error(res.msg || "鐧诲綍澶辫触");
+ vm.finishLogin(payload);
+ return;
+ }
+ vm.$message.error(res.msg || vm.text("login.error.loginFailed", "鐧诲綍澶辫触"));
},
error: function () {
- vm.$message.error("鐧诲綍澶辫触");
+ vm.$message.error(vm.text("login.error.loginFailed", "鐧诲綍澶辫触"));
},
complete: function () {
vm.loginLoading = false;
@@ -192,7 +251,7 @@
submitMfaLogin: function () {
var vm = this;
if (!vm.mfaPending.ticket) {
- vm.$message.error("鐧诲綍绁ㄦ嵁宸插け鏁堬紝璇烽噸鏂扮櫥褰�");
+ vm.$message.error(vm.text("login.error.mfaTicketExpired", "鐧诲綍绁ㄦ嵁宸插け鏁堬紝璇烽噸鏂扮櫥褰�"));
vm.closeMfaDialog();
return;
}
@@ -209,14 +268,46 @@
vm.finishLogin(res.data || {});
return;
}
- vm.$message.error(res.msg || "楠岃瘉澶辫触");
+ vm.$message.error(res.msg || vm.text("login.error.mfaFailed", "楠岃瘉澶辫触"));
},
error: function () {
- vm.$message.error("楠岃瘉澶辫触");
+ vm.$message.error(vm.text("login.error.mfaFailed", "楠岃瘉澶辫触"));
},
complete: function () {
vm.mfaLoading = false;
}
+ });
+ },
+ executePasskeyLogin: function (payload) {
+ var vm = this;
+ window.WCS_WEBAUTHN.authenticate(payload).then(function (assertion) {
+ ajaxJson({
+ url: baseUrl + "/login/passkey/verify.action",
+ data: {
+ ticket: payload.ticket,
+ credentialId: assertion.credentialId,
+ clientDataJSON: assertion.clientDataJSON,
+ authenticatorData: assertion.authenticatorData,
+ signature: assertion.signature
+ },
+ method: "POST",
+ success: function (res) {
+ if (Number(res.code) === 200) {
+ vm.finishLogin(res.data || {});
+ return;
+ }
+ vm.$message.error(res.msg || vm.text("login.error.passkeyVerifyFailed", "閫氳瀵嗛挜楠岃瘉澶辫触"));
+ },
+ error: function () {
+ vm.$message.error(vm.text("login.error.passkeyVerifyFailed", "閫氳瀵嗛挜楠岃瘉澶辫触"));
+ },
+ complete: function () {
+ vm.passkeyLoading = false;
+ }
+ });
+ }).catch(function (err) {
+ vm.passkeyLoading = false;
+ vm.$message.error(vm.resolvePasskeyErrorMessage(err, "login.error.passkeyVerifyFailed", "閫氳瀵嗛挜楠岃瘉澶辫触"));
});
},
finishLogin: function (payload) {
@@ -224,6 +315,19 @@
localStorage.setItem("username", payload.username || this.loginForm.mobile || "");
this.closeMfaDialog();
window.location.href = "index.html";
+ },
+ resolvePasskeyErrorMessage: function (err, fallbackKey, fallbackText) {
+ var message = err && err.message ? String(err.message) : "";
+ if (message === "secure-context") {
+ return this.text("login.passkey.secureContext", "閫氳瀵嗛挜浠呮敮鎸佸湪 HTTPS 鎴� localhost 鐜涓嬩娇鐢�");
+ }
+ if (message === "not-supported" || message === "extension-unsupported" || message === "public-key-missing") {
+ return this.text("login.passkey.browserUnsupported", "褰撳墠娴忚鍣ㄤ笉鏀寔閫氳瀵嗛挜锛岃浣跨敤鏈�鏂扮増 Chrome銆丒dge 鎴� Safari");
+ }
+ if (err && err.name === "NotAllowedError") {
+ return this.text(fallbackKey, fallbackText);
+ }
+ return this.text(fallbackKey, fallbackText);
},
openTextDialog: function (title, label, text, tip) {
var pretty = "";
@@ -250,9 +354,9 @@
textarea.select();
document.execCommand("copy");
document.body.removeChild(textarea);
- this.$message.success("宸插鍒跺埌鍓创鏉�");
+ this.$message.success(this.text("login.dialog.copied", "宸插鍒跺埌鍓创鏉�"));
} catch (err) {
- this.$message.error("澶嶅埗澶辫触");
+ this.$message.error(this.text("login.dialog.copyFailed", "澶嶅埗澶辫触"));
}
},
copyText: function () {
@@ -260,7 +364,7 @@
var text = vm.textDialog.text || "";
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(function () {
- vm.$message.success("宸插鍒跺埌鍓创鏉�");
+ vm.$message.success(vm.text("login.dialog.copied", "宸插鍒跺埌鍓创鏉�"));
}).catch(function () {
vm.fallbackCopy(text);
});
@@ -275,13 +379,18 @@
method: "GET",
success: function (res) {
if (Number(res.code) === 200) {
- vm.openTextDialog("鑾峰彇璇锋眰鐮�", "璇锋眰鐮�", res.msg || "", "璇锋眰鐮佷腑宸插寘鍚」鐩悕绉帮紝鐩存帴鍙戠粰璁稿彲璇佹湇鍔$鍗冲彲銆�");
+ vm.openTextDialog(
+ vm.text("login.requestCode.title", "鑾峰彇璇锋眰鐮�"),
+ vm.text("login.requestCode.label", "璇锋眰鐮�"),
+ res.msg || "",
+ vm.text("login.requestCode.tip", "璇锋眰鐮佷腑宸插寘鍚」鐩悕绉帮紝鐩存帴鍙戠粰璁稿彲璇佹湇鍔$鍗冲彲銆�")
+ );
return;
}
- vm.$message.error(res.msg || "鑾峰彇璇锋眰鐮佸け璐�");
+ vm.$message.error(res.msg || vm.text("login.error.requestCodeFailed", "鑾峰彇璇锋眰鐮佸け璐�"));
},
error: function () {
- vm.$message.error("鑾峰彇璇锋眰鐮佸け璐�");
+ vm.$message.error(vm.text("login.error.requestCodeFailed", "鑾峰彇璇锋眰鐮佸け璐�"));
}
});
},
@@ -291,17 +400,22 @@
url: baseUrl + "/license/getServerInfos",
method: "GET",
success: function (res) {
- vm.openTextDialog("鑾峰彇绯荤粺閰嶇疆", "绯荤粺閰嶇疆淇℃伅", res, "鑰侀」鐩粛鍙户缁娇鐢ㄨ繖浠界‖浠朵俊鎭� JSON 鐢宠璁稿彲璇併��");
+ vm.openTextDialog(
+ vm.text("login.serverInfo.title", "鑾峰彇绯荤粺閰嶇疆"),
+ vm.text("login.serverInfo.label", "绯荤粺閰嶇疆淇℃伅"),
+ res,
+ vm.text("login.serverInfo.tip", "鑰侀」鐩粛鍙户缁娇鐢ㄨ繖浠界‖浠朵俊鎭� JSON 鐢宠璁稿彲璇併��")
+ );
},
error: function () {
- vm.$message.error("鑾峰彇绯荤粺閰嶇疆淇℃伅澶辫触");
+ vm.$message.error(vm.text("login.error.serverInfoFailed", "鑾峰彇绯荤粺閰嶇疆淇℃伅澶辫触"));
}
});
},
submitLicense: function () {
var vm = this;
if (!vm.licenseBase64) {
- vm.$message.warning("璁稿彲璇佸唴瀹逛笉鑳戒负绌�");
+ vm.$message.warning(vm.text("login.error.licenseEmpty", "璁稿彲璇佸唴瀹逛笉鑳戒负绌�"));
return;
}
ajaxJson({
@@ -313,35 +427,35 @@
if (Number(res.code) === 200) {
vm.uploadDialogVisible = false;
vm.licenseBase64 = "";
- vm.$message.success("璁稿彲璇佹洿鏂版垚鍔�");
+ vm.$message.success(vm.text("login.license.success", "璁稿彲璇佹洿鏂版垚鍔�"));
return;
}
- vm.$message.error(res.msg || "璁稿彲璇佹洿鏂板け璐�");
+ vm.$message.error(res.msg || vm.text("login.error.licenseUpdateFailed", "璁稿彲璇佹洿鏂板け璐�"));
},
error: function () {
- vm.$message.error("璁稿彲璇佸綍鍏ュけ璐�");
+ vm.$message.error(vm.text("login.error.licenseImportFailed", "璁稿彲璇佸綍鍏ュけ璐�"));
}
});
},
activateLicense: function () {
var vm = this;
- vm.$confirm("纭畾鎵ц涓�閿縺娲诲悧锛�", "鎻愮ず", {
+ vm.$confirm(vm.text("login.activate.confirm", "纭畾鎵ц涓�閿縺娲诲悧锛�"), vm.text("common.prompt", "鎻愮ず"), {
type: "warning",
- confirmButtonText: "纭畾",
- cancelButtonText: "鍙栨秷"
+ confirmButtonText: vm.text("common.ok", "纭畾"),
+ cancelButtonText: vm.text("login.mfa.cancel", "鍙栨秷")
}).then(function () {
ajaxJson({
url: baseUrl + "/license/activate",
method: "POST",
success: function (res) {
if (Number(res.code) === 200) {
- vm.$message.success("婵�娲绘垚鍔�");
+ vm.$message.success(vm.text("login.activate.success", "婵�娲绘垚鍔�"));
return;
}
- vm.$message.error(res.msg || "婵�娲诲け璐�");
+ vm.$message.error(res.msg || vm.text("login.activate.failed", "婵�娲诲け璐�"));
},
error: function () {
- vm.$message.error("婵�娲诲け璐�");
+ vm.$message.error(vm.text("login.activate.failed", "婵�娲诲け璐�"));
}
});
}).catch(function () {
@@ -354,15 +468,15 @@
method: "GET",
success: function (res) {
if (Number(res.code) === 200) {
- vm.$alert(res.msg || "", "椤圭洰鍚嶇О", {
- confirmButtonText: "纭畾"
+ vm.$alert(res.msg || "", vm.text("login.projectName.title", "椤圭洰鍚嶇О"), {
+ confirmButtonText: vm.text("common.ok", "纭畾")
});
return;
}
- vm.$message.error(res.msg || "鑾峰彇椤圭洰鍚嶇О澶辫触");
+ vm.$message.error(res.msg || vm.text("login.error.projectNameFailed", "鑾峰彇椤圭洰鍚嶇О澶辫触"));
},
error: function () {
- vm.$message.error("鑾峰彇椤圭洰鍚嶇О澶辫触");
+ vm.$message.error(vm.text("login.error.projectNameFailed", "鑾峰彇椤圭洰鍚嶇О澶辫触"));
}
});
}
--
Gitblit v1.9.1