200 lines
4.8 KiB
Vue
200 lines
4.8 KiB
Vue
<template>
|
||
<el-dialog v-model="visible" title="修改密码" width="400px" @close="handleClose">
|
||
<el-form :model="form">
|
||
<!-- 用户账号(只读) -->
|
||
<el-form-item label="账号">
|
||
<el-input v-model="form.username" disabled />
|
||
</el-form-item>
|
||
|
||
<!-- 新密码 -->
|
||
<el-form-item label="新密码">
|
||
<el-input
|
||
v-model="passwordForm.newPassword"
|
||
type="password"
|
||
autocomplete="new-password"
|
||
show-password
|
||
placeholder="请输入新密码(6-16位)"
|
||
/>
|
||
</el-form-item>
|
||
|
||
<!-- 确认密码 -->
|
||
<el-form-item label="确认密码">
|
||
<el-input
|
||
v-model="passwordForm.confirmPassword"
|
||
type="password"
|
||
autocomplete="new-password"
|
||
show-password
|
||
placeholder="请再次输入新密码"
|
||
/>
|
||
</el-form-item>
|
||
|
||
<!-- 错误提示 -->
|
||
<el-form-item v-if="passwordError">
|
||
<el-alert :title="passwordError" type="error" :closable="false" style="color: #f56c6c;" />
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<!-- 对话框脚部 -->
|
||
<template #footer>
|
||
<el-button @click="handleCancel">取消</el-button>
|
||
<el-button type="primary" @click="handleSubmit">确定修改</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, watch } from "vue";
|
||
import { ElMessage } from "element-plus";
|
||
import { changePassword } from "@/api/user";
|
||
|
||
const props = defineProps({
|
||
modelValue: {
|
||
type: Boolean,
|
||
default: false,
|
||
},
|
||
userId: {
|
||
type: Number,
|
||
default: null,
|
||
},
|
||
});
|
||
|
||
const emit = defineEmits(['update:modelValue', 'submit', 'close']);
|
||
|
||
const visible = ref(false);
|
||
const passwordError = ref("");
|
||
|
||
const form = ref<any>({
|
||
id: null,
|
||
username: "",
|
||
});
|
||
|
||
const passwordForm = ref<any>({
|
||
newPassword: "",
|
||
confirmPassword: "",
|
||
});
|
||
|
||
// 监听 modelValue
|
||
watch(() => props.modelValue, (newVal) => {
|
||
visible.value = newVal;
|
||
if (newVal && props.userId) {
|
||
form.value.id = props.userId;
|
||
}
|
||
});
|
||
|
||
// 监听 userId 变化
|
||
watch(() => props.userId, (newVal) => {
|
||
if (newVal) {
|
||
form.value.id = newVal;
|
||
}
|
||
});
|
||
|
||
// 监听 visible 变化
|
||
watch(visible, (newVal) => {
|
||
if (!newVal) {
|
||
emit('update:modelValue', false);
|
||
}
|
||
});
|
||
|
||
// 校验密码
|
||
const validatePassword = (password: string) => {
|
||
if (!password) {
|
||
return "请输入密码";
|
||
}
|
||
if (password.length < 6) {
|
||
return "密码长度不能小于6位";
|
||
}
|
||
if (password.length > 16) {
|
||
return "密码长度不能大于16位";
|
||
}
|
||
return true;
|
||
};
|
||
|
||
// 校验确认密码
|
||
const validateConfirmPassword = (password: string, confirmPassword: string) => {
|
||
if (!confirmPassword) {
|
||
return "请再次输入密码";
|
||
}
|
||
if (confirmPassword !== password) {
|
||
return "两次输入的密码不一致";
|
||
}
|
||
return true;
|
||
};
|
||
|
||
const handleCancel = () => {
|
||
visible.value = false;
|
||
};
|
||
|
||
const handleClose = () => {
|
||
passwordForm.value = {
|
||
newPassword: "",
|
||
confirmPassword: "",
|
||
};
|
||
passwordError.value = "";
|
||
emit('close');
|
||
};
|
||
|
||
const handleSubmit = async () => {
|
||
// 清除之前的错误
|
||
passwordError.value = "";
|
||
|
||
try {
|
||
if (!form.value.id) {
|
||
passwordError.value = "用户ID不能为空";
|
||
return;
|
||
}
|
||
|
||
// 校验新密码格式
|
||
const passwordCheck = validatePassword(passwordForm.value.newPassword);
|
||
if (passwordCheck !== true) {
|
||
passwordError.value = passwordCheck;
|
||
return;
|
||
}
|
||
|
||
// 校验确认密码
|
||
const confirmCheck = validateConfirmPassword(
|
||
passwordForm.value.newPassword,
|
||
passwordForm.value.confirmPassword
|
||
);
|
||
if (confirmCheck !== true) {
|
||
passwordError.value = confirmCheck;
|
||
return;
|
||
}
|
||
|
||
// 调用接口修改密码
|
||
// 第三个参数 true:userId 是用户管理列表行主键,后端按主键精确匹配
|
||
const res = await changePassword(form.value.id, passwordForm.value, true);
|
||
|
||
if (res.code === 200 || res.msg === '修改成功') {
|
||
ElMessage.success("密码修改成功");
|
||
visible.value = false;
|
||
emit('update:modelValue', false);
|
||
emit('submit');
|
||
} else {
|
||
passwordError.value = res.msg || "密码修改失败";
|
||
}
|
||
} catch (e: any) {
|
||
const errorMsg = e?.response?.data?.msg || e?.response?.data?.message || e?.message || "操作失败";
|
||
passwordError.value = errorMsg;
|
||
}
|
||
};
|
||
|
||
// 暴露方法给父组件
|
||
defineExpose({
|
||
open: (userId: number, username: string) => {
|
||
form.value = {
|
||
id: userId,
|
||
username: username,
|
||
};
|
||
passwordForm.value = {
|
||
newPassword: "",
|
||
confirmPassword: "",
|
||
};
|
||
passwordError.value = "";
|
||
visible.value = true;
|
||
},
|
||
});
|
||
</script>
|
||
|
||
<style lang="less" scoped>
|
||
</style>
|