1.优化谷歌验证器-前端不显示验证器按钮

This commit is contained in:
2026-06-24 16:49:34 +08:00
parent 21def75ef1
commit ceb4386440
4 changed files with 41 additions and 6 deletions

View File

@@ -45,7 +45,7 @@
<!-- 带确认框的按钮 --> <!-- 带确认框的按钮 -->
<el-popconfirm <el-popconfirm
v-if="btn.render == 'confirmButton' && ((btn.name == 'delete' && baTable.auth('del')) || btn.name != 'delete')" v-if="btn.render == 'confirmButton' && isConfirmButtonVisible(btn)"
:disabled="btn.disabled && btn.disabled(row, field)" :disabled="btn.disabled && btn.disabled(row, field)"
v-bind="invokeTableContextDataFun(btn.popconfirm, { row, field, cellValue: btn, column, index })" v-bind="invokeTableContextDataFun(btn.popconfirm, { row, field, cellValue: btn, column, index })"
@confirm="onButtonClick(btn)" @confirm="onButtonClick(btn)"
@@ -108,6 +108,7 @@ import { inject } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { invokeTableContextDataFun } from '/@/components/table/index' import { invokeTableContextDataFun } from '/@/components/table/index'
import type baTableClass from '/@/utils/baTable' import type baTableClass from '/@/utils/baTable'
import { useAdminInfo } from '/@/stores/adminInfo'
interface Props { interface Props {
row: TableRow row: TableRow
@@ -119,6 +120,7 @@ interface Props {
const { t, te } = useI18n() const { t, te } = useI18n()
const props = defineProps<Props>() const props = defineProps<Props>()
const baTable = inject('baTable') as baTableClass const baTable = inject('baTable') as baTableClass
const adminInfo = useAdminInfo()
const onButtonClick = (btn: OptButton) => { const onButtonClick = (btn: OptButton) => {
if (typeof btn.click === 'function') { if (typeof btn.click === 'function') {
@@ -128,6 +130,16 @@ const onButtonClick = (btn: OptButton) => {
baTable.onTableAction(btn.name as BaTableActionEventName, props) baTable.onTableAction(btn.name as BaTableActionEventName, props)
} }
const isConfirmButtonVisible = (btn: OptButton) => {
if (btn.name === 'delete') {
return baTable.auth('del')
}
if (btn.name === 'resetTotp') {
return adminInfo.super || baTable.auth('resetTotp')
}
return true
}
const getTranslation = (key?: string) => { const getTranslation = (key?: string) => {
if (!key) return '' if (!key) return ''
return te(key) ? t(key) : key return te(key) ? t(key) : key

View File

@@ -15,4 +15,5 @@ export default {
'Not bound': 'Not bound', 'Not bound': 'Not bound',
'Reset authenticator': 'Reset authenticator', 'Reset authenticator': 'Reset authenticator',
'Reset authenticator confirm': 'Reset this admin\'s Google Authenticator? They must re-bind on next login.', 'Reset authenticator confirm': 'Reset this admin\'s Google Authenticator? They must re-bind on next login.',
'Pending bind tip': 'Not bound yet. This admin must complete binding on next login.',
} }

View File

@@ -15,4 +15,5 @@ export default {
'Not bound': '未绑定', 'Not bound': '未绑定',
'Reset authenticator': '重置验证器', 'Reset authenticator': '重置验证器',
'Reset authenticator confirm': '确定要重置该管理员的谷歌验证器吗?重置后该管理员下次登录需重新绑定。', 'Reset authenticator confirm': '确定要重置该管理员的谷歌验证器吗?重置后该管理员下次登录需重新绑定。',
'Pending bind tip': '该管理员尚未绑定,需在其下次登录时自行完成绑定',
} }

View File

@@ -9,7 +9,6 @@
/> />
<!-- 表格 --> <!-- 表格 -->
<!-- 要使用`el-table`组件原有的属性直接加在Table标签上即可 -->
<Table /> <Table />
<!-- 表单 --> <!-- 表单 -->
@@ -36,6 +35,18 @@ defineOptions({
const { t } = useI18n() const { t } = useI18n()
const adminInfo = useAdminInfo() const adminInfo = useAdminInfo()
/** 超管或拥有 resetTotp 权限,且不能操作自己 */
const canManageTotp = (row: TableRow) => {
if (row.id == adminInfo.id) {
return false
}
return adminInfo.super
}
const isTotpBound = (row: TableRow) => {
return row.totp_bound === true || row.totp_bound === 1 || row.totp_bound === '1'
}
const optButtons: OptButton[] = [ const optButtons: OptButton[] = [
{ {
render: 'confirmButton', render: 'confirmButton',
@@ -52,15 +63,25 @@ const optButtons: OptButton[] = [
title: t('auth.admin.Reset authenticator confirm'), title: t('auth.admin.Reset authenticator confirm'),
}, },
disabledTip: false, disabledTip: false,
display: (row: TableRow) => { display: (row: TableRow) => canManageTotp(row) && isTotpBound(row),
return adminInfo.super && row.id != adminInfo.id && !!row.totp_bound
},
click: (row: TableRow) => { click: (row: TableRow) => {
resetTotp(row.id).then(() => { resetTotp(row.id).then(() => {
baTable.onTableHeaderAction('refresh', {}) baTable.onTableHeaderAction('refresh', {})
}) })
}, },
}, },
{
render: 'tipButton',
name: 'bindTip',
title: 'auth.admin.Pending bind tip',
text: '',
type: 'info',
icon: 'fa fa-shield',
class: 'table-row-bind-tip',
disabledTip: false,
display: (row: TableRow) => canManageTotp(row) && !isTotpBound(row),
disabled: () => true,
},
...defaultOptButtons(['edit', 'delete']).map((btn) => { ...defaultOptButtons(['edit', 'delete']).map((btn) => {
if (btn.name === 'delete') { if (btn.name === 'delete') {
return { return {
@@ -115,7 +136,7 @@ const baTable = new baTableClass(
{ {
label: t('Operate'), label: t('Operate'),
align: 'center', align: 'center',
width: '140', width: '170',
render: 'buttons', render: 'buttons',
buttons: optButtons, buttons: optButtons,
operator: false, operator: false,