191 lines
4.6 KiB
Vue
191 lines
4.6 KiB
Vue
<template>
|
||
<el-drawer v-model="visible" title="用户信息预览" size="50%">
|
||
<div class="user-preview" v-if="user">
|
||
<div class="user-header">
|
||
<div class="user-avatar">
|
||
<el-avatar :size="80" :icon="UserFilled" />
|
||
</div>
|
||
<h2 class="user-name">{{ user.name || "未知用户" }}</h2>
|
||
<el-tag :type="user.status === 1 ? 'success' : 'danger'" size="large">
|
||
{{ user.status === 1 ? "启用" : "禁用" }}
|
||
</el-tag>
|
||
</div>
|
||
|
||
<el-divider />
|
||
|
||
<div class="user-info">
|
||
<el-descriptions :column="2" border>
|
||
<el-descriptions-item label="ID">
|
||
{{ user.id }}
|
||
</el-descriptions-item>
|
||
<el-descriptions-item label="账号">
|
||
{{ user.account || "未设置" }}
|
||
</el-descriptions-item>
|
||
<el-descriptions-item label="姓名">
|
||
{{ user.name || "未设置" }}
|
||
</el-descriptions-item>
|
||
<el-descriptions-item label="性别">
|
||
{{ user.sex === 1 ? "男" : "女" }}
|
||
</el-descriptions-item>
|
||
<el-descriptions-item label="手机号">
|
||
{{ user.phone || "未设置" }}
|
||
</el-descriptions-item>
|
||
<el-descriptions-item label="QQ">
|
||
{{ user.qq || "未设置" }}
|
||
</el-descriptions-item>
|
||
<el-descriptions-item label="邮箱">
|
||
{{ user.email || "未设置" }}
|
||
</el-descriptions-item>
|
||
<el-descriptions-item label="角色">
|
||
<el-tag :type="getRoleTagType(user.rid)" size="small">
|
||
{{ getRoleName(user.rid) }}
|
||
</el-tag>
|
||
</el-descriptions-item>
|
||
<el-descriptions-item label="最后登录IP">
|
||
{{ user.last_login_ip || "未登录" }}
|
||
</el-descriptions-item>
|
||
<el-descriptions-item label="登录次数">
|
||
{{ user.login_count || 0 }}
|
||
</el-descriptions-item>
|
||
<el-descriptions-item label="创建时间">
|
||
{{ user.create_time || "未知" }}
|
||
</el-descriptions-item>
|
||
<el-descriptions-item label="更新时间" :span="2">
|
||
{{ user.update_time || "未知" }}
|
||
</el-descriptions-item>
|
||
</el-descriptions>
|
||
</div>
|
||
</div>
|
||
<div v-else class="no-user">
|
||
<el-empty description="暂无用户信息" />
|
||
</div>
|
||
</el-drawer>
|
||
</template>
|
||
|
||
<script lang="ts" setup>
|
||
import { ref, watch } from "vue";
|
||
import { UserFilled } from "@element-plus/icons-vue";
|
||
import { getAllRoles } from "@/api/role";
|
||
|
||
interface User {
|
||
id: number;
|
||
account: string;
|
||
name: string;
|
||
phone: string;
|
||
qq: string;
|
||
email: string;
|
||
sex: number;
|
||
rid: number;
|
||
status: number;
|
||
last_login_ip: string;
|
||
login_count: number;
|
||
create_time: string;
|
||
update_time: string;
|
||
}
|
||
|
||
interface Role {
|
||
id: number;
|
||
name: string;
|
||
}
|
||
|
||
const props = defineProps({
|
||
modelValue: {
|
||
type: Boolean,
|
||
default: false,
|
||
},
|
||
user: {
|
||
type: Object as () => User | undefined,
|
||
default: undefined,
|
||
},
|
||
});
|
||
|
||
const emit = defineEmits(["update:modelValue"]);
|
||
|
||
const visible = ref(false);
|
||
const roles = ref<Role[]>([]);
|
||
|
||
// 监听对话框显示状态
|
||
watch(
|
||
() => props.modelValue,
|
||
(newVal) => {
|
||
visible.value = newVal;
|
||
}
|
||
);
|
||
|
||
// 监听visible变化,同步给父组件
|
||
watch(visible, (newVal) => {
|
||
emit("update:modelValue", newVal);
|
||
});
|
||
|
||
// 获取角色列表
|
||
const fetchRoles = async () => {
|
||
try {
|
||
const res = await getAllRoles();
|
||
roles.value = res.data || [];
|
||
} catch (e) {
|
||
roles.value = [];
|
||
}
|
||
};
|
||
|
||
// 获取角色tag状态
|
||
function getRoleTagType(rid: number): string {
|
||
const typeMap: Record<number, string> = {
|
||
1: "primary",
|
||
2: "success",
|
||
3: "warning",
|
||
4: "danger",
|
||
};
|
||
return typeMap[rid] || "primary";
|
||
}
|
||
|
||
// 获取角色名称
|
||
function getRoleName(rid: number): string {
|
||
const role = roles.value.find((r) => r.id === rid);
|
||
return role?.name || "未知";
|
||
}
|
||
|
||
// 暴露open方法供父组件调用
|
||
const open = (userData?: User) => {
|
||
visible.value = true;
|
||
fetchRoles();
|
||
};
|
||
|
||
defineExpose({
|
||
open,
|
||
});
|
||
|
||
// 初始化时获取角色列表
|
||
fetchRoles();
|
||
</script>
|
||
|
||
<style lang="less" scoped>
|
||
.user-preview {
|
||
padding: 20px;
|
||
|
||
.user-header {
|
||
text-align: center;
|
||
padding: 20px 0;
|
||
|
||
.user-avatar {
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.user-name {
|
||
margin: 15px 0;
|
||
font-size: 24px;
|
||
font-weight: 600;
|
||
color: #303133;
|
||
}
|
||
}
|
||
|
||
.user-info {
|
||
margin-top: 20px;
|
||
}
|
||
}
|
||
|
||
.no-user {
|
||
padding: 40px 0;
|
||
text-align: center;
|
||
}
|
||
</style>
|