feat: 添加管理员密码修改功能
This commit is contained in:
@@ -49,12 +49,20 @@ export const useAuthStore = defineStore("auth", () => {
|
||||
}
|
||||
}
|
||||
|
||||
async function changePassword(currentPassword: string, newPassword: string) {
|
||||
await apiClient.post("/auth/change-password", {
|
||||
currentPassword,
|
||||
newPassword
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
token,
|
||||
user,
|
||||
isAuthenticated,
|
||||
login,
|
||||
logout,
|
||||
changePassword,
|
||||
clearSession
|
||||
};
|
||||
});
|
||||
|
||||
@@ -9,11 +9,15 @@ import type {
|
||||
WebhookTestResult
|
||||
} from "@/types";
|
||||
import { outputFormatLabelMap, recordingTemplateLabelMap, saveModeLabelMap } from "@/types";
|
||||
import { useAuthStore } from "@/stores/auth";
|
||||
|
||||
type ScriptEventType = "live_started" | "live_ended" | "segment_completed";
|
||||
|
||||
const authStore = useAuthStore();
|
||||
|
||||
const loading = ref(false);
|
||||
const saving = ref(false);
|
||||
const changingPassword = ref(false);
|
||||
const testingEmail = ref(false);
|
||||
const testingWebhook = ref(false);
|
||||
const runningRetentionCleanup = ref(false);
|
||||
@@ -263,6 +267,54 @@ async function loadSettings() {
|
||||
}
|
||||
}
|
||||
|
||||
const pwdForm = reactive({
|
||||
currentPassword: "",
|
||||
newPassword: "",
|
||||
confirmPassword: ""
|
||||
});
|
||||
|
||||
const pwdRules = {
|
||||
currentPassword: [{ required: true, message: "请输入当前密码", trigger: "blur" }],
|
||||
newPassword: [
|
||||
{ required: true, message: "请输入新密码", trigger: "blur" },
|
||||
{ min: 6, message: "新密码长度不能少于 6 位", trigger: "blur" }
|
||||
],
|
||||
confirmPassword: [
|
||||
{ required: true, message: "请再次输入新密码", trigger: "blur" },
|
||||
{
|
||||
validator: (_rule: unknown, value: string, callback: (error?: Error) => void) => {
|
||||
if (value !== pwdForm.newPassword) {
|
||||
callback(new Error("两次输入的密码不一致"));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const pwdFormRef = ref<InstanceType<typeof import("element-plus").ElForm> | null>(null);
|
||||
|
||||
async function changePassword() {
|
||||
const valid = await pwdFormRef.value?.validate().catch(() => false);
|
||||
if (!valid) return;
|
||||
|
||||
changingPassword.value = true;
|
||||
try {
|
||||
await authStore.changePassword(pwdForm.currentPassword, pwdForm.newPassword);
|
||||
ElMessage.success("密码已修改,请妥善保管新密码。");
|
||||
pwdForm.currentPassword = "";
|
||||
pwdForm.newPassword = "";
|
||||
pwdForm.confirmPassword = "";
|
||||
pwdFormRef.value?.resetFields();
|
||||
} catch (error) {
|
||||
ElMessage.error(getApiErrorMessage(error, "密码修改失败,请稍后重试。"));
|
||||
} finally {
|
||||
changingPassword.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function saveSettings() {
|
||||
saving.value = true;
|
||||
|
||||
@@ -1370,6 +1422,30 @@ onMounted(loadSettings);
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-card class="surface-card settings-card settings-grid__full" shadow="never">
|
||||
<h3 class="section-title">管理员密码</h3>
|
||||
<p class="section-subtitle">修改当前登录账户的密码,修改后立即生效。</p>
|
||||
|
||||
<el-form
|
||||
ref="pwdFormRef"
|
||||
:model="pwdForm"
|
||||
:rules="pwdRules"
|
||||
label-position="top"
|
||||
style="max-width: 480px;"
|
||||
>
|
||||
<el-form-item label="当前密码" prop="currentPassword">
|
||||
<el-input v-model="pwdForm.currentPassword" type="password" show-password />
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop="newPassword">
|
||||
<el-input v-model="pwdForm.newPassword" type="password" show-password />
|
||||
</el-form-item>
|
||||
<el-form-item label="确认新密码" prop="confirmPassword">
|
||||
<el-input v-model="pwdForm.confirmPassword" type="password" show-password />
|
||||
</el-form-item>
|
||||
<el-button type="primary" :loading="changingPassword" @click="changePassword">修改密码</el-button>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card class="surface-card settings-card settings-grid__full" shadow="never">
|
||||
<h3 class="section-title">Douyin 请求头</h3>
|
||||
<p class="section-subtitle">这些伪装参数会同时用于 Douyin API 请求和 ffmpeg 输入拉流,适合处理直播流读取校验问题。</p>
|
||||
|
||||
Reference in New Issue
Block a user