#
Junjie
22 小时以前 bd6b518aae61608ddc2d82b43ccc283dc95b9c54
src/main/webapp/views/detail.html
@@ -394,6 +394,47 @@
                                </div>
                            </el-form-item>
                        </el-col>
                        <el-col :xs="24">
                            <el-form-item label="通行密钥">
                                <div class="mfa-panel">
                                    <div class="mfa-head">
                                        <div class="mfa-title">设备生物识别 / 安全密钥登录</div>
                                        <div class="mfa-actions">
                                            <el-button
                                                v-if="!form.passkeyBound"
                                                type="primary"
                                                plain
                                                icon="el-icon-key"
                                                @click="openPasskeyRegisterDialog">绑定通行密钥</el-button>
                                            <el-button
                                                v-else
                                                type="danger"
                                                plain
                                                icon="el-icon-delete"
                                                @click="openPasskeyRemoveDialog">解绑通行密钥</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.passkeyBound ? '已绑定' : '未绑定' }}</div>
                                        </div>
                                        <div class="mfa-meta-item">
                                            <div class="mfa-meta-label">显示名称</div>
                                            <div class="mfa-meta-value">{{ form.passkeyName || '--' }}</div>
                                        </div>
                                        <div class="mfa-meta-item">
                                            <div class="mfa-meta-label">绑定时间</div>
                                            <div class="mfa-meta-value">{{ form.passkeyBoundTime$ || '--' }}</div>
                                        </div>
                                    </div>
                                    <div class="mfa-tip">
                                        <span v-if="form.passkeyBound">最近使用:{{ form.passkeyLastUsedTime$ || '--' }}</span>
                                        <span v-else>绑定后可直接使用设备指纹、人脸或安全密钥登录。该能力要求浏览器支持通行密钥,且系统以 HTTPS 或 localhost 打开。</span>
                                    </div>
                                </div>
                            </el-form-item>
                        </el-col>
                    </el-row>
                    <div class="footer-bar">
                        <el-button type="primary" :loading="saving" @click="handleSave">确认修改</el-button>
@@ -476,12 +517,46 @@
            </div>
        </el-form>
    </el-dialog>
    <el-dialog
        class="mfa-dialog"
        :title="passkeyDialogMode === 'register' ? '绑定通行密钥' : '解绑通行密钥'"
        :visible.sync="passkeyDialogVisible"
        width="520px"
        :close-on-click-modal="false"
        @close="closePasskeyDialog"
        append-to-body>
        <div class="mfa-setup">
            <div v-if="passkeyDialogMode === 'register'" class="mfa-setup-tip">绑定时会弹出系统级身份验证窗口,请使用当前设备的人脸、指纹、PIN 或安全密钥完成确认。若浏览器或环境不支持,无法启用该能力。</div>
            <div v-else class="mfa-setup-tip">解绑前请输入当前密码确认。解绑后将不能再用当前通行密钥直接登录。</div>
        </div>
        <el-form
            ref="passkeyForm"
            class="password-form"
            :model="passkeyForm"
            :rules="passkeyRules"
            label-width="112px"
            size="small"
            @submit.native.prevent>
            <el-form-item v-if="passkeyDialogMode === 'register'" label="显示名称" prop="name">
                <el-input v-model.trim="passkeyForm.name" maxlength="100" autocomplete="off" placeholder="例如:办公室电脑"></el-input>
            </el-form-item>
            <el-form-item label="当前密码" prop="currentPassword">
                <el-input v-model="passkeyForm.currentPassword" type="password" show-password autocomplete="off"></el-input>
            </el-form-item>
            <div class="mfa-footer">
                <el-button @click="closePasskeyDialog">关闭</el-button>
                <el-button type="primary" :loading="passkeySubmitting" @click="handlePasskeySubmit">保存</el-button>
            </div>
        </el-form>
    </el-dialog>
</div>
</body>
<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/js/common.js"></script>
<script type="text/javascript" src="../static/js/webauthn-utils.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=20260311_detail_mfa"></script>
<script type="text/javascript" src="../static/js/detail/detail.js?v=20260311_detail_passkey"></script>
</html>