fix: 校正一次性密码展示与 CSV 下载
This commit is contained in:
@@ -38,6 +38,7 @@ import {
|
||||
} from "@/api/admin";
|
||||
import { ApiError } from "@/api/http";
|
||||
import { formatLocalMs } from "@/utils/time";
|
||||
import { buildPasswordCsv, downloadText } from "@/utils/csv";
|
||||
import { message } from "@/utils/notify";
|
||||
|
||||
const dialog = useDialog();
|
||||
@@ -67,7 +68,7 @@ const onlineOptions = [
|
||||
{ label: "离线", value: "false" },
|
||||
];
|
||||
|
||||
const onceSecret = ref<{ title: string; secret: string; filename: string } | null>(null);
|
||||
const onceSecret = ref<{ title: string; secret: string; filename: string; mime?: string } | null>(null);
|
||||
const importResult = ref<ImportItem[] | null>(null);
|
||||
|
||||
const createOpen = ref(false);
|
||||
@@ -211,11 +212,15 @@ async function submitCreate() {
|
||||
default_delay_seconds: createForm.default_delay_seconds,
|
||||
});
|
||||
createOpen.value = false;
|
||||
onceSecret.value = {
|
||||
title: "开通成功,登录密码只显示一次",
|
||||
secret: `${res.id}\t${res.login_password}`,
|
||||
filename: `${res.id}-password.txt`,
|
||||
};
|
||||
if (res.login_password) {
|
||||
onceSecret.value = {
|
||||
title: "开通成功,登录密码只显示一次",
|
||||
secret: `${res.id}\t${res.login_password}`,
|
||||
filename: `${res.id}-password.txt`,
|
||||
};
|
||||
} else {
|
||||
message.success(`已开通 ${res.id}`);
|
||||
}
|
||||
await load();
|
||||
} catch (e) {
|
||||
createError.value = e instanceof ApiError ? e.message : e instanceof Error ? e.message : "开通失败";
|
||||
@@ -337,11 +342,15 @@ async function onImport(options: UploadCustomRequestOptions) {
|
||||
const text = await raw.text();
|
||||
const res = await importEndpoints(text);
|
||||
importResult.value = res.items;
|
||||
onceSecret.value = {
|
||||
title: "CSV 导入成功,密码只显示一次",
|
||||
secret: res.items.map((i) => `${i.id},${i.name},${i.login_password}`).join("\n"),
|
||||
filename: "import-passwords.csv",
|
||||
};
|
||||
const pwdRows = res.items.filter((i): i is ImportItem & { login_password: string } => Boolean(i.login_password));
|
||||
if (pwdRows.length) {
|
||||
onceSecret.value = {
|
||||
title: "CSV 导入成功,密码只显示一次",
|
||||
secret: buildPasswordCsv(pwdRows),
|
||||
filename: "import-passwords.csv",
|
||||
mime: "text/csv;charset=utf-8",
|
||||
};
|
||||
}
|
||||
options.onFinish();
|
||||
await load();
|
||||
} catch (e) {
|
||||
@@ -355,6 +364,16 @@ async function onImport(options: UploadCustomRequestOptions) {
|
||||
}
|
||||
}
|
||||
|
||||
function downloadImportCsv() {
|
||||
if (!importResult.value?.length) {
|
||||
return;
|
||||
}
|
||||
const pwdRows = importResult.value.filter((i): i is ImportItem & { login_password: string } =>
|
||||
Boolean(i.login_password),
|
||||
);
|
||||
downloadText("import-passwords.csv", buildPasswordCsv(pwdRows), "text/csv;charset=utf-8");
|
||||
}
|
||||
|
||||
function onPageChange(p: number) {
|
||||
page.value = p;
|
||||
void load();
|
||||
@@ -387,6 +406,7 @@ function onPageSizeChange(s: number) {
|
||||
:title="onceSecret.title"
|
||||
:secret="onceSecret.secret"
|
||||
:filename="onceSecret.filename"
|
||||
:mime="onceSecret.mime"
|
||||
@dismiss="onceSecret = null"
|
||||
/>
|
||||
<n-space style="margin-bottom: 12px" align="center">
|
||||
@@ -439,7 +459,7 @@ function onPageSizeChange(s: number) {
|
||||
<n-input v-model:value="createForm.name" data-testid="create-name" placeholder="可选" />
|
||||
</n-form-item>
|
||||
<n-form-item label="登录密码">
|
||||
<n-input v-model:value="createForm.login_password" placeholder="留空则生成" type="password" show-password-on="click" />
|
||||
<n-input v-model:value="createForm.login_password" placeholder="留空则生成" type="password" show-password-on="click" data-testid="create-login-password" />
|
||||
</n-form-item>
|
||||
<n-form-item label="对话密码">
|
||||
<n-input v-model:value="createForm.talk_password" placeholder="可选" type="password" show-password-on="click" />
|
||||
@@ -502,10 +522,11 @@ function onPageSizeChange(s: number) {
|
||||
<n-modal v-if="importResult" :show="true" preset="card" title="导入结果" style="width: 560px" @update:show="(v) => !v && (importResult = null)">
|
||||
<n-scrollbar style="max-height: 280px">
|
||||
<n-text depth="3">以下密码仅本次可见,请下载保存。</n-text>
|
||||
<pre style="font-size: 12px; white-space: pre-wrap">{{ importResult.map((i) => `${i.id}\t${i.name}\t${i.login_password}`).join("\n") }}</pre>
|
||||
<pre style="font-size: 12px; white-space: pre-wrap">{{ importResult.map((i) => `${i.id}\t${i.name}\t${i.login_password ?? ""}`).join("\n") }}</pre>
|
||||
</n-scrollbar>
|
||||
<template #footer>
|
||||
<n-space justify="end">
|
||||
<n-button @click="downloadImportCsv">下载</n-button>
|
||||
<n-button @click="importResult = null">关闭</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user