refactor: 页面布局样式优化和接口合理性优化
Former-commit-id: 4af1b0aa5aca3569f540e3bcad99f6e14741e855
This commit is contained in:
@@ -44,9 +44,9 @@ export function listRoleOptions(
|
|||||||
*
|
*
|
||||||
* @param queryParams
|
* @param queryParams
|
||||||
*/
|
*/
|
||||||
export function getRoleResources(roleId: string): AxiosPromise<RoleResource> {
|
export function getRoleMenuIds(roleId: string): AxiosPromise<number[]> {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/v1/roles/' + roleId + '/resources',
|
url: '/api/v1/roles/' + roleId + '/menuIds',
|
||||||
method: 'get'
|
method: 'get'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -56,12 +56,12 @@ export function getRoleResources(roleId: string): AxiosPromise<RoleResource> {
|
|||||||
*
|
*
|
||||||
* @param queryParams
|
* @param queryParams
|
||||||
*/
|
*/
|
||||||
export function updateRoleResource(
|
export function updateRoleMenus(
|
||||||
roleId: string,
|
roleId: string,
|
||||||
data: RoleResource
|
data: number[]
|
||||||
): AxiosPromise<any> {
|
): AxiosPromise<any> {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/v1/roles/' + roleId + '/resources',
|
url: '/api/v1/roles/' + roleId + '/menus',
|
||||||
method: 'put',
|
method: 'put',
|
||||||
data: data
|
data: data
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -50,40 +50,3 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// fix: 内核较旧的浏览器不支持:not(selector list)
|
|
||||||
.el-button:not(.is-text),
|
|
||||||
.el-button:not(.is-link),
|
|
||||||
.el-button:not(.el-button--text) {
|
|
||||||
background-color: var(--el-button-bg-color);
|
|
||||||
border: var(--el-border);
|
|
||||||
border-color: var(--el-button-border-color)
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-button:not(.is-text):focus,
|
|
||||||
.el-button:not(.is-link):focus,
|
|
||||||
.el-button:not(.el-button--text):focus,
|
|
||||||
.el-button:not(.is-text):hover,
|
|
||||||
.el-button:not(.is-link):hover,
|
|
||||||
.el-button:not(.el-button--text):hover {
|
|
||||||
color: var(--el-button-hover-text-color);
|
|
||||||
border-color: var(--el-button-hover-border-color);
|
|
||||||
background-color: var(--el-button-hover-bg-color);
|
|
||||||
outline: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-button:not(.is-text):active,
|
|
||||||
.el-button:not(.is-link):active,
|
|
||||||
.el-button:not(.el-button--text):active {
|
|
||||||
color: var(--el-button-active-text-color);
|
|
||||||
border-color: var(--el-button-active-border-color);
|
|
||||||
background-color: var(--el-button-active-bg-color);
|
|
||||||
outline: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-button:not(.is-text):focus-visible,
|
|
||||||
.el-button:not(.is-link):focus-visible,
|
|
||||||
.el-button:not(.el-button--text):focus-visible {
|
|
||||||
border-color: transparent;
|
|
||||||
outline: 2px solid var(--el-button-border-color);
|
|
||||||
outline-offset: 1px
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
@import 'src/styles/variables.module';
|
@import 'src/styles/variables.module';
|
||||||
@import './mixin.scss';
|
|
||||||
@import './transition.scss';
|
|
||||||
@import 'src/styles/element-plus';
|
@import 'src/styles/element-plus';
|
||||||
@import './sidebar.scss';
|
@import './sidebar.scss';
|
||||||
|
|
||||||
@@ -66,3 +64,12 @@ div:focus {
|
|||||||
.app-container {
|
.app-container {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search{
|
||||||
|
padding:18px 0 0 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
box-shadow: var(--el-box-shadow-light);
|
||||||
|
border-radius: var(--el-card-border-radius);
|
||||||
|
border: 1px solid var(--el-card-border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
// global transition css
|
|
||||||
|
|
||||||
/* fade */
|
|
||||||
.fade-enter-active,
|
|
||||||
.fade-leave-active {
|
|
||||||
transition: opacity 0.28s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fade-enter,
|
|
||||||
.fade-leave-active {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fade-transform */
|
|
||||||
.fade-transform-leave-active,
|
|
||||||
.fade-transform-enter-active {
|
|
||||||
transition: all 0.5s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fade-transform-enter {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateX(-30px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.fade-transform-leave-to {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateX(30px);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* breadcrumb transition */
|
|
||||||
.breadcrumb-enter-active,
|
|
||||||
.breadcrumb-leave-active {
|
|
||||||
transition: all 0.5s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.breadcrumb-enter,
|
|
||||||
.breadcrumb-leave-active {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateX(20px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.breadcrumb-move {
|
|
||||||
transition: all 0.5s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.breadcrumb-leave-active {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
4
src/types/api/menu.d.ts
vendored
4
src/types/api/menu.d.ts
vendored
@@ -88,10 +88,6 @@ export interface Resource {
|
|||||||
* 子菜单
|
* 子菜单
|
||||||
*/
|
*/
|
||||||
children: Resource[];
|
children: Resource[];
|
||||||
/**
|
|
||||||
* 权限集合
|
|
||||||
*/
|
|
||||||
perms: Permission[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
2
src/types/api/role.d.ts
vendored
2
src/types/api/role.d.ts
vendored
@@ -4,7 +4,7 @@ import { PageQueryParam, PageResult } from './base';
|
|||||||
* 角色查询参数类型
|
* 角色查询参数类型
|
||||||
*/
|
*/
|
||||||
export interface RoleQueryParam extends PageQueryParam {
|
export interface RoleQueryParam extends PageQueryParam {
|
||||||
name?: string;
|
keywords?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
2
src/types/api/user.d.ts
vendored
2
src/types/api/user.d.ts
vendored
@@ -78,7 +78,7 @@ export interface UserFormData {
|
|||||||
/**
|
/**
|
||||||
* 用户导入表单类型声明
|
* 用户导入表单类型声明
|
||||||
*/
|
*/
|
||||||
export interface UserImportFormData {
|
export interface UserImportData {
|
||||||
deptId: number;
|
deptId: number;
|
||||||
roleIds: number[];
|
roleIds: number[];
|
||||||
}
|
}
|
||||||
|
|||||||
22
src/views/component/editor.vue
Normal file
22
src/views/component/editor.vue
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import Editor from '@/components/WangEditor/index.vue';
|
||||||
|
import { ElForm } from 'element-plus';
|
||||||
|
import { reactive, ref, toRefs } from 'vue';
|
||||||
|
|
||||||
|
const dataFormRef = ref(ElForm);
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
formData: {
|
||||||
|
content: '初始内容'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const { formData } = toRefs(state);
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-form ref="dataFormRef" :model="formData">
|
||||||
|
<editor v-model="formData.content" style="height: 600px" />
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -5,10 +5,8 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
// Vue依赖
|
|
||||||
import { onMounted, reactive, ref, toRefs } from 'vue';
|
import { onMounted, reactive, ref, toRefs } from 'vue';
|
||||||
|
|
||||||
// API依赖
|
|
||||||
import {
|
import {
|
||||||
getDeptForm,
|
getDeptForm,
|
||||||
deleteDept,
|
deleteDept,
|
||||||
@@ -18,36 +16,27 @@ import {
|
|||||||
listDepartments
|
listDepartments
|
||||||
} from '@/api/dept';
|
} from '@/api/dept';
|
||||||
|
|
||||||
// 组件依赖
|
|
||||||
import { Search, Plus, Edit, Refresh, Delete } from '@element-plus/icons-vue';
|
import { Search, Plus, Edit, Refresh, Delete } from '@element-plus/icons-vue';
|
||||||
import { ElForm, ElMessage, ElMessageBox } from 'element-plus';
|
import { ElForm, ElMessage, ElMessageBox } from 'element-plus';
|
||||||
import { DeptFormData, DeptItem, DeptQueryParam } from '@/types/api/dept';
|
import { DeptFormData, DeptItem, DeptQueryParam } from '@/types/api/dept';
|
||||||
import { Dialog, Option } from '@/types/common';
|
import { Dialog, Option } from '@/types/common';
|
||||||
|
|
||||||
// DOM元素的引用声明定义
|
|
||||||
const queryFormRef = ref(ElForm);
|
const queryFormRef = ref(ElForm);
|
||||||
const dataFormRef = ref(ElForm);
|
const dataFormRef = ref(ElForm);
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
|
loading: false,
|
||||||
// 选中ID数组
|
// 选中ID数组
|
||||||
ids: [] as number[],
|
ids: [] as number[],
|
||||||
// 非单个禁用
|
|
||||||
single: true,
|
|
||||||
loading: true,
|
|
||||||
// 表格树数据
|
// 表格树数据
|
||||||
deptList: [] as DeptItem[],
|
dataList: [] as DeptItem[],
|
||||||
// 部门下拉选项
|
|
||||||
deptOptions: [] as Option[],
|
deptOptions: [] as Option[],
|
||||||
// 弹窗属性
|
|
||||||
dialog: { visible: false } as Dialog,
|
dialog: { visible: false } as Dialog,
|
||||||
// 查询参数
|
|
||||||
queryParams: {} as DeptQueryParam,
|
queryParams: {} as DeptQueryParam,
|
||||||
// 表单数据
|
|
||||||
formData: {
|
formData: {
|
||||||
sort: 1,
|
sort: 1,
|
||||||
status: 1
|
status: 1
|
||||||
} as DeptFormData,
|
} as DeptFormData,
|
||||||
// 表单参数校验
|
|
||||||
rules: {
|
rules: {
|
||||||
parentId: [
|
parentId: [
|
||||||
{ required: true, message: '上级部门不能为空', trigger: 'blur' }
|
{ required: true, message: '上级部门不能为空', trigger: 'blur' }
|
||||||
@@ -58,9 +47,9 @@ const state = reactive({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
single,
|
ids,
|
||||||
loading,
|
loading,
|
||||||
deptList,
|
dataList,
|
||||||
deptOptions,
|
deptOptions,
|
||||||
queryParams,
|
queryParams,
|
||||||
formData,
|
formData,
|
||||||
@@ -69,18 +58,18 @@ const {
|
|||||||
} = toRefs(state);
|
} = toRefs(state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 部门查询
|
* 查询
|
||||||
*/
|
*/
|
||||||
function handleQuery() {
|
function handleQuery() {
|
||||||
state.loading = true;
|
loading.value = true;
|
||||||
listDepartments(state.queryParams).then(({ data }) => {
|
listDepartments(state.queryParams).then(({ data }) => {
|
||||||
state.deptList = data;
|
dataList.value = data;
|
||||||
state.loading = false;
|
loading.value = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置查询
|
* 重置
|
||||||
*/
|
*/
|
||||||
function resetQuery() {
|
function resetQuery() {
|
||||||
queryFormRef.value.resetFields();
|
queryFormRef.value.resetFields();
|
||||||
@@ -89,13 +78,12 @@ function resetQuery() {
|
|||||||
|
|
||||||
function handleSelectionChange(selection: any) {
|
function handleSelectionChange(selection: any) {
|
||||||
state.ids = selection.map((item: any) => item.id);
|
state.ids = selection.map((item: any) => item.id);
|
||||||
state.single = selection.length === 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载部门下拉数据源
|
* 获取部门下拉数据
|
||||||
*/
|
*/
|
||||||
async function loadDeptData() {
|
async function getDeptOptions() {
|
||||||
const deptOptions: any[] = [];
|
const deptOptions: any[] = [];
|
||||||
listDeptOptions().then(response => {
|
listDeptOptions().then(response => {
|
||||||
const rootDeptOption = {
|
const rootDeptOption = {
|
||||||
@@ -109,23 +97,23 @@ async function loadDeptData() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加部门
|
* 添加
|
||||||
*/
|
*/
|
||||||
function handleAdd(row: any) {
|
function handleAdd(row: any) {
|
||||||
loadDeptData();
|
getDeptOptions();
|
||||||
state.formData.id = undefined;
|
formData.value.id = undefined;
|
||||||
state.formData.parentId = row.id;
|
formData.value.parentId = row.id;
|
||||||
state.dialog = {
|
dialog.value = {
|
||||||
title: '添加部门',
|
title: '添加部门',
|
||||||
visible: true
|
visible: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改部门
|
* 修改
|
||||||
*/
|
*/
|
||||||
async function handleUpdate(row: any) {
|
async function handleUpdate(row: any) {
|
||||||
await loadDeptData();
|
await getDeptOptions();
|
||||||
const deptId = row.id || state.ids;
|
const deptId = row.id || state.ids;
|
||||||
state.dialog = {
|
state.dialog = {
|
||||||
title: '修改部门',
|
title: '修改部门',
|
||||||
@@ -137,7 +125,7 @@ async function handleUpdate(row: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 部门表单提交
|
* 提交
|
||||||
*/
|
*/
|
||||||
function submitForm() {
|
function submitForm() {
|
||||||
dataFormRef.value.validate((valid: any) => {
|
dataFormRef.value.validate((valid: any) => {
|
||||||
@@ -145,13 +133,13 @@ function submitForm() {
|
|||||||
if (state.formData.id) {
|
if (state.formData.id) {
|
||||||
updateDept(state.formData.id, state.formData).then(() => {
|
updateDept(state.formData.id, state.formData).then(() => {
|
||||||
ElMessage.success('修改成功');
|
ElMessage.success('修改成功');
|
||||||
cancel();
|
closeDialog();
|
||||||
handleQuery();
|
handleQuery();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
addDept(state.formData).then(() => {
|
addDept(state.formData).then(() => {
|
||||||
ElMessage.success('新增成功');
|
ElMessage.success('新增成功');
|
||||||
cancel();
|
closeDialog();
|
||||||
handleQuery();
|
handleQuery();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -160,12 +148,15 @@ function submitForm() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除部门
|
* 删除
|
||||||
*
|
|
||||||
* @param row
|
|
||||||
*/
|
*/
|
||||||
function handleDelete(row: any) {
|
function handleDelete(row: any) {
|
||||||
const ids = [row.id || state.ids].join(',');
|
const ids = [row.id || state.ids].join(',');
|
||||||
|
if (!ids) {
|
||||||
|
ElMessage.warning('请勾选删除项');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ElMessageBox.confirm(`确认删除已选中的数据项?`, '警告', {
|
ElMessageBox.confirm(`确认删除已选中的数据项?`, '警告', {
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
@@ -185,11 +176,10 @@ function handleDelete(row: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 取消/关闭弹窗
|
* 关闭弹窗
|
||||||
**/
|
**/
|
||||||
function cancel() {
|
function closeDialog() {
|
||||||
dialog.value.visible = false;
|
dialog.value.visible = false;
|
||||||
formData.value.id = undefined;
|
|
||||||
dataFormRef.value.resetFields();
|
dataFormRef.value.resetFields();
|
||||||
dataFormRef.value.clearValidate();
|
dataFormRef.value.clearValidate();
|
||||||
}
|
}
|
||||||
@@ -200,29 +190,17 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
|
<div class="search">
|
||||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||||
<el-form-item>
|
<el-form-item label="关键字" prop="keywords">
|
||||||
<el-button type="success" :icon="Plus" @click="handleAdd"
|
|
||||||
>新增</el-button
|
|
||||||
>
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
:icon="Delete"
|
|
||||||
:disabled="single"
|
|
||||||
@click="handleDelete"
|
|
||||||
>删除
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item prop="keywords">
|
|
||||||
<el-input
|
<el-input
|
||||||
v-model="queryParams.keywords"
|
v-model="queryParams.keywords"
|
||||||
placeholder="请输入部门名称"
|
placeholder="部门名称"
|
||||||
@keyup.enter="handleQuery"
|
@keyup.enter="handleQuery"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item prop="status">
|
<el-form-item label="部门状态" prop="status">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="queryParams.status"
|
v-model="queryParams.status"
|
||||||
placeholder="部门状态"
|
placeholder="部门状态"
|
||||||
@@ -244,10 +222,27 @@ onMounted(() => {
|
|||||||
<el-button :icon="Refresh" @click="resetQuery"> 重置 </el-button>
|
<el-button :icon="Refresh" @click="resetQuery"> 重置 </el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-card>
|
||||||
|
<!--toolbar-->
|
||||||
|
<template #header>
|
||||||
|
<el-button type="success" :icon="Plus" @click="handleAdd"
|
||||||
|
>新增</el-button
|
||||||
|
>
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
:icon="Delete"
|
||||||
|
@click="handleDelete"
|
||||||
|
:disabled="ids.length === 0"
|
||||||
|
>删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!--table-->
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
:data="deptList"
|
:data="dataList"
|
||||||
row-key="id"
|
row-key="id"
|
||||||
default-expand-all
|
default-expand-all
|
||||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||||
@@ -297,13 +292,14 @@ onMounted(() => {
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
<!-- 添加或修改部门对话框 -->
|
<!-- dialog -->
|
||||||
<el-dialog
|
<el-dialog
|
||||||
:title="dialog.title"
|
:title="dialog.title"
|
||||||
v-model="dialog.visible"
|
v-model="dialog.visible"
|
||||||
width="600px"
|
width="600px"
|
||||||
@closed="cancel"
|
@closed="closeDialog"
|
||||||
>
|
>
|
||||||
<el-form
|
<el-form
|
||||||
ref="dataFormRef"
|
ref="dataFormRef"
|
||||||
@@ -343,7 +339,7 @@ onMounted(() => {
|
|||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button type="primary" @click="submitForm"> 确 定 </el-button>
|
<el-button type="primary" @click="submitForm"> 确 定 </el-button>
|
||||||
<el-button @click="cancel"> 取 消 </el-button>
|
<el-button @click="closeDialog"> 取 消 </el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|||||||
@@ -5,23 +5,23 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { nextTick, onMounted, reactive, ref, toRefs } from 'vue';
|
import { onMounted, reactive, ref, toRefs } from 'vue';
|
||||||
import {
|
import {
|
||||||
listRolePages,
|
listRolePages,
|
||||||
updateRole,
|
updateRole,
|
||||||
getRoleFormDetail,
|
getRoleFormDetail,
|
||||||
addRole,
|
addRole,
|
||||||
deleteRoles,
|
deleteRoles,
|
||||||
getRoleResources,
|
getRoleMenuIds,
|
||||||
updateRoleResource
|
updateRoleMenus
|
||||||
} from '@/api/role';
|
} from '@/api/role';
|
||||||
import { listResources } from '@/api/menu';
|
import { listResources } from '@/api/menu';
|
||||||
|
|
||||||
import { ElForm, ElMessage, ElMessageBox, ElTree } from 'element-plus';
|
import { ElForm, ElMessage, ElMessageBox, ElTree } from 'element-plus';
|
||||||
import { Search, Plus, Edit, Refresh, Delete } from '@element-plus/icons-vue';
|
import { Search, Plus, Edit, Refresh, Delete } from '@element-plus/icons-vue';
|
||||||
import { RoleFormData, RoleItem, RoleQueryParam } from '@/types/api/role';
|
import { RoleFormData, RoleItem, RoleQueryParam } from '@/types/api/role';
|
||||||
import { Resource } from '@/types/api/menu';
|
|
||||||
import SvgIcon from '@/components/SvgIcon/index.vue';
|
import SvgIcon from '@/components/SvgIcon/index.vue';
|
||||||
|
import { Option, Dialog } from '@/types/common';
|
||||||
|
|
||||||
const emit = defineEmits(['roleClick']);
|
const emit = defineEmits(['roleClick']);
|
||||||
const queryFormRef = ref(ElForm);
|
const queryFormRef = ref(ElForm);
|
||||||
@@ -30,12 +30,8 @@ const resourceRef = ref(ElTree);
|
|||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
loading: true,
|
loading: true,
|
||||||
// 选中ID数组
|
// 选中ID
|
||||||
ids: [],
|
ids: [] as number[],
|
||||||
// 非单个禁用
|
|
||||||
single: true,
|
|
||||||
// 非多个禁用
|
|
||||||
multiple: true,
|
|
||||||
queryParams: {
|
queryParams: {
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 10
|
pageSize: 10
|
||||||
@@ -45,14 +41,14 @@ const state = reactive({
|
|||||||
dialog: {
|
dialog: {
|
||||||
title: '',
|
title: '',
|
||||||
visible: false
|
visible: false
|
||||||
},
|
} as Dialog,
|
||||||
formData: {} as RoleFormData,
|
formData: {} as RoleFormData,
|
||||||
rules: {
|
rules: {
|
||||||
name: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
|
name: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
|
||||||
code: [{ required: true, message: '请输入角色编码', trigger: 'blur' }]
|
code: [{ required: true, message: '请输入角色编码', trigger: 'blur' }]
|
||||||
},
|
},
|
||||||
resourceDialogVisible: false,
|
menuDialogVisible: false,
|
||||||
resourceOptions: [] as Resource[],
|
resourceOptions: [] as Option[],
|
||||||
btnPerms: {} as any,
|
btnPerms: {} as any,
|
||||||
// 勾选的菜单ID
|
// 勾选的菜单ID
|
||||||
checkedMenuIds: new Set([]),
|
checkedMenuIds: new Set([]),
|
||||||
@@ -65,20 +61,22 @@ const state = reactive({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
ids,
|
||||||
loading,
|
loading,
|
||||||
multiple,
|
|
||||||
queryParams,
|
queryParams,
|
||||||
roleList,
|
roleList,
|
||||||
total,
|
total,
|
||||||
dialog,
|
dialog,
|
||||||
formData,
|
formData,
|
||||||
rules,
|
rules,
|
||||||
resourceDialogVisible,
|
menuDialogVisible,
|
||||||
checkedRole,
|
checkedRole,
|
||||||
resourceOptions,
|
resourceOptions
|
||||||
btnPerms
|
|
||||||
} = toRefs(state);
|
} = toRefs(state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询
|
||||||
|
*/
|
||||||
function handleQuery() {
|
function handleQuery() {
|
||||||
emit('roleClick', {});
|
emit('roleClick', {});
|
||||||
state.loading = true;
|
state.loading = true;
|
||||||
@@ -89,7 +87,7 @@ function handleQuery() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 查询重置
|
* 重置查询
|
||||||
*/
|
*/
|
||||||
function resetQuery() {
|
function resetQuery() {
|
||||||
queryFormRef.value.resetFields();
|
queryFormRef.value.resetFields();
|
||||||
@@ -98,8 +96,6 @@ function resetQuery() {
|
|||||||
|
|
||||||
function handleSelectionChange(selection: any) {
|
function handleSelectionChange(selection: any) {
|
||||||
state.ids = selection.map((item: any) => item.id);
|
state.ids = selection.map((item: any) => item.id);
|
||||||
state.single = selection.length !== 1;
|
|
||||||
state.multiple = !selection.length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleRowClick(row: any) {
|
function handleRowClick(row: any) {
|
||||||
@@ -107,14 +103,14 @@ function handleRowClick(row: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleAdd() {
|
function handleAdd() {
|
||||||
state.dialog = {
|
dialog.value = {
|
||||||
title: '添加角色',
|
title: '添加角色',
|
||||||
visible: true
|
visible: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleUpdate(row: any) {
|
function handleUpdate(row: any) {
|
||||||
state.dialog = {
|
dialog.value = {
|
||||||
title: '修改角色',
|
title: '修改角色',
|
||||||
visible: true
|
visible: true
|
||||||
};
|
};
|
||||||
@@ -131,13 +127,13 @@ function submitFormData() {
|
|||||||
if (state.formData.id) {
|
if (state.formData.id) {
|
||||||
updateRole(state.formData.id as any, state.formData).then(() => {
|
updateRole(state.formData.id as any, state.formData).then(() => {
|
||||||
ElMessage.success('修改角色成功');
|
ElMessage.success('修改角色成功');
|
||||||
cancel();
|
closeDialog();
|
||||||
handleQuery();
|
handleQuery();
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
addRole(state.formData).then(() => {
|
addRole(state.formData).then(() => {
|
||||||
cancel();
|
closeDialog();
|
||||||
ElMessage.success('新增角色成功');
|
ElMessage.success('新增角色成功');
|
||||||
handleQuery();
|
handleQuery();
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
@@ -150,9 +146,8 @@ function submitFormData() {
|
|||||||
/**
|
/**
|
||||||
* 取消
|
* 取消
|
||||||
*/
|
*/
|
||||||
function cancel() {
|
function closeDialog() {
|
||||||
dialog.value.visible = false;
|
dialog.value.visible = false;
|
||||||
formData.value.id = undefined;
|
|
||||||
dataFormRef.value.resetFields();
|
dataFormRef.value.resetFields();
|
||||||
dataFormRef.value.clearValidate();
|
dataFormRef.value.clearValidate();
|
||||||
}
|
}
|
||||||
@@ -176,25 +171,11 @@ function handleDelete(row: any) {
|
|||||||
.catch(() => ElMessage.info('已取消删除'));
|
.catch(() => ElMessage.info('已取消删除'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleResourceCheckChange = (
|
|
||||||
data: Resource,
|
|
||||||
isCheck: boolean,
|
|
||||||
sonHasCheck: boolean
|
|
||||||
) => {
|
|
||||||
console.log('data', data);
|
|
||||||
console.log('isCheck', isCheck);
|
|
||||||
if (data.perms) {
|
|
||||||
data.perms.forEach(item => {
|
|
||||||
btnPerms.value[item.value] = isCheck;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 资源分配
|
* 资源分配
|
||||||
*/
|
*/
|
||||||
function openRoleResourceDialog(row: RoleItem) {
|
function showRoleMenuDialog(row: RoleItem) {
|
||||||
resourceDialogVisible.value = true;
|
menuDialogVisible.value = true;
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
|
|
||||||
const roleId: any = row.id;
|
const roleId: any = row.id;
|
||||||
@@ -206,80 +187,35 @@ function openRoleResourceDialog(row: RoleItem) {
|
|||||||
// 获取所有的资源
|
// 获取所有的资源
|
||||||
listResources().then(response => {
|
listResources().then(response => {
|
||||||
resourceOptions.value = response.data;
|
resourceOptions.value = response.data;
|
||||||
|
// 角色拥有的资源
|
||||||
// 获取角色拥有的资源
|
getRoleMenuIds(roleId).then(({ data }) => {
|
||||||
getRoleResources(roleId).then(({ data }) => {
|
// 勾选回显
|
||||||
// 勾选的菜单回显
|
const checkedMenuIds = data;
|
||||||
const checkedMenuIds = data.menuIds;
|
|
||||||
resourceRef.value.setCheckedKeys(checkedMenuIds);
|
resourceRef.value.setCheckedKeys(checkedMenuIds);
|
||||||
|
|
||||||
nextTick(() => {
|
|
||||||
// 勾选的权限回显
|
|
||||||
const rolePermIds = data.permIds;
|
|
||||||
|
|
||||||
state.allPermIds = filterResourcePermIds(response.data, []);
|
|
||||||
if (state.allPermIds) {
|
|
||||||
state.allPermIds.forEach(permId => {
|
|
||||||
if (rolePermIds.indexOf(permId) > -1) {
|
|
||||||
btnPerms.value[permId] = true;
|
|
||||||
} else {
|
|
||||||
btnPerms.value[permId] = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const filterResourcePermIds = (resources: Resource[], permIds: string[]) => {
|
|
||||||
resources.forEach(resource => {
|
|
||||||
if (resource.perms) {
|
|
||||||
resource.perms.forEach(perm => {
|
|
||||||
permIds.push(perm.value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (resource.children) {
|
|
||||||
filterResourcePermIds(resource.children, permIds);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return permIds;
|
|
||||||
};
|
|
||||||
/**
|
/**
|
||||||
* 分配资源提交
|
* 分配资源提交
|
||||||
*/
|
*/
|
||||||
function handleRoleResourceSubmit() {
|
function handleRoleResourceSubmit() {
|
||||||
const checkedMenuIds: any[] = resourceRef.value
|
const checkedMenuIds: number[] = resourceRef.value
|
||||||
.getCheckedNodes(false, true)
|
.getCheckedNodes(false, true)
|
||||||
.map((node: any) => node.value);
|
.map((node: any) => node.value);
|
||||||
|
|
||||||
const checkedPermIds = [] as string[];
|
updateRoleMenus(checkedRole.value.id, checkedMenuIds).then(res => {
|
||||||
if (state.allPermIds) {
|
|
||||||
state.allPermIds.forEach(permId => {
|
|
||||||
if (btnPerms.value[permId]) {
|
|
||||||
checkedPermIds.push(permId);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const RoleResource = {
|
|
||||||
menuIds: checkedMenuIds,
|
|
||||||
permIds: checkedPermIds
|
|
||||||
};
|
|
||||||
|
|
||||||
updateRoleResource(checkedRole.value.id, RoleResource).then(res => {
|
|
||||||
ElMessage.success('分配权限成功');
|
ElMessage.success('分配权限成功');
|
||||||
state.resourceDialogVisible = false;
|
menuDialogVisible.value = false;
|
||||||
handleQuery();
|
handleQuery();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 取消资源分配
|
* 关闭资源弹窗
|
||||||
*/
|
*/
|
||||||
function cancelResourceAssign() {
|
function closeMenuDialogVisible() {
|
||||||
state.resourceDialogVisible = false;
|
menuDialogVisible.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -289,24 +225,11 @@ onMounted(() => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<!-- 搜索表单 -->
|
<div class="search">
|
||||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||||
<el-form-item>
|
<el-form-item prop="name" label="关键字">
|
||||||
<el-button type="success" :icon="Plus" @click="handleAdd"
|
|
||||||
>新增</el-button
|
|
||||||
>
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
:icon="Delete"
|
|
||||||
:disabled="multiple"
|
|
||||||
@click="handleDelete"
|
|
||||||
>删除</el-button
|
|
||||||
>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item prop="name">
|
|
||||||
<el-input
|
<el-input
|
||||||
v-model="queryParams.name"
|
v-model="queryParams.keywords"
|
||||||
placeholder="角色名称"
|
placeholder="角色名称"
|
||||||
clearable
|
clearable
|
||||||
@keyup.enter="handleQuery"
|
@keyup.enter="handleQuery"
|
||||||
@@ -320,8 +243,22 @@ onMounted(() => {
|
|||||||
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 数据表格 -->
|
<el-card>
|
||||||
|
<template #header>
|
||||||
|
<el-button type="success" :icon="Plus" @click="handleAdd"
|
||||||
|
>新增</el-button
|
||||||
|
>
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
:icon="Delete"
|
||||||
|
:disabled="ids.length === 0"
|
||||||
|
@click="handleDelete"
|
||||||
|
>删除</el-button
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
<!--table-->
|
||||||
<el-table
|
<el-table
|
||||||
ref="dataTableRef"
|
ref="dataTableRef"
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
@@ -353,7 +290,7 @@ onMounted(() => {
|
|||||||
type="success"
|
type="success"
|
||||||
circle
|
circle
|
||||||
plain
|
plain
|
||||||
@click.stop="openRoleResourceDialog(scope.row)"
|
@click.stop="showRoleMenuDialog(scope.row)"
|
||||||
>
|
>
|
||||||
<svg-icon icon-class="perm" />
|
<svg-icon icon-class="perm" />
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -377,7 +314,7 @@ onMounted(() => {
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<!-- 分页工具条 -->
|
<!-- pagination -->
|
||||||
<pagination
|
<pagination
|
||||||
v-if="total > 0"
|
v-if="total > 0"
|
||||||
:total="total"
|
:total="total"
|
||||||
@@ -385,8 +322,9 @@ onMounted(() => {
|
|||||||
v-model:limit="queryParams.pageSize"
|
v-model:limit="queryParams.pageSize"
|
||||||
@pagination="handleQuery"
|
@pagination="handleQuery"
|
||||||
/>
|
/>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
<!-- 表单弹窗 -->
|
<!-- dialog -->
|
||||||
<el-dialog
|
<el-dialog
|
||||||
:title="dialog.title"
|
:title="dialog.title"
|
||||||
v-model="dialog.visible"
|
v-model="dialog.visible"
|
||||||
@@ -427,7 +365,7 @@ onMounted(() => {
|
|||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button type="primary" @click="submitFormData">确 定</el-button>
|
<el-button type="primary" @click="submitFormData">确 定</el-button>
|
||||||
<el-button @click="cancel">取 消</el-button>
|
<el-button @click="closeDialog">取 消</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@@ -435,7 +373,7 @@ onMounted(() => {
|
|||||||
<!--分配资源弹窗-->
|
<!--分配资源弹窗-->
|
||||||
<el-dialog
|
<el-dialog
|
||||||
:title="'【' + checkedRole.name + '】资源分配'"
|
:title="'【' + checkedRole.name + '】资源分配'"
|
||||||
v-model="resourceDialogVisible"
|
v-model="menuDialogVisible"
|
||||||
width="800px"
|
width="800px"
|
||||||
>
|
>
|
||||||
<el-scrollbar max-height="600px" v-loading="loading">
|
<el-scrollbar max-height="600px" v-loading="loading">
|
||||||
@@ -445,25 +383,9 @@ onMounted(() => {
|
|||||||
show-checkbox
|
show-checkbox
|
||||||
:data="resourceOptions"
|
:data="resourceOptions"
|
||||||
:default-expand-all="true"
|
:default-expand-all="true"
|
||||||
@check-change="handleResourceCheckChange"
|
|
||||||
>
|
>
|
||||||
<template #default="{ data }">
|
<template #default="{ data }">
|
||||||
{{ data.label }}
|
{{ data.label }}
|
||||||
|
|
||||||
<div v-if="data.perms" class="resource-tree-node">
|
|
||||||
<el-divider direction="vertical" />
|
|
||||||
<div class="node-content">
|
|
||||||
<el-checkbox
|
|
||||||
v-for="perm in data.perms"
|
|
||||||
:key="perm.value"
|
|
||||||
:label="perm.value"
|
|
||||||
border
|
|
||||||
size="small"
|
|
||||||
v-model="btnPerms[perm.value]"
|
|
||||||
>{{ perm.label }}</el-checkbox
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
</el-tree>
|
</el-tree>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
@@ -473,48 +395,9 @@ onMounted(() => {
|
|||||||
<el-button type="primary" @click="handleRoleResourceSubmit"
|
<el-button type="primary" @click="handleRoleResourceSubmit"
|
||||||
>确 定</el-button
|
>确 定</el-button
|
||||||
>
|
>
|
||||||
<el-button @click="cancelResourceAssign">取 消</el-button>
|
<el-button @click="closeMenuDialogVisible">取 消</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.resource-tree-node {
|
|
||||||
width: 100%;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
display: flex;
|
|
||||||
font-size: 14px;
|
|
||||||
justify-content: flex-end;
|
|
||||||
margin: 0 50px;
|
|
||||||
.node-content {
|
|
||||||
width: 400px;
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
.el-divider--vertical {
|
|
||||||
height: 2em !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.el-tree-node__content {
|
|
||||||
height: auto !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-checkbox-group {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
&:hover {
|
|
||||||
background-color: var(--el-tree-node-hover-bg-color);
|
|
||||||
}
|
|
||||||
&:active {
|
|
||||||
background-color: var(--el-tree-node-hover-bg-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-checkbox.el-checkbox--small {
|
|
||||||
margin: 5px;
|
|
||||||
z-index: 999;
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
// Vue依赖
|
|
||||||
import {
|
import {
|
||||||
reactive,
|
reactive,
|
||||||
ref,
|
ref,
|
||||||
@@ -15,7 +14,7 @@ import {
|
|||||||
toRefs
|
toRefs
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
|
|
||||||
// 导入API
|
// api
|
||||||
import {
|
import {
|
||||||
listUserPages,
|
listUserPages,
|
||||||
getUserFormData,
|
getUserFormData,
|
||||||
@@ -31,7 +30,6 @@ import {
|
|||||||
import { listDeptOptions } from '@/api/dept';
|
import { listDeptOptions } from '@/api/dept';
|
||||||
import { listRoleOptions } from '@/api/role';
|
import { listRoleOptions } from '@/api/role';
|
||||||
|
|
||||||
// 组件依赖
|
|
||||||
import {
|
import {
|
||||||
ElMessage,
|
ElMessage,
|
||||||
ElMessageBox,
|
ElMessageBox,
|
||||||
@@ -54,12 +52,11 @@ import {
|
|||||||
UserItem,
|
UserItem,
|
||||||
UserQueryParam,
|
UserQueryParam,
|
||||||
UserFormData,
|
UserFormData,
|
||||||
UserImportFormData
|
UserImportData
|
||||||
} from '@/types/api/user';
|
} from '@/types/api/user';
|
||||||
|
|
||||||
import { Option, Dialog } from '@/types/common';
|
import { Option, Dialog } from '@/types/common';
|
||||||
|
|
||||||
// DOM元素的引用声明定义 ,变量名和DOM的ref属性值一致
|
|
||||||
const deptTreeRef = ref(ElTree); // 部门树
|
const deptTreeRef = ref(ElTree); // 部门树
|
||||||
const queryFormRef = ref(ElForm); // 查询表单
|
const queryFormRef = ref(ElForm); // 查询表单
|
||||||
const dataFormRef = ref(ElForm); // 用户表单
|
const dataFormRef = ref(ElForm); // 用户表单
|
||||||
@@ -71,37 +68,27 @@ const state = reactive({
|
|||||||
// 遮罩层
|
// 遮罩层
|
||||||
loading: true,
|
loading: true,
|
||||||
// 选中数组
|
// 选中数组
|
||||||
ids: [],
|
ids: [] as number[],
|
||||||
// 非单个禁用
|
|
||||||
single: true,
|
|
||||||
// 非多个禁用
|
|
||||||
multiple: true,
|
|
||||||
// 总条数
|
// 总条数
|
||||||
total: 0,
|
total: 0,
|
||||||
// 用户分页数据
|
|
||||||
userList: [] as UserItem[],
|
userList: [] as UserItem[],
|
||||||
// 弹窗属性
|
|
||||||
dialog: {
|
dialog: {
|
||||||
visible: false
|
visible: false
|
||||||
} as Dialog,
|
} as Dialog,
|
||||||
deptName: undefined,
|
deptName: undefined,
|
||||||
// 部门树选项
|
// 部门下拉项
|
||||||
deptOptions: [] as Option[],
|
deptOptions: [] as Option[],
|
||||||
// 部门名称
|
// 性别下拉项
|
||||||
// 性别状态字典
|
genderOptions: [] as Option[],
|
||||||
genderOptions: [] as any[],
|
// 角色下拉项
|
||||||
// 角色选项
|
|
||||||
roleOptions: [] as Option[],
|
roleOptions: [] as Option[],
|
||||||
// 表单参数
|
|
||||||
formData: {
|
formData: {
|
||||||
status: 1
|
status: 1
|
||||||
} as UserFormData,
|
} as UserFormData,
|
||||||
// 查询参数
|
|
||||||
queryParams: {
|
queryParams: {
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 10
|
pageSize: 10
|
||||||
} as UserQueryParam,
|
} as UserQueryParam,
|
||||||
// 表单校验
|
|
||||||
rules: {
|
rules: {
|
||||||
username: [{ required: true, message: '用户名不能为空', trigger: 'blur' }],
|
username: [{ required: true, message: '用户名不能为空', trigger: 'blur' }],
|
||||||
nickname: [
|
nickname: [
|
||||||
@@ -129,14 +116,14 @@ const state = reactive({
|
|||||||
title: '用户搭配',
|
title: '用户搭配',
|
||||||
visible: false
|
visible: false
|
||||||
} as Dialog,
|
} as Dialog,
|
||||||
importFormData: {} as UserImportFormData,
|
importFormData: {} as UserImportData,
|
||||||
excelFile: undefined as any,
|
excelFile: undefined as any,
|
||||||
excelFilelist: [] as File[]
|
excelFilelist: [] as File[]
|
||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
ids,
|
||||||
loading,
|
loading,
|
||||||
multiple,
|
|
||||||
queryParams,
|
queryParams,
|
||||||
userList,
|
userList,
|
||||||
total,
|
total,
|
||||||
@@ -151,9 +138,6 @@ const {
|
|||||||
excelFilelist
|
excelFilelist
|
||||||
} = toRefs(state);
|
} = toRefs(state);
|
||||||
|
|
||||||
/**
|
|
||||||
* 部门筛选
|
|
||||||
*/
|
|
||||||
watchEffect(
|
watchEffect(
|
||||||
() => {
|
() => {
|
||||||
deptTreeRef.value.filter(state.deptName);
|
deptTreeRef.value.filter(state.deptName);
|
||||||
@@ -164,7 +148,7 @@ watchEffect(
|
|||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 部门列表筛选
|
* 部门筛选
|
||||||
*/
|
*/
|
||||||
function filterDeptNode(value: string, data: any) {
|
function filterDeptNode(value: string, data: any) {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
@@ -182,16 +166,16 @@ function handleDeptNodeClick(data: { [key: string]: any }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载角色下拉列表
|
* 获取角色下拉项
|
||||||
*/
|
*/
|
||||||
async function loadRoleOptions() {
|
async function getRoleOptions() {
|
||||||
listRoleOptions().then(response => {
|
listRoleOptions().then(response => {
|
||||||
state.roleOptions = response.data;
|
state.roleOptions = response.data;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户状态修改
|
* 用户状态change
|
||||||
*/
|
*/
|
||||||
function handleStatusChange(row: { [key: string]: any }) {
|
function handleStatusChange(row: { [key: string]: any }) {
|
||||||
const text = row.status === 1 ? '启用' : '停用';
|
const text = row.status === 1 ? '启用' : '停用';
|
||||||
@@ -216,8 +200,8 @@ function handleStatusChange(row: { [key: string]: any }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户查询
|
* 查询
|
||||||
**/
|
*/
|
||||||
function handleQuery() {
|
function handleQuery() {
|
||||||
state.loading = true;
|
state.loading = true;
|
||||||
listUserPages(state.queryParams).then(({ data }) => {
|
listUserPages(state.queryParams).then(({ data }) => {
|
||||||
@@ -228,7 +212,7 @@ function handleQuery() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置查询
|
* 重置
|
||||||
*/
|
*/
|
||||||
function resetQuery() {
|
function resetQuery() {
|
||||||
queryFormRef.value.resetFields();
|
queryFormRef.value.resetFields();
|
||||||
@@ -236,16 +220,14 @@ function resetQuery() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表格行选中事件
|
* 行选中
|
||||||
*/
|
*/
|
||||||
function handleSelectionChange(selection: any) {
|
function handleSelectionChange(selection: any) {
|
||||||
state.ids = selection.map((item: any) => item.id);
|
state.ids = selection.map((item: any) => item.id);
|
||||||
state.single = selection.length !== 1;
|
|
||||||
state.multiple = !selection.length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 密码重置
|
* 重置密码
|
||||||
*/
|
*/
|
||||||
function resetPassword(row: { [key: string]: any }) {
|
function resetPassword(row: { [key: string]: any }) {
|
||||||
ElMessageBox.prompt(
|
ElMessageBox.prompt(
|
||||||
@@ -276,8 +258,8 @@ async function handleAdd() {
|
|||||||
title: '添加用户',
|
title: '添加用户',
|
||||||
visible: true
|
visible: true
|
||||||
};
|
};
|
||||||
await loadDeptOptions();
|
await getDeptOptions();
|
||||||
await loadRoleOptions();
|
await getRoleOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -290,8 +272,8 @@ async function handleUpdate(row: { [key: string]: any }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const userId = row.id || state.ids;
|
const userId = row.id || state.ids;
|
||||||
await loadDeptOptions();
|
await getDeptOptions();
|
||||||
await loadRoleOptions();
|
await getRoleOptions();
|
||||||
getUserFormData(userId).then(({ data }) => {
|
getUserFormData(userId).then(({ data }) => {
|
||||||
formData.value = data;
|
formData.value = data;
|
||||||
});
|
});
|
||||||
@@ -307,13 +289,13 @@ function submitForm() {
|
|||||||
if (userId) {
|
if (userId) {
|
||||||
updateUser(userId, state.formData).then(() => {
|
updateUser(userId, state.formData).then(() => {
|
||||||
ElMessage.success('修改用户成功');
|
ElMessage.success('修改用户成功');
|
||||||
cancel();
|
closeDialog();
|
||||||
handleQuery();
|
handleQuery();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
addUser(state.formData).then(() => {
|
addUser(state.formData).then(() => {
|
||||||
ElMessage.success('新增用户成功');
|
ElMessage.success('新增用户成功');
|
||||||
cancel();
|
closeDialog();
|
||||||
handleQuery();
|
handleQuery();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -345,28 +327,27 @@ function handleDelete(row: { [key: string]: any }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 取消
|
* 关闭用户弹窗
|
||||||
*/
|
*/
|
||||||
function cancel() {
|
function closeDialog() {
|
||||||
dialog.value.visible = false;
|
dialog.value.visible = false;
|
||||||
formData.value.id = undefined;
|
|
||||||
dataFormRef.value.resetFields();
|
dataFormRef.value.resetFields();
|
||||||
dataFormRef.value.clearValidate();
|
dataFormRef.value.clearValidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载部门
|
* 获取部门下拉项
|
||||||
*/
|
*/
|
||||||
async function loadDeptOptions() {
|
async function getDeptOptions() {
|
||||||
listDeptOptions().then(response => {
|
listDeptOptions().then(response => {
|
||||||
state.deptOptions = response.data;
|
state.deptOptions = response.data;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载性别字典
|
* 获取性别下拉项
|
||||||
*/
|
*/
|
||||||
function loadGenderOptions() {
|
function getGenderOptions() {
|
||||||
proxy.$listDictItemsByTypeCode('gender').then((response: any) => {
|
proxy.$listDictItemsByTypeCode('gender').then((response: any) => {
|
||||||
state.genderOptions = response?.data;
|
state.genderOptions = response?.data;
|
||||||
});
|
});
|
||||||
@@ -394,11 +375,11 @@ function handleDownloadTemplate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示导入弹窗
|
* 导入弹窗
|
||||||
*/
|
*/
|
||||||
async function showImportDialog() {
|
async function showImportDialog() {
|
||||||
await loadDeptOptions();
|
await getDeptOptions();
|
||||||
await loadRoleOptions();
|
await getRoleOptions();
|
||||||
importDialog.value.visible = true;
|
importDialog.value.visible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -470,20 +451,13 @@ function handleExport() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
onMounted(() => {
|
||||||
* 初始化数据
|
|
||||||
*/
|
|
||||||
function loadData() {
|
|
||||||
// 初始化性别字典
|
// 初始化性别字典
|
||||||
loadGenderOptions();
|
getGenderOptions();
|
||||||
// 初始化部门
|
// 初始化部门
|
||||||
loadDeptOptions();
|
getDeptOptions();
|
||||||
// 初始化用户列表数据
|
// 初始化用户列表数据
|
||||||
handleQuery();
|
handleQuery();
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
loadData();
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -514,11 +488,42 @@ onMounted(() => {
|
|||||||
|
|
||||||
<!-- 用户数据 -->
|
<!-- 用户数据 -->
|
||||||
<el-col :span="20" :xs="24">
|
<el-col :span="20" :xs="24">
|
||||||
<el-card class="box-card">
|
<div class="search">
|
||||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||||
<el-row>
|
<el-form-item label="关键字" prop="keywords">
|
||||||
<el-col :span="18" :xs="24">
|
<el-input
|
||||||
|
v-model="queryParams.keywords"
|
||||||
|
placeholder="用户名/昵称/手机号"
|
||||||
|
clearable
|
||||||
|
style="width: 200px"
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="状态" prop="status">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.status"
|
||||||
|
placeholder="全部"
|
||||||
|
clearable
|
||||||
|
style="width: 200px"
|
||||||
|
>
|
||||||
|
<el-option label="启用" value="1" />
|
||||||
|
<el-option label="禁用" value="0" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
|
<el-button type="primary" :icon="Search" @click="handleQuery"
|
||||||
|
>搜索</el-button
|
||||||
|
>
|
||||||
|
<el-button :icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-card>
|
||||||
|
<template #header>
|
||||||
|
<el-form-item style="float: left">
|
||||||
<el-button
|
<el-button
|
||||||
type="success"
|
type="success"
|
||||||
:icon="Plus"
|
:icon="Plus"
|
||||||
@@ -529,47 +534,13 @@ onMounted(() => {
|
|||||||
<el-button
|
<el-button
|
||||||
type="danger"
|
type="danger"
|
||||||
:icon="Delete"
|
:icon="Delete"
|
||||||
:disabled="multiple"
|
:disabled="ids.length === 0"
|
||||||
@click="handleDelete"
|
@click="handleDelete"
|
||||||
v-hasPerm="['sys:user:delete']"
|
v-hasPerm="['sys:user:delete']"
|
||||||
>删除</el-button
|
>删除</el-button
|
||||||
>
|
>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item style="float: right">
|
||||||
<el-form-item prop="keywords">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.keywords"
|
|
||||||
placeholder="用户名/昵称/手机号"
|
|
||||||
clearable
|
|
||||||
style="width: 200px"
|
|
||||||
@keyup.enter="handleQuery"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item prop="status">
|
|
||||||
<el-select
|
|
||||||
v-model="queryParams.status"
|
|
||||||
placeholder="用户状态"
|
|
||||||
clearable
|
|
||||||
style="width: 200px"
|
|
||||||
>
|
|
||||||
<el-option label="正常" value="1" />
|
|
||||||
<el-option label="禁用" value="0" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" :icon="Search" @click="handleQuery"
|
|
||||||
>搜索</el-button
|
|
||||||
>
|
|
||||||
<el-button :icon="Refresh" @click="resetQuery"
|
|
||||||
>重置</el-button
|
|
||||||
>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<el-col :span="6" :xs="24" style="text-align: right">
|
|
||||||
<el-form-item>
|
|
||||||
<el-dropdown split-button style="margin-left: 12px">
|
<el-dropdown split-button style="margin-left: 12px">
|
||||||
导入
|
导入
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
@@ -592,9 +563,7 @@ onMounted(() => {
|
|||||||
>导出</el-button
|
>导出</el-button
|
||||||
>
|
>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</template>
|
||||||
</el-row>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
@@ -689,7 +658,7 @@ onMounted(() => {
|
|||||||
v-model="dialog.visible"
|
v-model="dialog.visible"
|
||||||
width="600px"
|
width="600px"
|
||||||
append-to-body
|
append-to-body
|
||||||
@close="cancel"
|
@close="closeDialog"
|
||||||
>
|
>
|
||||||
<el-form
|
<el-form
|
||||||
ref="dataFormRef"
|
ref="dataFormRef"
|
||||||
@@ -765,12 +734,12 @@ onMounted(() => {
|
|||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||||
<el-button @click="cancel">取 消</el-button>
|
<el-button @click="closeDialog">取 消</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!--用户导入弹窗-->
|
<!-- import dialog -->
|
||||||
<el-dialog
|
<el-dialog
|
||||||
:title="importDialog.title"
|
:title="importDialog.title"
|
||||||
v-model="importDialog.visible"
|
v-model="importDialog.visible"
|
||||||
@@ -842,5 +811,3 @@ onMounted(() => {
|
|||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
||||||
|
|||||||
Reference in New Issue
Block a user