| | |
| | | import {Search} from "@element-plus/icons-vue"; |
| | | import {reactive} from "vue"; |
| | | import {useRouter} from "vue-router" |
| | | import { useI18n } from 'vue-i18n' |
| | | const { t } = useI18n() |
| | | let language = ref(localStorage.getItem('lang') || 'zh') |
| | | const router = useRouter() |
| | | const add = ref(false) |
| | | const adda = ref(false) |
| | | const editingUser = ref({}); // 用于存储当前编辑的用户数据 |
| | | import request from "@/utils/request" |
| | | import { ref, onMounted } from "vue"; |
| | | // import { ref } from 'vue' |
| | | import { ElMessage, ElMessageBox } from 'element-plus' |
| | | // import LanguageMixin from './lang/LanguageMixin' |
| | | const selectedProjectNoa = ref(''); // 当前选中的角色 |
| | | const selectedProjectNoa = ref(null); // 当前选中的角色 |
| | | // const options = ref<any[]>([]); // 下拉选项列表 |
| | | const name = ref(''); |
| | | |
| | | const tableData = ref([]) |
| | | const options = ref([]) |
| | | const selectedOptions = ref([]) |
| | | // 定义级联选择器的属性 |
| | | const cascaderProps = { |
| | | value: 'id', |
| | | label: 'menuName', |
| | | multiple: true |
| | | }; |
| | | const slot = ref('') |
| | | |
| | | const titleSelectJsona = ref({ |
| | | processType: [], |
| | | |
| | | }) |
| | | // const handleInputChangea = async (value: string) => { |
| | | // if (value) { |
| | | // await fetchOptionsa(value); |
| | | // } else { |
| | | // options.value = []; // 清空选项列表 |
| | | // } |
| | | // }; |
| | | onMounted(() => { |
| | | // 在组件挂载后调用 fetchOptions('') 来加载初始数据(如果需要) |
| | | fetchOptionsa(''); |
| | | }); |
| | | // 角色下拉选 |
| | | const fetchOptionsa = async () => { |
| | | try { |
| | | // 发送请求到后端接口 |
| | | const response = await request.post('/loadGlass/sys/role/queryRole',{ |
| | | key: '' |
| | | }); |
| | | if (response.code == 200) { |
| | | tableData.value = response.data |
| | | // titleSelectJsona.value.processTypea = response.data.menuList; |
| | | // options.value = response.data.menuList |
| | | console.log(response.data); |
| | | |
| | | } else { |
| | |
| | | console.error('Error fetching options:', error); |
| | | } |
| | | }; |
| | | // 添加 |
| | | // 添加 |
| | | const getTableRow = async () => { |
| | | try { |
| | | const response = await request.post('/loadGlass/sys/role/saveRole', { |
| | | try { |
| | | let menuList = []; |
| | | let parentIdMap = {}; // 用于存储已经添加的父项 |
| | | selectedOptions.value.forEach(array => { |
| | | if (array.length >= 2) { |
| | | let id = array[0]; |
| | | let parentId = array[1]; |
| | | // 如果id还未作为父项添加,则添加它 |
| | | if (!parentIdMap[id]) { |
| | | menuList.push({ |
| | | id: id, |
| | | parentId: 0, // 通常,顶级项的parentId可能是null或特定的根ID,这里设为0可能是个特殊用途 |
| | | children: [] |
| | | }); |
| | | parentIdMap[id] = menuList[menuList.length - 1]; // 更新映射 |
| | | } |
| | | // 向对应的父项添加子项 |
| | | if (!parentIdMap[id].children.some(child => child.id === parentId)) { |
| | | // 检查是否已存在相同的子项(基于id),避免重复添加 |
| | | parentIdMap[id].children.push({ |
| | | id: parentId, |
| | | parentId: id |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | const dataToSend = { |
| | | name: name.value, |
| | | }); |
| | | |
| | | menuList: menuList |
| | | }; |
| | | const response = await request.post('/loadGlass/sys/role/saveRole', dataToSend); |
| | | if (response.code == 200) { |
| | | // 绑定成功,处理逻辑 |
| | | ElMessage.success(response.message); |
| | | add.value = false; |
| | | // tableData.value = response.data; |
| | | name.value = ''; |
| | | selectedOptions.value = ''; |
| | | fetchOptionsa(); |
| | | } else { |
| | | // 请求失败,显示错误消息 |
| | | ElMessage.error(response.msg); |
| | | ElMessage.error(response.message); |
| | | } |
| | | } catch (error) { |
| | | // 处理错误 |
| | | console.error(error); |
| | | } |
| | | }; |
| | | // 处理编辑按钮点击 |
| | | function handleEdit(row) { |
| | | editingUser.value = { ...row }; // 使用展开运算符复制当前行数据 |
| | | adda.value = true; // 显示对话框 |
| | | name.value = row.name; |
| | | adda.value = true; |
| | | window.localStorage.setItem('ids', row.id); |
| | | const parentIdMap = {}; |
| | | const menuItemsById = {}; // 快速查找菜单项 |
| | | let topLevelItems = []; // 存储顶级菜单项 |
| | | row.menuList.forEach(item => { |
| | | const parentId = item.parentId === 0 ? null : item.parentId; |
| | | const menuItem = { |
| | | id: item.id, |
| | | parentId: parentId, |
| | | menuName: item.menuName, |
| | | children: [] |
| | | }; |
| | | menuItemsById[item.id] = menuItem; |
| | | // 初始化或更新parentIdMap中的数组 |
| | | if (!parentIdMap[parentId]) { |
| | | parentIdMap[parentId] = []; |
| | | } |
| | | if (parentId === null) { |
| | | // 顶级菜单项直接添加到topLevelItems |
| | | topLevelItems.push(menuItem); |
| | | } else { |
| | | // 非顶级菜单项添加到parentIdMap中 |
| | | parentIdMap[parentId].push(menuItem); |
| | | } |
| | | }); |
| | | for (const parentId in parentIdMap) { |
| | | if (parentId !== 'null') { // 跳过顶级菜单项 |
| | | parentIdMap[parentId].forEach(child => { |
| | | // 查找父项并添加子项 |
| | | if (menuItemsById[parentId]) { |
| | | menuItemsById[parentId].children.push(child); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | if (selectedOptions.value !== topLevelItems) { |
| | | selectedOptions.value = topLevelItems; |
| | | } |
| | | |
| | | const topLevelItemsWithChildren = topLevelItems; // 包含顶级菜单项及其子菜单项的数组 |
| | | let selectedPath = []; |
| | | |
| | | // 循环遍历 topLevelItemsWithChildren 数组 |
| | | for (let i = 0; i < topLevelItemsWithChildren.length; i++) { |
| | | // 添加顶级菜单项的 id |
| | | selectedPath.push(topLevelItemsWithChildren[i].id); |
| | | |
| | | // 遍历该顶级菜单项的子菜单项 |
| | | if (topLevelItemsWithChildren[i].children && topLevelItemsWithChildren[i].children.length > 0) { |
| | | for (let j = 0; j < topLevelItemsWithChildren[i].children.length; j++) { |
| | | // 添加每个子菜单项的 id |
| | | selectedPath.push(topLevelItemsWithChildren[i].children[j].id); |
| | | } |
| | | } |
| | | } |
| | | |
| | | console.log(selectedPath); |
| | | selectedOptions.value = selectedPath; |
| | | } |
| | | // function handleEdit(row) { |
| | | // name.value = row.name; |
| | | // adda.value = true; |
| | | // window.localStorage.setItem('ids', row.id); |
| | | // // 构建菜单树 |
| | | // const buildMenuTree = (menuList) => { |
| | | // const parentIdMap = {}; |
| | | // const menuItemsById = {}; |
| | | // menuList.forEach(item => { |
| | | // const parentId = item.parentId === 0 ? null : item.parentId; |
| | | // const menuItem = { |
| | | // id: item.id, |
| | | // parentId: parentId, |
| | | // menuName: item.menuName, |
| | | // children: [] |
| | | // }; |
| | | // menuItemsById[item.id] = menuItem; |
| | | |
| | | // if (!parentIdMap[parentId]) { |
| | | // parentIdMap[parentId] = []; |
| | | // } |
| | | // parentIdMap[parentId].push(menuItem); |
| | | // }); |
| | | // // 构建父子关系 |
| | | // for (const parentId in parentIdMap) { |
| | | // if (parentId !== 'null') { |
| | | // parentIdMap[parentId].forEach(child => { |
| | | // if (menuItemsById[parentId]) { |
| | | // menuItemsById[parentId].children.push(child); |
| | | // } |
| | | // }); |
| | | // } |
| | | // } |
| | | // return parentIdMap[null] || []; |
| | | // }; |
| | | // const options = buildMenuTree(row.menuList); |
| | | // const selectedIds = row.menuList.filter(item => item.parentId === 0).map(item => item.id); |
| | | // selectedOptions.value = selectedIds; |
| | | // console.log(options); // 输出整个菜单树 |
| | | // console.log(selectedIds); // 输出应默认选中的节点ID数组 |
| | | // } |
| | | // function handleEdit(row) { |
| | | // name.value = row.name; |
| | | // adda.value = true; |
| | | // window.localStorage.setItem('ids', row.id); |
| | | // // 初始化 parentIdMap 和 menuItemsById |
| | | // const parentIdMap = {}; |
| | | // const menuItemsById = {}; |
| | | // let topLevelItems = []; |
| | | |
| | | // // 构建树形结构 |
| | | // row.menuList.forEach(item => { |
| | | // const parentId = item.parentId === 0 ? null : item.parentId; |
| | | // const menuItem = { |
| | | // id: item.id, |
| | | // parentId: parentId, |
| | | // label: item.menuName, // 注意:el-cascader 使用 label 而不是 menuName |
| | | // value: item.id, // 通常 value 是唯一标识符 |
| | | // children: [] |
| | | // }; |
| | | // menuItemsById[item.id] = menuItem; |
| | | |
| | | // if (!parentIdMap[parentId]) { |
| | | // parentIdMap[parentId] = []; |
| | | // } |
| | | |
| | | // if (parentId === null) { |
| | | // topLevelItems.push(menuItem); |
| | | // } else { |
| | | // parentIdMap[parentId].push(menuItem); |
| | | // } |
| | | // }); |
| | | |
| | | // // 构建父子关系 |
| | | // for (const parentId in parentIdMap) { |
| | | // if (parentId !== 'null') { |
| | | // parentIdMap[parentId].forEach(child => { |
| | | // if (menuItemsById[parentId]) { |
| | | // menuItemsById[parentId].children.push(child); |
| | | // } |
| | | // }); |
| | | // } |
| | | // } |
| | | |
| | | // // 设置 options |
| | | // options.value = topLevelItems; |
| | | |
| | | // // 构建 selectedOptions |
| | | // let selected = []; |
| | | // // 假设你想选中所有节点,你可以遍历 row.menuList 并构建路径 |
| | | // row.menuList.forEach(item => { |
| | | // let path = []; |
| | | // let currentParentId = item.parentId; |
| | | // while (currentParentId !== null) { |
| | | // const parentItem = menuItemsById[currentParentId]; |
| | | // if (parentItem) { |
| | | // path.unshift(parentItem.value); // 从父节点到子节点 |
| | | // currentParentId = parentItem.parentId; |
| | | // } else { |
| | | // break; // 如果找不到父节点,则停止 |
| | | // } |
| | | // } |
| | | // // 添加当前节点的 ID 到路径末尾 |
| | | // path.push(item.id); |
| | | // // 如果路径不为空,则添加到 selectedOptions |
| | | // if (path.length > 0) { |
| | | // selected.push(path); |
| | | // } |
| | | // }); |
| | | |
| | | // // 更新 selectedOptions |
| | | // selectedOptions.value = selected; |
| | | // console.log(selected); |
| | | // console.log(topLevelItems); |
| | | // // 注意:确保 selectedOptions 和 options 是响应式的 |
| | | // } |
| | | // 编辑 |
| | | const getTableRowa = async () => { |
| | | try { |
| | | const response = await request.post('/loadGlass/sys/role/updateRole', { |
| | | let ids = window.localStorage.getItem('ids') |
| | | try { |
| | | let menuList = []; |
| | | let parentIdMap = {}; // 用于存储已经添加的父项 |
| | | selectedOptions.value.forEach(array => { |
| | | if (array.length >= 2) { |
| | | let id = array[0]; |
| | | let parentId = array[1]; |
| | | // 如果id还未作为父项添加,则添加它 |
| | | if (!parentIdMap[id]) { |
| | | menuList.push({ |
| | | id: id, |
| | | parentId: 0, // 通常,顶级项的parentId可能是null或特定的根ID,这里设为0可能是个特殊用途 |
| | | children: [] |
| | | }); |
| | | parentIdMap[id] = menuList[menuList.length - 1]; // 更新映射 |
| | | } |
| | | // 向对应的父项添加子项 |
| | | if (!parentIdMap[id].children.some(child => child.id === parentId)) { |
| | | // 检查是否已存在相同的子项(基于id),避免重复添加 |
| | | parentIdMap[id].children.push({ |
| | | id: parentId, |
| | | parentId: id |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | const dataToSend = { |
| | | id:ids, |
| | | name: name.value, |
| | | |
| | | }); |
| | | |
| | | menuList: menuList |
| | | }; |
| | | const response = await request.post('/loadGlass/sys/role/updateRole', dataToSend); |
| | | if (response.code == 200) { |
| | | // 绑定成功,处理逻辑 |
| | | ElMessage.success(response.message); |
| | | editingUser.value = {}; |
| | | adda.value = false; |
| | | tableData.value = response.data; |
| | | name.value = ''; |
| | | selectedOptions.value = ''; |
| | | fetchOptionsa(); |
| | | } else { |
| | | // 请求失败,显示错误消息 |
| | | ElMessage.error(response.msg); |
| | | ElMessage.error(response.message); |
| | | } |
| | | } catch (error) { |
| | | // 处理错误 |
| | | console.error(error); |
| | | } |
| | | }; |
| | | // 删除 |
| | | const opena = async(row) => { |
| | | try { |
| | | try { |
| | | const confirmResult = await ElMessageBox.confirm( |
| | | '是否删除该用户?', |
| | | '提示', |
| | | t('delivery.derole'), |
| | | t('delivery.prompt'), |
| | | { |
| | | confirmButtonText: '是', |
| | | cancelButtonText: '取消', |
| | | confirmButtonText: t('delivery.yes'), |
| | | cancelButtonText: t('delivery.cancel'), |
| | | type: 'warning', |
| | | } |
| | | ); |
| | | } |
| | | ); |
| | | if (confirmResult === 'confirm') { |
| | | // 用户点击了“是”,现在调用删除接口 |
| | | const response = await request.post("/loadGlass/sys/role/delete", { |
| | | ids: row.id, |
| | | }) |
| | | const response = await request.post("/loadGlass/sys/role/delete",[row.id]) |
| | | if (response.code === 200) { |
| | | ElMessage.success(response.message); |
| | | fetchOptionsa() |
| | | } else { |
| | | // 删除失败,您可以处理错误或显示错误信息给用户 |
| | | ElMessage.error(response.msg); |
| | | ElMessage.error(response.message); |
| | | // alert('删除失败:' + deleteResponse.message); |
| | | } |
| | | } |
| | |
| | | // 处理可能出现的错误,比如 ElMessageBox 抛出的异常等 |
| | | console.error('发生错误:', error); |
| | | } |
| | | }; |
| | | |
| | | const gridOptions = reactive({ |
| | | border: "full",//表格加边框 |
| | | keepSource: true,//保持源数据 |
| | | align: 'center',//文字居中 |
| | | stripe:true,//斑马纹 |
| | | rowConfig: {isCurrent: true, isHover: true,height: 50},//鼠标移动或选择高亮 |
| | | id: 'OrderList', |
| | | showFooter: true,//显示脚 |
| | | printConfig: {}, |
| | | importConfig: {}, |
| | | exportConfig: {}, |
| | | scrollY:{ enabled: true },//开启虚拟滚动 |
| | | showOverflow:true, |
| | | columnConfig: { |
| | | resizable: true, |
| | | useKey: true |
| | | }, |
| | | filterConfig: { //筛选配置项 |
| | | remote: true |
| | | }, |
| | | customConfig: { |
| | | storage: true |
| | | }, |
| | | editConfig: { |
| | | trigger: 'click', |
| | | mode: 'row', |
| | | showStatus: true |
| | | }, |
| | | data: [ |
| | | { |
| | | 'id': '1', |
| | | 'long': '5', |
| | | 'wide': '1005', |
| | | 'thick': '183.6', |
| | | } |
| | | ] |
| | | |
| | | }) |
| | | }; |
| | | request.get("/loadGlass/sys/menu/nav").then((res) => { |
| | | if (res.code == 200) { |
| | | console.log(res.data); |
| | | options.value = res.data.tree |
| | | console.log( options.value); |
| | | } else { |
| | | ElMessage.warning(res.msg) |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <div> |
| | | <el-button type="primary" style="margin-top: 10px;margin-left: 10px;" size="mini" id="searchButton" @click="add = true">添加角色</el-button> |
| | | <el-button type="primary" style="margin-top: 10px;margin-left: 10px;" size="mini" id="searchButton" @click="add = true">{{ $t('delivery.addrole') }}</el-button> |
| | | <el-card style="flex: 1;margin-left: 10px;margin-top: 20px;" v-loading="loading"> |
| | | <div style="width: 98%; height: calc(100% - 35px); overflow-y: auto;"> |
| | | <el-table height="240" ref="table" |
| | | @selection-change="handleSelectionChange" |
| | | :data="tableData" :header-cell-style="{background:'#F2F3F5 ',color:'#1D2129'}"> |
| | | <el-table-column prop="name" align="center" label="角色" min-width="180" /> |
| | | <el-table-column fixed="right" label="操作" align="center" width="200"> |
| | | <el-table-column prop="name" align="center" :label="$t('delivery.role')" min-width="180" /> |
| | | <el-table-column fixed="right" :label="$t('delivery.operate')" align="center" width="200"> |
| | | <template #default="scope"> |
| | | <el-button size="mini" type="text" plain @click="handleEdit(scope.row)">编辑</el-button> |
| | | <el-button size="mini" type="text" plain @click="opena(scope.row)">删除</el-button> |
| | | <el-button size="mini" type="text" plain @click="handleEdit(scope.row)">{{ $t('delivery.edit') }}</el-button> |
| | | <el-button size="mini" type="text" plain @click="opena(scope.row)">{{ $t('delivery.delete') }}</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </el-card> |
| | | </div> |
| | | <el-dialog v-model="add" top="23vh" width="37%" title="添加角色" > |
| | | <el-dialog v-model="add" top="23vh" width="37%" :title="$t('productStock.addusername')" > |
| | | <div style="margin-left: -50px;margin-top: 10px;margin-bottom: 10px;"> |
| | | <el-form size="mini" label-width="150px"> |
| | | <el-form ref="formRef" size="mini" label-width="150px"> |
| | | <el-form label-width="100px" label-position="right"> |
| | | <el-row style="margin-top: -15px;margin-bottom: -2px;"> |
| | | <el-col :span="6"> |
| | | <div id="dt" style="font-size: 15px;"> |
| | | <div> |
| | | <el-form-item label="角色:" :required="true" style="width: 25vw"> |
| | | <el-input v-model="name" autocomplete="off" /> |
| | | <el-form-item :label="$t('delivery.rolea')" :required="true" style="width: 25vw"> |
| | | <el-input :placeholder="$t('delivery.inrole')" v-model="name" autocomplete="off" /> |
| | | </el-form-item></div></div> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row style="margin-top: 10px;"> |
| | | <el-col :span="6"> |
| | | <div id="dt" style="font-size: 15px;"> |
| | | <div> |
| | | <el-form-item :label="$t('delivery.choice')" :required="true" style="width: 25vw;"> |
| | | <el-cascader |
| | | v-model="selectedOptions" |
| | | :placeholder="$t('delivery.inchoice')" |
| | | :props="cascaderProps" |
| | | :options="options" |
| | | style="width: 330px" |
| | | clearable /> |
| | | </el-form-item></div></div> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | <template #footer> |
| | | <div id="dialog-footer"> |
| | | <el-button type="primary" @click="getTableRow"> |
| | | 确认 |
| | | {{ $t('delivery.sure') }} |
| | | </el-button> |
| | | <el-button @click="add = false">取消</el-button> |
| | | <el-button @click="add = false"> {{ $t('delivery.cancel') }}</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | <el-dialog v-model="adda" top="23vh" width="37%" title="修改角色" > |
| | | <el-dialog v-model="adda" top="23vh" width="37%" :title="$t('delivery.editrole')"> |
| | | <div style="margin-left: -50px;margin-top: 10px;margin-bottom: 10px;"> |
| | | <el-form :model="editingUser" ref="formRef" size="mini" label-width="150px"> |
| | | <el-form ref="formRef" size="mini" label-width="150px"> |
| | | <el-form label-width="100px" label-position="right"> |
| | | <el-row style="margin-top: -15px;margin-bottom: -2px;"> |
| | | <el-col :span="6"> |
| | | <div id="dt" style="font-size: 15px;"> |
| | | <div> |
| | | <el-form-item label="角色:" :required="true" style="width: 25vw"> |
| | | <el-input v-model="editingUser.name" autocomplete="off" /> |
| | | <el-form-item :label="$t('delivery.rolea')" :required="true" style="width: 25vw"> |
| | | <el-input :placeholder="$t('delivery.inrole')" v-model="name" autocomplete="off" /> |
| | | </el-form-item></div></div> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row style="margin-top: 10px;"> |
| | | <el-col :span="6"> |
| | | <div id="dt" style="font-size: 15px;"> |
| | | <div> |
| | | <el-form-item :label="$t('delivery.choice')" :required="true" style="width: 25vw;"> |
| | | <el-cascader |
| | | v-model="selectedOptions" |
| | | :placeholder="$t('delivery.inchoice')" |
| | | :props="cascaderProps" |
| | | :options="options" |
| | | style="width: 330px" |
| | | clearable /> |
| | | </el-form-item></div></div> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | <template #footer> |
| | | <div id="dialog-footer"> |
| | | <el-button type="primary" @click="getTableRowa"> |
| | | 确认 |
| | | {{ $t('delivery.sure') }} |
| | | </el-button> |
| | | <el-button @click="adda = false">取消</el-button> |
| | | <el-button @click="adda = false">{{ $t('delivery.cancel') }}</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |