WholeProcessPlatform/frontend/src/views/system/user/index.vue
2026-04-28 18:28:44 +08:00

1219 lines
37 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, watch } from "vue";
import {
getTreelist,
gettableData,
DataStatus,
deltableData,
getRole,
addUsers,
updataUser,
setpass,
delChoise,
getFishtree,
saveFishqvan,
getuserdata
} from "@/api/user";
import {
getDictItemsByCode
} from "@/api/dict";
import { ElMessageBox, ElMessage } from "element-plus";
import { useAppStore } from '@/store/modules/app';
import Page from '@/components/Pagination/page.vue'
import { Search } from '@element-plus/icons-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 fishTreeRef = 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(() => {
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(() => {
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(() => {
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
}
//过去设施权限维护
const fishway = ref(false)
const userId = ref('')
// 回显的权限ID数组
const fishhui = ref<any[]>([])
const fishTreeDialog = ref(false)
// 添加标志位,标识数据是否已加载完成
const isFishDataLoaded = ref(false)
async function openFishway(row: any) {
fishway.value = true
userId.value = row.id
// 重置状态
fishhui.value = []
tableDatafish.value = []
isFishDataLoaded.value = false
try {
// 使用 Promise.all 并行等待两个请求都完成
await Promise.all([
getFishTree(), // 获取树形数据
getuserdata({ userId: userId.value }).then((res: any) => {
console.log('用户权限数据:', res)
if (res.code == 0) {
res.data.forEach((item: any) => {
fishhui.value.push(item.orgId)
tableDatafish.value.push({
name: item.orgName,
type: item.orgType,
id: item.orgId.toString(),
code: item.orgId,
path: item.path,
userId: item.userId,
parentId: item.parentId,
orgLevel: item.orgLevel,
permissionType: item.permissionType
})
})
}
})
])
// 两个请求都完成后,标记数据已加载
isFishDataLoaded.value = true
console.log('所有数据加载完成,准备回显')
} catch (error) {
console.error('加载数据失败:', error)
ElMessage.error('加载数据失败,请重试')
}
}
// 监听fishway对话框打开,延迟回显
watch([fishway, isFishDataLoaded], ([newFishway, newDataLoaded]) => {
if (newFishway && newDataLoaded) {
// 确保两个数据都已加载完成后再执行回显
console.log('开始回显, fishTreeRef:', fishTreeRef.value);
console.log('回显ID:', fishhui.value);
console.log('树数据:', fishData.value);
// 使用 nextTick 确保 DOM 已更新
nextTick(() => {
if (fishTreeRef.value && fishhui.value.length > 0) {
// 清除所有选中状态
fishTreeRef.value.setCheckedKeys([], false);
// 再设置新的选中状态
setTimeout(() => {
fishTreeRef.value.setCheckedKeys(fishhui.value, false);
// 验证回显结果
const checkedKeys = fishTreeRef.value.getCheckedKeys();
const halfCheckedKeys = fishTreeRef.value.getHalfCheckedKeys();
console.log('回显完成 - 全选节点:', checkedKeys);
console.log('回显完成 - 半选节点:', halfCheckedKeys);
// 同步表格数据
fishTableData.value = tableDatafish.value
}, 100);
} else if (fishTreeRef.value) {
// 如果fishhui.value为空也需要清空表格数据
setTimeout(() => {
fishTreeRef.value.setCheckedKeys([], false);
fishTableData.value = [];
}, 100);
}
});
} else if (!newFishway) {
// 关闭时清空回显数据
console.log('关闭对话框,清理数据');
fishhui.value = [];
isFishDataLoaded.value = false;
// 清除tree选中状态
setTimeout(() => {
if (fishTreeRef.value) {
fishTreeRef.value.setCheckedKeys([], false);
}
fishTableData.value = [];
}, 300);
}
});
function fishHandleClose() {
fishway.value = false
isFishDataLoaded.value = false
fishTableData.value = []
fishData.value = []
}
//过鱼设施type分类
// const activeName = ref('1')
// 控制标签页禁用的状态(根据你的业务需求设置)
// const isBaseDisabled = ref(false) // 基地标签是否禁用
// const isCompanyDisabled = ref(false) // 公司标签是否禁用
// const handleClick = (tab: any, event: any) => {
// ElMessageBox.confirm("切换后现有数据将清空,是否切换", "删除提示", {
// confirmButtonText: "确定",
// cancelButtonText: "取消",
// type: "warning",
// })
// .then(() => {
// fishhui.value = []
// fishTreeDialog.value = true
// console.log(tab.props.name, event)
// activeName.value = tab.props.name
// treeInput.value = ''
// getFishTree()
// })
// .catch(() => {
// // 用户取消删除
// });
// }
//获取过鱼设施权限
const treeInput = ref('')
const fishProps = {
children: 'children',
label: 'name',
}
const fishData: any = ref([])
//获取左侧树的数据
// const huixiandata = ref([])
let tableDatafish: any = []
// 修改为返回 Promise便于外部等待
function getFishTree() {
fishTreeDialog.value = true
const params = {
// type:'1',
engName: treeInput.value
}
return getFishtree(params).then((res: any) => {
if (res.code == 0) {
fishData.value = res.data
fishTreeDialog.value = false
}
}).catch(() => {
fishTreeDialog.value = false
})
}
// 过鱼设施权限维护 - 获取所有子节点ID的辅助函数
function getAllChildrenIds(node: any): number[] {
const ids: number[] = [];
if (node.children && node.children.length > 0) {
node.children.forEach((child: any) => {
ids.push(child.code);
if (child.children && child.children.length > 0) {
ids.push(...getAllChildrenIds(child));
}
});
}
return ids;
}
// 过鱼设施权限维护 - 检查父节点下所有子节点是否都被选中
function areAllChildrenChecked(parentNode: any, checkedKeysArray: any[]): boolean {
const allChildrenIds = getAllChildrenIds(parentNode);
if (allChildrenIds.length === 0) {
return false;
}
// 检查所有子节点ID是否都在已选中的keys中
return allChildrenIds.every(code => checkedKeysArray.includes(code));
}
// 过鱼设施权限维护 - 检查节点是否被其他父节点包含
function isNodeContainedByOtherParent(nodeId: number, parentIds: number[], allCheckedNodes: any[]): boolean {
// 遍历所有被标记为"全选"的父节点
for (const parentId of parentIds) {
const parentNode = allCheckedNodes.find((n: any) => n.code === parentId);
if (parentNode) {
const childrenIds = getAllChildrenIds(parentNode);
// 如果当前节点是某个父节点的子节点,则返回true
if (childrenIds.includes(nodeId)) {
return true;
}
}
}
return false;
}
// 统一处理选中IDs的过滤逻辑如果父节点的所有子节点都被选中只保留父节点ID
function filterSelectedIds(checkedKeysArray: number[], allCheckedNodes: any[]): number[] {
const resultIds: number[] = [];
const fullySelectedParentIds: number[] = [];
const filteredNodeIds = new Set<number>();
// 第一阶段:找出所有"子节点全部被选中"的父节点
allCheckedNodes.forEach((node: any) => {
if (node.children && node.children.length > 0) {
if (areAllChildrenChecked(node, checkedKeysArray)) {
fullySelectedParentIds.push(node.code);
const childrenIds = getAllChildrenIds(node);
childrenIds.forEach(childId => {
filteredNodeIds.add(childId);
});
}
}
});
// 第二阶段:添加结果
// 1. 先添加所有"全选"的父节点(但要排除被其他父节点包含的)
fullySelectedParentIds.forEach(parentId => {
if (!isNodeContainedByOtherParent(parentId, fullySelectedParentIds, allCheckedNodes)) {
resultIds.push(parentId);
}
});
// 2. 添加未被过滤的独立节点(叶子节点或未全选的父节点)
allCheckedNodes.forEach((node: any) => {
if (!filteredNodeIds.has(node.code) && !resultIds.includes(node.code)) {
if (!isNodeContainedByOtherParent(node.code, fullySelectedParentIds, allCheckedNodes)) {
resultIds.push(node.code);
}
}
});
console.log('过滤后的IDs:', resultIds);
return resultIds;
}
// 过鱼设施权限维护 - 处理复选框选中事件
function handleFishCheckChange(checkedNode: any, checkedInfo: any) {
const treeInstance = fishTreeRef.value;
if (!treeInstance) return;
// 从 checkedInfo 中获取选中的keys数组和节点
const checkedKeysArray = checkedInfo.checkedKeys || [];
const allCheckedNodes = checkedInfo.checkedNodes || [];
// 使用统一的过滤逻辑处理IDs
const resultIds = filterSelectedIds(checkedKeysArray, allCheckedNodes);
console.log('最终获取的IDs:', resultIds);
// 更新表格数据
getFishTableData(resultIds);
tableids.value = resultIds;
}
//过鱼设施权限
const fishTableData: any = ref([])
const fishDialog = ref(false)
const fishTableSelection = ref([])
//获取过鱼设施权限数据
function getFishTableData(ids: any[]) {
// 提取fishData.value中code在ids数组中的所有数据项
const extractedData: any[] = [];
function extractMatchingNodes(nodes: any[]) {
for (const node of nodes) {
if (ids.includes(node.code)) {
// 如果当前节点的code在ids中则添加到结果数组
extractedData.push({
name: node.name,
type: node.type, // 默认类型为'站点'
id: node.code.toString(), // 使用code作为id
code: node.code,
path: node.path,
userId: userId.value,
parentId: node.parentId,
orgLevel: node.orgLevel,
permissionType: 'READ' // 默认选择读权限
});
}
// 递归检查子节点
if (node.children && node.children.length > 0) {
extractMatchingNodes(node.children);
}
}
}
extractMatchingNodes(fishData.value);
fishTableData.value = extractedData;
}
//权限给予
const tableids: any = ref([])
//选中的过鱼权限
function fishDataHandleSelectionChange(val: any) {
console.log('选中的行数据:', val);
fishTableSelection.value = val
}
//移除权限
function delFishTable() {
ElMessageBox.confirm("确定移除选中权限吗?", "删除提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
// 获取选中的ID数组
const selectedIds = fishTableSelection.value.map((item: any) => item.id);
// 过滤fishTableData删除与选中ID一致的项
fishTableData.value = fishTableData.value.filter((item: any) => {
return !selectedIds.includes(item.id);
});
// 同步更新树形控件的选中状态
if (fishTreeRef.value) {
// 获取树形数据,用于遍历子节点
const treeData = fishData.value;
// 收集所有需要取消选中的节点(包括选中的节点及其所有子节点)
const nodesToUncheck = new Set<any>();
// 对于每个选中的ID找到其在树中的节点及其所有子节点
selectedIds.forEach((id: any) => {
nodesToUncheck.add(id);
// 查找该节点的所有子节点
findAllChildNodes(treeData, id, nodesToUncheck);
});
// 将收集到的所有节点取消选中
nodesToUncheck.forEach((nodeId: any) => {
fishTreeRef.value.setChecked(nodeId, false, false);
});
}
ElMessage({
type: "success",
message: "删除成功",
});
// 清空选中状态
fishTableSelection.value = [];
})
.catch(() => {
// 用户取消删除
});
}
// 递归查找指定节点的所有子节点
function findAllChildNodes(nodes: any[], targetNodeId: any, result: Set<any>) {
for (const node of nodes) {
if (node.code == targetNodeId) {
// 找到了目标节点,递归收集它的所有子节点
if (node.children && node.children.length > 0) {
for (const child of node.children) {
result.add(child.code);
// 递归处理子节点的子节点
findAllChildNodes([child], child.code, result);
}
}
break; // 找到目标节点后就跳出循环
} else if (node.children && node.children.length > 0) {
// 继续在子节点中查找
findAllChildNodes(node.children, targetNodeId, result);
}
}
}
//权限确定
function fishSure() {
let params: any = []
fishTableData.value.forEach((item: any) => {
params.push({
engName: item.name,
userId: item.userId,
orgType: item.type,
orgId: item.code,
parentId: item.parentId,
orgLevel: item.orgLevel,
path: item.path,
permissionType: item.permissionType,
})
})
saveFishqvan({ userId: userId.value, dataScopeList: params }).then((res: any) => {
console.log(res);
if (res.code == 0) {
ElMessage({
message: '保存成功',
type: 'success',
})
fishHandleClose()
}
})
}
//删除用户
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;
}
}
//分页
//分类名字
function getName(arr: any[], type: any): string {
if (!arr || !Array.isArray(arr) || type === undefined || type === null) {
return ''
}
const item = arr.find((item: any) => item?.itemCode === type)
return item?.dictName || ''
}
onMounted(() => {
getTree();
getdictdata()
});
const dictData = ref([])
function getdictdata(){
getDictItemsByCode({dictCode:'resourceType'}).then(res=>{
dictData.value = res.data
})
}
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;
};
};
}
}
// 递归获取树形数据中所有节点的code
function getAllNodeCodes(nodes: any[]): number[] {
const codes: number[] = [];
nodes.forEach((node: any) => {
codes.push(node.code);
if (node.children && node.children.length > 0) {
codes.push(...getAllNodeCodes(node.children));
}
});
return codes;
}
// 全选:选中树中所有节点
function handleSelectAll() {
if (!fishTreeRef.value || !fishData.value || fishData.value.length === 0) {
ElMessage.warning('暂无数据可全选');
return;
}
const allCodes = getAllNodeCodes(fishData.value);
console.log('全选 - 所有节点codes:', allCodes);
fishTreeRef.value.setCheckedKeys(allCodes, true);
// 手动更新表格数据(使用统一过滤逻辑)
setTimeout(() => {
// 获取当前选中的节点信息
const checkedKeys = fishTreeRef.value.getCheckedKeys();
const checkedNodes = fishTreeRef.value.getCheckedNodes(false, false); // 只获取完全选中的节点
// 使用统一的过滤逻辑
const filteredIds = filterSelectedIds(checkedKeys, checkedNodes);
getFishTableData(filteredIds);
tableids.value = filteredIds;
console.log('全选 - 表格数据已更新过滤后IDs:', filteredIds);
}, 100);
ElMessage.success('已全选所有节点');
}
// 反选:反转当前选中状态
function handleInvertSelection() {
if (!fishTreeRef.value || !fishData.value || fishData.value.length === 0) {
ElMessage.warning('暂无数据可操作');
return;
}
// 获取当前完全选中的节点keys
const checkedKeys = fishTreeRef.value.getCheckedKeys();
// 获取当前半选的节点keys父节点部分子节点被选中
const halfCheckedKeys = fishTreeRef.value.getHalfCheckedKeys();
console.log('反选前 - 已选中codes:', checkedKeys);
console.log('反选前 - 半选codes:', halfCheckedKeys);
// 合并完全选中和半选的节点,这些是需要取消选中的
const currentSelectedKeys = [...new Set([...checkedKeys, ...halfCheckedKeys])];
console.log('反选前 - 当前有效选中状态:', currentSelectedKeys);
// 获取所有节点codes
const allCodes = getAllNodeCodes(fishData.value);
// 计算需要选中的节点:所有节点 - 当前有效选中状态
const invertedCodes = allCodes.filter(code => !currentSelectedKeys.includes(code));
console.log('反选后 - 新的选中codes:', invertedCodes);
// 先清空所有选中状态,避免级联影响
fishTreeRef.value.setCheckedKeys([], false);
// 然后设置新的选中状态
setTimeout(() => {
fishTreeRef.value.setCheckedKeys(invertedCodes, true);
// 手动更新表格数据(使用统一过滤逻辑)
setTimeout(() => {
// 获取当前选中的节点信息
const newCheckedKeys = fishTreeRef.value.getCheckedKeys();
const newCheckedNodes = fishTreeRef.value.getCheckedNodes(false, false);
// 使用统一的过滤逻辑
const filteredIds = filterSelectedIds(newCheckedKeys, newCheckedNodes);
getFishTableData(filteredIds);
tableids.value = filteredIds;
console.log('反选 - 表格数据已更新过滤后IDs:', filteredIds);
}, 100);
}, 50);
ElMessage.success('已反选操作');
}
// 取消选中:清空所有选中状态
function handleClearSelection() {
if (!fishTreeRef.value) {
return;
}
console.log('取消选中 - 清空所有选中');
fishTreeRef.value.setCheckedKeys([], true);
// 手动清空表格数据
setTimeout(() => {
getFishTableData([]);
tableids.value = [];
console.log('取消选中 - 表格数据已清空');
}, 100);
ElMessage.success('已取消所有选中');
}
</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="140"></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="130">
<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;">
<!-- frontend/src/assets/components/fish.png -->
<img src="@/assets/components/fish.png" alt="" title="过鱼设施权限维护" @click="openFishway(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>
<!-- 过鱼设施权限维护 -->
<el-dialog v-model="fishway" :close-on-click-modal="false" :before-close="fishHandleClose" title="过鱼设施权限维护"
append-to-body width="1600px" draggable>
<!-- <el-scrollbar height="610px"> -->
<!-- <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
<el-tab-pane label="基地" name="1" :disabled="isBaseDisabled"></el-tab-pane>
<el-tab-pane label="公司" name="2" :disabled="isCompanyDisabled"></el-tab-pane>
</el-tabs> -->
<div class="fishBody">
<div class="fishTree">
<div style="width: 100%;padding: 0px 10px; box-sizing: border-box;">
<el-input v-model="treeInput" style="width: 100%" placeholder="请输入电站名称" clearable
class="input-with-select">
<template #append>
<el-button :icon="Search" @click="getFishTree()" />
</template>
</el-input>
<div class="button_div">
<el-button type="primary" @click="handleSelectAll">全选</el-button>
<el-button type="primary" @click="handleInvertSelection">反选</el-button>
<el-button type="primary" @click="handleClearSelection">取消选中</el-button>
</div>
</div>
<el-scrollbar height="450px" style="margin-top: 10px;">
<el-tree ref="fishTreeRef" style="max-width: 300px" :data="fishData" show-checkbox default-expand-all
v-loading="fishTreeDialog" node-key="code" highlight-current :props="fishProps"
@check="handleFishCheckChange" />
</el-scrollbar>
</div>
<div class="fishTable">
<div class="topTable">
<el-button type="danger" :disabled="fishTableSelection.length == 0" @click="delFishTable">移除权限</el-button>
</div>
<el-table :data="fishTableData" style="width: 100%;" row-key="id" border default-expand-all
:v-loading="fishDialog" @selection-change="fishDataHandleSelectionChange" max-height="600"
: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="name" label="名称"></el-table-column>
<el-table-column prop="type" label="类型" width="200" align="center">
<template #default="scope">
<span>{{ getName(dictData,scope.row.type) }}</span>
</template>
</el-table-column>
<el-table-column prop="id" label="权限" align="center" width="200">
<template #default="scope">
<el-radio-group v-model="scope.row.permissionType">
<el-radio value="READ" size="large">读</el-radio>
<el-radio value="WRITE" size="large">写</el-radio>
</el-radio-group>
</template>
</el-table-column>
</el-table>
</div>
</div>
<!-- </el-scrollbar> -->
<span class="dialog-footer"
style="display: flex;display: -webkit-flex; justify-content: flex-end;-webkit-justify-content: flex-end;margin-top: 20px;">
<el-button @click="fishHandleClose">取 消</el-button>
<el-button type="primary" @click="fishSure">保存</el-button>
</span>
</el-dialog>
</div>
</template>
<style scoped lang="scss">
.fishBody {
// height: 620px;
width: 100%;
display: flex;
// align-items: center;
justify-content: space-between;
.fishTree {
width: 300px;
// height: 620px;
margin-right: 10px;
border-right: #409eff 1px solid;
.button_div {
// width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 10px;
}
}
.fishTable {
width: 100%;
height: 100%;
.topTable {
width: 100%;
display: flex;
align-items: center;
justify-content: end;
margin-bottom: 10px;
}
}
}
.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;
}
.fishTree {
:deep(.el-tree-node.is-current>.el-tree-node__content) {
width: 100%;
height: 40px;
background-color: #ecf5ff !important;
// color: #fff !important;
}
:deep(.el-tree-node__content) {
width: 100% !important;
height: 40px !important;
margin: auto !important;
}
}
:deep(.el-tree-node.is-current>.el-tree-node__content) {
width: 100%;
height: 40px;
background-color: #409eff !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>