Compare commits

..

14 Commits

@ -1,14 +1,14 @@
<template>
<!-- 整体的应用容器 div -->
<!-- 整体的应用容器 div用于包裹整个页面的各个功能模块 -->
<div class="app-container">
<!-- 筛选搜索区域的卡片容器设置了阴影效果为无 -->
<!-- 筛选搜索区域的卡片容器设置了阴影效果为无使其外观更简洁 -->
<el-card class="filter-container" shadow="never">
<div>
<!-- 搜索图标 -->
<!-- 搜索图标使用了element-ui提供的搜索图标样式类 -->
<i class="el-icon-search"></i>
<!-- 筛选搜索的文字提示 -->
<!-- 筛选搜索的文字提示向用户说明此区域功能 -->
<span>筛选搜索</span>
<!-- 查询搜索按钮设置了样式为右浮动按钮类型为主要primary点击时调用 handleSearchList 方法按钮大小为 small -->
<!-- 查询搜索按钮设置了样式为右浮动按钮类型为主要primary点击时调用 handleSearchList 方法来执行搜索操作按钮大小为 small -->
<el-button
style="float:right"
type="primary"
@ -16,7 +16,7 @@
size="small">
查询搜索
</el-button>
<!-- 重置按钮设置了样式为右浮动且距离右侧 15px点击时调用 handleResetSearch 方法按钮大小为 small -->
<!-- 重置按钮设置了样式为右浮动且距离右侧 15px点击时调用 handleResetSearch 方法来重置筛选搜索条件按钮大小为 small -->
<el-button
style="float:right;margin-right: 15px"
@click="handleResetSearch()"
@ -25,11 +25,11 @@
</el-button>
</div>
<div style="margin-top: 15px">
<!-- 内联表单绑定了 listQuery 数据对象表单大小为 small标签宽度为 140px -->
<!-- 内联表单绑定了 listQuery 数据对象表单大小为 small标签宽度为 140px用于收集用户输入的筛选搜索条件 -->
<el-form :inline="true" :model="listQuery" size="small" label-width="140px">
<!-- 表单项目标签为输入搜索 -->
<!-- 表单项目标签为输入搜索明确此输入框的用途 -->
<el-form-item label="输入搜索:">
<!-- 输入框双向绑定 listQuery.keyword设置了类名占位符以及可清空功能 -->
<!-- 输入框双向绑定 listQuery.keyword设置了类名占位符提示用户可输入帐号/姓名以及可清空功能方便用户操作 -->
<el-input v-model="listQuery.keyword" class="input-width" placeholder="帐号/姓名" clearable></el-input>
</el-form-item>
</el-form>
@ -37,21 +37,21 @@
</el-card>
<!-- 操作区域的卡片容器设置了阴影效果为无 -->
<el-card class="operate-container" shadow="never">
<!-- 图标 -->
<!-- 图标可能用于装饰或提示此区域与数据操作相关 -->
<i class="el-icon-tickets"></i>
<!-- 数据列表的文字提示 -->
<!-- 数据列表的文字提示告知用户下方展示的数据相关内容 -->
<span>数据列表</span>
<!-- 添加按钮大小为 mini设置了类名点击时调用 handleAdd 方法设置了左侧外边距为 20px -->
<!-- 添加按钮大小为 mini设置了类名点击时调用 handleAdd 方法用于打开添加用户的对话框设置了左侧外边距为 20px使其在页面上布局更合理 -->
<el-button size="mini" class="btn-add" @click="handleAdd()" style="margin-left: 20px">添加</el-button>
</el-card>
<!-- 表格容器 div -->
<!-- 表格容器 div用于包裹展示数据的表格 -->
<div class="table-container">
<!-- el-table 组件绑定了 list 数据用于展示表格内容设置了加载状态绑定宽度边框等属性 -->
<!-- el-table 组件绑定了 list 数据用于展示表格内容设置了加载状态绑定通过 v-loading="listLoading" 控制加载动画显示宽度占满父容器边框等属性使表格展示更规范美观 -->
<el-table ref="adminTable"
:data="list"
style="width: 100%;"
v-loading="listLoading" border>
<!-- 表格列标签为编号设置了宽度和内容居中对齐通过插槽作用域展示对应行数据的 id 属性 -->
<!-- 表格列标签为编号设置了宽度和内容居中对齐通过插槽作用域展示对应行数据的 id 属性将数据准确展示在表格相应单元格中 -->
<el-table-column label="编号" width="100" align="center">
<template slot-scope="scope">{{scope.row.id}}</template>
</el-table-column>
@ -67,7 +67,7 @@
<el-table-column label="邮箱" align="center">
<template slot-scope="scope">{{scope.row.email}}</template>
</el-table-column>
<!-- 表格列标签为添加时间设置了宽度和内容居中对齐通过插槽作用域展示对应行数据的 createTime 属性并使用了 formatDateTime 过滤器进行格式化 -->
<!-- 表格列标签为添加时间设置了宽度和内容居中对齐通过插槽作用域展示对应行数据的 createTime 属性并使用了 formatDateTime 过滤器进行格式化使时间展示格式更友好 -->
<el-table-column label="添加时间" width="160" align="center">
<template slot-scope="scope">{{scope.row.createTime | formatDateTime}}</template>
</el-table-column>
@ -75,7 +75,7 @@
<el-table-column label="最后登录" width="160" align="center">
<template slot-scope="scope">{{scope.row.loginTime | formatDateTime}}</template>
</el-table-column>
<!-- 表格列标签为是否启用设置了宽度和内容居中对齐通过插槽作用域展示对应行数据的 status 属性并使用 el-switch 组件进行切换操作绑定了相关的事件和值 -->
<!-- 表格列标签为是否启用设置了宽度和内容居中对齐通过插槽作用域展示对应行数据的 status 属性并使用 el-switch 组件进行切换操作绑定了相关的事件和值方便用户在表格中直接操作启用/禁用状态 -->
<el-table-column label="是否启用" width="140" align="center">
<template slot-scope="scope">
<el-switch
@ -86,7 +86,7 @@
</el-switch>
</template>
</el-table-column>
<!-- 表格列标签为操作设置了宽度和内容居中对齐通过插槽作用域展示操作按钮包括分配角色编辑删除按钮分别绑定了对应的点击事件方法 -->
<!-- 表格列标签为操作设置了宽度和内容居中对齐通过插槽作用域展示操作按钮包括分配角色编辑删除按钮分别绑定了对应的点击事件方法方便对每行数据进行相应操作 -->
<el-table-column label="操作" width="180" align="center">
<template slot-scope="scope">
<el-button size="mini"
@ -106,9 +106,9 @@
</el-table-column>
</el-table>
</div>
<!-- 分页容器 div -->
<!-- 分页容器 div用于放置分页组件 -->
<div class="pagination-container">
<!-- el-pagination 分页组件设置了背景色相关页面切换事件绑定布局样式当前页每页数量可选每页数量数组以及总记录数等属性 -->
<!-- el-pagination 分页组件设置了背景色相关页面切换事件绑定如每页数量改变当前页改变的事件处理布局样式当前页每页数量可选每页数量数组以及总记录数等属性实现数据分页展示功能 -->
<el-pagination
background
@size-change="handleSizeChange"
@ -120,39 +120,39 @@
:total="total">
</el-pagination>
</div>
<!-- 编辑/添加用户的对话框组件根据 isEdit 变量来动态设置标题绑定了显示状态设置了宽度 -->
<!-- 编辑/添加用户的对话框组件根据 isEdit 变量来动态设置标题绑定了显示状态设置了宽度用于弹出窗口进行用户的添加或编辑操作 -->
<el-dialog
:title="isEdit?'编辑用户':'添加用户'"
:visible.sync="dialogVisible"
width="40%">
<!-- 对话框内的表单绑定了 admin 数据对象设置了表单引用标签宽度和大小 -->
<!-- 对话框内的表单绑定了 admin 数据对象设置了表单引用标签宽度和大小用于收集用户输入的添加/编辑用户相关信息 -->
<el-form :model="admin"
ref="adminForm"
label-width="150px" size="small">
<!-- 表单项目标签为帐号输入框双向绑定 admin.username -->
<!-- 表单项目标签为帐号输入框双向绑定 admin.username方便获取用户输入的帐号信息 -->
<el-form-item label="帐号:">
<el-input v-model="admin.username" style="width: 250px"></el-input>
</el-form-item>
<!-- 表单项目标签为姓名输入框双向绑定 admin.nickName -->
<!-- 表单项目标签为姓名输入框双向绑定 admin.nickName用于获取用户输入的姓名信息 -->
<el-form-item label="姓名:">
<el-input v-model="admin.nickName" style="width: 250px"></el-input>
</el-form-item>
<!-- 表单项目标签为邮箱输入框双向绑定 admin.email -->
<!-- 表单项目标签为邮箱输入框双向绑定 admin.email用于获取用户输入的邮箱信息 -->
<el-form-item label="邮箱:">
<el-input v-model="admin.email" style="width: 250px"></el-input>
</el-form-item>
<!-- 表单项目标签为密码输入框双向绑定 admin.password设置了密码类型 -->
<!-- 表单项目标签为密码输入框双向绑定 admin.password设置了密码类型用于获取用户输入的密码信息且保证安全性 -->
<el-form-item label="密码:">
<el-input v-model="admin.password" type="password" style="width: 250px"></el-input>
</el-form-item>
<!-- 表单项目标签为备注输入框双向绑定 admin.note设置了文本域类型和行数 -->
<!-- 表单项目标签为备注输入框双向绑定 admin.note设置了文本域类型和行数方便用户输入多行的备注信息 -->
<el-form-item label="备注:">
<el-input v-model="admin.note"
type="textarea"
:rows="5"
style="width: 250px"></el-input>
</el-form-item>
<!-- 表单项目标签为是否启用使用单选按钮组绑定 admin.status -->
<!-- 表单项目标签为是否启用使用单选按钮组绑定 admin.status方便用户选择用户是否启用状态 -->
<el-form-item label="是否启用:">
<el-radio-group v-model="admin.status">
<el-radio :label="1"></el-radio>
@ -160,18 +160,18 @@
</el-radio-group>
</el-form-item>
</el-form>
<!-- 对话框底部的按钮区域通过插槽定义了取消和确定按钮分别绑定了对应的点击事件 -->
<!-- 对话框底部的按钮区域通过插槽定义了取消和确定按钮分别绑定了对应的点击事件用于用户确认或取消添加/编辑操作 -->
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false" size="small"> </el-button>
<el-button type="primary" @click="handleDialogConfirm()" size="small"> </el-button>
</span>
</el-dialog>
<!-- 分配角色的对话框组件设置了标题绑定了显示状态和宽度 -->
<!-- 分配角色的对话框组件设置了标题绑定了显示状态和宽度用于弹出窗口进行角色分配操作 -->
<el-dialog
title="分配角色"
:visible.sync="allocDialogVisible"
width="30%">
<!-- 多选的下拉选择框绑定了 allocRoleIds 数据设置了占位符大小和宽度通过循环渲染选项 -->
<!-- 多选的下拉选择框绑定了 allocRoleIds 数据设置了占位符大小和宽度通过循环渲染选项方便用户选择多个要分配的角色 -->
<el-select v-model="allocRoleIds" multiple placeholder="请选择" size="small" style="width: 80%">
<el-option
v-for="item in allRoleList"
@ -180,7 +180,7 @@
:value="item.id">
</el-option>
</el-select>
<!-- 对话框底部的按钮区域通过插槽定义了取消和确定按钮分别绑定了对应的点击事件 -->
<!-- 对话框底部的按钮区域通过插槽定义了取消和确定按钮分别绑定了对应的点击事件用于用户确认或取消角色分配操作 -->
<span slot="footer" class="dialog-footer">
<el-button @click="allocDialogVisible = false" size="small"> </el-button>
<el-button type="primary" @click="handleAllocDialogConfirm()" size="small"> </el-button>
@ -188,21 +188,21 @@
</el-dialog>
</div>
</template>
<script>
// @/api/login API
<<script>
// @/api/login API
import {fetchList,createAdmin,updateAdmin,updateStatus,deleteAdmin,getRoleByAdmin,allocRole} from '@/api/login';
// @/api/role API
// @/api/role API
import {fetchAllRoleList} from '@/api/role';
// @/utils/date
// @/utils/date
import {formatDate} from '@/utils/date';
//
//
const defaultListQuery = {
pageNum: 1,
pageSize: 10,
keyword: null
};
// id
// id
const defaultAdmin = {
id: null,
username: null,
@ -217,82 +217,112 @@ export default {
name: 'adminList',
data() {
return {
// defaultListQuery
// defaultListQuery
listQuery: Object.assign({}, defaultListQuery),
//
//
list: null,
//
//
total: null,
//
// true false
listLoading: false,
// /
// /true false
dialogVisible: false,
// defaultAdmin
// defaultAdmin 使
admin: Object.assign({}, defaultAdmin),
//
// true false
isEdit: false,
//
//
allocDialogVisible: false,
// ID ID
allocRoleIds:[],
//
allRoleList:[],
// ID
allocAdminId:null
// ID ID便
allocRoleIds: [],
//
allRoleList: [],
// ID ID使
allocAdminId: null
}
},
created() {
//
//
this.getList();
this.getAllRoleList();
},
filters: {
formatDateTime(time) {
// null 'N/A'
// null 'N/A'
if (time == null || time === '') {
return 'N/A';
}
// Date
// Date 便
let date = new Date(time);
// 使 formatDate
// 使 formatDate 使'yyyy-MM-dd hh:mm:ss'
return formatDate(date, 'yyyy-MM-dd hh:mm:ss')
}
},
methods: {
// handleResetSearch
handleResetSearch() {
//
//
// 使 Object.assign defaultListQuery
// listQuery listQuery
// 便
this.listQuery = Object.assign({}, defaultListQuery);
},
// handleSearchList
handleSearchList() {
// 1
//
// pageNum 1
//
// getList
// 1
this.listQuery.pageNum = 1;
this.getList();
},
// handleSizeChange
handleSizeChange(val) {
// 1
// val
//
// pageNum 1
// pageSizeval
// getList
//
this.listQuery.pageNum = 1;
this.listQuery.pageSize = val;
this.getList();
},
// handleCurrentChange
handleCurrentChange(val) {
//
// val
// pageNumval
// getList
// 使
this.listQuery.pageNum = val;
this.getList();
},
// handleAdd
handleAdd() {
// /
//
// /dialogVisible true使
// isEdit false
// admin Object.assign defaultAdmin admin
// 便
this.dialogVisible = true;
this.isEdit = false;
this.admin = Object.assign({},defaultAdmin);
this.admin = Object.assign({}, defaultAdmin);
},
// handleStatusChange
handleStatusChange(index, row) {
//
// row
// ?
// warning
this.$confirm('是否要修改该状态?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// API ID
//
// updateStatus API
// IDrow.id{status: row.status}
// $message !
updateStatus(row.id, {status: row.status}).then(response => {
this.$message({
type: 'success',
@ -300,7 +330,9 @@ export default {
});
});
}).catch(() => {
//
//
// $message
// getList
this.$message({
type: 'info',
message: '取消修改'
@ -308,14 +340,20 @@ export default {
this.getList();
});
},
// handleDelete
handleDelete(index, row) {
//
//
// ?
// warning
this.$confirm('是否要删除该用户?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// API ID
//
// deleteAdmin API IDrow.id
// $message !
// getList 使
deleteAdmin(row.id).then(response => {
this.$message({
type: 'success',
@ -325,60 +363,79 @@ export default {
});
});
},
// handleUpdate
handleUpdate(index, row) {
// /
//
// /dialogVisible true使
// isEdit true
// admin Object.assign row admin
// 便
this.dialogVisible = true;
this.isEdit = true;
this.admin = Object.assign({},row);
this.admin = Object.assign({}, row);
},
// handleDialogConfirm
handleDialogConfirm() {
//
// /
// ?
// warning
this.$confirm('是否要确认?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
//
// isEdit
if (this.isEdit) {
// API ID
// /
updateAdmin(this.admin.id,this.admin).then(response => {
//
// updateAdmin API
// IDthis.admin.idthis.admin
// $message
// /dialogVisible false
// getList 使
updateAdmin(this.admin.id, this.admin).then(response => {
this.$message({
message: '修改成功!',
type: 'success'
});
this.dialogVisible =false;
this.dialogVisible = false;
this.getList();
})
} else {
// API
// /
//
// createAdmin API this.admin
// $message
// /dialogVisible false
// getList 使
createAdmin(this.admin).then(response => {
this.$message({
message: '添加成功!',
type: 'success'
});
this.dialogVisible =false;
this.dialogVisible = false;
this.getList();
})
}
})
},
handleAllocDialogConfirm(){
//
// handleAllocDialogConfirm
handleAllocDialogConfirm() {
//
// ?
// warning
this.$confirm('是否要确认?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// URLSearchParams
// URLSearchParams URL
let params = new URLSearchParams();
// ID
// ID append adminId this.allocAdminId ID
params.append("adminId", this.allocAdminId);
// ID
// ID roleIds this.allocRoleIds ID
params.append("roleIds", this.allocRoleIds);
// API
//
// allocRole API params
// $message
// allocDialogVisible false
allocRole(params).then(response => {
this.$message({
message: '分配成功!',
@ -388,45 +445,59 @@ export default {
})
})
},
handleSelectRole(index,row){
// ID
// handleSelectRole
handleSelectRole(index, row) {
//
// ID row IDrow.id this.allocAdminId
// 便
this.allocAdminId = row.id;
//
// allocDialogVisible true使
// 便
this.allocDialogVisible = true;
// ID
// getRoleListByAdmin IDrow.id
// 便
this.getRoleListByAdmin(row.id);
},
// getList
getList() {
//
//
// listLoading true
// fetchList API this.listQuery
// then
// listLoading false
// response.data.list list
// response.data.total total
this.listLoading = true;
// API
fetchList(this.listQuery).then(response => {
//
this.listLoading = false;
// list
this.list = response.data.list;
// total
this.total = response.data.total;
});
},
// getAllRoleList
getAllRoleList() {
// API
//
// fetchAllRoleList API
// response.data allRoleList
// 使
fetchAllRoleList().then(response => {
// allRoleList 使
this.allRoleList = response.data;
});
},
// getRoleListByAdmin
getRoleListByAdmin(adminId) {
// API ID
//
// getRoleByAdmin API IDadminId
// response.data allocRoleList
// ID this.allocRoleIds
// allocRoleList null 0
// allocRoleList IDallocRoleList[i].id ID this.allocRoleIds
// 便使 ID
getRoleByAdmin(adminId).then(response => {
//
let allocRoleList = response.data;
// ID
this.allocRoleIds=[];
//
if(allocRoleList!=null&&allocRoleList.length>0){
// ID ID
for(let i=0;i<allocRoleList.length;i++){
this.allocRoleIds = [];
if (allocRoleList != null && allocRoleList.length > 0) {
for (let i = 0; i < allocRoleList.length; i++) {
this.allocRoleIds.push(allocRoleList[i].id);
}
}
@ -435,4 +506,7 @@ export default {
}
}
</script>
<style></style>
<style>
/*
scoped 属性表示样式仅作用于当前组件内的元素避免样式冲突 */
</style>

@ -1,14 +1,24 @@
<template> 
<template>
<!-- 使用 MenuDetail 组件通过绑定 :is-edit 属性为 false传递给 MenuDetail 组件当前处于添加非编辑状态的信息
这里 MenuDetail 组件应该是用于展示菜单详情相关表单等功能的自定义组件 -->
<menu-detail :is-edit='false'></menu-detail>
</template>
<script>
import MenuDetail from './components/MenuDetail'
export default {
name: 'addMenu',
components: { MenuDetail }
}
// MenuDetail ./components/MenuDetail MenuDetail components
import MenuDetail from './components/MenuDetail';
export default {
name: 'addMenu',
// components aaa MenuDetail 使使
// Vue.js
components: { MenuDetail }
}
</script>
<style>
/* 当前样式部分为空,可在此处添加针对 addMenu 组件的样式规则,比如设置组件整体的布局、颜色、字体等样式相关属性 */
/* CSS resourceList
- 设置表格的样式如表头单元格的字体颜色边框样式等
- 对筛选区域操作按钮分页组件等元素的布局外观进行调整比如按钮的颜色大小间距等
- 定制对话框的样式像对话框的背景色边框按钮在对话框内的排版等
通过添加这些样式规则可以让页面的显示更加符合设计要求和美观性 */
</style>

@ -183,4 +183,9 @@ export default {
</script>
<style scoped>
/* scoped 属性表示样式仅作用于当前组件内的元素,避免样式冲突 */
/* CSS resourceList
- 设置表格的样式如表头单元格的字体颜色边框样式等
- 对筛选区域操作按钮分页组件等元素的布局外观进行调整比如按钮的颜色大小间距等
- 定制对话框的样式像对话框的背景色边框按钮在对话框内的排版等
通过添加这些样式规则可以让页面的显示更加符合设计要求和美观性 */
</style>

@ -1,8 +1,13 @@
<template>
<!-- 整体的应用容器 div作为整个页面功能模块的外层包裹元素用于限定页面内容的布局范围 -->
<div class="app-container">
<!-- 操作区域的卡片容器设置了阴影效果为无使其在页面上呈现出简洁扁平的视觉效果常用于放置一些操作按钮或相关提示信息 -->
<el-card class="operate-container" shadow="never">
<!-- el-icon-tickets 图标设置了顶部外边距为 5px通过添加一定的外边距来调整图标在容器内的垂直位置使其布局更加合理美观 -->
<i class="el-icon-tickets" style="margin-top: 5px"></i>
<!-- 数据列表文字提示设置了顶部外边距为 5px同样是为了在垂直方向上与图标及其他元素保持合适的间距清晰地向用户表明下方表格展示的是相关数据列表内容 -->
<span style="margin-top: 5px">数据列表</span>
<!-- 添加按钮设置了类名可能用于后续的样式定制或通过类名来进行特定的 JavaScript 操作识别点击时调用 handleAddMenu 方法该方法应定义在对应的 JavaScript 部分用于触发添加菜单相关的业务逻辑按钮大小为 mini通常这种较小尺寸的按钮在页面布局上更加紧凑适用于操作较为频繁但空间有限的区域 -->
<el-button
class="btn-add"
@click="handleAddMenu()"
@ -10,26 +15,39 @@
添加
</el-button>
</el-card>
<!-- 表格容器 div专门用于包裹展示数据的表格元素将表格与其他页面元素在布局上进行区分方便进行样式控制和整体页面结构的组织 -->
<div class="table-container">
<!-- el-table 组件用于展示数据表格这是一个基于 Element UI 等类似 UI 框架提供的表格组件用于以表格形式呈现数据
设置了引用名ref="menuTable"方便在 JavaScript 代码中通过 this.$refs.menuTable 来获取对该表格实例的引用进行一些额外的操作比如操作表格的滚动获取选中行等宽度style="width: 100%"使其能够自适应父容器的宽度占满所在的空间绑定的数据列表:data="list"意味着表格展示的数据来源于组件实例中的 list 属性 list 属性值变化时表格内容会相应更新加载状态绑定v-loading="listLoading"通过控制 listLoading 的值来决定是否显示加载动画比如在数据加载过程中显示加载提示加载完成后隐藏以及边框border用于显示表格的边框线使表格结构更清晰等属性 -->
<el-table ref="menuTable"
style="width: 100%"
:data="list"
v-loading="listLoading" border>
<!-- 表格列标签为编号设置了宽度和内容居中对齐通过插槽作用域展示对应行数据的 id 属性
这里定义了表格中的一列标签label用于在表头显示该列的名称宽度width="100"指定了该列在表格中的宽度居中对齐align="center"使列内的数据在水平方向上居中展示插槽作用域slot-scope="scope"则是一种机制允许在表格单元格中访问该行的数据对象scope.row此处通过双花括号插值表达式{{scope.row.id}}将对应行数据中的 id 属性值展示在该单元格内 -->
<el-table-column label="编号" width="100" align="center">
<template slot-scope="scope">{{scope.row.id}}</template>
</el-table-column>
<!-- 表格列标签为菜单名称内容居中对齐通过插槽作用域展示对应行数据的 title 属性功能与上述编号列类似只是展示的是对应行数据中的 title 属性值用于在表格中呈现菜单的名称信息 -->
<el-table-column label="菜单名称" align="center">
<template slot-scope="scope">{{scope.row.title}}</template>
</el-table-column>
<!-- 表格列标签为菜单级数设置了宽度和内容居中对齐通过插槽作用域展示对应行数据的 level 属性并使用 levelFilter 过滤器对数据进行格式化转换
除了基本的列定义属性外此处使用了一个过滤器levelFilter它会对要展示的 level 属性值进行处理按照一定的规则转换格式后再显示在表格单元格中例如可能将数字形式的级数转换为更友好的文字描述形式方便用户直观理解菜单的层级关系 -->
<el-table-column label="菜单级数" width="100" align="center">
<template slot-scope="scope">{{scope.row.level | levelFilter}}</template>
</el-table-column>
<!-- 表格列标签为前端名称内容居中对齐通过插槽作用域展示对应行数据的 name 属性用于展示与菜单相关的前端显示名称等信息 -->
<el-table-column label="前端名称" align="center">
<template slot-scope="scope">{{scope.row.name}}</template>
</el-table-column>
<!-- 表格列标签为前端图标设置了宽度和内容居中对齐通过插槽作用域使用 svg-icon 组件展示对应行数据的 icon 属性对应的图标
此列用于在表格中展示菜单对应的前端图标借助 svg-icon 组件可能是自定义或基于 UI 框架扩展的组件根据每行数据中的 icon 属性来渲染相应的图标增强表格数据的可视化效果 -->
<el-table-column label="前端图标" width="100" align="center">
<template slot-scope="scope"><svg-icon :icon-class="scope.row.icon"></svg-icon></template>
</el-table-column>
<!-- 表格列标签为是否显示设置了宽度和内容居中对齐通过插槽作用域展示对应行数据的 hidden 属性并使用 el-switch 组件进行切换操作绑定了相关的事件和值
该列用于展示和控制菜单是否显示的状态通过 el-switch 组件实现了一个开关功能用户可以直接在表格中切换菜单的显示隐藏状态同时绑定了相关的事件@change="handleHiddenChange(scope.$index, scope.row)"当开关状态改变时会触发对应的 JavaScript 方法handleHiddenChange来处理状态更新等业务逻辑通过设置 active-value inactive-value 来确定开关打开和关闭时对应的数据值 -->
<el-table-column label="是否显示" width="100" align="center">
<template slot-scope="scope">
<el-switch
@ -40,9 +58,12 @@
</el-switch>
</template>
</el-table-column>
<!-- 表格列标签为排序设置了宽度和内容居中对齐通过插槽作用域展示对应行数据的 sort 属性用于展示菜单在排序方面的相关属性值方便用户查看和了解菜单的排列顺序信息 -->
<el-table-column label="排序" width="100" align="center">
<template slot-scope="scope">{{scope.row.sort }}</template>
</el-table-column>
<!-- 表格列标签为设置设置了宽度和内容居中对齐通过插槽作用域展示查看下级按钮按钮根据条件判断是否禁用通过 disableNextLevel 过滤器点击时调用 handleShowNextLevel 方法
此列添加了一个操作按钮查看下级按钮的禁用状态由 disableNextLevel 过滤器根据对应行数据的某些条件此处可能是菜单级数等情况来动态决定点击按钮时会触发 handleShowNextLevel 方法用于跳转到查看当前菜单下级菜单的相关页面或执行相应的业务逻辑 -->
<el-table-column label="设置" width="120" align="center">
<template slot-scope="scope">
<el-button
@ -53,6 +74,8 @@
</el-button>
</template>
</el-table-column>
<!-- 表格列标签为操作设置了宽度和内容居中对齐通过插槽作用域展示编辑和删除按钮分别点击时调用 handleUpdate handleDelete 方法
这是一个常见的操作列用于对每行数据进行编辑和删除操作通过定义两个按钮并分别绑定对应的 JavaScript 方法handleUpdate handleDelete当用户点击相应按钮时会触发对应的业务逻辑比如跳转到编辑页面或者弹出确认框进行删除操作等 -->
<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<el-button
@ -69,7 +92,10 @@
</el-table-column>
</el-table>
</div>
<!-- 分页容器 div用于放置分页组件将分页功能相关的元素集中在一个区域便于在页面上进行布局和样式控制同时与表格等其他展示内容区分开来 -->
<div class="pagination-container">
<!-- el-pagination 分页组件设置了背景色相关页面切换事件绑定布局样式每页数量可选每页数量数组当前页以及总记录数等属性
这是一个常用的分页组件通过设置背景色background可以使其在页面上有更明显的视觉区分绑定页面切换事件如每页数量改变的 @size-change 和当前页改变的 @current-change 事件分别对应相应的 JavaScript 方法来重新加载数据指定布局样式layout来确定分页组件中各个元素的排列方式设置每页数量:page-size可选每页数量数组:page-sizes当前页:current-page.sync以及总记录数:total等属性来实现完整的分页功能根据总记录数和每页数量计算总页数并提供用户切换页面选择每页显示数量等操作功能 -->
<el-pagination
background
@size-change="handleSizeChange"
@ -83,114 +109,189 @@
</div>
</div>
</template>
<script>
import {fetchList,deleteMenu,updateMenu,updateHidden} from '@/api/menu'
export default {
name: "menuList",
data() {
return {
list: null,
total: null,
listLoading: true,
listQuery: {
pageNum: 1,
pageSize: 5
},
parentId: 0
// @/api/menu API API
import {fetchList,deleteMenu,updateMenu,updateHidden} from '@/api/menu';
export default {
name: "menuList",
data() {
return {
//
list: null,
//
total: null,
// true true false
listLoading: true,
//
listQuery: {
pageNum: 1,
pageSize: 5
},
// ID 0 ID
parentId: 0
}
},
created() {
// ID ID created
this.resetParentId();
this.getList();
},
watch: {
$route(route) {
// ID URL watch
this.resetParentId();
this.getList();
}
},
methods: {
resetParentId() {
// 1 ID
// parentId ID ID
this.listQuery.pageNum = 1;
if (this.$route.query.parentId != null) {
// ID parentId ID
this.parentId = this.$route.query.parentId;
} else {
// ID 0
this.parentId = 0;
}
},
created() {
this.resetParentId();
handleAddMenu() {
// /ums/addMenu 使 Vue Router Vue.js $router.push 便
this.$router.push('/ums/addMenu');
},
getList() {
//
this.listLoading = true;
// API ID ID Promise then
fetchList(this.parentId, this.listQuery).then(response => {
//
this.listLoading = false;
// list :data="list"
this.list = response.data.list;
// total
this.total = response.data.total;
});
},
// handleSizeChange
handleSizeChange(val) {
//
//
//
// listQuerypageNum 1
//
//
this.listQuery.pageNum = 1;
// listQuerypageSizeval
// val
// getList
// 1
//
this.getList();
},
watch: {
$route(route) {
this.resetParentId();
this.getList();
}
// handleCurrentChange
handleCurrentChange(val) {
//
// val
// listQuerypageNumval
// 便
// getList
// 使
this.listQuery.pageNum = val;
this.getList();
},
methods: {
resetParentId(){
this.listQuery.pageNum = 1;
if (this.$route.query.parentId != null) {
this.parentId = this.$route.query.parentId;
} else {
this.parentId = 0;
}
},
handleAddMenu() {
this.$router.push('/ums/addMenu');
},
getList() {
this.listLoading = true;
fetchList(this.parentId, this.listQuery).then(response => {
this.listLoading = false;
this.list = response.data.list;
this.total = response.data.total;
// handleHiddenChange
handleHiddenChange(index, row) {
//
// el-switch
// index
// row
// updateHidden API
// ID row.id {hidden: row.hidden} hidden
// this.$message
// success绿
// 1000 1 使
updateHidden(row.id, {hidden: row.hidden}).then(response => {
this.$message({
message: '修改成功',
type: 'success',
duration: 1000
});
},
handleSizeChange(val) {
this.listQuery.pageNum = 1;
this.listQuery.pageSize = val;
this.getList();
},
handleCurrentChange(val) {
this.listQuery.pageNum = val;
this.getList();
},
handleHiddenChange(index, row) {
updateHidden(row.id,{hidden:row.hidden}).then(response=>{
});
},
// handleShowNextLevel
handleShowNextLevel(index, row) {
//
//
// 使 this.$router.push Vue Router
// /ums/menu ID parentId query
// /ums/menu
// 便
this.$router.push({path: '/ums/menu', query: {parentId: row.id}});
},
// handleUpdate
handleUpdate(index, row) {
//
//
// this.$router.push /ums/updateMenu ID id query
// /ums/updateMenu
// 便便
this.$router.push({path: '/ums/updateMenu', query: {id: row.id}});
},
// handleDelete
handleDelete(index, row) {
//
//
//
//
// warning
// then
// deleteMenu API ID row.id
// this.$message
// success 1000 1 便
// getList 使
this.$confirm('是否要删除该菜单', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteMenu(row.id).then(response => {
this.$message({
message: '修改成功',
message: '删除成功',
type: 'success',
duration: 1000
});
this.getList();
});
},
handleShowNextLevel(index, row) {
this.$router.push({path: '/ums/menu', query: {parentId: row.id}})
},
handleUpdate(index, row) {
this.$router.push({path:'/ums/updateMenu',query:{id:row.id}});
},
handleDelete(index, row) {
this.$confirm('是否要删除该菜单', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteMenu(row.id).then(response => {
this.$message({
message: '删除成功',
type: 'success',
duration: 1000
});
this.getList();
});
});
}
},
filters: {
levelFilter(value) {
if (value === 0) {
return '一级';
} else if (value === 1) {
return '二级';
}
},
disableNextLevel(value) {
if (value === 0) {
return false;
} else {
return true;
}
}
});
}
}
}
</script>
<style scoped>
/*
scoped 属性表示样式仅作用于当前组件内的元素避免样式冲突 */
/* CSS resourceList
- 设置表格的样式如表头单元格的字体颜色边框样式等
- 对筛选区域操作按钮分页组件等元素的布局外观进行调整比如按钮的颜色大小间距等
- 定制对话框的样式像对话框的背景色边框按钮在对话框内的排版等
通过添加这些样式规则可以让页面的显示更加符合设计要求和美观性 */
</style>

@ -1,14 +1,28 @@
<template> 
<template>
<!-- 使用 MenuDetail 组件并通过绑定 :is-edit 属性为 true MenuDetail 组件传递当前处于编辑状态的信息
MenuDetail 组件大概率是一个自定义组件用于展示和处理菜单详情相关的表单等内容在这里用于编辑菜单的场景 -->
<menu-detail :is-edit='true'></menu-detail>
</template>
<script>
import MenuDetail from './components/MenuDetail'
export default {
name: 'updateMenu',
components: { MenuDetail }
}
// ./components/ MenuDetail MenuDetail components
// 使
import MenuDetail from './components/MenuDetail';
export default {
name: 'updateMenu',
// components MenuDetail 使template使
// Vue.js MenuDetail
components: { MenuDetail }
}
</script>
<style>
/* CSS updateMenu
来对组件的外观进行定制化显示 */
/* CSS resourceList
- 设置表格的样式如表头单元格的字体颜色边框样式等
- 对筛选区域操作按钮分页组件等元素的布局外观进行调整比如按钮的颜色大小间距等
- 定制对话框的样式像对话框的背景色边框按钮在对话框内的排版等
通过添加这些样式规则可以让页面的显示更加符合设计要求和美观性 */
</style>

@ -1,27 +1,39 @@
<template> 
<template>
<!-- 整体的应用容器 div -->
<div class="app-container">
<!-- 操作区域的卡片容器设置了阴影效果为无 -->
<el-card shadow="never" class="operate-container">
<!-- 图标元素使用了 el-icon-tickets 图标 -->
<i class="el-icon-tickets"></i>
<!-- 文字提示显示数据列表字样 -->
<span>数据列表</span>
<!-- 添加按钮设置了按钮大小为 mini添加了自定义类名 btn-add点击时调用 handleAdd 方法 -->
<el-button size="mini" class="btn-add" @click="handleAdd()"></el-button>
</el-card>
<!-- 表格容器 div用于放置展示数据的表格 -->
<div class="table-container">
<!-- el-table 组件用于展示数据列表设置了引用名绑定的数据表格宽度加载状态绑定以及边框等属性 -->
<el-table ref="resourceCategoryTable"
:data="list"
style="width: 100%;"
v-loading="listLoading" border>
<!-- 表格列标签为编号设置了宽度和内容居中对齐通过插槽作用域展示对应行数据的 id 属性 -->
<el-table-column label="编号" width="100" align="center">
<template slot-scope="scope">{{scope.row.id}}</template>
</el-table-column>
<!-- 表格列标签为名称内容居中对齐通过插槽作用域展示对应行数据的 name 属性 -->
<el-table-column label="名称" align="center">
<template slot-scope="scope">{{scope.row.name}}</template>
</el-table-column>
<!-- 表格列标签为创建时间内容居中对齐通过插槽作用域展示对应行数据的 createTime 属性并使用 formatDateTime 过滤器对时间进行格式化展示 -->
<el-table-column label="创建时间" align="center">
<template slot-scope="scope">{{scope.row.createTime | formatDateTime}}</template>
</el-table-column>
<!-- 表格列标签为排序内容居中对齐通过插槽作用域展示对应行数据的 sort 属性 -->
<el-table-column label="排序" align="center">
<template slot-scope="scope">{{scope.row.sort}}</template>
</el-table-column>
<!-- 表格列标签为操作设置了宽度和内容居中对齐通过插槽作用域展示编辑和删除按钮分别点击时调用 handleUpdate handleDelete 方法 -->
<el-table-column label="操作" width="180" align="center">
<template slot-scope="scope">
<el-button size="mini"
@ -36,20 +48,25 @@
</el-table-column>
</el-table>
</div>
<!-- el-dialog 对话框组件设置了标题为添加分类绑定了显示状态设置了宽度 -->
<el-dialog
title="添加分类"
:visible.sync="dialogVisible"
width="40%">
<!-- 对话框内的表单绑定了 resourceCategory 数据对象设置了表单引用标签宽度和大小 -->
<el-form :model="resourceCategory"
ref="resourceCategoryForm"
label-width="150px" size="small">
<!-- 表单项目标签为名称输入框双向绑定 resourceCategory.name并设置了宽度 -->
<el-form-item label="名称:">
<el-input v-model="resourceCategory.name" style="width: 250px"></el-input>
</el-form-item>
<!-- 表单项目标签为排序输入框双向绑定 resourceCategory.sort并设置了宽度 -->
<el-form-item label="排序:">
<el-input v-model="resourceCategory.sort" style="width: 250px"></el-input>
</el-form-item>
</el-form>
<!-- 对话框底部的按钮区域通过插槽定义了取消和确定按钮分别绑定了对应的点击事件 -->
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false" size="small"> </el-button>
<el-button type="primary" @click="handleDialogConfirm()" size="small"> </el-button>
@ -58,99 +75,133 @@
</div>
</template>
<script>
import {listAllCate,createResourceCategory,updateResourceCategory,deleteResourceCategory} from '@/api/resourceCategory';
import {formatDate} from '@/utils/date';
const defaultResourceCategory={
name:null,
sort:0
};
export default {
name: 'resourceCategoryList',
data() {
return {
list: null,
listLoading: false,
dialogVisible:false,
isEdit:false,
resourceCategory:Object.assign({},defaultResourceCategory)
// @/api/resourceCategory API
import {listAllCate,createResourceCategory,updateResourceCategory,deleteResourceCategory} from '@/api/resourceCategory';
// @/utils/date
import {formatDate} from '@/utils/date';
// null 0
const defaultResourceCategory={
name:null,
sort:0
};
export default {
name: 'resourceCategoryList',
data() {
return {
// null API
list: null,
// false
listLoading: false,
// / false
dialogVisible:false,
// false
isEdit:false,
// defaultResourceCategory
resourceCategory:Object.assign({},defaultResourceCategory)
}
},
created() {
//
this.getList();
},
filters: {
formatDateTime(time) {
// 'N/A'
if (time == null || time === '') {
return 'N/A';
}
// Date 便
let date = new Date(time);
// 使 formatDate
return formatDate(date, 'yyyy-MM-dd hh:mm:ss')
}
},
methods: {
handleAdd() {
// /isEdit false resourceCategory
this.dialogVisible = true;
this.isEdit = false;
this.resourceCategory = Object.assign({},defaultResourceCategory);
},
created() {
this.getList();
handleUpdate(index,row){
// /isEdit true resourceCategory
this.dialogVisible = true;
this.isEdit = true;
this.resourceCategory = Object.assign({},row);
},
filters:{
formatDateTime(time) {
if (time == null || time === '') {
return 'N/A';
}
let date = new Date(time);
return formatDate(date, 'yyyy-MM-dd hh:mm:ss')
}
handleDelete(index,row){
//
this.$confirm('是否要删除该分类?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// API id
//
deleteResourceCategory(row.id).then(response => {
this.$message({
type: 'success',
message: '删除成功!'
});
this.getList();
});
});
},
methods: {
handleAdd() {
this.dialogVisible = true;
this.isEdit = false;
this.resourceCategory = Object.assign({},defaultResourceCategory);
},
handleUpdate(index,row){
this.dialogVisible = true;
this.isEdit = true;
this.resourceCategory = Object.assign({},row);
},
handleDelete(index,row){
this.$confirm('是否要删除该分类?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteResourceCategory(row.id).then(response => {
handleDialogConfirm() {
// /
this.$confirm('是否要确认?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// isEdit true
if (this.isEdit) {
// API id resourceCategory
//
updateResourceCategory(this.resourceCategory.id,this.resourceCategory).then(response => {
this.$message({
type: 'success',
message: '删除成功!'
message: '修改成功!',
type: 'success'
});
this.dialogVisible =false;
this.getList();
});
});
},
handleDialogConfirm() {
this.$confirm('是否要确认?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
if (this.isEdit) {
updateResourceCategory(this.resourceCategory.id,this.resourceCategory).then(response => {
this.$message({
message: '修改成功!',
type: 'success'
});
this.dialogVisible =false;
this.getList();
})
} else {
createResourceCategory(this.resourceCategory).then(response => {
this.$message({
message: '添加成功!',
type: 'success'
});
this.dialogVisible =false;
this.getList();
})
}
})
},
getList() {
this.listLoading = true;
listAllCate({}).then(response => {
this.listLoading = false;
this.list = response.data;
});
}
})
} else {
// API resourceCategory
//
createResourceCategory(this.resourceCategory).then(response => {
this.$message({
message: '添加成功!',
type: 'success'
});
this.dialogVisible =false;
this.getList();
})
}
})
},
getList() {
//
this.listLoading = true;
// API API
listAllCate({}).then(response => {
//
this.listLoading = false;
// list
this.list = response.data;
});
}
}
}
</script>
<style>
/* CSS resourceCategoryList
例如设置表格样式对话框样式按钮样式以及整体布局相关的样式等来美化组件的外观显示效果 */
/* CSS resourceList
- 设置表格的样式如表头单元格的字体颜色边框样式等
- 对筛选区域操作按钮分页组件等元素的布局外观进行调整比如按钮的颜色大小间距等
- 定制对话框的样式像对话框的背景色边框按钮在对话框内的排版等
通过添加这些样式规则可以让页面的显示更加符合设计要求和美观性 */
</style>

@ -1,9 +1,14 @@
<template> 
<template>
<!-- 整体的应用容器 div用于包裹页面内的各个功能模块 -->
<div class="app-container">
<!-- 筛选搜索区域的卡片容器设置了阴影效果为无 -->
<el-card class="filter-container" shadow="never">
<div>
<!-- 搜索图标元素使用了 el-icon-search 图标 -->
<i class="el-icon-search"></i>
<!-- 筛选搜索的文字提示 -->
<span>筛选搜索</span>
<!-- 查询搜索按钮设置了样式为右浮动按钮类型为主要primary点击时调用 handleSearchList 方法按钮大小为 small -->
<el-button
style="float:right"
type="primary"
@ -11,6 +16,7 @@
size="small">
查询搜索
</el-button>
<!-- 重置按钮设置了样式为右浮动且距离右侧 15px点击时调用 handleResetSearch 方法按钮大小为 small -->
<el-button
style="float:right;margin-right: 15px"
@click="handleResetSearch()"
@ -19,13 +25,17 @@
</el-button>
</div>
<div style="margin-top: 15px">
<!-- 内联表单绑定了 listQuery 数据对象表单大小为 small标签宽度为 140px用于设置筛选条件 -->
<el-form :inline="true" :model="listQuery" size="small" label-width="140px">
<!-- 表单项目标签为资源名称内部的输入框双向绑定 listQuery.nameKeyword设置了类名占位符以及可清空功能 -->
<el-form-item label="资源名称:">
<el-input v-model="listQuery.nameKeyword" class="input-width" placeholder="资源名称" clearable></el-input>
</el-form-item>
<!-- 表单项目标签为资源路径内部的输入框双向绑定 listQuery.urlKeyword设置了类名占位符以及可清空功能 -->
<el-form-item label="资源路径:">
<el-input v-model="listQuery.urlKeyword" class="input-width" placeholder="资源路径" clearable></el-input>
</el-form-item>
<!-- 表单项目标签为资源分类内部是一个下拉选择框双向绑定 listQuery.categoryId设置了占位符可清空以及类名通过循环渲染选项 -->
<el-form-item label="资源分类:">
<el-select v-model="listQuery.categoryId" placeholder="全部" clearable class="input-width">
<el-option v-for="item in categoryOptions"
@ -38,32 +48,45 @@
</el-form>
</div>
</el-card>
<!-- 操作区域的卡片容器设置了阴影效果为无 -->
<el-card class="operate-container" shadow="never">
<!-- 图标元素使用了 el-icon-tickets 图标 -->
<i class="el-icon-tickets"></i>
<!-- 数据列表的文字提示 -->
<span>数据列表</span>
<!-- 添加按钮大小为 mini添加了自定义类名 btn-add点击时调用 handleAdd 方法设置了左侧外边距为 20px -->
<el-button size="mini" class="btn-add" @click="handleAdd()" style="margin-left: 20px">添加</el-button>
<!-- 资源分类按钮大小为 mini添加了自定义类名 btn-add点击时调用 handleShowCategory 方法用于跳转到资源分类页面 -->
<el-button size="mini" class="btn-add" @click="handleShowCategory()"></el-button>
</el-card>
<!-- 表格容器 div用于放置展示资源数据的表格 -->
<div class="table-container">
<!-- el-table 组件用于展示资源数据列表设置了引用名绑定的数据表格宽度加载状态绑定以及边框等属性 -->
<el-table ref="resourceTable"
:data="list"
style="width: 100%;"
v-loading="listLoading" border>
<!-- 表格列标签为编号设置了宽度和内容居中对齐通过插槽作用域展示对应行数据的 id 属性 -->
<el-table-column label="编号" width="100" align="center">
<template slot-scope="scope">{{scope.row.id}}</template>
</el-table-column>
<!-- 表格列标签为资源名称内容居中对齐通过插槽作用域展示对应行数据的 name 属性 -->
<el-table-column label="资源名称" align="center">
<template slot-scope="scope">{{scope.row.name}}</template>
</el-table-column>
<!-- 表格列标签为资源路径内容居中对齐通过插槽作用域展示对应行数据的 url 属性 -->
<el-table-column label="资源路径" align="center">
<template slot-scope="scope">{{scope.row.url}}</template>
</el-table-column>
<!-- 表格列标签为描述内容居中对齐通过插槽作用域展示对应行数据的 description 属性 -->
<el-table-column label="描述" align="center">
<template slot-scope="scope">{{scope.row.description}}</template>
</el-table-column>
<!-- 表格列标签为添加时间设置了宽度和内容居中对齐通过插槽作用域展示对应行数据的 createTime 属性并使用 formatDateTime 过滤器对时间进行格式化展示 -->
<el-table-column label="添加时间" width="160" align="center">
<template slot-scope="scope">{{scope.row.createTime | formatDateTime}}</template>
</el-table-column>
<!-- 表格列标签为操作设置了宽度和内容居中对齐通过插槽作用域展示编辑和删除按钮分别点击时调用 handleUpdate handleDelete 方法 -->
<el-table-column label="操作" width="140" align="center">
<template slot-scope="scope">
<el-button size="mini"
@ -79,7 +102,9 @@
</el-table-column>
</el-table>
</div>
<!-- 分页容器 div用于放置分页组件 -->
<div class="pagination-container">
<!-- el-pagination 分页组件设置了背景色相关页面切换事件绑定布局样式当前页每页数量可选每页数量数组以及总记录数等属性 -->
<el-pagination
background
@size-change="handleSizeChange"
@ -91,19 +116,24 @@
:total="total">
</el-pagination>
</div>
<!-- el-dialog 对话框组件根据 isEdit 变量动态设置标题为编辑资源添加资源绑定了显示状态设置了宽度 -->
<el-dialog
:title="isEdit?'编辑资源':'添加资源'"
:visible.sync="dialogVisible"
width="40%">
<!-- 对话框内的表单绑定了 resource 数据对象设置了表单引用标签宽度和大小 -->
<el-form :model="resource"
ref="resourceForm"
label-width="150px" size="small">
<!-- 表单项目标签为资源名称输入框双向绑定 resource.name并设置了宽度 -->
<el-form-item label="资源名称:">
<el-input v-model="resource.name" style="width: 250px"></el-input>
</el-form-item>
<!-- 表单项目标签为资源路径输入框双向绑定 resource.url并设置了宽度 -->
<el-form-item label="资源路径:">
<el-input v-model="resource.url" style="width: 250px"></el-input>
</el-form-item>
<!-- 表单项目标签为资源分类内部是一个下拉选择框双向绑定 resource.categoryId设置了占位符可清空以及宽度通过循环渲染选项 -->
<el-form-item label="资源分类:">
<el-select v-model="resource.categoryId" placeholder="全部" clearable style="width: 250px">
<el-option v-for="item in categoryOptions"
@ -113,6 +143,7 @@
</el-option>
</el-select>
</el-form-item>
<!-- 表单项目标签为描述输入框双向绑定 resource.description设置了文本域类型和行数以及宽度 -->
<el-form-item label="描述:">
<el-input v-model="resource.description"
type="textarea"
@ -120,6 +151,7 @@
style="width: 250px"></el-input>
</el-form-item>
</el-form>
<!-- 对话框底部的按钮区域通过插槽定义了取消和确定按钮分别绑定了对应的点击事件 -->
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false" size="small"> </el-button>
<el-button type="primary" @click="handleDialogConfirm()" size="small"> </el-button>
@ -128,146 +160,205 @@
</div>
</template>
<script>
import {fetchList,createResource,updateResource,deleteResource} from '@/api/resource';
import {listAllCate} from '@/api/resourceCategory';
import {formatDate} from '@/utils/date';
// @/api/resource API
import {fetchList,createResource,updateResource,deleteResource} from '@/api/resource';
// @/api/resourceCategory API
import {listAllCate} from '@/api/resourceCategory';
// @/utils/date
import {formatDate} from '@/utils/date';
const defaultListQuery = {
pageNum: 1,
pageSize: 10,
nameKeyword: null,
urlKeyword: null,
categoryId:null
};
const defaultResource = {
id: null,
name: null,
url: null,
categoryId: null,
description:''
};
export default {
name: 'resourceList',
data() {
return {
listQuery: Object.assign({}, defaultListQuery),
list: null,
total: null,
listLoading: false,
dialogVisible: false,
resource: Object.assign({}, defaultResource),
isEdit: false,
categoryOptions:[],
defaultCategoryId:null
// ID
const defaultListQuery = {
pageNum: 1,
pageSize: 10,
nameKeyword: null,
urlKeyword: null,
categoryId:null
};
// id ID
const defaultResource = {
id: null,
name: null,
url: null,
categoryId: null,
description:''
};
export default {
name: 'resourceList',
data() {
return {
// defaultListQuery
listQuery: Object.assign({}, defaultListQuery),
// null API
list: null,
// null
total: null,
// false
listLoading: false,
// / false
dialogVisible: false,
// defaultResource
resource: Object.assign({}, defaultResource),
// false
isEdit: false,
// label value
categoryOptions: [],
// ID null
defaultCategoryId: null
}
},
created() {
//
this.getList();
this.getCateList();
},
filters: {
formatDateTime(time) {
// 'N/A'
if (time == null || time === '') {
return 'N/A';
}
// Date 便
let date = new Date(time);
// 使 formatDate
return formatDate(date, 'yyyy-MM-dd hh:mm:ss')
}
},
methods: {
handleResetSearch() {
//
this.listQuery = Object.assign({}, defaultListQuery);
},
created() {
handleSearchList() {
// 1
this.listQuery.pageNum = 1;
this.getList();
this.getCateList();
},
filters: {
formatDateTime(time) {
if (time == null || time === '') {
return 'N/A';
}
let date = new Date(time);
return formatDate(date, 'yyyy-MM-dd hh:mm:ss')
}
handleSizeChange(val) {
// 1
this.listQuery.pageNum = 1;
this.listQuery.pageSize = val;
this.getList();
},
handleCurrentChange(val) {
//
this.listQuery.pageNum = val;
this.getList();
},
methods: {
handleResetSearch() {
this.listQuery = Object.assign({}, defaultListQuery);
},
handleSearchList() {
this.listQuery.pageNum = 1;
this.getList();
},
handleSizeChange(val) {
this.listQuery.pageNum = 1;
this.listQuery.pageSize = val;
this.getList();
},
handleCurrentChange(val) {
this.listQuery.pageNum = val;
this.getList();
},
handleAdd() {
this.dialogVisible = true;
this.isEdit = false;
this.resource = Object.assign({},defaultResource);
this.resource.categoryId = this.defaultCategoryId;
},
handleDelete(index, row) {
this.$confirm('是否要删除该资源?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteResource(row.id).then(response => {
handleAdd() {
// /isEdit false resource ID
this.dialogVisible = true;
this.isEdit = false;
this.resource = Object.assign({}, defaultResource);
this.resource.categoryId = this.defaultCategoryId;
},
handleDelete(index, row) {
//
this.$confirm('是否要删除该资源?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// API id
//
deleteResource(row.id).then(response => {
this.$message({
type: 'success',
message: '删除成功!'
});
this.getList();
});
});
},
handleUpdate(index, row) {
// /isEdit true resource
this.dialogVisible = true;
this.isEdit = true;
this.resource = Object.assign({}, row);
},
handleDialogConfirm() {
// /
this.$confirm('是否要确认?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// isEdit true
if (this.isEdit) {
// API id resource
//
updateResource(this.resource.id, this.resource).then(response => {
this.$message({
type: 'success',
message: '删除成功!'
message: '修改成功!',
type: 'success'
});
this.dialogVisible = false;
this.getList();
});
});
},
handleUpdate(index, row) {
this.dialogVisible = true;
this.isEdit = true;
this.resource = Object.assign({},row);
},
handleDialogConfirm() {
this.$confirm('是否要确认?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
if (this.isEdit) {
updateResource(this.resource.id,this.resource).then(response => {
this.$message({
message: '修改成功!',
type: 'success'
});
this.dialogVisible =false;
this.getList();
})
} else {
createResource(this.resource).then(response => {
this.$message({
message: '添加成功!',
type: 'success'
});
this.dialogVisible =false;
this.getList();
})
}
})
},
handleShowCategory(){
this.$router.push({path: '/ums/resourceCategory'})
},
getList() {
this.listLoading = true;
fetchList(this.listQuery).then(response => {
this.listLoading = false;
this.list = response.data.list;
this.total = response.data.total;
});
},
getCateList(){
listAllCate().then(response=>{
let cateList = response.data;
for(let i=0;i<cateList.length;i++){
let cate = cateList[i];
this.categoryOptions.push({label:cate.name,value:cate.id});
}
this.defaultCategoryId=cateList[0].id;
})
}
})
} else {
// API resource
//
createResource(this.resource).then(response => {
this.$message({
message: '添加成功!',
type: 'success'
});
this.dialogVisible = false;
this.getList();
})
}
})
},
//
// '/ums/resourceCategory'
//
handleShowCategory() {
this.$router.push({path: '/ums/resourceCategory'})
},
//
// listLoading true
//
// fetchList API listQuery
// then listLoading false
// response list list
// total total
getList() {
this.listLoading = true;
fetchList(this.listQuery).then(response => {
this.listLoading = false;
this.list = response.data.list;
this.total = response.data.total;
});
},
//
// listAllCate API Promise then
getCateList() {
listAllCate().then(response => {
// cateList 便
let cateList = response.data;
//
for (let i = 0; i < cateList.length; i++) {
// cate 便
let cate = cateList[i];
// label ID value categoryOptions
// categoryOptions UI 便
this.categoryOptions.push({label: cate.name, value: cate.id});
}
// ID defaultCategoryId
// ID 使使
this.defaultCategoryId = cateList[0].id;
})
}
}
}
</script>
<style></style>
<style>
/* CSS resourceList
- 设置表格的样式如表头单元格的字体颜色边框样式等
- 对筛选区域操作按钮分页组件等元素的布局外观进行调整比如按钮的颜色大小间距等
- 定制对话框的样式像对话框的背景色边框按钮在对话框内的排版等
通过添加这些样式规则可以让页面的显示更加符合设计要求和美观性 */
</style>

@ -1,5 +1,8 @@
<template>
<!-- 使用 el-card 组件创建一个表单容器卡片设置阴影效果为无 -->
<el-card class="form-container" shadow="never">
<!-- el-tree 组件用于展示树形结构的数据绑定了 menuTreeList 数据作为树的数据源 -->
<!-- 显示复选框默认展开所有节点设置节点的唯一标识键为 'id'添加了引用名 'tree'高亮当前选中节点并配置了节点属性映射 -->
<el-tree
:data="menuTreeList"
show-checkbox
@ -9,93 +12,131 @@
highlight-current
:props="defaultProps">
</el-tree>
<!-- 包含两个按钮的 div 容器设置了顶部外边距为 20px并使其内容居中对齐 -->
<div style="margin-top: 20px" align="center">
<!-- 保存按钮类型为主要primary点击时调用 handleSave 方法 -->
<el-button type="primary" @click="handleSave()"></el-button>
<!-- 清空按钮点击时调用 handleClear 方法 -->
<el-button @click="handleClear()"></el-button>
</div>
</el-card>
</template>
<script>
import {fetchTreeList} from '@/api/menu';
import {listMenuByRole,allocMenu} from '@/api/role';
// @/api/menu API
import {fetchTreeList} from '@/api/menu';
// @/api/role API
import {listMenuByRole, allocMenu} from '@/api/role';
export default {
name: "allocMenu",
data() {
return {
menuTreeList: [],
defaultProps: {
children: 'children',
label: 'title'
},
roleId:null
};
},
created() {
this.roleId = this.$route.query.roleId;
this.treeList();
this.getRoleMenu(this.roleId);
},
methods: {
treeList() {
fetchTreeList().then(response => {
this.menuTreeList = response.data;
});
export default {
name: "allocMenu",
data() {
return {
// API
menuTreeList: [],
// el-tree 'children' 'title'
defaultProps: {
children: 'children',
label: 'title'
},
getRoleMenu(roleId){
listMenuByRole(roleId).then(response=>{
let menuList = response.data;
let checkedMenuIds=[];
if(menuList!=null&&menuList.length>0){
for(let i=0;i<menuList.length;i++){
let menu = menuList[i];
if(menu.parentId!==0){
checkedMenuIds.push(menu.id);
}
// ID null
roleId: null
};
},
created() {
// ID roleId
this.roleId = this.$route.query.roleId;
//
this.treeList();
// ID
this.getRoleMenu(this.roleId);
},
methods: {
treeList() {
// API Promise menuTreeList el-tree
fetchTreeList().then(response => {
this.menuTreeList = response.data;
});
},
getRoleMenu(roleId) {
// API ID Promise
listMenuByRole(roleId).then(response => {
// menuList 便
let menuList = response.data;
// ID
let checkedMenuIds = [];
//
if (menuList!= null && menuList.length > 0) {
for (let i = 0; i < menuList.length; i++) {
//
let menu = menuList[i];
// ID 0 ID ID
if (menu.parentId!== 0) {
checkedMenuIds.push(menu.id);
}
}
this.$refs.tree.setCheckedKeys(checkedMenuIds);
});
},
handleSave() {
let checkedNodes = this.$refs.tree.getCheckedNodes();
let checkedMenuIds=new Set();
if(checkedNodes!=null&&checkedNodes.length>0){
for(let i=0;i<checkedNodes.length;i++){
let checkedNode = checkedNodes[i];
checkedMenuIds.add(checkedNode.id);
if(checkedNode.parentId!==0){
checkedMenuIds.add(checkedNode.parentId);
}
}
// el-tree ref='tree' ID
this.$refs.tree.setCheckedKeys(checkedMenuIds);
});
},
handleSave() {
// el-tree
let checkedNodes = this.$refs.tree.getCheckedNodes();
// 使 Set ID ID
let checkedMenuIds = new Set();
//
if (checkedNodes!= null && checkedNodes.length > 0) {
for (let i = 0; i < checkedNodes.length; i++) {
//
let checkedNode = checkedNodes[i];
// ID Set
checkedMenuIds.add(checkedNode.id);
// ID 0 ID Set
if (checkedNode.parentId!== 0) {
checkedMenuIds.add(checkedNode.parentId);
}
}
this.$confirm('是否分配菜单?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(()=>{
let params = new URLSearchParams();
params.append("roleId",this.roleId);
params.append("menuIds",Array.from(checkedMenuIds));
allocMenu(params).then(response => {
this.$message({
message: '分配成功',
type: 'success',
duration: 1000
});
this.$router.back();
})
})
},
handleClear() {
this.$refs.tree.setCheckedKeys([]);
}
//
this.$confirm('是否分配菜单?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// URLSearchParams
let params = new URLSearchParams();
// ID
params.append("roleId", this.roleId);
// ID Array.from
params.append("menuIds", Array.from(checkedMenuIds));
// API Promise
allocMenu(params).then(response => {
// success 1000
this.$message({
message: '分配成功',
type: 'success',
duration: 1000
});
//
this.$router.back();
})
})
},
handleClear() {
// el-tree ID
this.$refs.tree.setCheckedKeys([]);
}
}
}
</script>
<style scoped>
/* CSS allocMenu
例如设置 el-tree 组件的样式像节点的字体颜色间距等以及按钮的样式包括按钮的大小颜色边框等
scoped 属性表示样式仅作用于当前组件内的元素避免样式冲突 */
/* CSS resourceList
- 设置表格的样式如表头单元格的字体颜色边框样式等
- 对筛选区域操作按钮分页组件等元素的布局外观进行调整比如按钮的颜色大小间距等
- 定制对话框的样式像对话框的背景色边框按钮在对话框内的排版等
通过添加这些样式规则可以让页面的显示更加符合设计要求和美观性 */
</style>

@ -1,187 +1,303 @@
<template>
<!-- 使用 el-card 组件创建一个表单容器卡片设置阴影效果为无 -->
<el-card class="form-container" shadow="never">
<!-- 使用 v-for 指令循环遍历 allResourceCate 数组中的每个元素cate同时传递索引index -->
<!-- 根据索引判断是否添加 'top-line' 类名第一个元素添加用于样式区分可能是添加顶部边框之类的效果并设置了唯一的 key -->
<div v-for="(cate,index) in allResourceCate" :class="index===0?'top-line':null" :key="'cate'+cate.id">
<!-- el-row 组件添加了 'table-layout' 类名用于样式布局设置了背景颜色 -->
<el-row class="table-layout" style="background: #F2F6FC;">
<!-- el-checkbox 复选框组件双向绑定 cate 对象的 checked 属性通过调用 isIndeterminate 方法设置不确定状态绑定 change 事件到 handleCheckAllChange 方法 -->
<!-- 复选框显示的文本为 cate 对象的 name 属性值 -->
<el-checkbox v-model="cate.checked"
:indeterminate="isIndeterminate(cate.id)"
@change="handleCheckAllChange(cate)">
{{cate.name}}
</el-checkbox>
</el-row>
<!-- 另一个 el-row 组件同样添加了 'table-layout' 类名用于样式布局 -->
<el-row class="table-layout">
<!-- 使用 v-for 指令循环遍历当前分类cate下的资源列表通过 getResourceByCate 方法获取每个资源对应一个 el-checkbox 组件 -->
<!-- 设置了 el-col 组件的占比为 8给每个复选框添加了上下内边距为 4px 的样式 -->
<el-col :span="8" v-for="resource in getResourceByCate(cate.id)" :key="resource.id" style="padding: 4px 0">
<!-- el-checkbox 复选框组件双向绑定 resource 对象的 checked 属性绑定 change 事件到 handleCheckChange 方法 -->
<!-- 复选框显示的文本为 resource 对象的 name 属性值 -->
<el-checkbox v-model="resource.checked" @change="handleCheckChange(resource)">
{{resource.name}}
</el-checkbox>
</el-col>
</el-row>
</div>
<!-- 包含两个按钮的 div 容器设置了顶部外边距为 20px并使其内容居中对齐 -->
<div style="margin-top: 20px" align="center">
<!-- 保存按钮类型为主要primary点击时调用 handleSave 方法 -->
<el-button type="primary" @click="handleSave()"></el-button>
<!-- 清空按钮点击时调用 handleClear 方法 -->
<el-button @click="handleClear()"></el-button>
</div>
</el-card>
</template>
<script>
import {fetchAllResourceList} from '@/api/resource';
import {listAllCate} from '@/api/resourceCategory';
import {allocResource,listResourceByRole} from '@/api/role';
// @/api/resource API
import {fetchAllResourceList} from '@/api/resource';
// @/api/resourceCategory API
import {listAllCate} from '@/api/resourceCategory';
// @/api/role API
import {allocResource, listResourceByRole} from '@/api/role';
export default {
name: "allocResource",
data() {
return {
roleId: null,
allResource: null,
allResourceCate: null
};
},
created() {
this.roleId = this.$route.query.roleId;
this.getAllResourceCateList();
},
methods: {
getAllResourceList() {
fetchAllResourceList().then(response => {
this.allResource = response.data;
for (let i = 0; i < this.allResource.length; i++) {
this.allResource[i].checked = false;
}
this.getResourceByRole(this.roleId);
});
},
getAllResourceCateList() {
listAllCate().then(response => {
this.allResourceCate = response.data;
for (let i = 0; i < this.allResourceCate.length; i++) {
this.allResourceCate[i].checked = false;
}
this.getAllResourceList();
});
},
getResourceByCate(categoryId) {
let cateResource = [];
if (this.allResource == null) return null;
export default {
name: "allocResource",
data() {
return {
// ID null
roleId: null,
// null API
allResource: null,
// null API
allResourceCate: null
};
},
created() {
// ID roleId
this.roleId = this.$route.query.roleId;
//
this.getAllResourceCateList();
},
methods: {
//
getAllResourceList() {
// API Promise
fetchAllResourceList().then(response => {
// allResource
this.allResource = response.data;
// checked false
for (let i = 0; i < this.allResource.length; i++) {
let resource = this.allResource[i];
if (resource.categoryId === categoryId) {
cateResource.push(resource);
}
}
return cateResource;
},
getResourceByRole(roleId){
listResourceByRole(roleId).then(response=>{
let allocResource = response.data;
this.allResource.forEach(item=>{
item.checked = this.getResourceChecked(item.id,allocResource);
});
this.allResourceCate.forEach(item=>{
item.checked = this.isAllChecked(item.id);
});
this.$forceUpdate();
});
},
getResourceChecked(resourceId,allocResource){
if(allocResource==null||allocResource.length===0) return false;
for(let i=0;i<allocResource.length;i++){
if(allocResource[i].id===resourceId){
return true;
}
}
return false;
},
isIndeterminate(categoryId) {
let cateResources = this.getResourceByCate(categoryId);
if (cateResources == null) return false;
let checkedCount = 0;
for (let i = 0; i < cateResources.length; i++) {
if (cateResources[i].checked === true) {
checkedCount++;
}
this.allResource[i].checked = false;
}
return !(checkedCount === 0 || checkedCount === cateResources.length);
},
isAllChecked(categoryId) {
let cateResources = this.getResourceByCate(categoryId);
if (cateResources == null) return false;
let checkedCount = 0;
for (let i = 0; i < cateResources.length; i++) {
if (cateResources[i].checked === true) {
checkedCount++;
}
// ID
this.getResourceByRole(this.roleId);
});
},
//
getAllResourceCateList() {
// API Promise
listAllCate().then(response => {
// allResourceCate
this.allResourceCate = response.data;
// checked false
for (let i = 0; i < this.allResourceCate.length; i++) {
this.allResourceCate[i].checked = false;
}
if(checkedCount===0){
return false;
//
this.getAllResourceList();
});
},
// ID
getResourceByCate(categoryId) {
//
let cateResource = [];
// null
if (this.allResource == null) return null;
//
for (let i = 0; i < this.allResource.length; i++) {
//
let resource = this.allResource[i];
// ID ID
if (resource.categoryId === categoryId) {
cateResource.push(resource);
}
return checkedCount === cateResources.length;
},
handleSave() {
this.$confirm('是否分配资源?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let checkedResourceIds = new Set();
if (this.allResource != null && this.allResource.length > 0) {
this.allResource.forEach(item => {
if (item.checked) {
checkedResourceIds.add(item.id);
}
});
}
let params = new URLSearchParams();
params.append("roleId", this.roleId);
params.append("resourceIds", Array.from(checkedResourceIds));
allocResource(params).then(response => {
this.$message({
message: '分配成功',
type: 'success',
duration: 1000
});
this.$router.back();
})
})
},
handleClear() {
this.allResourceCate.forEach(item => {
item.checked = false;
});
}
return cateResource;
},
// ID
getResourceByRole(roleId) {
// API ID Promise
listResourceByRole(roleId).then(response => {
// allocResource 便
let allocResource = response.data;
// getResourceChecked
this.allResource.forEach(item => {
item.checked = false;
item.checked = this.getResourceChecked(item.id, allocResource);
});
// isAllChecked
this.allResourceCate.forEach(item => {
item.checked = this.isAllChecked(item.id);
});
//
this.$forceUpdate();
},
handleCheckAllChange(cate) {
let cateResources = this.getResourceByCate(cate.id);
for (let i = 0; i < cateResources.length; i++) {
cateResources[i].checked = cate.checked;
});
},
// ID
getResourceChecked(resourceId, allocResource) {
// false
if (allocResource == null || allocResource.length === 0) return false;
//
for (let i = 0; i < allocResource.length; i++) {
// ID true
if (allocResource[i].id === resourceId) {
return true;
}
this.$forceUpdate();
},
handleCheckChange(resource) {
this.allResourceCate.forEach(item=>{
if(item.id===resource.categoryId){
item.checked = this.isAllChecked(resource.categoryId);
}
return false;
},
//
isIndeterminate(categoryId) {
//
let cateResources = this.getResourceByCate(categoryId);
// false
if (cateResources == null) return false;
// 0
let checkedCount = 0;
//
for (let i = 0; i < cateResources.length; i++) {
if (cateResources[i].checked === true) {
checkedCount++;
}
}
// 0 true
return!(checkedCount === 0 || checkedCount === cateResources.length);
},
//
isAllChecked(categoryId) {
//
let cateResources = this.getResourceByCate(categoryId);
// false
if (cateResources == null) return false;
// 0
let checkedCount = 0;
//
for (let i = 0; i < cateResources.length; i++) {
if (cateResources[i].checked === true) {
checkedCount++;
}
}
// 0 false
if (checkedCount === 0) {
return false;
}
// true
return checkedCount === cateResources.length;
},
//
handleSave() {
// Set ID
let checkedResourceIds = new Set();
//
if (this.allResource!= null && this.allResource.length > 0) {
// checked true ID Set
this.allResource.forEach(item => {
if (item.checked) {
checkedResourceIds.add(item.id);
}
});
this.$forceUpdate();
}
// URLSearchParams
let params = new URLSearchParams();
// ID
params.append("roleId", this.roleId);
// ID Array.from
params.append("resourceIds", Array.from(checkedResourceIds));
// API Promise
allocResource(params).then(response => {
// success 1000
this.$message({
message: '分配成功',
type: 'success',
duration: 1000
});
//
this.$router.back();
})
},
//
handleClear() {
// checked false
this.allResourceCate.forEach(item => {
item.checked = false;
});
// checked false
this.allResource.forEach(item => {
item.checked = false;
});
//
this.$forceUpdate();
},
// /
handleCheckAllChange(cate) {
//
let cateResources = this.getResourceByCate(cate.id);
//
for (let i = 0; i < cateResources.length; i++) {
cateResources[i].checked = cate.checked;
}
//
this.$forceUpdate();
},
//
handleCheckChange(resource) {
//
this.allResourceCate.forEach(item => {
if (item.id === resource.categoryId) {
//
item.checked = this.isAllChecked(resource.categoryId);
}
});
//
this.$forceUpdate();
}
}
}
</script>
<style scoped>
.table-layout {
padding: 20px;
border-left: 1px solid #DCDFE6;
border-right: 1px solid #DCDFE6;
border-bottom: 1px solid #DCDFE6;
}
/* 定义了名为 'table-layout' 的类选择器样式规则,用于设置布局相关的样式 */
.table-layout {
/* 设置内边距为 20px使内部元素有合适的间距 */
padding: 20px;
/* 设置左边框样式,颜色为 #DCDFE6线条样式为实线宽度为 1px */
border-left: 1px solid #DCDFE6;
/* 设置右边框样式,与左边框相同 */
border-right: 1px solid #DCDFE6;
/* 设置下边框样式,与左右边框相同 */
border-bottom: 1px solid #DCDFE6;
}
.top-line {
border-top: 1px solid #DCDFE6;
}
/* 定义了名为 'top-line' 的类选择器样式规则,用于给元素添加顶部边框,可能用于区分不同部分等样式效果 */
.top-line {
border-top: 1px solid #DCDFE6;
}
</style><style scoped>
/* 定义了名为 'table-layout' 的类选择器样式规则,用于设置布局相关的样式 */
.table-layout {
/* 设置内边距为 20px使内部元素有合适的间距 */
padding: 20px;
/* 设置左边框样式,颜色为 #DCDFE6线条样式为实线宽度为 1px */
border-left: 1px solid #DCDFE6;
/* 设置右边框样式,与左边框相同 */
border-right: 1px solid #DCDFE6;
/* 设置下边框样式,与左右边框相同 */
border-bottom: 1px solid #DCDFE6;
}
/* 定义了名为 'top-line' 的类选择器样式规则,用于给元素添加顶部边框,可能用于区分不同部分等样式效果 */
.top-line {
border-top: 1px solid #DCDFE6;
}
</style><style scoped>
/* 定义了名为 'table-layout' 的类选择器样式规则,用于设置布局相关的样式 */
.table-layout {
/* 设置内边距为 20px使内部元素有合适的间距 */
padding: 20px;
/* 设置左边框样式,颜色为 #DCDFE6线条样式为实线宽度为 1px */
border-left: 1px solid #DCDFE6;
/* 设置右边框样式,与左边框相同 */
border-right: 1px solid #DCDFE6;
/* 设置下边框样式,与左右边框相同 */
border-bottom: 1px solid #DCDFE6;
}
/* 定义了名为 'top-line' 的类选择器样式规则,用于给元素添加顶部边框,可能用于区分不同部分等样式效果 */
.top-line {
border-top: 1px solid #DCDFE6;
}
</style>

@ -1,9 +1,14 @@
<template> 
<template>
<!-- 整体的应用容器 div用于包裹页面内的各个功能模块 -->
<div class="app-container">
<!-- 筛选搜索区域的卡片容器设置了阴影效果为无 -->
<el-card class="filter-container" shadow="never">
<div>
<!-- 搜索图标元素使用了 el-icon-search 图标 -->
<i class="el-icon-search"></i>
<!-- 筛选搜索的文字提示 -->
<span>筛选搜索</span>
<!-- 查询搜索按钮设置了样式为右浮动按钮类型为主要primary点击时调用 handleSearchList 方法按钮大小为 small -->
<el-button
style="float:right"
type="primary"
@ -11,6 +16,7 @@
size="small">
查询搜索
</el-button>
<!-- 重置按钮设置了样式为右浮动且距离右侧 15px点击时调用 handleResetSearch 方法按钮大小为 small -->
<el-button
style="float:right;margin-right: 15px"
@click="handleResetSearch()"
@ -19,38 +25,52 @@
</el-button>
</div>
<div style="margin-top: 15px">
<!-- 内联表单绑定了 listQuery 数据对象表单大小为 small标签宽度为 140px用于设置筛选条件 -->
<el-form :inline="true" :model="listQuery" size="small" label-width="140px">
<!-- 表单项目标签为输入搜索内部的输入框双向绑定 listQuery.keyword设置了类名占位符以及可清空功能 -->
<el-form-item label="输入搜索:">
<el-input v-model="listQuery.keyword" class="input-width" placeholder="角色名称" clearable></el-input>
</el-form-item>
</el-form>
</div>
</el-card>
<!-- 操作区域的卡片容器设置了阴影效果为无 -->
<el-card class="operate-container" shadow="never">
<!-- 图标元素使用了 el-icon-tickets 图标 -->
<i class="el-icon-tickets"></i>
<!-- 数据列表的文字提示 -->
<span>数据列表</span>
<!-- 添加按钮大小为 mini添加了自定义类名 btn-add点击时调用 handleAdd 方法设置了左侧外边距为 20px -->
<el-button size="mini" class="btn-add" @click="handleAdd()" style="margin-left: 20px">添加</el-button>
</el-card>
<!-- 表格容器 div用于放置展示角色数据的表格 -->
<div class="table-container">
<!-- el-table 组件用于展示角色数据列表设置了引用名绑定的数据表格宽度加载状态绑定以及边框等属性 -->
<el-table ref="roleTable"
:data="list"
style="width: 100%;"
v-loading="listLoading" border>
<!-- 表格列标签为编号设置了宽度和内容居中对齐通过插槽作用域展示对应行数据的 id 属性 -->
<el-table-column label="编号" width="100" align="center">
<template slot-scope="scope">{{scope.row.id}}</template>
</el-table-column>
<!-- 表格列标签为角色名称内容居中对齐通过插槽作用域展示对应行数据的 name 属性 -->
<el-table-column label="角色名称" align="center">
<template slot-scope="scope">{{scope.row.name}}</template>
</el-table-column>
<!-- 表格列标签为描述内容居中对齐通过插槽作用域展示对应行数据的 description 属性 -->
<el-table-column label="描述" align="center">
<template slot-scope="scope">{{scope.row.description}}</template>
</el-table-column>
<!-- 表格列标签为用户数设置了宽度和内容居中对齐通过插槽作用域展示对应行数据的 adminCount 属性 -->
<el-table-column label="用户数" width="100" align="center">
<template slot-scope="scope">{{scope.row.adminCount}}</template>
</el-table-column>
<!-- 表格列标签为添加时间设置了宽度和内容居中对齐通过插槽作用域展示对应行数据的 createTime 属性并使用 formatDateTime 过滤器对时间进行格式化展示 -->
<el-table-column label="添加时间" width="160" align="center">
<template slot-scope="scope">{{scope.row.createTime | formatDateTime}}</template>
</el-table-column>
<!-- 表格列标签为是否启用设置了宽度和内容居中对齐通过插槽作用域展示对应行数据的 status 属性并使用 el-switch 组件进行切换操作绑定了相关的事件和值 -->
<el-table-column label="是否启用" width="140" align="center">
<template slot-scope="scope">
<el-switch
@ -61,6 +81,7 @@
</el-switch>
</template>
</el-table-column>
<!-- 表格列标签为操作设置了宽度和内容居中对齐通过插槽作用域展示多个操作按钮包括分配菜单分配资源编辑和删除按钮分别绑定了对应的点击事件 -->
<el-table-column label="操作" width="160" align="center">
<template slot-scope="scope">
<el-row>
@ -74,21 +95,23 @@
</el-button>
</el-row>
<el-row>
<el-button size="mini"
type="text"
@click="handleUpdate(scope.$index, scope.row)">
编辑
</el-button>
<el-button size="mini"
type="text"
@click="handleDelete(scope.$index, scope.row)">删除
</el-button>
<el-button size="mini"
type="text"
@click="handleUpdate(scope.$index, scope.row)">
编辑
</el-button>
<el-button size="mini"
type="text"
@click="handleDelete(scope.$index, scope.row)">删除
</el-button>
</el-row>
</template>
</el-table-column>
</el-table>
</div>
<!-- 分页容器 div用于放置分页组件 -->
<div class="pagination-container">
<!-- el-pagination 分页组件设置了背景色相关页面切换事件绑定布局样式当前页每页数量可选每页数量数组以及总记录数等属性 -->
<el-pagination
background
@size-change="handleSizeChange"
@ -100,22 +123,27 @@
:total="total">
</el-pagination>
</div>
<!-- el-dialog 对话框组件根据 isEdit 变量动态设置标题为编辑角色添加角色绑定了显示状态设置了宽度 -->
<el-dialog
:title="isEdit?'编辑角色':'添加角色'"
:visible.sync="dialogVisible"
width="40%">
<!-- 对话框内的表单绑定了 role 数据对象设置了表单引用标签宽度和大小 -->
<el-form :model="role"
ref="roleForm"
label-width="150px" size="small">
<!-- 表单项目标签为角色名称输入框双向绑定 role.name并设置了宽度 -->
<el-form-item label="角色名称:">
<el-input v-model="role.name" style="width: 250px"></el-input>
</el-form-item>
<!-- 表单项目标签为描述输入框双向绑定 role.description设置了文本域类型和行数以及宽度 -->
<el-form-item label="描述:">
<el-input v-model="role.description"
type="textarea"
:rows="5"
style="width: 250px"></el-input>
</el-form-item>
<!-- 表单项目标签为是否启用内部是一个单选按钮组双向绑定 role.status用于选择角色是否启用的状态 -->
<el-form-item label="是否启用:">
<el-radio-group v-model="role.status">
<el-radio :label="1"></el-radio>
@ -123,6 +151,7 @@
</el-radio-group>
</el-form-item>
</el-form>
<!-- 对话框底部的按钮区域通过插槽定义了取消和确定按钮分别绑定了对应的点击事件 -->
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false" size="small"> </el-button>
<el-button type="primary" @click="handleDialogConfirm()" size="small"> </el-button>
@ -131,156 +160,199 @@
</div>
</template>
<script>
import {fetchList,createRole,updateRole,updateStatus,deleteRole} from '@/api/role';
import {formatDate} from '@/utils/date';
// '@/api/role'API
import {fetchList, createRole, updateRole, updateStatus, deleteRole} from '@/api/role';
// '@/utils/date'formatDate
import {formatDate} from '@/utils/date';
// 15null
const defaultListQuery = {
pageNum: 1,
pageSize: 5,
keyword: null
};
// IDIDnull01
const defaultRole = {
id: null,
name: null,
description: null,
adminCount: 0,
status: 1
};
const defaultListQuery = {
pageNum: 1,
pageSize: 5,
keyword: null
};
const defaultRole = {
id: null,
name: null,
description: null,
adminCount: 0,
status: 1
};
export default {
name: 'roleList',
data() {
return {
listQuery: Object.assign({}, defaultListQuery),
list: null,
total: null,
listLoading: false,
dialogVisible: false,
role: Object.assign({}, defaultRole),
isEdit: false
export default {
name: 'roleList',
data() {
return {
// Object.assigndefaultListQuery
listQuery: Object.assign({}, defaultListQuery),
// nullAPI
list: null,
// nullAPI
total: null,
// truefalsefalse
listLoading: false,
// truefalsefalse
dialogVisible: false,
// defaultRole
role: Object.assign({}, defaultRole),
// truefalsefalse
isEdit: false
}
},
//
created() {
this.getList();
},
filters: {
// time
formatDateTime(time) {
// null'N/A'
if (time == null || time === '') {
return 'N/A';
}
// JavaScriptDate
let date = new Date(time);
// formatDate'yyyy-MM-dd hh:mm:ss'
return formatDate(date, 'yyyy-MM-dd hh:mm:ss')
}
},
methods: {
//
handleResetSearch() {
this.listQuery = Object.assign({}, defaultListQuery);
},
created() {
// 1
handleSearchList() {
this.listQuery.pageNum = 1;
this.getList();
},
filters: {
formatDateTime(time) {
if (time == null || time === '') {
return 'N/A';
}
let date = new Date(time);
return formatDate(date, 'yyyy-MM-dd hh:mm:ss')
}
// 1val
handleSizeChange(val) {
this.listQuery.pageNum = 1;
this.listQuery.pageSize = val;
this.getList();
},
methods: {
handleResetSearch() {
this.listQuery = Object.assign({}, defaultListQuery);
},
handleSearchList() {
this.listQuery.pageNum = 1;
this.getList();
},
handleSizeChange(val) {
this.listQuery.pageNum = 1;
this.listQuery.pageSize = val;
this.getList();
},
handleCurrentChange(val) {
this.listQuery.pageNum = val;
this.getList();
},
handleAdd() {
this.dialogVisible = true;
this.isEdit = false;
this.role = Object.assign({},defaultRole);
},
handleStatusChange(index, row) {
this.$confirm('是否要修改该状态?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
updateStatus(row.id, {status: row.status}).then(response => {
this.$message({
type: 'success',
message: '修改成功!'
});
// val
handleCurrentChange(val) {
this.listQuery.pageNum = val;
this.getList();
},
//
handleAdd() {
this.dialogVisible = true;
this.isEdit = false;
this.role = Object.assign({}, defaultRole);
},
//
handleStatusChange(index, row) {
this.$confirm('是否要修改该状态?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// updateStatusID
updateStatus(row.id, {status: row.status}).then(response => {
this.$message({
type: 'success',
message: '修改成功!'
});
}).catch(() => {
});
}).catch(() => {
//
this.$message({
type: 'info',
message: '取消修改'
});
this.getList();
});
},
//
handleDelete(index, row) {
this.$confirm('是否要删除该角色?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let ids = [];
// ID
ids.push(row.id);
let params = new URLSearchParams();
// IDURLSearchParamsAPI
params.append("ids", ids);
// deleteRole
deleteRole(params).then(response => {
this.$message({
type: 'info',
message: '取消修改'
type: 'success',
message: '删除成功!'
});
this.getList();
});
},
handleDelete(index, row) {
this.$confirm('是否要删除该角色?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let ids = [];
ids.push(row.id);
let params=new URLSearchParams();
params.append("ids",ids);
deleteRole(params).then(response => {
});
},
//
handleUpdate(index, row) {
this.dialogVisible = true;
this.isEdit = true;
this.role = Object.assign({}, row);
},
//
handleDialogConfirm() {
this.$confirm('是否要确认?', '提示', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// updateRoleID
if (this.isEdit) {
updateRole(this.role.id, this.role).then(response => {
this.$message({
type: 'success',
message: '删除成功!'
message: '修改成功!',
type: 'success'
});
this.dialogVisible = false;
this.getList();
});
});
},
handleUpdate(index, row) {
this.dialogVisible = true;
this.isEdit = true;
this.role = Object.assign({},row);
},
handleDialogConfirm() {
this.$confirm('是否要确认?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
if (this.isEdit) {
updateRole(this.role.id,this.role).then(response => {
this.$message({
message: '修改成功!',
type: 'success'
});
this.dialogVisible =false;
this.getList();
})
} else {
createRole(this.role).then(response => {
this.$message({
message: '添加成功!',
type: 'success'
});
this.dialogVisible =false;
this.getList();
})
}
})
},
handleSelectMenu(index,row){
this.$router.push({path:'/ums/allocMenu',query:{roleId:row.id}})
},
handleSelectResource(index,row){
this.$router.push({path:'/ums/allocResource',query:{roleId:row.id}})
},
getList() {
this.listLoading = true;
fetchList(this.listQuery).then(response => {
this.listLoading = false;
this.list = response.data.list;
this.total = response.data.total;
});
}
})
} else {
// createRole
createRole(this.role).then(response => {
this.$message({
message: '添加成功!',
type: 'success'
});
this.dialogVisible = false;
this.getList();
})
}
})
},
// '/ums/allocMenu'ID
handleSelectMenu(index, row) {
this.$router.push({path: '/ums/allocMenu', query: {roleId: row.id}})
},
// '/ums/allocResource'ID
handleSelectResource(index, row) {
this.$router.push({path: '/ums/allocResource', query: {roleId: row.id}})
},
// fetchList
getList() {
this.listLoading = true;
fetchList(this.listQuery).then(response => {
this.listLoading = false;
this.list = response.data.list;
this.total = response.data.total;
});
}
}
}
</script>
<style></style>
<style>
/* CSS updateMenu
来对组件的外观进行定制化显示 */
/* CSS resourceList
- 设置表格的样式如表头单元格的字体颜色边框样式等
- 对筛选区域操作按钮分页组件等元素的布局外观进行调整比如按钮的颜色大小间距等
- 定制对话框的样式像对话框的背景色边框按钮在对话框内的排版等
通过添加这些样式规则可以让页面的显示更加符合设计要求和美观性 */
</style>

Loading…
Cancel
Save