JavaProjectRepo/business-css/frontend/src/views/system/user/index.vue
2025-12-23 14:53:57 +08:00

560 lines
16 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.

<script lang="ts">
export default {
name: "user",
};
</script>
<script setup lang="ts">
import { ref, onMounted, nextTick } from "vue";
import {
getTreelist,
gettableData,
DataStatus,
deltableData,
getRole,
addUsers,
updataUser,
setpass,
delChoise
} from "@/api/user";
import { ElMessageBox, ElMessage } from "element-plus";
import { useAppStore } from '@/store/modules/app';
import Page from '@/components/Pagination/page.vue'
// import { constant } from "lodash";
//左侧树形控件
interface Tree {
[x: string]: any;
label: string;
children?: Tree[];
}
// 表格加载
const loading = ref(false);
// 搜索框
const queryParams = ref({
current: 1,
size: 10,
querystr: ''
});
//分页 总条数
const total = ref()
const treedata: any = ref([]);
const dialog = ref(false)
const treeRef = ref();
const infoForm = ref();
//获取企业树形信息
const treeloading = ref(true)
function getTree() {
const params = {
parentid: "0",
};
getTreelist(params).then((res: any) => {
treedata.value = res
treeloading.value = false
orgId.value = res[0].childList[0].id
nextTick(() => {
treeRef.value?.setCurrentKey(orgId.value);
});
getdata()
})
.catch((error:any)=>{
treeloading.value = false
})
}
const currentNodeKey = ref("")
function handleNodeClick(data: Tree, node: any) {
if (data.childList.length == 0) {
orgId.value = data.id;
dialog.value = true
getdata();
} else {
node.isCurrent = false
currentNodeKey.value = ""
nextTick(() => {
currentNodeKey.value = orgId.value
})
}
}
const defaultProps = {
children: "childList",
label: "orgname"
};
//新建
const dialogVisible = ref(false);
const title = ref("");
function addClick() {
title.value = "新增用户";
dialogVisible.value = true;
info.value = {
id: "",
username: "",
nickname: "",
email: "",
phone: "",
roleinfo: [],
};
getrole();
}
//用户列表
const multipleSelection = ref([]);
const tableData = ref([]);
const orgId = ref("");
//获取用户列表信息
function getdata() {
const params = {
current: queryParams.value.current,
size: queryParams.value.size,
orgid: orgId.value,
username: queryParams.value.querystr,
}
loading.value = true;
gettableData(params).then((res => {
total.value = res.data.total
tableData.value = res.data.records
queryParams.value.size = res.data.size
queryParams.value.current = res.data.current
dialog.value = true
loading.value = false;
})).catch(() => {
loading.value = false;
})
}
//禁用启用
function switchChange(row: any) {
const elmassage = ref('')
if (row.status == '0') {
elmassage.value = '确定停用该账号吗?'
} else if (row.status == '1') {
elmassage.value = '确定启用该账号吗?'
}
ElMessageBox.confirm(elmassage.value, "提示信息", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
let params = {
status: row.status,
id: row.id,
};
DataStatus(params).then((res) => {
getdata();
ElMessage({
type: "success",
message: "改变成功",
});
});
})
.catch(() => {
getdata();
});
}
//新建用户弹窗
const info = ref({
id: "",
username: "",
nickname: "",
email: "",
phone: "",
roleinfo: [] as any[],
});
//修改-用户
function editdepartment(row: any) {
const selectID: any = []
row.roles.forEach((item: any) => {
selectID.push(item.id)
})
info.value = JSON.parse(JSON.stringify(row));
info.value.roleinfo = selectID;
rolesdata.value = row.roles
title.value = "修改用户";
dialogVisible.value = true;
getrole();
}
//用户弹窗-所属角色
const rolesdata: any = ref([]);
//用户弹窗-保存
function confirmClick(formEl: any) {
formEl.validate((valid: any) => {
if (valid) {
if (info.value.id) {
const params = {
id: info.value.id,
username: info.value.username,
nickname: info.value.nickname,
email: info.value.email,
phone: info.value.phone,
orgid: orgId.value,
};
const roleids = String(info.value.roleinfo)
updataUser(params, roleids).then((res) => {
getdata();
dialogVisible.value = false;
ElMessage({
type: "success",
message: "修改成功",
});
});
} else {
const params = {
username: info.value.username,
nickname: info.value.nickname,
email: info.value.email,
phone: info.value.phone,
orgid: orgId.value,
};
const roleids = info.value.roleinfo;
addUsers(params, roleids).then((res) => {
getdata();
dialogVisible.value = false;
ElMessage({
type: 'success',
message: res.data.msg,
});
});
}
}
})
}
//用户弹窗规则定义
const moderules = ref({
username: [{ required: true, message: "请输入用户账号", trigger: "blur" }],
nickname: [{ required: true, message: "请输入用户名称", trigger: "blur" }],
});
//弹窗关闭
function handleClose() {
infoForm.value.resetFields();
dialogVisible.value = false;
}
//重置密码
const userid = ref("");
function setpassword(row: any) {
ElMessageBox.confirm(
'确定将该账号密码重置为123456吗',
'重置密码',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
const params = {
id: userid.value
}
setpass(params).then(() => {
ElMessage({
type: 'success',
message: '密码重置成功',
})
})
})
userid.value = row.id
}
//删除用户
function delclick(row: any) {
ElMessageBox.confirm("确定删除此用户吗?", "删除提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
const params = {
id: row.id,
};
deltableData(params).then(() => {
ElMessage({
type: "success",
message: "删除成功",
});
getdata();
});
})
}
//获取角色
function getrole() {
const params = {
rolename: "",
};
getRole(params).then((res) => {
rolesdata.value = res;
});
}
//多选删除
const ids = ref([])
function handleSelectionChange(val: any) {
multipleSelection.value = val;
ids.value = val
}
function delchoice() {
const choice: any = []
ids.value.forEach((item: any) => {
choice.push(item.id)
})
ElMessageBox.confirm("确定删除此用户吗?", "删除提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
const params = {
id: String(choice)
};
delChoise(params).then(() => {
ElMessage({
type: "success",
message: "删除成功",
});
getdata();
});
})
}
function dateFormat(row: any) {
const daterc = row;
if (daterc != null) {
var date = new Date(daterc);
var year = date.getFullYear();
var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1;
date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
var day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
var hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
var minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
var seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
// 拼接
return year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds;
}
}
//分页
onMounted(() => {
getTree();
});
const vMove = {
mounted(el: any) {
el.onmousedown = function (e: any) {
var init = e.clientX;
var parent: any = document.getElementById("silderLeft");
const initWidth: any = parent.offsetWidth;
document.onmousemove = function (e) {
var end = e.clientX;
var newWidth = end - init + initWidth;
parent.style.width = newWidth + "px";
};
document.onmouseup = function () {
document.onmousemove = document.onmouseup = null;
};
};
}
}
</script>
<template>
<div class="faulttemplate-box">
<aside id="silderLeft">
<el-tree ref="treeRef" :class="useAppStore().size === 'default' ? 'silderLeft-large' : 'silderLeft-default'"
node-key="id" :data="treedata" :current-node-key="currentNodeKey" :highlight-current="true" :props="defaultProps" v-loading="treeloading"
@node-click="handleNodeClick" style="height: calc(100vh - 150px); overflow: auto">
</el-tree>
<div class="moveBtn" v-move>
<div class="moveBtn-line"></div>
</div>
</aside>
<section class="silderRight">
<el-row>
<el-col :span="24">
<div style="margin-bottom:10px;display: flex;display: -webkit-flex; justify-content: space-between;-webkit-justify-content: space-between; width: 100%;">
<div>
<el-input v-model="queryParams.querystr" placeholder="请输入用户姓名" clearable style="width: 200px"
@keyup.enter="getdata" />
<el-button type="primary" style="margin-left: 10px;" @click="getdata">搜索</el-button>
</div>
<div>
<el-button v-hasPerm="['add:user']" type="primary" @click="addClick">
<img src="@/assets/MenuIcon/jscz_xz.png" alt="" style="margin-right: 5px;">
新增</el-button>
<el-button v-hasPerm="['del:user']" @click="delchoice" :disabled="multipleSelection.length <= 0"
:type="multipleSelection.length > 0 ? 'primary' : ''"><el-icon style="margin-right: 5px;">
<Delete />
</el-icon>删除</el-button>
</div>
</div>
</el-col>
</el-row>
<el-table :data="tableData" style="width: 100%;margin-bottom: 20px;" row-key="id" border default-expand-all
:v-loading="dialog" @selection-change="handleSelectionChange"
:header-cell-style="{ background: 'rgb(250 250 250)', color: ' #383838', height: '50px' }">
<el-table-column type="selection" width="50" align="center" />
<el-table-column type="index" label="序号" width="70" align="center" />
<el-table-column prop="nickname" label="用户姓名" width="100"></el-table-column>
<!-- <el-table-column prop="avatar" label="头像"></el-table-column> -->
<el-table-column prop="email" label="邮箱" ></el-table-column>
<el-table-column prop="phone" label="手机号" min-width="90"></el-table-column>
<el-table-column prop="username" label="登录账号" width="120"></el-table-column>
<!-- <el-table-column prop="custom1" label="登录账号"></el-table-column> -->
<el-table-column prop="rolename" label="所属角色" width="120">
<template #default="scope">
<span v-for="(item, index) in scope.row.roles" :key="index">{{ item.rolename }} <span></span> </span>
</template>
</el-table-column>
<el-table-column prop="status" label="账号状态" align="center" width="120">
<template #default="scope">
<el-switch v-model="scope.row.status" active-value="1" inactive-value="0" @change="switchChange(scope.row)"
style="margin-right: 4px;"></el-switch>
<span v-if="scope.row.status == 1" style="color:#0099FF">启用</span>
<span v-else style="color:#D7D7D7">停用</span>
</template>
</el-table-column>
<el-table-column prop="lastmodifier" label="最近修改者" width="120"></el-table-column>
<el-table-column prop="lastmodifydate" label="最近修改日期" width="205">
<template #default="scope">
{{ dateFormat(scope.row.lastmodifydate) }}
</template>
</el-table-column>
<el-table-column fixed="right" label="操作" width="110">
<template #default="scope">
<span style="display: flex;display: -webkit-flex;justify-content: space-around;-webkit-justify-content: space-around; ">
<img src="@/assets/MenuIcon/lbcz_xg.png" alt="" title="修改" @click="editdepartment(scope.row)"
style="cursor: pointer;">
<img src="@/assets/MenuIcon/lbcz_czmm.png" alt="" title="重置密码" @click="setpassword(scope.row)"
style="cursor: pointer;">
<img src="@/assets/MenuIcon/lbcz_sc.png" alt="" title="删除" @click="delclick(scope.row)"
style="cursor: pointer;">
</span>
</template>
</el-table-column>
</el-table>
<Page :total="total" v-model:size="queryParams.size" v-model:current="queryParams.current" @pagination="getdata()" ></Page>
</section>
<!-- 用户 弹框-->
<el-dialog v-model="dialogVisible" :close-on-click-modal="false" :before-close="handleClose" :title="title"
append-to-body width="620px" draggable>
<el-form ref="infoForm" :model="info" :rules="moderules" label-width="90px">
<el-form-item label="用户姓名" prop="nickname">
<el-input v-model="info.nickname" style="width: 100%" placeholder="请输入用户姓名"></el-input>
</el-form-item>
<el-form-item label="联系邮箱" >
<el-input v-model="info.email" style="width: 100%" placeholder="请输入联系邮箱"></el-input>
</el-form-item>
<el-form-item label="联系电话" >
<el-input v-model="info.phone" style="width: 100%" placeholder="请输入联系电话"></el-input>
</el-form-item>
<el-form-item label="登录账号" prop="username">
<el-input v-model="info.username" style="width: 100%" placeholder="请输入登录账号"></el-input>
</el-form-item>
<el-form-item label="所属角色" >
<el-select v-model="info.roleinfo" placeholder=" " style="width: 100%" multiple>
<el-option v-for="item in rolesdata" :key="item.id" :label="item.rolename" :value="item.id" />
</el-select>
</el-form-item>
</el-form>
<span class="dialog-footer" style="display: flex;display: -webkit-flex; justify-content: flex-end;-webkit-justify-content: flex-end;">
<el-button @click="handleClose">取 消</el-button>
<el-button type="primary" @click="confirmClick(infoForm)">保存</el-button>
</span>
</el-dialog>
</div>
</template>
<style scoped lang="scss">
.silderLeft-default {
:deep(.el-tree-node__label) {
font-size: 16px !important;
}
}
.faulttemplate-box {
height: 100%;
display: flex;
display: -webkit-flex;
background-color: #f2f4f9;
}
#silderLeft {
width: 300px;
padding: 5px 0px 10px;
box-sizing: border-box;
background: #fff;
border-radius: 3px;
position: relative;
&:hover {
.moveBtn {
opacity: 1;
}
}
}
/* 拖动条 */
.moveBtn {
height: 100%;
width: 15px;
padding: 0 6px;
opacity: 0;
position: absolute;
right: -15px;
top: 0;
}
.moveBtn-line {
width: 100%;
height: 100%;
cursor: col-resize;
user-select: none;
background-color: #60bfff;
}
.silderRight {
flex: 1;
width: 100%;
height: calc(100vh - 130px);
overflow: auto;
background-color: rgba(255, 255, 255, 1);
border-radius: 3px;
padding: 15px;
padding-bottom: 0px;
box-sizing: border-box;
margin-left: 15px;
}
.avatar {
width: 86px;
height: 86px;
display: block;
}
:deep(.el-tree-node.is-current>.el-tree-node__content) {
width: 100%;
height: 40px;
background-color: #266fff !important;
color: #fff !important;
}
:deep(.el-tree-node__content) {
width: 100% !important;
height: 40px !important;
margin: auto !important;
}
.el-message-box{
width: 300px !important;
}
</style>