From ab6dd7555377d0d5fe3a78149c0cdb98e2f15275 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期三, 11 三月 2026 13:38:51 +0800
Subject: [PATCH] #
---
src/main/resources/i18n/zh-CN/messages.properties | 40 ++++++++++
src/main/resources/i18n/en-US/messages.properties | 40 ++++++++++
src/main/webapp/views/login.html | 53 ++++++-------
src/main/webapp/static/js/login/login.js | 103 ++++++++++++++++++-------
4 files changed, 177 insertions(+), 59 deletions(-)
diff --git a/src/main/resources/i18n/en-US/messages.properties b/src/main/resources/i18n/en-US/messages.properties
index aeedcc1..2d7e9ec 100644
--- a/src/main/resources/i18n/en-US/messages.properties
+++ b/src/main/resources/i18n/en-US/messages.properties
@@ -16,6 +16,17 @@
common.workPage=Work Page
common.businessPage=Business Page
login.title=WCS System V3.0
+login.subtitle=Please enter your account and password to access the system.
+login.hero.title=The WCS keeps device scheduling, task execution, and on-site monitoring within the same business workflow.
+login.hero.subtitle=The Warehouse Control System is built for automated AS/RS execution, coordinating cranes, RGVs, conveyor stations, task commands, location status, and log tracing through unified dispatch and visualization. It helps warehouse operations stay stable, traceable, and collaborative. Zhejiang Zhongyang Warehouse Technology Co., Ltd. focuses on automated AS/RS and intelligent intralogistics systems, covering solution design, software control, equipment integration, and project delivery.
+login.hero.metric.dispatch.title=Dispatch
+login.hero.metric.dispatch.desc=Unified orchestration of on-site execution tasks
+login.hero.metric.trace.title=Traceability
+login.hero.metric.trace.desc=End-to-end traceability across jobs, devices, and logs
+login.hero.metric.integration.title=Integration
+login.hero.metric.integration.desc=Integrates WMS, devices, and business rules
+login.hero.company.name=Zhejiang Zhongyang Warehouse Technology Co., Ltd.
+login.hero.company.solution=Automated AS/RS and intelligent logistics system solutions
login.username=Account
login.password=Password
login.submit=Sign In
@@ -37,6 +48,35 @@
login.serverInfo.title=System Configuration
login.serverInfo.label=System Configuration
login.serverInfo.tip=Legacy projects can still use this hardware JSON to apply for a license.
+login.dialog.close=Close
+login.mfa.title=MFA Verification
+login.mfa.tip=Account and password verified. Enter the 6-digit code from your authenticator app to continue signing in.
+login.mfa.currentAccount=Current account:
+login.mfa.codeLabel=Verification Code
+login.mfa.codePlaceholder=Please enter the 6-digit code
+login.mfa.cancel=Cancel
+login.mfa.submit=Verify and Sign In
+login.license.label=License Base64
+login.license.tip=Paste the full license field returned by the license service here.
+login.license.submit=Submit
+login.license.success=License updated successfully
+login.validation.usernameRequired=Please enter the account
+login.validation.passwordRequired=Please enter the password
+login.validation.mfaRequired=Please enter the 6-digit verification code
+login.validation.mfaInvalid=Please enter a 6-digit numeric verification code
+login.error.loginFailed=Login failed
+login.error.mfaTicketExpired=The login ticket has expired. Please sign in again
+login.error.mfaFailed=Verification failed
+login.error.requestCodeFailed=Failed to get request code
+login.error.serverInfoFailed=Failed to get system configuration
+login.error.licenseEmpty=License content cannot be empty
+login.error.licenseUpdateFailed=Failed to update license
+login.error.licenseImportFailed=Failed to import license
+login.activate.confirm=Are you sure you want to activate now?
+login.activate.success=Activation successful
+login.activate.failed=Activation failed
+login.projectName.title=Project Name
+login.error.projectNameFailed=Failed to get project name
index.searchMenu=Search menu
index.noMatchedMenu=No matching menus
index.noAvailableMenu=No available menus for current account
diff --git a/src/main/resources/i18n/zh-CN/messages.properties b/src/main/resources/i18n/zh-CN/messages.properties
index 19a8d5d..3c465bd 100644
--- a/src/main/resources/i18n/zh-CN/messages.properties
+++ b/src/main/resources/i18n/zh-CN/messages.properties
@@ -16,6 +16,17 @@
common.workPage=宸ヤ綔椤甸潰
common.businessPage=涓氬姟椤甸潰
login.title=WCS绯荤粺V3.0
+login.subtitle=璇疯緭鍏ヨ处鍙峰拰瀵嗙爜杩涘叆绯荤粺銆�
+login.hero.title=WCS绯荤粺璁╄澶囪皟搴︺�佷换鍔℃墽琛屼笌鐜板満鐩戞帶淇濇寔鍦ㄥ悓涓�濂椾笟鍔¢摼璺腑銆�
+login.hero.subtitle=Warehouse Control System 闈㈠悜鑷姩鍖栫珛浣撲粨搴撶幇鍦烘墽琛屽眰锛屽洿缁曞爢鍨涙満銆丷GV銆佽緭閫佺珯鍙般�佷换鍔℃寚浠ゃ�佸簱浣嶇姸鎬佸拰鏃ュ織杩借釜杩涜缁熶竴璋冨害涓庡彲瑙嗗寲绠$悊锛屽府鍔╀粨鍌ㄧ郴缁熷疄鐜扮ǔ瀹氥�佸彲杩芥函銆佸彲鑱斿姩鐨勪綔涓氭帶鍒躲�傛禉姹熶腑鎵珛搴撴妧鏈湁闄愬叕鍙搁暱鏈熶笓娉ㄤ簬鑷姩鍖栫珛浣撲粨搴撲笌鏅鸿兘鐗╂祦绯荤粺寤鸿锛岃鐩栨柟妗堣璁°�佽蒋浠舵帶鍒躲�佽澶囬泦鎴愪笌椤圭洰瀹炴柦浜や粯銆�
+login.hero.metric.dispatch.title=璋冨害
+login.hero.metric.dispatch.desc=缁熶竴缂栨帓鐜板満鎵ц浠诲姟
+login.hero.metric.trace.title=杩芥函
+login.hero.metric.trace.desc=浣滀笟銆佽澶囥�佹棩蹇楀叏閾捐矾鐣欑棔
+login.hero.metric.integration.title=闆嗘垚
+login.hero.metric.integration.desc=瀵规帴WMS銆佽澶囦笌涓氬姟瑙勫垯
+login.hero.company.name=娴欐睙涓壃绔嬪簱鎶�鏈湁闄愬叕鍙�
+login.hero.company.solution=鑷姩鍖栫珛浣撲粨搴撲笌鏅鸿兘鐗╂祦绯荤粺瑙e喅鏂规
login.username=璐﹀彿
login.password=瀵嗙爜
login.submit=鐧诲綍
@@ -37,6 +48,35 @@
login.serverInfo.title=鑾峰彇绯荤粺閰嶇疆
login.serverInfo.label=绯荤粺閰嶇疆淇℃伅
login.serverInfo.tip=鑰侀」鐩粛鍙户缁娇鐢ㄨ繖浠界‖浠朵俊鎭� JSON 鐢宠璁稿彲璇併��
+login.dialog.close=鍏抽棴
+login.mfa.title=MFA浜屾楠岃瘉
+login.mfa.tip=璐﹀彿瀵嗙爜宸查�氳繃锛岃杈撳叆韬唤楠岃瘉鍣ㄤ腑鐨� 6 浣嶅姩鎬侀獙璇佺爜鍚庣户缁櫥褰曘��
+login.mfa.currentAccount=褰撳墠璐﹀彿锛�
+login.mfa.codeLabel=楠岃瘉鐮�
+login.mfa.codePlaceholder=璇疯緭鍏�6浣嶅姩鎬佺爜
+login.mfa.cancel=鍙栨秷
+login.mfa.submit=楠岃瘉骞剁櫥褰�
+login.license.label=璁稿彲璇� Base64
+login.license.tip=灏嗚鍙瘉鏈嶅姟绔繑鍥炵殑 license 瀛楁瀹屾暣绮樿创鍒拌繖閲屻��
+login.license.submit=鎻愪氦
+login.license.success=璁稿彲璇佹洿鏂版垚鍔�
+login.validation.usernameRequired=璇疯緭鍏ヨ处鍙�
+login.validation.passwordRequired=璇疯緭鍏ュ瘑鐮�
+login.validation.mfaRequired=璇疯緭鍏�6浣嶉獙璇佺爜
+login.validation.mfaInvalid=璇疯緭鍏�6浣嶆暟瀛楅獙璇佺爜
+login.error.loginFailed=鐧诲綍澶辫触
+login.error.mfaTicketExpired=鐧诲綍绁ㄦ嵁宸插け鏁堬紝璇烽噸鏂扮櫥褰�
+login.error.mfaFailed=楠岃瘉澶辫触
+login.error.requestCodeFailed=鑾峰彇璇锋眰鐮佸け璐�
+login.error.serverInfoFailed=鑾峰彇绯荤粺閰嶇疆淇℃伅澶辫触
+login.error.licenseEmpty=璁稿彲璇佸唴瀹逛笉鑳戒负绌�
+login.error.licenseUpdateFailed=璁稿彲璇佹洿鏂板け璐�
+login.error.licenseImportFailed=璁稿彲璇佸綍鍏ュけ璐�
+login.activate.confirm=纭畾鎵ц涓�閿縺娲诲悧锛�
+login.activate.success=婵�娲绘垚鍔�
+login.activate.failed=婵�娲诲け璐�
+login.projectName.title=椤圭洰鍚嶇О
+login.error.projectNameFailed=鑾峰彇椤圭洰鍚嶇О澶辫触
index.searchMenu=鎼滅储鑿滃崟
index.noMatchedMenu=娌℃湁鍖归厤鑿滃崟
index.noAvailableMenu=褰撳墠璐﹀彿娌℃湁鍙敤鑿滃崟
diff --git a/src/main/webapp/static/js/login/login.js b/src/main/webapp/static/js/login/login.js
index 6365e4c..9a7b1d0 100644
--- a/src/main/webapp/static/js/login/login.js
+++ b/src/main/webapp/static/js/login/login.js
@@ -69,19 +69,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++;
});
},
@@ -138,13 +169,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 +223,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,10 +240,10 @@
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;
@@ -250,9 +281,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 +291,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 +306,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 +327,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 +354,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 +395,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", "鑾峰彇椤圭洰鍚嶇О澶辫触"));
}
});
}
diff --git a/src/main/webapp/views/login.html b/src/main/webapp/views/login.html
index 1574206..47918db 100644
--- a/src/main/webapp/views/login.html
+++ b/src/main/webapp/views/login.html
@@ -454,37 +454,34 @@
<div class="login-layout">
<section class="hero-panel animate__animated animate__fadeInLeft">
<div class="brand-chip">Zoneyung WCS</div>
- <div class="hero-title">WCS绯荤粺璁╄澶囪皟搴︺�佷换鍔℃墽琛屼笌鐜板満鐩戞帶淇濇寔鍦ㄥ悓涓�濂椾笟鍔¢摼璺腑銆�</div>
+ <div class="hero-title">{{ text('login.hero.title', 'WCS绯荤粺璁╄澶囪皟搴︺�佷换鍔℃墽琛屼笌鐜板満鐩戞帶淇濇寔鍦ㄥ悓涓�濂椾笟鍔¢摼璺腑銆�') }}</div>
<div class="hero-subtitle">
- Warehouse Control System 闈㈠悜鑷姩鍖栫珛浣撲粨搴撶幇鍦烘墽琛屽眰锛屽洿缁曞爢鍨涙満銆丷GV銆佽緭閫佺珯鍙般�佷换鍔℃寚浠ゃ��
- 搴撲綅鐘舵�佸拰鏃ュ織杩借釜杩涜缁熶竴璋冨害涓庡彲瑙嗗寲绠$悊锛屽府鍔╀粨鍌ㄧ郴缁熷疄鐜扮ǔ瀹氥�佸彲杩芥函銆佸彲鑱斿姩鐨勪綔涓氭帶鍒躲��
- 娴欐睙涓壃绔嬪簱鎶�鏈湁闄愬叕鍙搁暱鏈熶笓娉ㄤ簬鑷姩鍖栫珛浣撲粨搴撲笌鏅鸿兘鐗╂祦绯荤粺寤鸿锛岃鐩栨柟妗堣璁°�佽蒋浠舵帶鍒躲��
- 璁惧闆嗘垚涓庨」鐩疄鏂戒氦浠樸��
+ {{ text('login.hero.subtitle', 'Warehouse Control System 闈㈠悜鑷姩鍖栫珛浣撲粨搴撶幇鍦烘墽琛屽眰锛屽洿缁曞爢鍨涙満銆丷GV銆佽緭閫佺珯鍙般�佷换鍔℃寚浠ゃ�佸簱浣嶇姸鎬佸拰鏃ュ織杩借釜杩涜缁熶竴璋冨害涓庡彲瑙嗗寲绠$悊锛屽府鍔╀粨鍌ㄧ郴缁熷疄鐜扮ǔ瀹氥�佸彲杩芥函銆佸彲鑱斿姩鐨勪綔涓氭帶鍒躲�傛禉姹熶腑鎵珛搴撴妧鏈湁闄愬叕鍙搁暱鏈熶笓娉ㄤ簬鑷姩鍖栫珛浣撲粨搴撲笌鏅鸿兘鐗╂祦绯荤粺寤鸿锛岃鐩栨柟妗堣璁°�佽蒋浠舵帶鍒躲�佽澶囬泦鎴愪笌椤圭洰瀹炴柦浜や粯銆�') }}
</div>
<div class="hero-metrics">
<div class="metric-card">
- <div class="metric-value">璋冨害</div>
- <div class="metric-label">缁熶竴缂栨帓鐜板満鎵ц浠诲姟</div>
+ <div class="metric-value">{{ text('login.hero.metric.dispatch.title', '璋冨害') }}</div>
+ <div class="metric-label">{{ text('login.hero.metric.dispatch.desc', '缁熶竴缂栨帓鐜板満鎵ц浠诲姟') }}</div>
</div>
<div class="metric-card">
- <div class="metric-value">杩芥函</div>
- <div class="metric-label">浣滀笟銆佽澶囥�佹棩蹇楀叏閾捐矾鐣欑棔</div>
+ <div class="metric-value">{{ text('login.hero.metric.trace.title', '杩芥函') }}</div>
+ <div class="metric-label">{{ text('login.hero.metric.trace.desc', '浣滀笟銆佽澶囥�佹棩蹇楀叏閾捐矾鐣欑棔') }}</div>
</div>
<div class="metric-card">
- <div class="metric-value">闆嗘垚</div>
- <div class="metric-label">瀵规帴WMS銆佽澶囦笌涓氬姟瑙勫垯</div>
+ <div class="metric-value">{{ text('login.hero.metric.integration.title', '闆嗘垚') }}</div>
+ <div class="metric-label">{{ text('login.hero.metric.integration.desc', '瀵规帴WMS銆佽澶囦笌涓氬姟瑙勫垯') }}</div>
</div>
</div>
<div class="hero-footer">
- <span>娴欐睙涓壃绔嬪簱鎶�鏈湁闄愬叕鍙�</span>
- <span>鑷姩鍖栫珛浣撲粨搴撲笌鏅鸿兘鐗╂祦绯荤粺瑙e喅鏂规</span>
+ <span>{{ text('login.hero.company.name', '娴欐睙涓壃绔嬪簱鎶�鏈湁闄愬叕鍙�') }}</span>
+ <span>{{ text('login.hero.company.solution', '鑷姩鍖栫珛浣撲粨搴撲笌鏅鸿兘鐗╂祦绯荤粺瑙e喅鏂规') }}</span>
</div>
</section>
<section class="login-card animate__animated animate__fadeInUp">
<div class="login-head">
<h1 class="login-title" @click="handleTitleClick">{{ text('login.title', 'WCS绯荤粺V3.0') }}</h1>
- <div class="login-subtitle">璇疯緭鍏ヨ处鍙峰拰瀵嗙爜杩涘叆绯荤粺銆�</div>
+ <div class="login-subtitle">{{ text('login.subtitle', '璇疯緭鍏ヨ处鍙峰拰瀵嗙爜杩涘叆绯荤粺銆�') }}</div>
</div>
<div class="login-body">
<el-form ref="loginForm" class="login-form" :model="loginForm" :rules="loginRules" @submit.native.prevent>
@@ -506,7 +503,7 @@
</section>
</div>
- <el-dialog class="tools-dialog" title="绯荤粺宸ュ叿" :visible.sync="toolsDialogVisible" width="560px" :close-on-click-modal="true" append-to-body>
+ <el-dialog class="tools-dialog" :title="text('login.tools.title', '绯荤粺宸ュ叿')" :visible.sync="toolsDialogVisible" width="560px" :close-on-click-modal="true" append-to-body>
<div class="tool-group">
<div class="tool-title">{{ text('login.tools.recommended', '鎺ㄨ崘鎿嶄綔') }}</div>
<div class="tool-actions">
@@ -527,22 +524,22 @@
<el-dialog
class="mfa-dialog"
- title="MFA浜屾楠岃瘉"
+ :title="text('login.mfa.title', 'MFA浜屾楠岃瘉')"
:visible.sync="mfaDialogVisible"
width="420px"
:close-on-click-modal="false"
@close="closeMfaDialog"
append-to-body>
- <div class="mfa-tip">璐﹀彿瀵嗙爜宸查�氳繃锛岃杈撳叆韬唤楠岃瘉鍣ㄤ腑鐨� 6 浣嶅姩鎬侀獙璇佺爜鍚庣户缁櫥褰曘��</div>
- <div class="mfa-account">褰撳墠璐﹀彿锛�<strong>{{ mfaPending.username || loginForm.mobile || '--' }}</strong></div>
+ <div class="mfa-tip">{{ text('login.mfa.tip', '璐﹀彿瀵嗙爜宸查�氳繃锛岃杈撳叆韬唤楠岃瘉鍣ㄤ腑鐨� 6 浣嶅姩鎬侀獙璇佺爜鍚庣户缁櫥褰曘��') }}</div>
+ <div class="mfa-account">{{ text('login.mfa.currentAccount', '褰撳墠璐﹀彿锛�') }}<strong>{{ mfaPending.username || loginForm.mobile || '--' }}</strong></div>
<el-form ref="mfaForm" :model="mfaForm" :rules="mfaRules" label-width="82px" size="small" @submit.native.prevent>
- <el-form-item label="楠岃瘉鐮�" prop="code">
- <el-input v-model.trim="mfaForm.code" maxlength="6" placeholder="璇疯緭鍏�6浣嶅姩鎬佺爜" @keyup.enter.native="handleMfaLogin"></el-input>
+ <el-form-item :label="text('login.mfa.codeLabel', '楠岃瘉鐮�')" prop="code">
+ <el-input v-model.trim="mfaForm.code" maxlength="6" :placeholder="text('login.mfa.codePlaceholder', '璇疯緭鍏�6浣嶅姩鎬佺爜')" @keyup.enter.native="handleMfaLogin"></el-input>
</el-form-item>
</el-form>
<div class="mfa-footer">
- <el-button @click="closeMfaDialog">鍙栨秷</el-button>
- <el-button type="primary" :loading="mfaLoading" @click="handleMfaLogin">楠岃瘉骞剁櫥褰�</el-button>
+ <el-button @click="closeMfaDialog">{{ text('login.mfa.cancel', '鍙栨秷') }}</el-button>
+ <el-button type="primary" :loading="mfaLoading" @click="handleMfaLogin">{{ text('login.mfa.submit', '楠岃瘉骞剁櫥褰�') }}</el-button>
</div>
</el-dialog>
@@ -551,18 +548,18 @@
<div v-if="textDialog.tip" class="dialog-text-tip">{{ textDialog.tip }}</div>
<el-input v-model="textDialog.text" type="textarea" :rows="10" readonly></el-input>
<div class="text-footer">
- <el-button @click="textDialogVisible = false">鍏抽棴</el-button>
+ <el-button @click="textDialogVisible = false">{{ text('login.dialog.close', '鍏抽棴') }}</el-button>
<el-button type="primary" @click="copyText">{{ text('copy', '澶嶅埗') }}</el-button>
</div>
</el-dialog>
- <el-dialog class="upload-dialog" title="褰曞叆璁稿彲璇�" :visible.sync="uploadDialogVisible" width="760px" append-to-body>
- <div class="dialog-text-label">璁稿彲璇� Base64</div>
- <div class="dialog-text-tip">灏嗚鍙瘉鏈嶅姟绔繑鍥炵殑 license 瀛楁瀹屾暣绮樿创鍒拌繖閲屻��</div>
+ <el-dialog class="upload-dialog" :title="text('login.tools.uploadLicense', '褰曞叆璁稿彲璇�')" :visible.sync="uploadDialogVisible" width="760px" append-to-body>
+ <div class="dialog-text-label">{{ text('login.license.label', '璁稿彲璇� Base64') }}</div>
+ <div class="dialog-text-tip">{{ text('login.license.tip', '灏嗚鍙瘉鏈嶅姟绔繑鍥炵殑 license 瀛楁瀹屾暣绮樿创鍒拌繖閲屻��') }}</div>
<el-input v-model.trim="licenseBase64" type="textarea" :rows="10"></el-input>
<div class="upload-footer">
- <el-button @click="uploadDialogVisible = false">鍙栨秷</el-button>
- <el-button type="primary" @click="submitLicense">鎻愪氦</el-button>
+ <el-button @click="uploadDialogVisible = false">{{ text('login.mfa.cancel', '鍙栨秷') }}</el-button>
+ <el-button type="primary" @click="submitLicense">{{ text('login.license.submit', '鎻愪氦') }}</el-button>
</div>
</el-dialog>
</div>
--
Gitblit v1.9.1