<template>
|
<el-container>
|
<el-container>
|
<el-header style="padding-top: 10px; margin-left: 10px; height: 50px">
|
<div class="env__header">
|
<div class="env__header--item">
|
<el-input
|
style="width: 300px"
|
size="small"
|
placeholder="请输入用户名或姓名"
|
v-model="search"
|
clearable
|
>
|
</el-input>
|
</div>
|
|
<div class="env__header--item">
|
<el-button
|
plain
|
size="small"
|
icon="el-icon-refresh"
|
@click="resetSearch"
|
>重置</el-button
|
>
|
</div>
|
|
<div class="env__header--item" v-if="isSuperuser">
|
<el-button
|
type="primary"
|
size="small"
|
icon="el-icon-plus"
|
@click="handleAdd"
|
>新增用户</el-button
|
>
|
</div>
|
|
<div class="env__header--item" v-if="isSuperuser || isStaff">
|
<el-button
|
type="success"
|
size="small"
|
icon="el-icon-s-check"
|
@click="handleApproval"
|
>注册用户审批</el-button
|
>
|
</div>
|
</div>
|
</el-header>
|
|
<el-dialog
|
:title="dialogTitle"
|
width="50%"
|
:close-on-click-modal="false"
|
:visible.sync="dialogVisible"
|
@close="handleDialogClose"
|
>
|
<el-form
|
:inline="true"
|
label-position="right"
|
:model="userForm"
|
:rules="rules"
|
ref="userForm"
|
label-width="100px"
|
>
|
<el-form-item label="用户名" prop="username" v-if="isCreate">
|
<el-input v-model="userForm.username" placeholder="请输入用户名"></el-input>
|
</el-form-item>
|
|
<el-form-item label="用户名" prop="username" v-if="!isCreate">
|
<el-input v-model="userForm.username" disabled></el-input>
|
</el-form-item>
|
|
<el-form-item label="姓名" prop="name">
|
<el-input v-model="userForm.name" placeholder="请输入姓名"></el-input>
|
</el-form-item>
|
|
<el-form-item label="手机号" prop="phone">
|
<el-input v-model="userForm.phone" placeholder="请输入手机号"></el-input>
|
</el-form-item>
|
|
<el-form-item label="密码" prop="password" v-if="isCreate">
|
<el-input
|
type="password"
|
v-model="userForm.password"
|
placeholder="请输入密码"
|
></el-input>
|
</el-form-item>
|
|
<el-form-item label="确认密码" prop="confirm_password" v-if="isCreate">
|
<el-input
|
type="password"
|
v-model="userForm.confirm_password"
|
placeholder="请再次输入密码"
|
></el-input>
|
</el-form-item>
|
|
<el-form-item label="是否激活" prop="is_active" v-if="isSuperuser">
|
<el-switch v-model="userForm.is_active"></el-switch>
|
</el-form-item>
|
|
<el-form-item label="是否管理员" prop="is_staff" v-if="isSuperuser">
|
<el-switch v-model="userForm.is_staff"></el-switch>
|
</el-form-item>
|
|
<el-form-item label="超级用户" prop="is_superuser" v-if="isSuperuser">
|
<el-switch v-model="userForm.is_superuser"></el-switch>
|
</el-form-item>
|
|
<el-form-item label="显示Hosts" prop="show_hosts" v-if="isSuperuser">
|
<el-switch v-model="userForm.show_hosts"></el-switch>
|
</el-form-item>
|
|
<el-form-item label="所属分组" prop="groups" v-if="isSuperuser">
|
<el-select
|
v-model="userForm.groups"
|
multiple
|
placeholder="请选择分组"
|
style="width: 100%"
|
>
|
<el-option
|
v-for="group in groupList"
|
:key="group.id"
|
:label="group.name"
|
:value="group.id"
|
></el-option>
|
</el-select>
|
</el-form-item>
|
</el-form>
|
|
<span slot="footer" class="dialog-footer">
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
<el-button type="primary" @click="handleSubmit">确 定</el-button>
|
</span>
|
</el-dialog>
|
|
<el-dialog
|
title="用户详情"
|
width="50%"
|
:close-on-click-modal="false"
|
:visible.sync="detailDialogVisible"
|
>
|
<el-form
|
:inline="true"
|
label-position="right"
|
:model="userDetail"
|
label-width="100px"
|
>
|
<el-form-item label="用户名">
|
<el-input v-model="userDetail.username" readonly></el-input>
|
</el-form-item>
|
|
<el-form-item label="姓名">
|
<el-input v-model="userDetail.name" readonly></el-input>
|
</el-form-item>
|
|
<el-form-item label="手机号">
|
<el-input v-model="userDetail.phone" readonly></el-input>
|
</el-form-item>
|
|
<el-form-item label="是否激活">
|
<el-tag :type="userDetail.is_active ? 'success' : 'danger'">
|
{{ userDetail.is_active ? '是' : '否' }}
|
</el-tag>
|
</el-form-item>
|
|
<el-form-item label="是否管理员">
|
<el-tag :type="userDetail.is_staff ? 'success' : 'info'">
|
{{ userDetail.is_staff ? '是' : '否' }}
|
</el-tag>
|
</el-form-item>
|
|
<el-form-item label="超级用户">
|
<el-tag :type="userDetail.is_superuser ? 'success' : 'info'">
|
{{ userDetail.is_superuser ? '是' : '否' }}
|
</el-tag>
|
</el-form-item>
|
|
<el-form-item label="显示Hosts">
|
<el-tag :type="userDetail.show_hosts ? 'success' : 'info'">
|
{{ userDetail.show_hosts ? '是' : '否' }}
|
</el-tag>
|
</el-form-item>
|
|
<el-form-item label="所属分组">
|
<el-tag
|
v-for="group in userDetail.groups"
|
:key="group"
|
style="margin-right: 5px"
|
>
|
{{ group }}
|
</el-tag>
|
</el-form-item>
|
|
<el-form-item label="可访问项目">
|
<el-tag
|
v-for="project in userDetail.accessible_projects"
|
:key="project"
|
style="margin-right: 5px"
|
>
|
{{ project }}
|
</el-tag>
|
</el-form-item>
|
|
<el-form-item label="注册时间">
|
<el-input
|
:value="userDetail.date_joined | datetimeFormat"
|
readonly
|
></el-input>
|
</el-form-item>
|
|
<el-form-item label="最后登录">
|
<el-input
|
:value="userDetail.last_login ? (userDetail.last_login | datetimeFormat) : '从未登录'"
|
readonly
|
></el-input>
|
</el-form-item>
|
</el-form>
|
|
<span slot="footer" class="dialog-footer">
|
<el-button @click="detailDialogVisible = false">关 闭</el-button>
|
</span>
|
</el-dialog>
|
|
<el-drawer
|
title="注册用户审批"
|
:visible.sync="approvalDrawerVisible"
|
direction="rtl"
|
size="60%"
|
>
|
<div class="approval-container">
|
<el-table
|
:data="approvalData"
|
v-loading="approvalLoading"
|
stripe
|
style="width: 100%"
|
>
|
<el-table-column prop="username" label="用户名" width="120"></el-table-column>
|
<el-table-column prop="name" label="姓名" width="120"></el-table-column>
|
<el-table-column prop="phone" label="手机号" width="120"></el-table-column>
|
<el-table-column label="所属分组" width="200">
|
<template slot-scope="scope">
|
<el-tag
|
v-for="group in scope.row.groups"
|
:key="group"
|
size="mini"
|
style="margin-right: 3px"
|
>
|
{{ group }}
|
</el-tag>
|
</template>
|
</el-table-column>
|
<el-table-column label="状态" width="100">
|
<template slot-scope="scope">
|
<el-tag :type="getStatusType(scope.row.status)">
|
{{ scope.row.status_display }}
|
</el-tag>
|
</template>
|
</el-table-column>
|
<el-table-column label="注册时间" width="180">
|
<template slot-scope="scope">
|
{{ scope.row.date_joined | datetimeFormat }}
|
</template>
|
</el-table-column>
|
<el-table-column label="操作" fixed="right" width="200">
|
<template slot-scope="scope">
|
<el-button
|
type="success"
|
size="mini"
|
icon="el-icon-check"
|
@click="handleApprove(scope.row, 'approve')"
|
>
|
通过
|
</el-button>
|
<el-button
|
type="danger"
|
size="mini"
|
icon="el-icon-close"
|
@click="handleApprove(scope.row, 'reject')"
|
>
|
不通过
|
</el-button>
|
</template>
|
</el-table-column>
|
</el-table>
|
<div v-if="!approvalLoading && approvalData.length === 0" class="empty-tip">
|
<el-empty description="暂无待审批用户"></el-empty>
|
</div>
|
</div>
|
</el-drawer>
|
|
<el-container>
|
<el-main style="margin-left: 10px; margin-top: 10px">
|
<div class="user-body-table">
|
<el-table
|
highlight-current-row
|
stripe
|
:data="userData"
|
v-loading="isLoading"
|
height="calc(100%)"
|
@cell-mouse-enter="cellMouseEnter"
|
@cell-mouse-leave="cellMouseLeave"
|
>
|
<el-table-column label="用户名" width="120">
|
<template slot-scope="scope">
|
<div
|
:title="scope.row.username"
|
class="table-column"
|
>
|
{{ scope.row.username }}
|
</div>
|
</template>
|
</el-table-column>
|
|
<el-table-column label="姓名" width="120">
|
<template slot-scope="scope">
|
<div
|
:title="scope.row.name"
|
class="table-column"
|
>
|
{{ scope.row.name }}
|
</div>
|
</template>
|
</el-table-column>
|
|
<el-table-column label="手机号" width="120">
|
<template slot-scope="scope">
|
<div
|
:title="scope.row.phone"
|
class="table-column"
|
>
|
{{ scope.row.phone }}
|
</div>
|
</template>
|
</el-table-column>
|
|
<el-table-column label="是否激活" width="100">
|
<template slot-scope="scope">
|
<el-tag :type="scope.row.is_active ? 'success' : 'danger'">
|
{{ scope.row.is_active ? '是' : '否' }}
|
</el-tag>
|
</template>
|
</el-table-column>
|
|
<el-table-column label="是否管理员" width="100">
|
<template slot-scope="scope">
|
<el-tag :type="scope.row.is_staff ? 'success' : 'info'">
|
{{ scope.row.is_staff ? '是' : '否' }}
|
</el-tag>
|
</template>
|
</el-table-column>
|
|
<el-table-column label="超级用户" width="100">
|
<template slot-scope="scope">
|
<el-tag :type="scope.row.is_superuser ? 'success' : 'info'">
|
{{ scope.row.is_superuser ? '是' : '否' }}
|
</el-tag>
|
</template>
|
</el-table-column>
|
|
<el-table-column label="所属分组" width="200">
|
<template slot-scope="scope">
|
<div class="table-column">
|
<el-tag
|
v-for="group in scope.row.groups"
|
:key="group"
|
size="mini"
|
style="margin-right: 3px"
|
>
|
{{ group }}
|
</el-tag>
|
</div>
|
</template>
|
</el-table-column>
|
|
<el-table-column label="注册时间" width="180">
|
<template slot-scope="scope">
|
<div>
|
{{ scope.row.date_joined | datetimeFormat }}
|
</div>
|
</template>
|
</el-table-column>
|
|
<el-table-column label="操作" width="200" fixed="right">
|
<template slot-scope="scope">
|
<el-row v-show="currentRow === scope.row">
|
<el-button
|
type="success"
|
icon="el-icon-view"
|
title="查看"
|
circle
|
size="mini"
|
@click="handleView(scope.row)"
|
></el-button>
|
<el-button
|
type="primary"
|
icon="el-icon-edit"
|
title="编辑"
|
circle
|
size="mini"
|
v-if="isSuperuser"
|
@click="handleEdit(scope.row)"
|
></el-button>
|
<el-button
|
type="danger"
|
icon="el-icon-delete"
|
title="删除"
|
circle
|
size="mini"
|
v-if="isSuperuser && scope.row.id !== currentUserId"
|
@click="handleDelete(scope.row)"
|
></el-button>
|
</el-row>
|
</template>
|
</el-table-column>
|
</el-table>
|
</div>
|
</el-main>
|
</el-container>
|
</el-container>
|
</el-container>
|
</template>
|
|
<script>
|
export default {
|
name: "UserManagement",
|
data() {
|
var validateConfirmPassword = (rule, value, callback) => {
|
if (value !== this.userForm.password) {
|
callback(new Error("两次输入的密码不一致"));
|
} else {
|
callback();
|
}
|
};
|
|
return {
|
search: "",
|
currentRow: "",
|
isLoading: true,
|
userData: [],
|
groupList: [],
|
dialogVisible: false,
|
detailDialogVisible: false,
|
approvalDrawerVisible: false,
|
approvalLoading: false,
|
approvalData: [],
|
isCreate: false,
|
isSuperuser: false,
|
isStaff: false,
|
currentUserId: null,
|
userForm: {
|
id: null,
|
username: "",
|
name: "",
|
phone: "",
|
password: "",
|
confirm_password: "",
|
is_active: true,
|
is_staff: false,
|
is_superuser: false,
|
show_hosts: false,
|
groups: []
|
},
|
userDetail: {
|
username: "",
|
name: "",
|
phone: "",
|
is_active: false,
|
is_staff: false,
|
is_superuser: false,
|
show_hosts: false,
|
groups: [],
|
accessible_projects: [],
|
date_joined: "",
|
last_login: ""
|
},
|
rules: {
|
username: [
|
{ required: true, message: "请输入用户名", trigger: "blur" }
|
],
|
name: [
|
{ required: true, message: "请输入姓名", trigger: "blur" }
|
],
|
password: [
|
{ required: true, message: "请输入密码", trigger: "blur" },
|
{ min: 6, message: "密码长度不能少于6位", trigger: "blur" }
|
],
|
confirm_password: [
|
{ required: true, message: "请再次输入密码", trigger: "blur" },
|
{ validator: validateConfirmPassword, trigger: "blur" }
|
]
|
}
|
};
|
},
|
computed: {
|
dialogTitle() {
|
return this.isCreate ? "新增用户" : "编辑用户";
|
}
|
},
|
methods: {
|
cellMouseEnter(row) {
|
this.currentRow = row;
|
},
|
cellMouseLeave() {
|
this.currentRow = "";
|
},
|
handleAdd() {
|
this.isCreate = true;
|
this.dialogVisible = true;
|
this.resetForm();
|
},
|
handleEdit(row) {
|
this.isCreate = false;
|
this.dialogVisible = true;
|
this.userForm = {
|
id: row.id,
|
username: row.username,
|
name: row.name,
|
phone: row.phone,
|
is_active: row.is_active,
|
is_staff: row.is_staff,
|
is_superuser: row.is_superuser,
|
show_hosts: row.show_hosts,
|
groups: []
|
};
|
},
|
handleView(row) {
|
this.getUserDetail(row.id);
|
},
|
handleDelete(row) {
|
this.$confirm("确定要删除该用户吗?", "提示", {
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning"
|
}).then(() => {
|
this.$api.deleteUser(row.id).then(() => {
|
this.$message.success("删除成功");
|
this.getUserList();
|
});
|
}).catch(() => {});
|
},
|
handleSubmit() {
|
this.$refs.userForm.validate(valid => {
|
if (valid) {
|
if (this.isCreate) {
|
this.$api.createUser(this.userForm).then(() => {
|
this.$message.success("创建成功");
|
this.dialogVisible = false;
|
this.getUserList();
|
});
|
} else {
|
this.$api.updateUser(this.userForm.id, this.userForm).then(() => {
|
this.$message.success("更新成功");
|
this.dialogVisible = false;
|
this.getUserList();
|
});
|
}
|
}
|
});
|
},
|
handleDialogClose() {
|
this.$refs.userForm.resetFields();
|
},
|
resetForm() {
|
this.userForm = {
|
id: null,
|
username: "",
|
name: "",
|
phone: "",
|
password: "",
|
confirm_password: "",
|
is_active: true,
|
is_staff: false,
|
is_superuser: false,
|
show_hosts: false,
|
groups: []
|
};
|
},
|
getUserList() {
|
this.isLoading = true;
|
this.$api.getUserManagementList({ search: this.search }).then(resp => {
|
this.userData = resp.results || resp;
|
this.isLoading = false;
|
});
|
},
|
getUserDetail(userId) {
|
this.$api.getUserDetail(userId).then(resp => {
|
this.userDetail = resp;
|
this.detailDialogVisible = true;
|
});
|
},
|
getGroupList() {
|
this.$api.getGroupList().then(resp => {
|
this.groupList = resp;
|
});
|
},
|
resetSearch() {
|
this.search = "";
|
this.getUserList();
|
},
|
handleApproval() {
|
this.approvalDrawerVisible = true;
|
this.getApprovalList();
|
},
|
getApprovalList() {
|
this.approvalLoading = true;
|
this.$api.getUserApprovalList({ search: this.search }).then(resp => {
|
this.approvalData = resp.results || resp;
|
this.approvalLoading = false;
|
}).catch(() => {
|
this.approvalLoading = false;
|
});
|
},
|
getStatusType(status) {
|
const statusMap = {
|
'pending': 'warning',
|
'approved': 'success',
|
'rejected': 'danger'
|
};
|
return statusMap[status] || 'info';
|
},
|
handleApprove(row, action) {
|
const actionText = action === 'approve' ? '通过' : '不通过';
|
this.$confirm(`确定要${actionText}该用户的注册申请吗?`, "提示", {
|
confirmButtonText: "确定",
|
cancelButtonText: "取消",
|
type: "warning"
|
}).then(() => {
|
this.$api.approveUser(row.id, { action: action }).then(() => {
|
this.$message.success(`用户审批已${actionText}`);
|
this.getApprovalList();
|
});
|
}).catch(() => {});
|
}
|
},
|
watch: {
|
search() {
|
this.getUserList();
|
}
|
},
|
mounted() {
|
this.isSuperuser = this.$store.state.is_superuser;
|
this.isStaff = this.$store.state.is_staff;
|
this.currentUserId = this.$store.state.id;
|
this.getUserList();
|
if (this.isSuperuser) {
|
this.getGroupList();
|
}
|
}
|
};
|
</script>
|
|
<style scoped>
|
.env__header {
|
display: flex;
|
align-items: center;
|
margin-left: -30px;
|
}
|
|
.env__header--item {
|
display: flex;
|
margin-left: 10px;
|
}
|
|
.table-column {
|
overflow: hidden;
|
text-overflow: ellipsis;
|
white-space: nowrap;
|
}
|
|
.user-body-table {
|
position: fixed;
|
bottom: 0;
|
right: 0;
|
left: 220px;
|
top: 100px;
|
margin-left: -10px;
|
padding-bottom: 60px;
|
}
|
|
.approval-container {
|
padding: 20px;
|
}
|
|
.empty-tip {
|
text-align: center;
|
padding: 40px 0;
|
}
|
</style>
|