yunzer_go/pc/src/views/apps/oa/employees/index.vue

965 lines
30 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="container-box">
<div class="header-bar">
<h2>员工管理</h2>
<div class="header-actions">
<el-button type="primary" @click="handleAddEmployee">
<el-icon><Plus /></el-icon>
添加员工
</el-button>
<el-button @click="refresh">
<el-icon><Refresh /></el-icon>
刷新
</el-button>
</div>
</div>
<el-divider></el-divider>
<el-table :data="employees" style="width: 100%" v-loading="loading">
<el-table-column
prop="employeeNo"
label="工号"
width="120"
align="center"
/>
<el-table-column
prop="name"
label="姓名"
width="120"
align="center"
/>
<el-table-column
prop="phone"
label="手机号"
width="150"
align="center"
/>
<el-table-column
prop="email"
label="邮箱"
align="center"
min-width="200"
/>
<el-table-column prop="department" label="部门" width="150" align="center">
<template #default="scope">
<span>{{ scope.row.departmentName || '未分配' }}</span>
</template>
</el-table-column>
<el-table-column prop="position" label="职位" width="150" align="center">
<template #default="scope">
<span>{{ scope.row.positionName || '未分配' }}</span>
</template>
</el-table-column>
<el-table-column prop="bankName" label="开户行" width="150" align="center">
<template #default="scope">
<span>{{ scope.row.bankName || '-' }}</span>
</template>
</el-table-column>
<el-table-column prop="bankAccount" label="卡号" width="180" align="center">
<template #default="scope">
<span>{{ scope.row.bankAccount || '-' }}</span>
</template>
</el-table-column>
<el-table-column prop="status" label="状态" width="100">
<template #default="scope">
<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
{{ scope.row.status === 1 ? "在职" : "离职" }}
</el-tag>
</template>
</el-table-column>
<el-table-column
prop="createTime"
label="入职时间"
width="180"
align="center"
/>
<el-table-column label="操作" width="280" align="center" fixed="right">
<template #default="scope">
<el-button size="small" @click="handleEdit(scope.row)"
>编辑</el-button
>
<el-button
size="small"
type="warning"
@click="handleResetPassword(scope.row)"
>重置密码</el-button
>
<el-button
size="small"
type="info"
@click="handleChangePassword(scope.row)"
>修改密码</el-button
>
<el-button
size="small"
type="danger"
@click="handleDelete(scope.row)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<div class="pagination-bar">
<el-pagination
background
:current-page="page"
:page-size="pageSize"
:total="total"
@current-change="handlePageChange"
layout="total, prev, pager, next"
/>
</div>
<!-- Dialog for add/edit -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="500px">
<el-form :model="form" label-width="80px">
<el-form-item label="工号">
<el-input v-model="form.employeeNo" placeholder="请输入工号" />
</el-form-item>
<el-form-item label="姓名">
<el-input v-model="form.name" placeholder="请输入姓名" />
</el-form-item>
<el-form-item label="手机号">
<el-input v-model="form.phone" placeholder="请输入手机号" />
</el-form-item>
<el-form-item label="邮箱">
<el-input v-model="form.email" placeholder="请输入邮箱" />
</el-form-item>
<el-form-item label="部门">
<el-tree-select
v-model="form.department_id"
:data="departmentTree"
:props="{ label: 'name', children: 'children' }"
value-key="id"
placeholder="请选择部门"
check-strictly
clearable
style="width: 100%"
:loading="loadingDepartments"
@change="handleDepartmentChange"
:render-after-expand="false"
/>
<div v-if="departmentTree.length === 0 && !loadingDepartments" style="color: #999; font-size: 12px; margin-top: 4px;">
暂无部门数据,请先创建部门
</div>
</el-form-item>
<el-form-item label="职位">
<el-select
v-model="form.position_id"
placeholder="请选择职位"
style="width: 100%"
:loading="loadingPositions"
clearable
>
<el-option
v-for="pos in positionList"
:key="pos.id"
:label="pos.name"
:value="pos.id"
/>
</el-select>
</el-form-item>
<el-form-item label="开户行">
<el-input v-model="form.bank_name" placeholder="请输入工资卡开户行" />
</el-form-item>
<el-form-item label="卡号">
<el-input v-model="form.bank_account" placeholder="请输入工资卡卡号" />
</el-form-item>
<el-form-item label="状态">
<el-select v-model="form.status" placeholder="请选择状态">
<el-option label="在职" :value="1" />
<el-option label="离职" :value="0" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitForm">保存</el-button>
</template>
</el-dialog>
<!-- 修改密码对话框 -->
<el-dialog v-model="passwordDialogVisible" title="修改密码" width="400px">
<el-form :model="passwordForm" label-width="100px">
<el-form-item label="旧密码">
<el-input
v-model="passwordForm.old_password"
type="password"
placeholder="请输入旧密码"
show-password
/>
</el-form-item>
<el-form-item label="新密码">
<el-input
v-model="passwordForm.new_password"
type="password"
placeholder="请输入新密码"
show-password
/>
</el-form-item>
<el-form-item label="确认密码">
<el-input
v-model="passwordForm.confirm_password"
type="password"
placeholder="请再次输入新密码"
show-password
/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="passwordDialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitPasswordForm">确定</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, nextTick } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { Plus, Refresh } from "@element-plus/icons-vue";
import {
getAllEmployees,
getTenantEmployees,
addEmployee,
editEmployee,
deleteEmployee,
getEmployeeInfo,
resetEmployeePassword,
changeEmployeePassword,
} from "@/api/employee";
import { getTenantDepartments, getDepartmentInfo } from "@/api/department";
import { getTenantPositions, getPositionsByDepartment, getPositionInfo } from "@/api/position";
import { useAuthStore } from "@/stores/auth";
interface Employee {
id: number;
employeeNo: string;
name: string;
phone: string;
email: string;
department: string;
position: string;
status: number;
createTime: string;
tenant_id: number;
}
const authStore = useAuthStore();
const page = ref(1);
const pageSize = ref(10);
const total = ref(0);
const employees = ref<any[]>([]);
const departmentList = ref<any[]>([]);
const departmentTree = ref<any[]>([]);
const loadingDepartments = ref(false);
const positionList = ref<any[]>([]);
const loadingPositions = ref(false);
const loading = ref(false);
// 获取当前登录用户的租户ID
const getCurrentTenantId = () => {
if (authStore.user && authStore.user.tenant_id) {
return authStore.user.tenant_id;
}
const userInfo = localStorage.getItem('userInfo');
if (userInfo) {
try {
const user = JSON.parse(userInfo);
return user.tenant_id || user.tenantId || 0;
} catch (e) {
console.error('Failed to parse user info:', e);
}
}
return 0;
};
const fetchEmployees = async () => {
loading.value = true;
let tenantId = getCurrentTenantId ? getCurrentTenantId() : null;
try {
const res = await getTenantEmployees(tenantId);
// 兼容接口返回的数据结构
let employeeList: any[] = [];
if (Array.isArray(res)) {
employeeList = res;
} else if (res?.data && Array.isArray(res.data)) {
employeeList = res.data;
} else if (res?.data?.data && Array.isArray(res.data.data)) {
employeeList = res.data.data;
} else if (res?.data) {
employeeList = res.data;
}
// 映射接口字段到表格所需结构
employees.value = employeeList.map((item: any) => {
// 查找部门名称
let departmentName = '';
const departmentId = item.department_id || null;
if (departmentId) {
const deptInfo = departmentList.value.find(d => d.id === departmentId);
departmentName = deptInfo ? deptInfo.name : '';
}
// 查找职位名称
let positionName = '';
const positionId = item.position_id || null;
if (positionId) {
const posInfo = positionList.value.find(p => p.id === positionId);
positionName = posInfo ? posInfo.name : '';
}
// 处理入职时间
const createTime = item.create_time || item.createTime || null;
return {
id: item.id,
employeeNo: item.employee_no || item.employeeNo || '',
name: item.name || '',
phone: item.phone || '',
email: item.email || '',
department_id: departmentId,
departmentName: departmentName,
position_id: positionId,
positionName: positionName,
bankName: item.bank_name || item.bankName || '',
bankAccount: item.bank_account || item.bankAccount || '',
status: item.status || 1,
createTime: createTime
? new Date(createTime).toLocaleString("zh-CN", {
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hour12: false,
})
: "",
};
});
total.value = employees.value.length;
} catch (e) {
employees.value = [];
total.value = 0;
ElMessage.error("获取员工列表失败");
} finally {
loading.value = false;
}
};
// 构建部门树(参考组织架构页面的实现)
const buildDepartmentTree = (deptList: any[], tenantId?: number) => {
if (!deptList || deptList.length === 0) {
console.warn('部门列表为空');
return [];
}
// 先按tenant_id过滤双重保险确保只显示当前租户的部门
let filteredList = deptList;
if (tenantId !== undefined && tenantId !== null) {
filteredList = deptList.filter((dept) => {
const deptTenantId = dept.tenant_id || dept.tenantId;
return deptTenantId === tenantId || deptTenantId === 0;
});
}
const tree: any[] = [];
const map = new Map<number, any>();
// 第一遍:创建所有节点的映射
filteredList.forEach((dept) => {
if (!dept.id) {
console.warn('部门数据缺少id字段:', dept);
return;
}
map.set(dept.id, {
...dept,
children: [],
});
});
// 第二遍:构建树结构
// 先处理parent_id为0或null的节点作为根节点
filteredList.forEach((dept) => {
if (!dept.id) return;
const node = map.get(dept.id);
if (!node) return;
const parentId = dept.parent_id || 0;
// 先判断parent_id如果为0或null直接作为根节点
if (parentId === 0 || parentId === null || parentId === undefined) {
tree.push(node);
} else {
// 查找父节点,如果父节点存在且在当前租户下,则作为子节点
const parent = map.get(parentId);
if (parent) {
parent.children.push(node);
} else {
// 如果找不到父节点(可能是其他租户的部门),作为根节点显示
tree.push(node);
}
}
});
// 排序
const sortTree = (nodes: any[]) => {
nodes.sort((a, b) => (a.sort_order || 0) - (b.sort_order || 0));
nodes.forEach((node) => {
if (node.children && node.children.length > 0) {
sortTree(node.children);
}
});
};
sortTree(tree);
return tree;
};
// 获取部门列表
const fetchDepartments = async () => {
loadingDepartments.value = true;
try {
const tenantId = getCurrentTenantId();
const res = await getTenantDepartments(tenantId);
let deptList: any[] = [];
if (Array.isArray(res)) {
deptList = res;
} else if (res?.data && Array.isArray(res.data)) {
deptList = res.data;
} else if (res?.data?.data && Array.isArray(res.data.data)) {
deptList = res.data.data;
} else if (res?.data) {
deptList = res.data;
}
departmentList.value = deptList;
// 构建部门树时传入tenant_id确保先按租户过滤再处理parent_id=0的情况
const tree = buildDepartmentTree(deptList, tenantId);
departmentTree.value = tree;
// 详细调试日志
console.log('=== 部门数据加载 ===');
console.log('租户ID:', tenantId);
console.log('部门原始数据:', JSON.stringify(deptList, null, 2));
console.log('构建的部门树:', JSON.stringify(tree, null, 2));
console.log('部门树长度:', tree.length);
if (tree.length > 0) {
console.log('第一个部门节点:', tree[0]);
console.log('第一个部门节点的结构:', {
id: tree[0].id,
name: tree[0].name,
children: tree[0].children,
allKeys: Object.keys(tree[0])
});
}
} catch (error: any) {
console.error('获取部门列表失败:', error);
departmentList.value = [];
departmentTree.value = [];
} finally {
loadingDepartments.value = false;
}
};
// 获取职位列表
const fetchPositions = async (departmentId?: number) => {
loadingPositions.value = true;
try {
const tenantId = getCurrentTenantId();
let res;
if (departmentId && departmentId > 0) {
res = await getPositionsByDepartment(departmentId);
} else {
res = await getTenantPositions(tenantId);
}
let posList: any[] = [];
if (Array.isArray(res)) {
posList = res;
} else if (res?.data && Array.isArray(res.data)) {
posList = res.data;
} else if (res?.data?.data && Array.isArray(res.data.data)) {
posList = res.data.data;
} else if (res?.data) {
posList = res.data;
}
// 去重确保职位列表中没有重复的ID
const uniquePositions = new Map<number, any>();
posList.forEach((pos: any) => {
const posId = Number(pos.id);
if (posId && !uniquePositions.has(posId)) {
uniquePositions.set(posId, pos);
}
});
positionList.value = Array.from(uniquePositions.values());
} catch (error: any) {
console.error('获取职位列表失败:', error);
positionList.value = [];
} finally {
loadingPositions.value = false;
}
};
// 部门改变时,重新加载职位列表
const handleDepartmentChange = (departmentId: number | null) => {
form.value.position_id = null; // 清空职位选择
if (departmentId && departmentId > 0) {
fetchPositions(departmentId);
} else {
fetchPositions(); // 加载所有职位
}
};
onMounted(async () => {
await Promise.all([
fetchDepartments(),
fetchPositions(),
]);
fetchEmployees();
});
const handlePageChange = (p: number) => {
page.value = p;
// 分页仅前端做演示
};
// 为添加 / 编辑对话框而添加
const dialogVisible = ref(false);
const dialogTitle = ref("");
const isEdit = ref(false);
const form = ref<any>({
id: null,
employeeNo: "",
name: "",
phone: "",
email: "",
department_id: null,
position_id: null,
bank_name: "",
bank_account: "",
status: 1,
tenant_id: null,
});
// 修改密码对话框
const passwordDialogVisible = ref(false);
const currentEmployeeId = ref<number | null>(null);
const passwordForm = ref<any>({
old_password: "",
new_password: "",
confirm_password: "",
});
//刷新界面
const refresh = async () => {
loading.value = true;
try {
await fetchEmployees();
ElMessage.success('刷新成功');
} catch (error) {
ElMessage.error('刷新失败');
} finally {
loading.value = false;
}
};
const handleAddEmployee = () => {
dialogTitle.value = "添加员工";
isEdit.value = false;
// 从本地缓存读取tenant_id
let tenantId = null;
const cachedUser = localStorage.getItem("userInfo");
if (cachedUser) {
try {
const userInfo = JSON.parse(cachedUser);
tenantId = userInfo.tenant_id || null;
} catch (e) {
tenantId = null;
}
}
form.value = {
id: 0,
employeeNo: "",
name: "",
phone: "",
email: "",
department_id: null,
position_id: null,
bank_name: "",
bank_account: "",
status: 1,
tenant_id: tenantId,
};
// 重新加载职位列表(所有职位)
fetchPositions();
dialogVisible.value = true;
};
const handleEdit = async (employee: Employee) => {
dialogTitle.value = "编辑员工";
isEdit.value = true;
try {
// 获取当前租户ID
const tenantId = getCurrentTenantId();
// 强制重新获取部门列表(确保使用最新的部门数据)
await fetchDepartments();
// 先获取员工信息
const res = await getEmployeeInfo(employee.id);
const data = res.data || res;
// 确保department_id是数字类型与树中的id类型匹配
const departmentId = data.department_id ? Number(data.department_id) : null;
form.value = {
id: data.id,
employeeNo: data.employee_no || data.employeeNo || '',
name: data.name || '',
phone: data.phone || '',
email: data.email || '',
department_id: departmentId,
position_id: data.position_id ? Number(data.position_id) : null,
bank_name: data.bank_name || data.bankName || '',
bank_account: data.bank_account || data.bankAccount || '',
status: data.status || 1,
tenant_id: data.tenant_id || tenantId,
};
// 验证员工的部门ID是否在当前租户的部门树中存在
console.log('=== 编辑员工数据 ===');
console.log('员工数据:', data);
console.log('员工department_id:', data.department_id, typeof data.department_id);
console.log('当前部门树:', departmentTree.value);
console.log('form.department_id (设置前):', form.value.department_id);
if (form.value.department_id) {
// 检查部门是否在部门树中(递归查找)
const findDepartmentInTree = (tree: any[], deptId: number): any => {
for (const node of tree) {
// 确保id类型匹配
const nodeId = Number(node.id);
console.log(`比较节点: nodeId=${nodeId}, deptId=${deptId}, 匹配=${nodeId === deptId}`);
if (nodeId === deptId) {
return node;
}
if (node.children && node.children.length > 0) {
const found = findDepartmentInTree(node.children, deptId);
if (found) {
return found;
}
}
}
return null;
};
const deptId = Number(form.value.department_id);
const foundNode = findDepartmentInTree(departmentTree.value, deptId);
if (!foundNode) {
console.warn(`⚠️ 员工的部门ID ${deptId} 不在当前租户的部门树中尝试通过API获取部门信息`);
// 如果部门不在树中尝试通过API获取该部门信息
try {
const deptRes = await getDepartmentInfo(deptId);
const deptData = deptRes.data || deptRes;
if (deptData && deptData.name) {
console.log(`✅ 通过API获取到部门信息: ${deptData.name}`);
// 如果获取到部门信息,将该部门添加到部门树中(作为临时节点)
const tempDept = {
id: deptId,
name: deptData.name,
tenant_id: deptData.tenant_id,
parent_id: deptData.parent_id || 0,
children: []
};
// 如果parent_id为0添加到根节点否则尝试找到父节点
if (tempDept.parent_id === 0 || !tempDept.parent_id) {
departmentTree.value.push(tempDept);
} else {
// 尝试找到父节点并添加到其children中
const findParent = (tree: any[], parentId: number): any => {
for (const node of tree) {
if (Number(node.id) === parentId) {
return node;
}
if (node.children && node.children.length > 0) {
const found = findParent(node.children, parentId);
if (found) return found;
}
}
return null;
};
const parent = findParent(departmentTree.value, tempDept.parent_id);
if (parent) {
parent.children.push(tempDept);
} else {
// 找不到父节点,作为根节点添加
departmentTree.value.push(tempDept);
}
}
form.value.department_id = deptId;
} else {
// 如果获取不到部门信息保留ID值让el-tree-select尝试显示
form.value.department_id = deptId;
}
} catch (error) {
console.error('获取部门信息失败:', error);
// 即使获取失败也保留ID值
form.value.department_id = deptId;
}
} else {
console.log('✅ 找到部门节点:', foundNode);
// 确保使用数字类型
form.value.department_id = deptId;
console.log('form.department_id (设置后):', form.value.department_id);
}
}
// 先加载职位列表
if (form.value.department_id) {
await fetchPositions(form.value.department_id);
} else {
await fetchPositions(); // 加载所有职位
}
// 如果职位ID存在确保职位列表中有该职位如果没有则通过API获取
if (form.value.position_id) {
const positionId = Number(form.value.position_id);
// 检查职位是否已存在(避免重复添加)
const positionExists = positionList.value.some((pos: any) => Number(pos.id) === positionId);
if (!positionExists) {
console.warn(`⚠️ 职位ID ${positionId} 不在当前职位列表中尝试通过API获取职位信息`);
try {
const posRes = await getPositionInfo(positionId);
const posData = posRes.data || posRes;
if (posData && posData.name) {
console.log(`✅ 通过API获取到职位信息: ${posData.name}`);
// 再次检查是否已存在(防止异步操作期间重复添加)
const alreadyExists = positionList.value.some((pos: any) => Number(pos.id) === positionId);
if (!alreadyExists) {
// 将职位添加到职位列表中,然后去重
positionList.value.push({
id: posData.id || positionId,
name: posData.name,
code: posData.code || '',
level: posData.level || 0,
description: posData.description || '',
status: posData.status || 1,
});
// 再次去重,确保没有重复
const uniquePositions = new Map<number, any>();
positionList.value.forEach((pos: any) => {
const posId = Number(pos.id);
if (posId && !uniquePositions.has(posId)) {
uniquePositions.set(posId, pos);
}
});
positionList.value = Array.from(uniquePositions.values());
}
}
} catch (error) {
console.error('获取职位信息失败:', error);
}
}
}
// 等待一个tick确保DOM更新完成
await nextTick();
console.log('=== 编辑完成等待DOM更新 ===');
} catch (e) {
console.error('加载员工信息失败:', e);
ElMessage.error("加载员工信息失败");
return;
}
dialogVisible.value = true;
};
const submitForm = async () => {
try {
if (isEdit.value) {
// 检查ID是否存在
if (!form.value.id || form.value.id === 0) {
ElMessage.error("员工ID不能为空请重新选择员工");
return;
}
// 构建提交数据
const submitData: any = {
id: form.value.id,
employee_no: form.value.employeeNo,
name: form.value.name,
phone: form.value.phone,
email: form.value.email,
department_id: form.value.department_id || 0,
position_id: form.value.position_id || 0,
bank_name: form.value.bank_name || '',
bank_account: form.value.bank_account || '',
status: form.value.status,
};
if (form.value.tenant_id) {
submitData.tenant_id = form.value.tenant_id;
}
await editEmployee(form.value.id, submitData);
ElMessage.success({
message: "更新成功",
type: "success",
customClass: "my-el-message-success",
showClose: true,
center: true,
offset: 60,
});
dialogVisible.value = false;
fetchEmployees();
} else {
// 构建提交数据
const submitData: any = {
employee_no: form.value.employeeNo,
name: form.value.name,
phone: form.value.phone,
email: form.value.email,
department_id: form.value.department_id || 0,
position_id: form.value.position_id || 0,
bank_name: form.value.bank_name || '',
bank_account: form.value.bank_account || '',
status: form.value.status,
};
if (form.value.tenant_id) {
submitData.tenant_id = form.value.tenant_id;
}
await addEmployee(submitData);
ElMessage.success({
message: "添加成功",
type: "success",
customClass: "my-el-message-success",
showClose: true,
center: true,
offset: 60,
});
dialogVisible.value = false;
fetchEmployees();
}
} catch (e: any) {
// 显示具体的错误信息
const errorMsg = e?.response?.data?.message || e?.message || "操作失败";
ElMessage.error(errorMsg);
}
};
const handleDelete = async (employee: Employee) => {
ElMessageBox.confirm("确认删除该员工?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(async () => {
try {
await deleteEmployee(employee.id);
ElMessage.success("删除成功");
fetchEmployees();
} catch (e) {
ElMessage.error("删除失败");
}
});
};
// 重置密码
const handleResetPassword = async (employee: Employee) => {
ElMessageBox.confirm("确认重置该员工密码为默认密码yunzer123", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(async () => {
try {
const res = await resetEmployeePassword(employee.id);
if (res.code === 0 || res.success) {
ElMessage.success("密码重置成功,新密码为: yunzer123");
} else {
ElMessage.error(res.message || "重置密码失败");
}
} catch (e: any) {
const errorMsg = e?.response?.data?.message || e?.message || "重置密码失败";
ElMessage.error(errorMsg);
}
});
};
// 修改密码
const handleChangePassword = (employee: Employee) => {
currentEmployeeId.value = employee.id;
passwordForm.value = {
old_password: "",
new_password: "",
confirm_password: "",
};
passwordDialogVisible.value = true;
};
// 提交密码修改
const submitPasswordForm = async () => {
if (!passwordForm.value.new_password) {
ElMessage.error("新密码不能为空");
return;
}
if (passwordForm.value.new_password !== passwordForm.value.confirm_password) {
ElMessage.error("两次输入的新密码不一致");
return;
}
if (passwordForm.value.new_password.length < 6) {
ElMessage.error("新密码长度不能少于6位");
return;
}
if (!currentEmployeeId.value) {
ElMessage.error("员工ID无效");
return;
}
try {
const res = await changeEmployeePassword(currentEmployeeId.value, {
old_password: passwordForm.value.old_password,
new_password: passwordForm.value.new_password,
});
if (res.code === 0 || res.success) {
ElMessage.success("密码修改成功");
passwordDialogVisible.value = false;
passwordForm.value = {
old_password: "",
new_password: "",
confirm_password: "",
};
} else {
ElMessage.error(res.message || "修改密码失败");
}
} catch (e: any) {
const errorMsg = e?.response?.data?.message || e?.message || "修改密码失败";
ElMessage.error(errorMsg);
}
};
</script>
<style lang="less" scoped>
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
span {
font-size: 1.4rem;
font-weight: 700;
}
}
</style>