815 lines
23 KiB
Vue
815 lines
23 KiB
Vue
<template>
|
||
<div class="container-box">
|
||
<div class="header-bar">
|
||
<h2>用户管理</h2>
|
||
<div class="header-actions">
|
||
<el-button type="primary" @click="handleAddUser">
|
||
<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="users" style="width: 100%" v-loading="loading">
|
||
<el-table-column
|
||
prop="username"
|
||
label="用户名"
|
||
width="150"
|
||
align="center"
|
||
/>
|
||
<el-table-column
|
||
prop="nickname"
|
||
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="role" label="角色" width="150" align="center">
|
||
<template #default="scope">
|
||
<el-tag :type="getRoleTagType(scope.row.roleName)">
|
||
{{ scope.row.roleName || '未分配角色' }}
|
||
</el-tag>
|
||
</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="lastLoginTime"
|
||
label="最后登录"
|
||
width="180"
|
||
align="center"
|
||
/>
|
||
<el-table-column
|
||
prop="lastLoginIp"
|
||
label="最后登录IP"
|
||
width="150"
|
||
align="center"
|
||
>
|
||
<template #default="scope">
|
||
<span>{{ scope.row.lastLoginIp || '未知' }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="240" align="center" fixed="right">
|
||
<template #default="scope">
|
||
<el-button size="small" @click="handleEdit(scope.row)"
|
||
>编辑</el-button
|
||
>
|
||
<el-button size="small" type="warning" @click="handleChangePassword(scope.row)">
|
||
修改密码
|
||
</el-button>
|
||
<el-button
|
||
v-if="scope.row.username !== 'admin'"
|
||
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="currentForm">
|
||
<el-form-item label="用户名" v-show="dialogTitle !== '修改密码'">
|
||
<el-input v-model="form.username" />
|
||
</el-form-item>
|
||
<el-form-item label="昵称" v-if="dialogTitle !== '修改密码'">
|
||
<el-input v-model="form.nickname" />
|
||
</el-form-item>
|
||
<el-form-item label="密码" v-if="dialogTitle === '添加用户'">
|
||
<el-input
|
||
v-model="form.password"
|
||
type="password"
|
||
autocomplete="new-password"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="旧密码" v-if="dialogTitle === '修改密码'">
|
||
<el-input
|
||
v-model="passwordForm.oldPassword"
|
||
type="password"
|
||
autocomplete="current-password"
|
||
show-password
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="新密码" v-if="dialogTitle === '修改密码'">
|
||
<el-input
|
||
v-model="passwordForm.newPassword"
|
||
type="password"
|
||
autocomplete="new-password"
|
||
show-password
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="确认密码" v-if="dialogTitle === '修改密码'">
|
||
<el-input
|
||
v-model="passwordForm.confirmPassword"
|
||
type="password"
|
||
autocomplete="new-password"
|
||
show-password
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item v-if="dialogTitle === '修改密码' && passwordError">
|
||
<el-alert :title="passwordError" type="error" :closable="false" style="color: #f56c6c;" />
|
||
</el-form-item>
|
||
<el-form-item label="邮箱" v-if="dialogTitle !== '修改密码'">
|
||
<el-input v-model="form.email" />
|
||
</el-form-item>
|
||
<el-form-item label="部门" v-if="dialogTitle !== '修改密码'">
|
||
<el-select
|
||
v-model="form.department_id"
|
||
placeholder="请选择部门"
|
||
style="width: 100%"
|
||
:loading="loadingDepartments"
|
||
clearable
|
||
@change="handleDepartmentChange"
|
||
>
|
||
<el-option
|
||
v-for="dept in departmentList"
|
||
:key="dept.id"
|
||
:label="dept.name"
|
||
:value="dept.id"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="职位" v-if="dialogTitle !== '修改密码'">
|
||
<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="角色" v-if="dialogTitle !== '修改密码'">
|
||
<el-select
|
||
v-model="form.role"
|
||
placeholder="请选择角色"
|
||
style="width: 100%"
|
||
:loading="loadingRoles"
|
||
>
|
||
<el-option
|
||
v-for="role in roleList"
|
||
:key="role.roleId"
|
||
:label="role.roleName"
|
||
:value="role.roleId"
|
||
>
|
||
<span>{{ role.roleName }}</span>
|
||
<span style="color: #8492a6; font-size: 13px; margin-left: 8px;">
|
||
({{ role.roleCode }})
|
||
</span>
|
||
</el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="状态" v-if="dialogTitle !== '修改密码'">
|
||
<el-select v-model="form.status">
|
||
<el-option label="启用" value="active" />
|
||
<el-option label="禁用" value="disabled" />
|
||
</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>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, computed, onMounted } from "vue";
|
||
import { ElMessage, ElMessageBox } from "element-plus";
|
||
import { Plus, Refresh } from "@element-plus/icons-vue";
|
||
import {
|
||
getAllUsers,
|
||
getTenantUsers,
|
||
addUser,
|
||
editUser,
|
||
deleteUser,
|
||
getUserInfo,
|
||
changePassword,
|
||
} from "@/api/user";
|
||
import { getRoleByTenantId } from "@/api/role";
|
||
import { getTenantDepartments } from "@/api/department";
|
||
import { getTenantPositions, getPositionsByDepartment } from "@/api/position";
|
||
import { useAuthStore } from "@/stores/auth";
|
||
|
||
interface User {
|
||
id: number;
|
||
username: string;
|
||
nickname: string;
|
||
email: string;
|
||
role: string;
|
||
status: string;
|
||
lastLogin: string;
|
||
tenant_id: number;
|
||
}
|
||
|
||
const authStore = useAuthStore();
|
||
|
||
const page = ref(1);
|
||
const pageSize = ref(10);
|
||
const total = ref(0);
|
||
|
||
const users = ref<any[]>([]);
|
||
const roleList = ref<any[]>([]);
|
||
const loadingRoles = ref(false);
|
||
const departmentList = 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 fetchRoles = async () => {
|
||
loadingRoles.value = true;
|
||
try {
|
||
const tenantId = getCurrentTenantId();
|
||
const res = await getRoleByTenantId(tenantId);
|
||
if (res.code === 0 && res.data) {
|
||
roleList.value = Array.isArray(res.data) ? res.data : [];
|
||
} else {
|
||
roleList.value = [];
|
||
}
|
||
} catch (error: any) {
|
||
console.error('获取角色列表失败:', error);
|
||
roleList.value = [];
|
||
} finally {
|
||
loadingRoles.value = false;
|
||
}
|
||
};
|
||
|
||
// 获取部门列表
|
||
const fetchDepartments = async () => {
|
||
loadingDepartments.value = true;
|
||
try {
|
||
const tenantId = getCurrentTenantId();
|
||
const res = await getTenantDepartments(tenantId);
|
||
if (res.code === 0 && res.data) {
|
||
departmentList.value = Array.isArray(res.data) ? res.data : [];
|
||
} else {
|
||
departmentList.value = [];
|
||
}
|
||
} catch (error: any) {
|
||
console.error('获取部门列表失败:', error);
|
||
departmentList.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);
|
||
}
|
||
if (res.code === 0 && res.data) {
|
||
positionList.value = Array.isArray(res.data) ? res.data : [];
|
||
} else {
|
||
positionList.value = [];
|
||
}
|
||
} 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(); // 加载所有职位
|
||
}
|
||
};
|
||
|
||
// 获取角色标签类型
|
||
const getRoleTagType = (roleName: string) => {
|
||
if (!roleName) return 'info';
|
||
if (roleName.includes('管理员')) return 'danger';
|
||
if (roleName.includes('用户')) return 'primary';
|
||
return 'success';
|
||
};
|
||
|
||
//校验密码
|
||
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 fetchUsers = async () => {
|
||
loading.value = true;
|
||
// 传tenantid给接口
|
||
let tenantId = getCurrentTenantId ? getCurrentTenantId() : null;
|
||
try {
|
||
const res = await getTenantUsers(tenantId);
|
||
// 兼容接口返回的数据结构
|
||
let userList: any[] = [];
|
||
if (Array.isArray(res)) {
|
||
userList = res;
|
||
} else if (res?.data && Array.isArray(res.data)) {
|
||
userList = res.data;
|
||
} else if (res?.data?.data && Array.isArray(res.data.data)) {
|
||
userList = res.data.data;
|
||
} else if (res?.data) {
|
||
userList = res.data;
|
||
}
|
||
// 映射接口字段到表格所需结构
|
||
users.value = userList.map((item: any) => {
|
||
// 查找角色名称
|
||
let roleName = '';
|
||
let roleValue = item.role || null; // role 字段存储的是角色ID(数字)
|
||
|
||
if (roleValue) {
|
||
// 通过角色ID查找角色信息
|
||
const roleInfo = roleList.value.find(r => r.roleId === roleValue);
|
||
roleName = roleInfo ? roleInfo.roleName : '';
|
||
}
|
||
|
||
// 查找部门名称
|
||
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 : '';
|
||
}
|
||
|
||
// 处理最后登录时间,后端返回的是 last_login_time
|
||
const lastLoginTime = item.last_login_time || item.lastLoginTime || null;
|
||
// 处理最后登录IP,后端返回的是 last_login_ip
|
||
const lastLoginIp = item.last_login_ip || item.lastLoginIp || null;
|
||
|
||
return {
|
||
id: item.id,
|
||
username: item.username,
|
||
nickname: item.nickname,
|
||
email: item.email,
|
||
role: roleValue,
|
||
roleName: roleName,
|
||
department_id: departmentId,
|
||
departmentName: departmentName,
|
||
position_id: positionId,
|
||
positionName: positionName,
|
||
status: item.status,
|
||
lastLoginTime: lastLoginTime
|
||
? new Date(lastLoginTime).toLocaleString("zh-CN", {
|
||
year: "numeric",
|
||
month: "2-digit",
|
||
day: "2-digit",
|
||
hour: "2-digit",
|
||
minute: "2-digit",
|
||
second: "2-digit",
|
||
hour12: false,
|
||
})
|
||
: "从未登录",
|
||
lastLoginIp: lastLoginIp || null,
|
||
};
|
||
});
|
||
total.value = users.value.length;
|
||
} catch (e) {
|
||
users.value = [];
|
||
total.value = 0;
|
||
} finally {
|
||
loading.value = false;
|
||
}
|
||
};
|
||
|
||
onMounted(async () => {
|
||
// 先加载角色、部门、职位列表,再加载用户列表
|
||
await Promise.all([
|
||
fetchRoles(),
|
||
fetchDepartments(),
|
||
fetchPositions(),
|
||
]);
|
||
fetchUsers();
|
||
});
|
||
|
||
const handlePageChange = (p: number) => {
|
||
page.value = p;
|
||
// 分页仅前端做演示
|
||
};
|
||
|
||
// 为添加 / 编辑对话框而添加
|
||
const dialogVisible = ref(false);
|
||
const dialogTitle = ref("");
|
||
const isEdit = ref(false);
|
||
const form = ref<any>({
|
||
id: null,
|
||
username: "",
|
||
nickname: "",
|
||
password: "",
|
||
email: "",
|
||
role: null, // role 字段存储角色ID
|
||
status: "active",
|
||
tenant_id: null,
|
||
});
|
||
const passwordForm = ref<any>({
|
||
oldPassword: "",
|
||
newPassword: "",
|
||
confirmPassword: "",
|
||
});
|
||
|
||
const passwordError = ref("");
|
||
|
||
// 根据对话框类型返回对应的表单数据
|
||
const currentForm = computed(() => {
|
||
return dialogTitle.value === '修改密码' ? passwordForm.value : form.value;
|
||
});
|
||
|
||
//刷新界面
|
||
const refresh = async () => {
|
||
loading.value = true;
|
||
try {
|
||
await Promise.all([
|
||
fetchRoles(),
|
||
fetchDepartments(),
|
||
fetchPositions(),
|
||
]);
|
||
await fetchUsers();
|
||
ElMessage.success('刷新成功');
|
||
} catch (error) {
|
||
ElMessage.error('刷新失败');
|
||
} finally {
|
||
loading.value = false;
|
||
}
|
||
};
|
||
|
||
const handleAddUser = () => {
|
||
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, // 添加用户时ID为0
|
||
username: "",
|
||
nickname: "",
|
||
password: "",
|
||
email: "",
|
||
role: null, // role 字段存储角色ID
|
||
department_id: null,
|
||
position_id: null,
|
||
status: "active",
|
||
tenant_id: tenantId,
|
||
};
|
||
// 重新加载职位列表(所有职位)
|
||
fetchPositions();
|
||
dialogVisible.value = true;
|
||
};
|
||
|
||
const handleEdit = async (user: User) => {
|
||
dialogTitle.value = "编辑用户";
|
||
isEdit.value = true;
|
||
try {
|
||
const res = await getUserInfo(user.id);
|
||
const data = res.data || res;
|
||
|
||
// 获取当前租户ID
|
||
const tenantId = getCurrentTenantId();
|
||
|
||
// 处理角色:data.role 存储的是角色ID(数字)
|
||
let roleValue = data.role || null;
|
||
|
||
// 处理状态:后端返回的是数字(0或1),前端使用字符串("active"或"inactive")
|
||
let statusStr = "active";
|
||
if (typeof data.status === 'number') {
|
||
statusStr = data.status === 1 ? "active" : "inactive";
|
||
} else if (typeof data.status === 'string') {
|
||
statusStr = data.status;
|
||
}
|
||
|
||
form.value = {
|
||
id: data.id,
|
||
username: data.username,
|
||
nickname: data.nickname,
|
||
password: "",
|
||
email: data.email,
|
||
role: roleValue, // role 字段存储角色ID
|
||
department_id: data.department_id || null,
|
||
position_id: data.position_id || null,
|
||
status: statusStr,
|
||
tenant_id: data.tenant_id || tenantId,
|
||
};
|
||
|
||
// 如果用户有部门,根据部门加载职位列表
|
||
if (form.value.department_id) {
|
||
fetchPositions(form.value.department_id);
|
||
} else {
|
||
fetchPositions(); // 加载所有职位
|
||
}
|
||
} catch (e) {
|
||
ElMessage.error("加载用户失败");
|
||
return;
|
||
}
|
||
dialogVisible.value = true;
|
||
};
|
||
|
||
const submitForm = async () => {
|
||
// 清除之前的错误
|
||
passwordError.value = "";
|
||
|
||
try {
|
||
if (dialogTitle.value === "修改密码") {
|
||
// 校验旧密码
|
||
if (!passwordForm.value.oldPassword) {
|
||
passwordError.value = "请输入旧密码";
|
||
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;
|
||
}
|
||
|
||
const res = await changePassword(form.value.id, passwordForm.value);
|
||
|
||
// 检查返回结果
|
||
if (res.code === 0) {
|
||
// 先显示成功消息
|
||
ElMessage.success({
|
||
message: "密码修改成功",
|
||
type: "success",
|
||
customClass: "my-el-message-success",
|
||
showClose: true,
|
||
center: true,
|
||
offset: 60,
|
||
});
|
||
// 延迟关闭弹窗,确保消息已经渲染
|
||
setTimeout(() => {
|
||
dialogVisible.value = false;
|
||
// 重置密码表单
|
||
passwordForm.value = {
|
||
oldPassword: "",
|
||
newPassword: "",
|
||
confirmPassword: "",
|
||
};
|
||
}, 100);
|
||
} else {
|
||
passwordError.value = res.message || "密码修改失败";
|
||
}
|
||
} else if (isEdit.value) {
|
||
// 检查ID是否存在
|
||
if (!form.value.id || form.value.id === 0) {
|
||
ElMessage.error("用户ID不能为空,请重新选择用户");
|
||
return;
|
||
}
|
||
|
||
// 构建提交数据
|
||
const submitData: any = {
|
||
id: form.value.id,
|
||
username: form.value.username,
|
||
nickname: form.value.nickname,
|
||
email: form.value.email,
|
||
status: form.value.status,
|
||
};
|
||
|
||
// role 字段存储角色ID
|
||
if (form.value.role) {
|
||
submitData.role = form.value.role; // 后端接收 role 参数
|
||
}
|
||
|
||
// 部门和职位ID
|
||
if (form.value.department_id) {
|
||
submitData.department_id = form.value.department_id;
|
||
}
|
||
if (form.value.position_id) {
|
||
submitData.position_id = form.value.position_id;
|
||
}
|
||
|
||
if (form.value.tenant_id) {
|
||
submitData.tenant_id = form.value.tenant_id;
|
||
}
|
||
|
||
console.log('编辑用户提交数据:', submitData); // 调试日志
|
||
await editUser(form.value.id, submitData);
|
||
ElMessage.success({
|
||
message: "更新成功",
|
||
type: "success",
|
||
customClass: "my-el-message-success",
|
||
showClose: true,
|
||
center: true,
|
||
offset: 60,
|
||
});
|
||
dialogVisible.value = false;
|
||
fetchUsers();
|
||
} else {
|
||
// 构建提交数据
|
||
const submitData: any = {
|
||
username: form.value.username,
|
||
nickname: form.value.nickname,
|
||
password: form.value.password,
|
||
email: form.value.email,
|
||
status: form.value.status,
|
||
};
|
||
|
||
// role 字段存储角色ID
|
||
if (form.value.role) {
|
||
submitData.role = form.value.role; // 后端接收 role 参数
|
||
}
|
||
|
||
// 部门和职位ID
|
||
if (form.value.department_id) {
|
||
submitData.department_id = form.value.department_id;
|
||
}
|
||
if (form.value.position_id) {
|
||
submitData.position_id = form.value.position_id;
|
||
}
|
||
|
||
if (form.value.tenant_id) {
|
||
submitData.tenant_id = form.value.tenant_id;
|
||
}
|
||
|
||
console.log('添加用户提交数据:', submitData); // 调试日志
|
||
await addUser(submitData);
|
||
ElMessage.success({
|
||
message: "添加成功",
|
||
type: "success",
|
||
customClass: "my-el-message-success",
|
||
showClose: true,
|
||
center: true,
|
||
offset: 60,
|
||
});
|
||
dialogVisible.value = false;
|
||
fetchUsers();
|
||
}
|
||
} catch (e: any) {
|
||
// 显示具体的错误信息
|
||
const errorMsg = e?.response?.data?.message || e?.message || "操作失败";
|
||
if (dialogTitle.value === "修改密码") {
|
||
passwordError.value = errorMsg;
|
||
} else {
|
||
ElMessage.error(errorMsg);
|
||
}
|
||
}
|
||
};
|
||
|
||
const handleDelete = async (user: User) => {
|
||
ElMessageBox.confirm("确认删除该用户?", "提示", {
|
||
confirmButtonText: "确定",
|
||
cancelButtonText: "取消",
|
||
type: "warning",
|
||
}).then(async () => {
|
||
try {
|
||
await deleteUser(user.id);
|
||
ElMessage.success("删除成功");
|
||
fetchUsers();
|
||
} catch (e) {
|
||
ElMessage.error("删除失败");
|
||
}
|
||
});
|
||
};
|
||
|
||
//修改密码
|
||
const handleChangePassword = async (user: User) => {
|
||
dialogTitle.value = "修改密码";
|
||
isEdit.value = true;
|
||
passwordError.value = "";
|
||
form.value = {
|
||
id: user.id,
|
||
username: user.username,
|
||
};
|
||
passwordForm.value = {
|
||
oldPassword: "",
|
||
newPassword: "",
|
||
confirmPassword: "",
|
||
};
|
||
dialogVisible.value = true;
|
||
};
|
||
</script>
|
||
|
||
<style lang="less" scoped>
|
||
.card-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
|
||
span {
|
||
font-size: 1.4rem;
|
||
font-weight: 700;
|
||
}
|
||
}
|
||
|
||
:deep(.el-alert__title) {
|
||
color: #f56c6c !important;
|
||
}
|
||
</style>
|