Commit 39860647 authored by 张伯涛's avatar 张伯涛

角色管理增删改查功能完善

parent 0e22d060
......@@ -11,7 +11,7 @@ export function getRolePage(
queryParams?: RoleQuery
): AxiosPromise<RolePageResult> {
return request({
url: "/api/v1/roles/page",
url: '/system/role/list',
method: "get",
params: queryParams,
});
......@@ -43,7 +43,32 @@ export function getRoleMenuIds(roleId: number): AxiosPromise<number[]> {
method: "get",
});
}
/**
* 查询菜单下拉树结构
*
*/
export function treeSelect() {
return request({
url: '/system/menu/treeSelect',
method: 'get'
})
}
/**
* 用户状态修改
*
*/
export function changeRoleStatus(businessId: number,flag:string) {
const data = {
businessId,
flag
}
return request({
url: '/system/role/changeStatus',
method: 'put',
params: data
});
}
/**
* 分配菜单权限给角色
*
......@@ -67,11 +92,21 @@ export function updateRoleMenus(
*/
export function getRoleForm(id: number): AxiosPromise<RoleForm> {
return request({
url: "/api/v1/roles/" + id + "/form",
url: '/system/role/detail/' + id,
method: "get",
});
}
/**
* 根据角色ID查询菜单下拉树结构
*
* @param id
*/
export function roleMenuTreeSelect(roleId) {
return request({
url: '/system/menu/roleMenuTreeSelect/' + roleId,
method: 'get'
})
}
/**
* 添加角色
*
......@@ -79,7 +114,7 @@ export function getRoleForm(id: number): AxiosPromise<RoleForm> {
*/
export function addRole(data: RoleForm) {
return request({
url: "/api/v1/roles",
url: '/system/role/add',
method: "post",
data: data,
});
......@@ -93,7 +128,7 @@ export function addRole(data: RoleForm) {
*/
export function updateRole(id: number, data: RoleForm) {
return request({
url: "/api/v1/roles/" + id,
url: '/system/role/update/' + id,
method: "put",
data: data,
});
......@@ -104,9 +139,9 @@ export function updateRole(id: number, data: RoleForm) {
*
* @param ids
*/
export function deleteRoles(ids: string) {
export function deleteRoles(roleId: any) {
return request({
url: "/api/v1/roles/" + ids,
url: '/system/role/deleteLogical/' + roleId,
method: "delete",
});
}
......@@ -2,42 +2,48 @@
* 角色查询参数
*/
export interface RoleQuery extends PageQuery {
keywords?: string;
/**
* 角色名称
*/
roleName?: string;
/**
* 权限字符
*/
roleKey?: string;
/**
* 角色状态
*/
flag?: string;
}
/**
* 角色分页对象
*/
export interface RolePageVO {
/**
* 角色编码
*/
code?: string;
/**
* 角色ID
*/
id?: number;
businessId?: number;
/**
* 角色名称
* 名称
*/
name?: string;
roleName?: string;
/**
* 排序
* 权限字符
*/
sort?: number;
roleKey?: string;
/**
* 角色状态
* 显示顺序
*/
status?: number;
roleSort?: number;
/**
* 创建时间
* 状态
*/
createTime?: Date;
flag?: string;
/**
* 修改时间
* 创建时间
*/
updateTime?: Date;
createDate?: Date;
}
/**
......@@ -52,27 +58,29 @@ export interface RoleForm {
/**
* 角色ID
*/
id?: number;
businessId?: number | undefined;
/**
* 角色编码
* 名称
*/
code: string;
roleName?: string;
/**
* 数据权限
* 权限字符
*/
dataScope?: number;
roleKey?: string;
/**
* 角色名称
* 排序
*/
roleSort?: number;
/**
* 排序
*/
name: string;
flag?: string;
/**
* 排序
*/
sort?: number;
menuIds?: number[];
/**
* 角色状态(1-正常;0-停用)
* 备注
*/
status?: number;
remarks?: string;
}
......@@ -102,7 +102,7 @@ export interface UserPageVO {
/**
* 创建时间
*/
createTime?: Date;
createDate?: Date;
}
/**
......
import {Plus, Delete, Edit, Search, Share, Upload } from '@element-plus/icons-vue'
import {Plus, Delete, Edit, Search, Share, Upload,Download } from '@element-plus/icons-vue'
/** 公共字段*/
export const commonField = {
typeParent: 'primary', // typeParent: 'text', type="text" 已在3.00移除,用了typeParent这个字段的需要在按钮用link设置链接按钮
......@@ -32,7 +32,7 @@ export const commonField = {
addIcon: Plus,
delIcon: 'el-icon-delete',
importIcon: Upload,
exportIcon: 'el-icon-download',
exportIcon: Download,
deleteTypePrimary: 'danger',
deleteSize: 'small',
deleteDisabled: 'ids.length === 0',
......
......@@ -7,15 +7,23 @@ import {
deleteRoles,
getRoleMenuIds,
updateRoleMenus,
changeRoleStatus,
treeSelect,
roleMenuTreeSelect
} from "@/api/role";
import { getMenuOptions } from "@/api/menu";
import { RolePageVO, RoleForm, RoleQuery } from "@/api/role/types";
import { commonField } from "@/utils/commonField";
defineOptions({
name: "Role",
inheritAttrs: false,
});
const hasDelPerm = ref(['sys:role:delete']);
const hasResetPerm = ref(['sys:role:resetPwd']);
const hasUpdatePerm = ref(['sys:role:update']);
const hasAddPerm = ref(['sys:role:add']);
const hasExportPerm = ref(['sys:role:export']);
const queryFormRef = ref(ElForm);
const roleFormRef = ref(ElForm);
......@@ -24,12 +32,27 @@ const menuRef = ref(ElTree);
const loading = ref(false);
const ids = ref<number[]>([]);
const total = ref(0);
const menuOptions = ref([])
const updateMenu = ref([])
const menu = ref(ElTree);
const defaultProps = reactive({
children: 'children',
label: 'label'
})
const queryParams = reactive<RoleQuery>({
pageNum: 1,
pageSize: 10,
});
const statusOptions = reactive([
{
dictLabel: '启用',
dictValue: '1'
},
{
dictLabel: '停用',
dictValue: '0'
}
])
const roleList = ref<RolePageVO[]>();
const dialog = reactive({
......@@ -38,17 +61,27 @@ const dialog = reactive({
});
const formData = reactive<RoleForm>({
sort: 1,
status: 1,
code: "",
name: "",
businessId: undefined,
roleName: '',
roleKey: '',
roleSort: 0,
flag: '1',
menuIds: [],
remarks: '',
});
const validatePass = (rule, value, callback) => {
const arr = menu.value.getCheckedKeys()
if (arr.length === 0 || !arr) {
callback(new Error('请选择菜单权限'))
} else {
callback()
}
}
const rules = reactive({
name: [{ required: true, message: "请输入角色名称", trigger: "blur" }],
code: [{ required: true, message: "请输入角色编码", trigger: "blur" }],
dataScope: [{ required: true, message: "请选择数据权限", trigger: "blur" }],
status: [{ required: true, message: "请选择状态", trigger: "blur" }],
roleName: [{ required: true, message: "请输入角色名称", trigger: "blur" }],
roleKey: [{ required: true, message: "请输入权限字符", trigger: "blur" }],
roleSort: [{ required: true, message: "请输入角色排序", trigger: "blur" }],
menuIds: [{ required: true, validator: validatePass, trigger: ["blur","change"] }]
});
const menuDialogVisible = ref(false);
......@@ -65,9 +98,9 @@ let checkedRole: CheckedRole = reactive({});
function handleQuery() {
loading.value = true;
getRolePage(queryParams)
.then(({ data }) => {
roleList.value = data.list;
total.value = data.total;
.then(res => {
roleList.value = res.rows;
total.value = res.total;
})
.finally(() => {
loading.value = false;
......@@ -84,28 +117,85 @@ function resetQuery() {
function handleSelectionChange(selection: any) {
ids.value = selection.map((item: any) => item.id);
}
/** 菜单权限check事件*/
function handleCheck(data, { checkedKeys }) {
console.log('data',data)
console.log('checkedKeys',checkedKeys)
if (checkedKeys.includes(data.id)) { // 选中
const node = menu.value.getNode(data.id) // getNode(node-key)
console.log('node',node)
selectChildren(data, true) // 选中子节点
parentNodesChange(node) // 选中父节点
} else {
selectChildren(data, false) // 取消子节点
}
}
/** 选中子节点*/
function selectChildren(data, checked) {
data && data.children && data.children.map(item => {
menu.value.setChecked(item.id, checked)
if (data.children) {
selectChildren(item, checked)
}
})
}
/** 父级递归*/
function parentNodesChange(node) {
if (node.parent) {
for (const key in node) {
if (key === 'id') {
menu.value.setChecked(node, true)
}
}
if (node.parent && node.id !== 0) {
parentNodesChange(node.parent)
}
}
}
/** 打开角色表单弹窗 */
function openDialog(roleId?: number) {
dialog.visible = true;
getMenuTreeSelect() // 查询菜单树结构
if (roleId) {
const roleMenu = getRoleMenuTreeSelect(roleId)
dialog.title = "修改角色";
getRoleForm(roleId).then(({ data }) => {
Object.assign(formData, data);
nextTick(() => {
roleMenu.then(res => {
menu.value.setCheckedKeys(res.data.checkedKeys)
})
});
});
} else {
dialog.title = "新增角色";
}
}
/** 根据角色ID查询菜单树结构 */
function getRoleMenuTreeSelect(roleId) {
return roleMenuTreeSelect(roleId).then(response => {
menuOptions.value = response.data.menus
return response
})
}
/** 查询菜单树结构*/
function getMenuTreeSelect() {
treeSelect().then(res => {
menuOptions.value = res.data
updateMenu.value.push(menuOptions.value[0].id)
})
}
/** 角色保存提交 */
function handleSubmit() {
updateMenu.value = []
roleFormRef.value.validate((valid: any) => {
if (valid) {
loading.value = true;
const roleId = formData.id;
formData.menuCheckStrictly = 0
const roleId = formData.businessId;
if (roleId) {
updateRole(roleId, formData)
formData.menuIds = getMenuAllCheckedKeys()
updateRole(roleId,formData)
.then(() => {
ElMessage.success("修改成功");
closeDialog();
......@@ -113,6 +203,7 @@ function handleSubmit() {
})
.finally(() => (loading.value = false));
} else {
formData.menuIds = getMenuAllCheckedKeys()
addRole(formData)
.then(() => {
ElMessage.success("新增成功");
......@@ -124,32 +215,56 @@ function handleSubmit() {
}
});
}
/** 所有菜单节点数据 */
function getMenuAllCheckedKeys() {
// 目前被选中的菜单节点
const checkedKeys = menu.value.getHalfCheckedKeys()
// 半选中的菜单节点
const halfCheckedKeys = menu.value.getCheckedKeys()
checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys)
return checkedKeys
}
/** 关闭表单弹窗 */
function closeDialog() {
dialog.visible = false;
resetForm();
}
/** 角色状态修改*/
function handleStatusChange(row: any) {
const text = row.flag === '1' ? '启用' : '停用'
ElMessageBox.confirm("是否确认操作?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
return changeRoleStatus(row.businessId, row.flag)
}).then(() => {
ElMessage.success(text + '成功');
})
.catch(function () {
row.flag = row.flag === '0' ? '1' : '0'
});
}
/** 重置表单 */
function resetForm() {
roleFormRef.value.resetFields();
roleFormRef.value.clearValidate();
formData.id = undefined;
formData.sort = 1;
formData.status = 1;
if (menu.value !== undefined) {
menu.value.setCheckedKeys([])
}
formData.businessId = undefined;
formData.roleName = '';
formData.roleKey = '';
formData.roleSort = 0;
formData.flag = '1';
formData.menuIds = [];
formData.remarks = '';
}
/** 删除角色 */
function handleDelete(roleId?: number) {
const roleIds = [roleId || ids.value].join(",");
if (!roleIds) {
ElMessage.warning("请勾选删除项");
return;
}
ElMessageBox.confirm("确认删除已选中的数据项?", "警告", {
function handleDelete(row?: any) {
const roleIds = row.businessId
ElMessageBox.confirm("是否确认操作?", "警告", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
......@@ -223,15 +338,43 @@ onMounted(() => {
<div class="app-container">
<div class="search-container">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item prop="keywords" label="关键字">
<el-form-item prop="roleName" label="角色名称">
<el-input
v-model="queryParams.keywords"
v-model="queryParams.roleName"
placeholder="角色名称"
clearable
:maxlength="30"
size="small"
style="width: 150px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="权限字符" prop="roleKey">
<el-input
v-model="queryParams.roleKey"
placeholder="请输入权限字符"
clearable
size="small"
style="width: 150px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="角色状态" prop="flag">
<el-select
v-model="queryParams.flag"
placeholder="请选择角色状态"
clearable
size="small"
style="width: 150px"
>
<el-option
v-for="dict in statusOptions"
:key="dict.dictValue"
:label="dict.dictLabel"
:value="dict.dictValue"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleQuery"
><i-ep-search />搜索</el-button
......@@ -243,15 +386,15 @@ onMounted(() => {
<el-card shadow="never" class="table-container">
<template #header>
<el-button type="success" @click="openDialog()"
><i-ep-plus />新增</el-button
>
<!-- //新增按钮-->
<el-button
type="danger"
:disabled="ids.length === 0"
@click="handleDelete()"
><i-ep-delete />删除</el-button
>
v-hasPermi="hasAddPerm"
:class="commonField.addClass"
:type="commonField.typePrimary"
:icon="commonField.addIcon"
:size="commonField.smallSize"
@click="openDialog()"
>{{ commonField.addName }}</el-button>
</template>
<el-table
......@@ -260,47 +403,66 @@ onMounted(() => {
:data="roleList"
highlight-current-row
border
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="角色名称" prop="name" min-width="100" />
<el-table-column label="角色编码" prop="code" width="150" />
<el-table-column type="index" label="序号" width="90" />
<el-table-column label="名称" prop="roleName" :show-overflow-tooltip="true">
<template #default="scope">
{{ scope.row.roleName || '-' }}
</template>
</el-table-column>
<el-table-column label="权限字符" prop="roleKey">
<template #default="scope">
{{ scope.row.roleKey || '-' }}
</template>
</el-table-column>
<el-table-column label="显示顺序" prop="roleSort">
<template #default="scope">
{{ scope.row.roleSort || '-' }}
</template>
</el-table-column>
<el-table-column label="状态" align="center" width="100">
<template #default="scope">
<el-tag v-if="scope.row.status === 1" type="success">正常</el-tag>
<el-tag v-else type="info">禁用</el-tag>
<el-switch
v-model="scope.row.flag"
active-value="1"
inactive-value="0"
@change="handleStatusChange(scope.row)"
/>
</template>
</el-table-column>
<el-table-column label="创建时间" :show-overflow-tooltip="true" align="center" prop="createTime">
<template #default="scope">
<span>{{ scope.row.createDate || '-' }}</span>
</template>
</el-table-column>
<el-table-column label="排序" align="center" width="80" prop="sort" />
<el-table-column fixed="right" label="操作" width="220">
<template #default="scope">
<!-- //修改-->
<el-button
type="primary"
size="small"
v-hasPermi="hasUpdatePerm"
:class="commonField.updateClass"
:type="commonField.typeParent"
link
@click="openMenuDialog(scope.row)"
>
<i-ep-position />分配权限
</el-button>
:size="commonField.size"
@click="openDialog(scope.row.businessId)"
>{{ commonField.updateName }}</el-button>
<el-button
type="primary"
size="small"
v-hasPermi="hasDelPerm"
:class="commonField.delClass"
:type="commonField.typeParent"
link
@click="openDialog(scope.row.id)"
>
<i-ep-edit />编辑
</el-button>
:size="commonField.size"
@click="openMenuDialog(scope.row)"
>{{ commonField.dataPower }}</el-button>
<!-- //删除-->
<el-button
type="primary"
size="small"
v-hasPermi="hasDelPerm"
:class="commonField.delClass"
:type="commonField.typeParent"
link
@click="handleDelete(scope.row.id)"
>
<i-ep-delete />删除
</el-button>
:size="commonField.size"
@click="handleDelete(scope.row)"
>{{ commonField.deleteName }}</el-button>
</template>
</el-table-column>
</el-table>
......@@ -327,38 +489,35 @@ onMounted(() => {
:rules="rules"
label-width="100px"
>
<el-form-item label="角色名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入角色名称" />
<el-form-item label="名称" prop="roleName">
<el-input v-model="formData.roleName" placeholder="请输入名称" />
</el-form-item>
<el-form-item label="角色编码" prop="code">
<el-input v-model="formData.code" placeholder="请输入角色编码" />
<el-form-item label="权限字符" prop="roleKey">
<el-input v-model.trim="formData.roleKey" show-word-limit :maxlength="30" placeholder="请输入权限字符" />
</el-form-item>
<el-form-item label="数据权限" prop="dataScope">
<el-select v-model="formData.dataScope">
<el-option :key="0" label="全部数据" :value="0" />
<el-option :key="1" label="部门及子部门数据" :value="1" />
<el-option :key="2" label="本部门数据" :value="2" />
<el-option :key="3" label="本人数据" :value="3" />
</el-select>
<el-form-item label="排序" prop="roleSort">
<el-input-number v-model="formData.roleSort" style="width: 100%" controls-position="right" :min="0" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="formData.status">
<el-radio :label="1">正常</el-radio>
<el-radio :label="0">停用</el-radio>
</el-radio-group>
<el-form-item label="状态">
<el-radio v-model="formData.flag" label="1">启用</el-radio>
<el-radio v-model="formData.flag" label="0">停用</el-radio>
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input-number
v-model="formData.sort"
controls-position="right"
:min="0"
style="width: 100px"
<el-form-item label="菜单权限" prop="menuIds">
<el-tree
ref="menu"
:check-strictly="true"
:data="menuOptions"
show-checkbox
node-key="id"
empty-text="加载中,请稍后"
:props="defaultProps"
:default-expanded-keys="updateMenu"
@check="handleCheck"
/>
</el-form-item>
<el-form-item label="备注">
<el-input v-model.trim="formData.remarks" maxlength="200" show-word-limit type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<template #footer>
......
......@@ -467,9 +467,15 @@ onMounted(() => {
:size="commonField.smallSize"
@click="openDialog('user-import')"
>{{ commonField.importName }}</el-button>
<el-button class="ml-3" @click="handleExport"
><template #icon><i-ep-download /></template>导出</el-button
>
<!-- //导出-->
<el-button
v-hasPermi="hasExportPerm"
:class="commonField.exportClass"
:type="commonField.typeSuccess"
:icon="commonField.exportIcon"
:size="commonField.smallSize"
@click="handleExport"
>{{ commonField.exportName }}</el-button>
</div>
</div>
</template>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment