feat: 支持展示并复制重置后的密码
- 账号重置接口返回本次使用的默认强密码 - 管理端新增紧凑结果弹窗与复制反馈 - 补充服务测试和中英文文案
This commit is contained in:
@@ -32,6 +32,7 @@ import { useDictStore } from '#/store';
|
||||
|
||||
import SysAccountImportModal from './SysAccountImportModal.vue';
|
||||
import SysAccountModal from './SysAccountModal.vue';
|
||||
import SysAccountPasswordResultModal from './SysAccountPasswordResultModal.vue';
|
||||
|
||||
onMounted(() => {
|
||||
initDict();
|
||||
@@ -40,6 +41,7 @@ onMounted(() => {
|
||||
const pageDataRef = ref();
|
||||
const tableRef = ref();
|
||||
const importDialog = ref();
|
||||
const passwordResultDialog = ref();
|
||||
const saveDialog = ref();
|
||||
const selectedRows = ref<any[]>([]);
|
||||
const batchActionLoading = ref(false);
|
||||
@@ -124,6 +126,7 @@ function remove(row: any) {
|
||||
}).catch(() => {});
|
||||
}
|
||||
function resetPassword(row: any) {
|
||||
let plainPassword = '';
|
||||
ElMessageBox.confirm(
|
||||
$t('sysAccount.resetPasswordConfirm'),
|
||||
$t('message.noticeTitle'),
|
||||
@@ -139,7 +142,7 @@ function resetPassword(row: any) {
|
||||
.then((res) => {
|
||||
instance.confirmButtonLoading = false;
|
||||
if (res.errorCode === 0) {
|
||||
ElMessage.success($t('sysAccount.resetPasswordSuccess'));
|
||||
plainPassword = typeof res.data === 'string' ? res.data : '';
|
||||
clearSelection();
|
||||
done();
|
||||
}
|
||||
@@ -152,7 +155,15 @@ function resetPassword(row: any) {
|
||||
}
|
||||
},
|
||||
},
|
||||
).catch(() => {});
|
||||
)
|
||||
.then(() => {
|
||||
if (!plainPassword) {
|
||||
ElMessage.error($t('sysAccount.resetPasswordResultMissing'));
|
||||
return;
|
||||
}
|
||||
passwordResultDialog.value?.openDialog(plainPassword);
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
function handleSelectionChange(rows: any[]) {
|
||||
selectedRows.value = rows;
|
||||
@@ -260,6 +271,7 @@ function isAdmin(data: any) {
|
||||
<div class="flex h-full flex-col gap-6 p-6">
|
||||
<SysAccountImportModal ref="importDialog" @reload="reset" />
|
||||
<SysAccountModal ref="saveDialog" @reload="reset" />
|
||||
<SysAccountPasswordResultModal ref="passwordResultDialog" />
|
||||
<ListPageShell>
|
||||
<template #filters>
|
||||
<HeaderSearch
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue';
|
||||
|
||||
import { EasyFlowPanelModal } from '@easyflow/common-ui';
|
||||
|
||||
import { CopyDocument } from '@element-plus/icons-vue';
|
||||
import { ElButton, ElInput } from 'element-plus';
|
||||
|
||||
import { $t } from '#/locales';
|
||||
import { copyTextWithFeedback } from '#/utils/clipboard-feedback';
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const password = ref('');
|
||||
|
||||
watch(dialogVisible, (visible) => {
|
||||
if (!visible) {
|
||||
password.value = '';
|
||||
}
|
||||
});
|
||||
|
||||
function openDialog(value: string) {
|
||||
password.value = value;
|
||||
dialogVisible.value = true;
|
||||
}
|
||||
|
||||
function closeDialog() {
|
||||
dialogVisible.value = false;
|
||||
}
|
||||
|
||||
function selectPassword(event: FocusEvent) {
|
||||
if (event.target instanceof HTMLInputElement) {
|
||||
event.target.select();
|
||||
}
|
||||
}
|
||||
|
||||
async function copyPassword() {
|
||||
await copyTextWithFeedback(
|
||||
password.value,
|
||||
$t('message.copySuccess'),
|
||||
$t('message.copyFail'),
|
||||
);
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
openDialog,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<EasyFlowPanelModal
|
||||
v-model:open="dialogVisible"
|
||||
centered
|
||||
width="482px"
|
||||
:confirm-text="$t('message.ok')"
|
||||
:description="$t('sysAccount.resetPasswordResultDescription')"
|
||||
:show-cancel-button="false"
|
||||
:title="$t('sysAccount.resetPasswordResultTitle')"
|
||||
@confirm="closeDialog"
|
||||
>
|
||||
<div class="password-result">
|
||||
<label class="password-result__label" for="reset-password-result">
|
||||
{{ $t('sysAccount.resetPasswordResultLabel') }}
|
||||
</label>
|
||||
<ElInput
|
||||
id="reset-password-result"
|
||||
class="password-result__input"
|
||||
:model-value="password"
|
||||
readonly
|
||||
size="large"
|
||||
@focus="selectPassword"
|
||||
>
|
||||
<template #suffix>
|
||||
<ElButton
|
||||
class="password-result__copy"
|
||||
:aria-label="$t('sysAccount.copyPassword')"
|
||||
:icon="CopyDocument"
|
||||
link
|
||||
:title="$t('sysAccount.copyPassword')"
|
||||
@click="copyPassword"
|
||||
/>
|
||||
</template>
|
||||
</ElInput>
|
||||
</div>
|
||||
</EasyFlowPanelModal>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.password-result {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.password-result__label {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
line-height: 20px;
|
||||
color: hsl(var(--text-strong));
|
||||
}
|
||||
|
||||
:deep(.password-result__input .el-input__wrapper) {
|
||||
padding-inline: var(--space-4) var(--space-2);
|
||||
background: hsl(var(--surface-subtle));
|
||||
border-radius: var(--radius-control);
|
||||
box-shadow: 0 0 0 1px hsl(var(--line-subtle)) inset;
|
||||
transition:
|
||||
background-color var(--motion-duration-fast) var(--motion-ease-standard),
|
||||
box-shadow var(--motion-duration-fast) var(--motion-ease-standard);
|
||||
}
|
||||
|
||||
:deep(.password-result__input .el-input__wrapper:hover) {
|
||||
box-shadow: 0 0 0 1px hsl(var(--border)) inset;
|
||||
}
|
||||
|
||||
:deep(.password-result__input .el-input__wrapper.is-focus) {
|
||||
background: hsl(var(--surface-panel));
|
||||
box-shadow: 0 0 0 2px hsl(var(--primary) / 18%) inset;
|
||||
}
|
||||
|
||||
:deep(.password-result__input .el-input__inner) {
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.04em;
|
||||
color: hsl(var(--text-strong));
|
||||
}
|
||||
|
||||
:deep(.password-result__copy) {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
padding: 0;
|
||||
font-size: 16px;
|
||||
color: hsl(var(--text-muted));
|
||||
border-radius: var(--radius-control);
|
||||
}
|
||||
|
||||
:deep(.password-result__copy:not(.is-disabled):hover),
|
||||
:deep(.password-result__copy:not(.is-disabled):focus-visible) {
|
||||
color: hsl(var(--primary));
|
||||
background: hsl(var(--primary) / 8%);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user