From be1cd9e5b30097ca427a9c2b7b054b28854e410a Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期三, 11 三月 2026 13:21:36 +0800
Subject: [PATCH] #
---
src/main/webapp/views/detail.html | 217 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 211 insertions(+), 6 deletions(-)
diff --git a/src/main/webapp/views/detail.html b/src/main/webapp/views/detail.html
index 4985baa..301d6b2 100644
--- a/src/main/webapp/views/detail.html
+++ b/src/main/webapp/views/detail.html
@@ -108,6 +108,65 @@
flex: 0 0 118px;
}
+ .mfa-panel {
+ border: 1px solid rgba(222, 230, 239, 0.92);
+ border-radius: 14px;
+ background: #f8fbff;
+ padding: 14px 16px;
+ }
+
+ .mfa-head {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 12px;
+ margin-bottom: 10px;
+ }
+
+ .mfa-title {
+ font-size: 14px;
+ font-weight: 700;
+ color: #2f4358;
+ }
+
+ .mfa-actions {
+ display: flex;
+ gap: 10px;
+ flex-wrap: wrap;
+ }
+
+ .mfa-meta {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 10px;
+ }
+
+ .mfa-meta-item {
+ padding: 10px 12px;
+ border-radius: 12px;
+ background: rgba(255, 255, 255, 0.95);
+ border: 1px solid rgba(226, 233, 242, 0.96);
+ }
+
+ .mfa-meta-label {
+ font-size: 12px;
+ color: #7b8b9b;
+ margin-bottom: 6px;
+ }
+
+ .mfa-meta-value {
+ font-size: 13px;
+ color: #2f4358;
+ word-break: break-all;
+ }
+
+ .mfa-tip {
+ margin-top: 10px;
+ font-size: 12px;
+ line-height: 1.7;
+ color: #7b8b9b;
+ }
+
.footer-bar {
display: flex;
justify-content: flex-end;
@@ -123,18 +182,21 @@
overflow: hidden;
}
- .password-dialog .el-dialog__header {
+ .password-dialog .el-dialog__header,
+ .mfa-dialog .el-dialog__header {
padding: 18px 20px 12px;
border-bottom: 1px solid rgba(222, 230, 239, 0.92);
background: #f8fbff;
}
- .password-dialog .el-dialog__title {
+ .password-dialog .el-dialog__title,
+ .mfa-dialog .el-dialog__title {
font-weight: 700;
color: var(--text-main);
}
- .password-dialog .el-dialog__body {
+ .password-dialog .el-dialog__body,
+ .mfa-dialog .el-dialog__body {
padding: 18px 20px 12px;
}
@@ -169,18 +231,77 @@
padding-top: 4px;
}
+ .mfa-setup {
+ margin-bottom: 16px;
+ padding: 14px;
+ border-radius: 14px;
+ background: rgba(248, 251, 255, 0.92);
+ border: 1px solid rgba(226, 233, 242, 0.96);
+ }
+
+ .mfa-setup-tip {
+ font-size: 12px;
+ line-height: 1.7;
+ color: #738396;
+ margin-bottom: 12px;
+ }
+
+ .mfa-qr-wrap {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ min-height: 220px;
+ margin-bottom: 14px;
+ background: #fff;
+ border-radius: 14px;
+ border: 1px dashed rgba(210, 220, 233, 0.96);
+ }
+
+ .mfa-qr-wrap img {
+ width: 220px;
+ height: 220px;
+ object-fit: contain;
+ }
+
+ .mfa-secret-row {
+ display: flex;
+ gap: 10px;
+ align-items: center;
+ }
+
+ .mfa-secret-row .el-input {
+ flex: 1;
+ }
+
+ .mfa-footer {
+ display: flex;
+ justify-content: center;
+ gap: 12px;
+ padding-top: 6px;
+ }
+
@media (max-width: 768px) {
.page-shell {
padding: 10px;
}
- .password-row {
+ .password-row,
+ .mfa-secret-row {
flex-direction: column;
align-items: stretch;
}
.form-shell {
max-width: none;
+ }
+
+ .mfa-head {
+ flex-direction: column;
+ align-items: stretch;
+ }
+
+ .mfa-meta {
+ grid-template-columns: 1fr;
}
}
</style>
@@ -194,7 +315,6 @@
<div class="card-body">
<div class="form-shell">
<input id="id" type="hidden" v-model="form.id">
- <input id="password" type="hidden" v-model="form.password">
<el-form
ref="profileForm"
class="profile-form"
@@ -229,6 +349,48 @@
<div class="password-row">
<el-input class="password-mask" value="宸茶缃瘑鐮�" disabled></el-input>
<el-button type="primary" plain icon="el-icon-lock" @click="openPasswordDialog">淇敼瀵嗙爜</el-button>
+ </div>
+ </el-form-item>
+ </el-col>
+ <el-col :xs="24">
+ <el-form-item label="MFA">
+ <div class="mfa-panel">
+ <div class="mfa-head">
+ <div class="mfa-title">澶氬洜瀛愮櫥褰曢獙璇�</div>
+ <div class="mfa-actions">
+ <el-button
+ v-if="Number(form.mfaAllow) === 1 && Number(form.mfaEnabled) !== 1"
+ type="primary"
+ plain
+ icon="el-icon-key"
+ @click="openMfaEnableDialog">鍚敤 MFA</el-button>
+ <el-button
+ v-if="Number(form.mfaEnabled) === 1"
+ type="danger"
+ plain
+ icon="el-icon-switch-button"
+ @click="openMfaDisableDialog">鍋滅敤 MFA</el-button>
+ </div>
+ </div>
+ <div class="mfa-meta">
+ <div class="mfa-meta-item">
+ <div class="mfa-meta-label">璐﹀彿鎺堟潈</div>
+ <div class="mfa-meta-value">{{ form.mfaAllow$ || '--' }}</div>
+ </div>
+ <div class="mfa-meta-item">
+ <div class="mfa-meta-label">鍚敤鐘舵��</div>
+ <div class="mfa-meta-value">{{ form.mfaEnabled$ || '--' }}</div>
+ </div>
+ <div class="mfa-meta-item">
+ <div class="mfa-meta-label">缁戝畾鏃堕棿</div>
+ <div class="mfa-meta-value">{{ form.mfaBoundTime$ || '--' }}</div>
+ </div>
+ </div>
+ <div class="mfa-tip">
+ <span v-if="Number(form.mfaAllow) !== 1">褰撳墠璐﹀彿鏈紑閫� MFA 浣跨敤鏉冮檺锛岃鑱旂郴绠$悊鍛樻巿鏉冦��</span>
+ <span v-else-if="Number(form.mfaEnabled) === 1">宸茬粦瀹氬瘑閽ワ細{{ form.mfaMaskedSecret || '--' }}銆傜櫥褰曟椂闇�瑕佸啀杈撳叆涓�娆″姩鎬侀獙璇佺爜銆�</span>
+ <span v-else>褰撳墠璐﹀彿宸插厑璁镐娇鐢� MFA锛屽惎鐢ㄥ悗鐧诲綍浼氬鍔犱竴娆� 6 浣嶅姩鎬侀獙璇佺爜鏍¢獙銆�</span>
+ </div>
</div>
</el-form-item>
</el-col>
@@ -271,6 +433,49 @@
</div>
</el-form>
</el-dialog>
+
+ <el-dialog
+ class="mfa-dialog"
+ :title="mfaDialogMode === 'enable' ? '鍚敤 MFA' : '鍋滅敤 MFA'"
+ :visible.sync="mfaDialogVisible"
+ width="520px"
+ :close-on-click-modal="false"
+ @close="closeMfaDialog"
+ append-to-body>
+ <div v-if="mfaDialogMode === 'enable'" class="mfa-setup">
+ <div class="mfa-setup-tip">璇峰厛浣跨敤 Google Authenticator銆丮icrosoft Authenticator 绛夎韩浠介獙璇佸櫒鎵弿浜岀淮鐮侊紝鍐嶈緭鍏ュ綋鍓嶅瘑鐮佸拰 6 浣嶅姩鎬佺爜瀹屾垚缁戝畾銆�</div>
+ <div class="mfa-qr-wrap" v-loading="mfaSetupLoading">
+ <img v-if="mfaSetup.qrCode" :src="mfaSetup.qrCode" alt="MFA QR Code">
+ <span v-else>浜岀淮鐮佺敓鎴愪腑...</span>
+ </div>
+ <div class="mfa-secret-row">
+ <el-input :value="mfaSetup.secret" readonly placeholder="MFA瀵嗛挜"></el-input>
+ <el-button plain @click="copySecret">澶嶅埗瀵嗛挜</el-button>
+ </div>
+ </div>
+ <div v-else class="mfa-setup">
+ <div class="mfa-setup-tip">鍋滅敤 MFA 鍓嶏紝璇疯緭鍏ュ綋鍓嶅瘑鐮佸拰韬唤楠岃瘉鍣ㄤ腑鐨� 6 浣嶅姩鎬佺爜杩涜纭銆�</div>
+ </div>
+ <el-form
+ ref="mfaForm"
+ class="password-form"
+ :model="mfaForm"
+ :rules="mfaRules"
+ label-width="112px"
+ size="small"
+ @submit.native.prevent>
+ <el-form-item label="褰撳墠瀵嗙爜" prop="currentPassword">
+ <el-input v-model="mfaForm.currentPassword" type="password" show-password autocomplete="off"></el-input>
+ </el-form-item>
+ <el-form-item label="鍔ㄦ�侀獙璇佺爜" prop="code">
+ <el-input v-model.trim="mfaForm.code" maxlength="6" autocomplete="off" placeholder="璇疯緭鍏�6浣嶉獙璇佺爜"></el-input>
+ </el-form-item>
+ <div class="mfa-footer">
+ <el-button @click="closeMfaDialog">鍏抽棴</el-button>
+ <el-button type="primary" :loading="mfaSubmitting" @click="handleMfaSubmit">淇濆瓨</el-button>
+ </div>
+ </el-form>
+ </el-dialog>
</div>
</body>
<script type="text/javascript" src="../static/js/jquery/jquery-3.3.1.min.js"></script>
@@ -278,5 +483,5 @@
<script type="text/javascript" src="../static/js/common.js"></script>
<script type="text/javascript" src="../static/vue/js/vue.min.js"></script>
<script type="text/javascript" src="../static/vue/element/element.js"></script>
-<script type="text/javascript" src="../static/js/detail/detail.js?v=20260310_detail_vue3"></script>
+<script type="text/javascript" src="../static/js/detail/detail.js?v=20260311_detail_mfa"></script>
</html>
--
Gitblit v1.9.1