fix(后台用户): 管理员密码显示出来之后能再隐藏
Some checks failed
Deploy / deploy (push) Has been cancelled

原来只发 reveal 事件,露出去就没有回头路,只有翻页 / 搜索才会回到打码状态 ——
看一眼就该关掉,不然一整页管理员密码那么摊着。改成 toggle,打码与否只看
revealed 这一个 prop,按钮文案跟着走。

密码列顺带从 150 拓到 180:露出明文后面还跟着「隐藏」按钮,150 挤不下。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017xu912Rv5JUUuy6MqMcQW2
This commit is contained in:
2026-09-07 19:59:54 -06:00
parent 6a438872b9
commit 3a8f4fcd51
2 changed files with 17 additions and 12 deletions

View File

@@ -9,11 +9,11 @@ interface Props {
} }
const props = defineProps<Props>() const props = defineProps<Props>()
defineEmits<{ defineEmits<{
(e: "reveal", value: number): void (e: "toggle", value: number): void
}>() }>()
/** /**
* 只有**管理员账号**的密码默认打码。 * 只有**管理员账号**的密码需要打码。
* *
* 学生的密码照旧直接显示 —— 老师查学生密码是日常动作(明文列 `raw_password` 就是为它 * 学生的密码照旧直接显示 —— 老师查学生密码是日常动作(明文列 `raw_password` 就是为它
* 保留的),挡一道只是添乱。要防的是管理员密码在投屏、或者旁人路过时被看到。 * 保留的),挡一道只是添乱。要防的是管理员密码在投屏、或者旁人路过时被看到。
@@ -21,18 +21,20 @@ defineEmits<{
* `rawPassword` 为空时不打码:给一个点了什么也不显示的按钮没有意义,直接走原来的 * `rawPassword` 为空时不打码:给一个点了什么也不显示的按钮没有意义,直接走原来的
* TextCopy渲染成空 * TextCopy渲染成空
*/ */
const masked = computed( const maskable = computed(
() => () =>
!props.revealed &&
props.user.adminType !== USER_TYPE.REGULAR_USER && props.user.adminType !== USER_TYPE.REGULAR_USER &&
!!props.user.rawPassword, !!props.user.rawPassword,
) )
</script> </script>
<template> <template>
<n-flex v-if="masked" align="center" :size="6" :wrap="false"> <!-- 显示出来之后要能再收回去看一眼就该关掉不然一整页管理员密码就那么摊着
<span class="dots"></span> 只有翻页 / 搜索才会回到打码状态 -->
<n-button size="tiny" secondary @click="$emit('reveal', props.user.id)"> <n-flex v-if="maskable" align="center" :size="6" :wrap="false">
显示 <span v-if="!props.revealed" class="dots"></span>
<TextCopy v-else>{{ props.user.rawPassword }}</TextCopy>
<n-button size="tiny" secondary @click="$emit('toggle', props.user.id)">
{{ props.revealed ? "隐藏" : "显示" }}
</n-button> </n-button>
</n-flex> </n-flex>
<TextCopy v-else>{{ props.user.rawPassword }}</TextCopy> <TextCopy v-else>{{ props.user.rawPassword }}</TextCopy>

View File

@@ -51,8 +51,8 @@ const sortOptions = [
] ]
const [create, toggleCreate] = useToggle(false) const [create, toggleCreate] = useToggle(false)
const password = ref("") const password = ref("")
// 已经点开的管理员密码,按 user id 记。listUsers() 里清空,所以翻页/搜索/换筛选之后 // 已经点开的管理员密码,按 user id 记。同一个按钮再点一下收回去;listUsers() 里清空,
// 一律回到打码状态 —— 不做定时自动隐藏,也不记进 localStorage。 // 所以翻页/搜索/换筛选之后也一律回到打码状态 —— 不做定时自动隐藏,也不记进 localStorage。
const revealedPasswords = ref(new Set<number>()) const revealedPasswords = ref(new Set<number>())
const userIDs = ref<DataTableRowKey[]>([]) const userIDs = ref<DataTableRowKey[]>([])
@@ -68,14 +68,17 @@ const columns: DataTableColumn<User>[] = [
render: (row) => h(Name, { user: row }), render: (row) => h(Name, { user: row }),
}, },
{ {
// 显示出来的密码后面还跟着「隐藏」按钮150 挤得下点点、挤不下密码
title: "密码", title: "密码",
key: "raw_password", key: "raw_password",
width: 150, width: 180,
render: (row) => render: (row) =>
h(Password, { h(Password, {
user: row, user: row,
revealed: revealedPasswords.value.has(row.id), revealed: revealedPasswords.value.has(row.id),
onReveal: (id: number) => revealedPasswords.value.add(id), onToggle: (id: number) => {
if (!revealedPasswords.value.delete(id)) revealedPasswords.value.add(id)
},
}), }),
}, },
{ {