math/ui/src/components/users/RepasswdDialog.vue

117 lines
3.8 KiB
Vue

<template>
<v-dialog v-model="dialogRepasswdShow" max-width="448">
<v-card class="mx-auto pa-12 pb-8" elevation="8" width="100%" rounded="lg">
<v-form fast-fail @submit.prevent="submit">
<v-text-field v-model="passwords[0]" :rules="passwordRules" label="原密码"
:append-inner-icon="visible[0] ? 'mdi-eye' : 'mdi-eye-off'" :type="visible[0] ? 'text' : 'password'"
@click:append-inner="visible[0] = !visible[0]" prepend-inner-icon="mdi-lock-outline"></v-text-field>
<v-divider :thickness="10" class="border-opacity-0"></v-divider>
<v-text-field v-model="passwords[1]" :rules="passwordRules" label="新密码"
:append-inner-icon="visible[1] ? 'mdi-eye' : 'mdi-eye-off'" :type="visible[1] ? 'text' : 'password'"
@click:append-inner="visible[1] = !visible[1]" prepend-inner-icon="mdi-lock-outline"></v-text-field>
<v-divider :thickness="10" class="border-opacity-0"></v-divider>
<v-text-field :rules="passwordRules2" label="重复输入新密码"
:append-inner-icon="visible[2] ? 'mdi-eye-off' : 'mdi-eye'" :type="visible[2] ? 'text' : 'password'"
@click:append-inner="visible[2] = !visible[2]" prepend-inner-icon="mdi-lock-outline"></v-text-field>
<v-divider :thickness="10" class="border-opacity-0"></v-divider>
<v-btn :loading="loading" class="mb-8" color="blue" size="large" type="submit" variant="tonal" block>
修改密码
</v-btn>
</v-form>
</v-card>
</v-dialog>
<v-dialog v-model="dialogShow" width="auto">
<v-card max-width="400" prepend-icon="mdi-update" :text="dialogText" :title="dialogTitle">
<template v-slot:actions>
<v-btn class="ms-auto" text="Ok" @click="dialogShow = false, dialogClose()"></v-btn>
</template>
</v-card>
</v-dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { useAuthStore } from '@/store/auth';
import axios, { AxiosError } from 'axios';
const dialogShow = ref(false);
const dialogTitle = ref('');
const dialogText = ref('');
const dialogClose = ref(() => { });
const dialog = (title: string, text: string) => {
dialogTitle.value = title;
dialogText.value = text;
dialogShow.value = true;
return new Promise(res => {
dialogClose.value = res as () => void;
});
};
const dialogRepasswdShow = defineModel({ default: true });
const loading = ref(false);
const passwords = ref(['', '']);
const authStore = useAuthStore();
const token = ref(authStore.token);
const visible = ref([false, false, false]);
type RepasswdResponse = { success?: string, error?: string };
const requestRepasswd = async () => {
try {
const formData = new FormData;
formData.append("token", token.value);
formData.append("raw_passwd", passwords.value[0]);
formData.append("new_passwd", passwords.value[1]);
let res = await axios.post('/api/auth/repasswd', formData);
return res.data as RepasswdResponse;
} catch (e) {
let ex = e as AxiosError;
if (ex.response?.data) {
return ex.response?.data as RepasswdResponse;
} {
return { error: ex.message };
}
}
}
const repasswd = async () => {
loading.value = true;
let res = await requestRepasswd();
loading.value = false;
if (res?.error) {
await dialog('错误', `修改密码失败:${res.error}`);
} else {
await dialog('信息', `修改密码成功,请重新登录。`);
authStore.clearToken();
}
}
const submit = async (event: SubmitEvent) => {
const results: any = await event;
if (results.valid) {
await repasswd();
}
};
const passwordRules: any = [(value: string) => {
if (value?.length > 0) return true;
return '密码不能为空';
}];
const passwordRules2: any = [(value: string) => {
if (value == passwords.value[1]) return true;
return '两次输入需保持一致';
}];
</script>