• eyb:职称管理页面设计到部门删除功能实现(三)



    目录:

    (1)职称管理页面设计

    (2)职称管理接口调用

    (3)职称管理编辑功能实现

    (4)职称管理批量删除功能实现

    (5)权限组页面设计

    (6) 权限组树形菜单展示

    (7)角色菜单功能实现

    (8)角色操作功能实现 

    (9)部门展示与搜索功能实现

    (10)部门操作按钮设计

    (11)部门添加功能实现

    (12) 部门删除功能实现


    (1)职称管理页面设计

    JoblevelMana.vue 

     

     (2)职称管理接口调用

     

    添加职称:

     

     

     删除方法:

     

    点击取消 

     点击确定:

    (3)职称管理编辑功能实现

     

     

     

    更新方法:

    (4)职称管理批量删除功能实现

    添加批量删除按钮: 

     

     

     JoblevelMana.vue:详细代码:

    1. <template>
    2. <div>
    3. <div>
    4. <el-input size="small" v-model="jl.name" style="width: 300px" prefix-icon="el-icon-plus"
    5. placeholder="添加职称...">
    6. el-input>
    7. <el-select v-model="jl.titleLevel" palaceholder="职称等级" size="small" style="margin-left: 6px;margin-right: 6px">
    8. <el-option v-for="item in titleLevels"
    9. :key="item"
    10. :label="item"
    11. :value="item">
    12. el-option>
    13. el-select>
    14. <el-button type="primary" icon="el-icon-plus" size="small" @click="addJl">添加el-button>
    15. div>
    16. <div style="margin-top: 10px">
    17. <el-table :data="jls"
    18. border
    19. stripe
    20. size="small"
    21. @selection-change="handleSelectionChange"
    22. style="width: 80%">
    23. <el-table-column
    24. type="selection"
    25. width="55">
    26. el-table-column>
    27. <el-table-column
    28. prop="id"
    29. label="编号"
    30. width="55">
    31. el-table-column>
    32. <el-table-column
    33. prop="name"
    34. label="职称名称"
    35. width="150">
    36. el-table-column>
    37. <el-table-column
    38. prop="titleLevel"
    39. label="职称级别"
    40. width="150">
    41. el-table-column>
    42. <el-table-column
    43. prop="createDate"
    44. label="创建时间"
    45. width="150">
    46. el-table-column>
    47. <el-table-column prop="enabled"
    48. label="是否启用"
    49. width="150">
    50. <template slot-scope="scope">
    51. <el-tag v-if="scope.row.enabled" type="success">已启用el-tag>
    52. <el-tag v-else type="danger">未启用el-tag>
    53. template>
    54. el-table-column>
    55. <el-table-column label="操作">
    56. <template slot-scope="scope">
    57. <el-button size="small" @click="showEditView(scope.row)">编辑el-button>
    58. <el-button size="small" type="danger" @click="deleteHandler(scope.row)">删除el-button>
    59. template>
    60. el-table-column>
    61. el-table>
    62. <el-button type="danger" size="small" style="margin-top: 10px" :disabled="multipleSelection.length == 0"
    63. @click="deleteMany">批量删除
    64. el-button>
    65. div>
    66. <el-dialog
    67. title="编辑职称"
    68. :visible.sync="dialogVisible"
    69. width="30%">
    70. <div>
    71. <table>
    72. <tr>
    73. <td>
    74. <el-tag>职称名称el-tag>
    75. td>
    76. <td>
    77. <el-input v-model="updateJl.name" size="small" style="margin-left: 6px">el-input>
    78. td>
    79. tr>
    80. <tr>
    81. <td>
    82. <el-tag>职称级别el-tag>
    83. td>
    84. <td>
    85. <el-select v-model="updateJl.titleLevel"
    86. placeholder="职称等级" size="small"
    87. style="margin-left: 6px;margin-right:6px">
    88. <el-option
    89. v-for="item in titleLevels"
    90. :key="item"
    91. :label="item"
    92. :value="item">
    93. el-option>
    94. el-select>
    95. td>
    96. tr>
    97. <tr>
    98. <td>
    99. <el-tag>是否启用el-tag>
    100. td>
    101. <td>
    102. <el-switch
    103. style="margin-left: 6px"
    104. v-model="updateJl.enabled"
    105. activecolor="#13ce66"
    106. inactive-color="#ff4949"
    107. active-text="启用"
    108. inactive-text="禁用">
    109. el-switch>
    110. td>
    111. tr>
    112. table>
    113. div>
    114. <span slot="footer" class="dialog-footer">
    115. <el-button size="small" @click="dialogVisible = false">取 消el-button>
    116. <el-button size="small" type="primary" @click="doUpdate">确 定el-button>
    117. span>
    118. el-dialog>
    119. div>
    120. template>
    121. <script>
    122. export default {
    123. name: "JoblevelMana",
    124. data() {
    125. return {
    126. //json对象
    127. jl: {
    128. name: '',
    129. titleLevel: ''
    130. },
    131. //更新的json数据
    132. updateJl: {
    133. name: '',
    134. titleLevel: '',
    135. enabled: false
    136. },
    137. titleLevels: [
    138. '正高级',
    139. '副高级',
    140. '中级',
    141. '初级',
    142. '员级',
    143. ],
    144. jls: [],
    145. dialogVisible: false,
    146. //数组
    147. multipleSelection: []
    148. }
    149. },
    150. //当页面刚加载的时候调用initJls方法调用后端接口,获取所有职称列表
    151. mounted() {
    152. this.initJls();
    153. },
    154. methods:{
    155. //批量删除方法
    156. deleteMany() {
    157. this.$confirm('此操作将永久删除【' + this.multipleSelection.length + '】条记录,是否继续?', '提示', {
    158. confirmButtonText: '确定',
    159. cancelButtonText: '取消',
    160. type: 'warning'
    161. }).then(() => {
    162. let ids = '?';
    163. this.multipleSelection.forEach(item => {
    164. ids += 'ids=' + item.id + '&';
    165. })
    166. this.deleteRequest('/system/basic/joblevel/' + ids).then(resp => {
    167. if (resp) {
    168. //批量删除之后,在次获取称列表,进行刷新
    169. this.initJls();
    170. }
    171. });
    172. }).catch(() => {
    173. this.$message({
    174. type: 'info',
    175. message: '已取消删除'
    176. })
    177. })
    178. },
    179. //表单勾选的对象,放到multipleSelection数组里面
    180. handleSelectionChange(val) {
    181. this.multipleSelection = val;
    182. },
    183. //显示编辑框
    184. showEditView(data) {
    185. //在编辑框里显示数据,采用Object.assign()这个方式
    186. Object.assign(this.updateJl, data);
    187. //把日期传过去,否则更改的时候会报错
    188. this.updateJl.createDate = '';
    189. //显示弹出框
    190. this.dialogVisible = true;
    191. },
    192. //修改职称方法
    193. doUpdate() {
    194. this.putRequest('/system/basic/joblevel/', this.updateJl).then(resp => {
    195. if (resp) {
    196. //更改数据之后,再次获取职位列表,进行更新
    197. this.initJls();
    198. this.updateJl.name = '';
    199. this.updateJl.titleLevel = '';
    200. //把弹出框隐藏
    201. this.dialogVisible = false;
    202. }
    203. })
    204. },
    205. //删除职称方法
    206. deleteHandler(data) {
    207. //删除
    208. this.$confirm('此操作将永久删除【' + data.name + '】职称, 是否继续?', '提示', {
    209. confirmButtonText: '确定',
    210. cancelButtonText: '取消',
    211. type: 'warning'
    212. }).then(() => {
    213. this.deleteRequest('/system/basic/joblevel/' +
    214. data.id).then(resp => {
    215. if (resp) {
    216. //删除之后,再次获取职位列表,进行更新
    217. this.initJls();
    218. }
    219. });
    220. }).catch(() => {
    221. this.$message({
    222. type: 'info',
    223. message: '已取消删除'
    224. });
    225. });
    226. },
    227. //添加职称方法
    228. addJl() {
    229. //判断输入框是否为空
    230. if (this.jl.name && this.jl.titleLevel) {
    231. //调用后端接口/system/basic/joblevel
    232. this.postRequest('/system/basic/joblevel/', this.jl).then(resp => {
    233. if (resp) {
    234. //添加之后,再次获取职位列表,进行更新
    235. this.initJls();
    236. //添加完之后,输入框设为空
    237. this.jl.name = '';
    238. this.jl.titleLevel = '';
    239. }
    240. })
    241. } else {
    242. this.$message.error("字段不能为空!");
    243. }
    244. },
    245. //初始化获取职称列表
    246. initJls() {
    247. this.getRequest('/system/basic/joblevel/').then(resp => {
    248. if (resp) {
    249. this.jls = resp;
    250. /*this.jl = {
    251. name: '',
    252. titleLevel: ''
    253. }*/
    254. }
    255. })
    256. }
    257. }
    258. }
    259. script>
    260. <style scoped>
    261. style>

    (5)权限组页面设计

     权限组主要用来干什么呢?主要用来更新以及展示咱们不同的角色所拥有的不同的菜单权限,这里涉及到很多操作,以及角色的添加,角色的查询,角色的删除,以及跟角色相关的菜单一个权限的操作,比如说菜单权限的展示,每一个角色所对应的一个菜单权限的展示,以及你去更新你的角色菜单权限

     

    (6) 权限组树形菜单展示

     

     

     

    (7)角色菜单功能实现

     设置默认菜单列表的选中状态

     

    这样每个角色默认拥有的菜单权限,就进行相应的一个展示了 

     更新角色菜单:

    在mian.js中添加:

    这样以后在使用elementUI的时候就不用每次进行设置size:small了

     

    (8)角色操作功能实现 

     

     

     删除角色:

     

    PermissManan.vue:详细代码:

    1. <template>
    2. <div>
    3. <div class="permissManaTool">
    4. <el-input size="small" placeholder="请输入角色英文名" v-model="role.name">
    5. <template slot="prepend">ROLE_template>
    6. el-input>
    7. <el-input size="small" placeholder="请输入角色中文名" v-model="role.nameZh" @keydown.enter.native="doAddRole">el-input>
    8. <el-button type="primary" size="small" icon="el-icon-plus" @click="doAddRole">添加角色el-button>
    9. div>
    10. <div class="permissManaMain">
    11. <el-collapse v-model="activeName" accordion @change="change">
    12. <el-collapse-item :title="r.nameZh" :name="r.id" v-for="(r,index) in roles" :key="index">
    13. <el-card class="box-card">
    14. <div slot="header" class="clearfix">
    15. <span>可访问资源span>
    16. <el-button style="float: right;padding: 3px 0;color: #ff0000" icon="el-icon-delete"
    17. type="text" @click="doDeleteRole(r)">
    18. el-button>
    19. div>
    20. <div>
    21. <el-tree
    22. show-checkbox
    23. :key="index"
    24. ref="tree"
    25. :default-checked-keys="selectedMenus"
    26. node-key="id"
    27. :data="allMenus" :props="defaultProps">
    28. el-tree>
    29. <div style="display: flex;justify-content: flex-end">
    30. <el-button @click="cancelUpdate">取消修改el-button>
    31. <el-button type="primary" @click="doUpdate(r.id,index)">确认修改el-button>
    32. div>
    33. div>
    34. el-card>
    35. el-collapse-item>
    36. el-collapse>
    37. div>
    38. div>
    39. template>
    40. <script>
    41. export default {
    42. name: "PermissMana",
    43. data() {
    44. return {
    45. //默认打开,上面第二个div
    46. activeName: '2',
    47. //json对象
    48. role: {
    49. name: '',
    50. nameZh: ''
    51. },
    52. //角色数组
    53. roles: [],
    54. //所有菜单数据
    55. allMenus: [],
    56. //菜单选中的数组
    57. selectedMenus: [],
    58. //让接口返回的数据与树形控件对应 指定节点对象的某个属性值
    59. defaultProps: {
    60. children: 'children',
    61. label: 'name'
    62. }
    63. }
    64. },
    65. //当页面刚加载的时候调用initRoles方法调用后端接口,获取所有角色列表
    66. mounted() {
    67. this.initRoles();
    68. },
    69. methods:{
    70. //删除角色方法
    71. doDeleteRole(role) {
    72. this.$confirm('此操作将永久删除该【' + role.nameZh + '】角色, 是否继 ? ', '提示', {
    73. confirmButtonText: '确定',
    74. cancelButtonText: '取消',
    75. type: 'warning'
    76. }
    77. ).then(() => {
    78. //调用后端接口/system/basic/permission/role/
    79. this.deleteRequest('/system/basic/permission/role/' + role.id).then(resp => {
    80. if (resp) {
    81. //删除完之后,更新一下角色列表
    82. this.initRoles();
    83. }
    84. });
    85. }).catch(() => {
    86. this.$message({
    87. type: 'info',
    88. message: '已取消删除'
    89. });
    90. });
    91. },
    92. //添加角色方法
    93. doAddRole() {
    94. //首先判断两个输入框不为空
    95. if (this.role.name && this.role.nameZh) {
    96. //调用后端接口/system/basic/permission/
    97. this.postRequest('/system/basic/permission/role', this.role).then(resp => {
    98. if (resp) {
    99. //添加完之后输入框为空
    100. this.name = '';
    101. this.nameZh = '';
    102. //添加完之后,更新一下角色列表
    103. this.initRoles();
    104. }
    105. })
    106. } else {
    107. this.$message.error('字段不能为空!');
    108. }
    109. },
    110. //更新角色菜单方法
    111. doUpdate(rid, index) {
    112. let tree = this.$refs.tree[index];
    113. //获取所有的key,只获取叶子节点
    114. let selectedKeys = tree.getCheckedKeys(true);
    115. let url = '/system/basic/permission/?rid=' + rid;
    116. selectedKeys.forEach(key => {
    117. url += '&mids=' + key;
    118. })
    119. //调用后端接口/system/basic/permission
    120. this.putRequest(url).then(resp => {
    121. if (resp) {
    122. //等于-1 更新完之后下拉框就会关掉
    123. this.activeName = -1;
    124. }
    125. })
    126. },
    127. //取消更新
    128. cancelUpdate() {
    129. this.activeName = -1;
    130. },
    131. //改变事件
    132. change(rid) {
    133. if (rid) {
    134. //调用initAllMenus方法
    135. this.initAllMenus();
    136. //调用initSelectedMenus方法获取角色对应的菜单
    137. this.initSelectedMenus(rid);
    138. }
    139. },
    140. //初始化所有菜单
    141. initAllMenus() {
    142. //调用后端接口
    143. this.getRequest('/system/basic/permission/menus').then(resp => {
    144. //让allMenus数组接收返回的数据resp
    145. this.allMenus = resp;
    146. })
    147. },
    148. //根据id获取角色拥有的菜单方法
    149. initSelectedMenus(rid) {
    150. //调用后端接口/system/basic/permission/mid
    151. this.getRequest('/system/basic/permission/mid/' + rid).then(resp => {
    152. //让定义的数组接收返回的数据resp
    153. this.selectedMenus = resp;
    154. })
    155. },
    156. //查询所有角色
    157. initRoles() {
    158. //调用后端接口
    159. this.getRequest('/system/basic/permission/').then(resp => {
    160. if (resp) {
    161. this.roles = resp;
    162. }
    163. })
    164. }
    165. }
    166. }
    167. script>
    168. <style>
    169. .permissManaTool {
    170. display: flex;
    171. justify-content: flex-start;
    172. }
    173. .permissManaTool .el-input {
    174. width: 300px;
    175. margin-right: 6px;
    176. }
    177. .permissManaMain {
    178. margin-top: 10px;
    179. width: 700px
    180. }
    181. style>

    以上权限功能都实现完了,有哪些功能呢?添加角色、查询角色、删除角色

    查询角色:使用折叠面板(手风琴形式) 角色里面,还有菜单与角色相关的功能:查询所有菜单(使用了树形控件)查询角色所拥有的的菜单权限 

     (9)部门展示与搜索功能实现

     DepManan.vue:

     

     (10)部门操作按钮设计

    在每一行下面都要有一个添加删除的按钮 

     

    (11)部门添加功能实现

     点击添加部门弹出一个弹出框

     

     

     这里不是刷新列表,而是调用方法手动添加到树形节点,因为刷新的话,添加成功后列表的关闭了

    (12) 部门删除功能实现

     

     

    当aaa部门下有子部门,删除失败:

     先删除111:

    DepManan.vue:详细代码:

    1. <template>
    2. <div style="width: 500px">
    3. <el-input placeholder="请输入部门名称进行搜索..."
    4. prefix-icon="el-icon-search"
    5. v-model="filterText">
    6. el-input>
    7. <el-tree
    8. :data="deps"
    9. :props="defaultProps"
    10. :filter-node-method="filterNode"
    11. :expand-on-click-node="false"
    12. ref="tree">
    13. <span class="custom-tree-node" style="display: flex;justify-content: space-between;width: 100%;"
    14. slot-scope="{node,data}">
    15. <span>{{data.name}}span>
    16. <span>
    17. <el-button
    18. type="primary"
    19. size="mini"
    20. class="depBtn"
    21. @click="()=>showAddDepView(data)">
    22. 添加部门
    23. el-button>
    24. <el-button
    25. type="danger"
    26. size="mini"
    27. class="depBtn"
    28. @click="()=>deleteDep(data)">
    29. 删除部门
    30. el-button>
    31. span>
    32. span>
    33. el-tree>
    34. <el-dialog
    35. title="添加部门"
    36. :visible.sync="dialogVisible"
    37. width="30%">
    38. <div>
    39. <table>
    40. <tr>
    41. <td>
    42. <el-tag>上级部门el-tag>
    43. td>
    44. <td>{{pname}}td>
    45. tr>
    46. <tr>
    47. <td>
    48. <el-tag>部门名称el-tag>
    49. td>
    50. <td>
    51. <el-input v-model="dep.name" placeholder="请输入部门名称...">el-input>
    52. td>
    53. tr>
    54. table>
    55. div>
    56. <span slot="footer" class="dialog-footer">
    57. <el-button @click="dialogVisible= false">取消el-button>
    58. <el-button type="primary" @click="doAddDep">确定el-button>
    59. span>
    60. el-dialog>
    61. div>
    62. template>
    63. <script>
    64. export default {
    65. name: "DepMana",
    66. data() {
    67. return {
    68. filterText: '',
    69. //返回的数据数组
    70. deps: [],
    71. //接口返回数据与树形节点的属性的相对应
    72. defaultProps: {
    73. children: 'children',
    74. label: 'name'
    75. },
    76. //添加部门的数据对象
    77. dep: {
    78. name: '',
    79. parentId: -1
    80. },
    81. pname: '',
    82. //定义弹出框是否可见
    83. dialogVisible: false
    84. }
    85. },
    86. //观察者事件,观察上面filterText的值,有值的话去找树形控件tree,filter调用下面filterNode方法
    87. watch: {
    88. filterText(val) {
    89. this.$refs.tree.filter(val);
    90. }
    91. },
    92. //当页面刚加载的时候调用initRoles方法调用后端接口,获取所有角色列表
    93. mounted() {
    94. this.initDeps();
    95. },
    96. methods: {
    97. //获取数据部门列表的方法
    98. initDeps() {
    99. //调用后端接口,/system/basic/department
    100. this.getRequest('/system/basic/department/').then(resp => {
    101. if (resp) {
    102. this.deps = resp;
    103. }
    104. })
    105. },
    106. //手动添加到树形控件的方法
    107. addDep2Deps(deps, dep) {
    108. //循环所有部门
    109. for (let i = 0; i < deps.length; i++) {
    110. let d = deps[i];
    111. //deps是所有部门 dep是添加的部门,当添加的部门是所有部门中的一个的id相等的话,添加进去
    112. if (d.id == dep.parentId) {
    113. d.children = d.children.concat(dep);
    114. //添加完后,判断它子部门长度是否大于0,有的话它的属性parent变为true
    115. if (d.children.length > 0) {
    116. d.isParent = true;
    117. }
    118. return;
    119. } else {
    120. //递归循环子部门知道id相等
    121. this.addDep2Deps(d.children, dep);
    122. }
    123. }
    124. },
    125. //添加部门,让弹出框显示,并把数据在弹出框内显示
    126. showAddDepView(data) {
    127. this.pname = data.name;
    128. this.dep.parentId = data.id;
    129. this.dialogVisible = true;
    130. },
    131. //初始化部门
    132. initDep() {
    133. this.dep = {
    134. name: '',
    135. parentId: -1
    136. }
    137. this.pname = '';
    138. },
    139. //添加部门方法
    140. doAddDep() {
    141. //调用后端接口/system/basic/department
    142. this.postRequest('/system/basic/department/',
    143. this.dep).then(resp => {
    144. if (resp) {
    145. //调用手动添加到树形控件的方法
    146. this.addDep2Deps(this.deps, resp.obj);
    147. //添加成功后,弹出框隐藏
    148. this.dialogVisible = false;
    149. //添加成功后,弹出框,初始化部门设为空
    150. this.initDep();
    151. }
    152. })
    153. },
    154. //手动删除属性节点的方法
    155. removeDepFromDeps(p, deps, id) {
    156. for (let i = 0; i < deps.length; i++) {
    157. let d = deps[i];
    158. //当循环的id和删除的id一样进行删除
    159. if (d.id ==id) {
    160. deps.splice(i,1);
    161. //删除子部门后,判断一下deps是否为0,0的话改为false,否则副部们一直不能删除
    162. if (deps.length == 0) {
    163. p.isParent = false;
    164. }
    165. return;
    166. } else {
    167. //递归查找id
    168. this.removeDepFromDeps(d, d.children, id);
    169. }
    170. }
    171. },
    172. //删除部门
    173. deleteDep(data) {
    174. //删除的时候,可以判断一下,是否是parent,是parent的话不能删
    175. if (data.isParent) {
    176. this.$message.error("父部门删除失败!");
    177. } else {
    178. this.$confirm('此操作将永久删除该【' + data.name + '】部门, 是否继续?', '提示', {
    179. confirmButtonText: '确定',
    180. cancelButtonText: '取消',
    181. type: 'warning'
    182. }).then(() => {
    183. //调用后端接口/system/basic/department
    184. this.deleteRequest('/system/basic/department/' + data.id).then(resp => {
    185. if (resp) {
    186. //手动删除属性节点的方法
    187. this.removeDepFromDeps(null, this.deps, data.id);
    188. }
    189. });
    190. }).catch(() => {
    191. this.$message({
    192. type: 'info',
    193. message: '已取消删除'
    194. });
    195. });
    196. }
    197. },
    198. //拦截节点的方法,对树的节点筛选的一个方法
    199. filterNode(value, data) {
    200. if (!value) return true;//输入为空,返回true节点展示,false节点隐藏
    201. return data.name.indexOf(value) !== -1;//返回true的话节点展示
    202. }
    203. }
    204. }
    205. script>
    206. <style>
    207. .depBtn {
    208. padding: 2px;
    209. }
    210. style>

     

     

  • 相关阅读:
    第43期:多表关联场景下如何用好分区表
    Springboot+vue校园新闻网站idea
    【RocketMQ】发送事务消息
    利用Linux虚拟化技术实现资源隔离和管理
    115. 关于将本地 SAP UI5 应用配置到本地 Fiori Launchpad 的技术实现深入讲解
    分类预测 | MATLAB实现SSA-CNN-LSTM-Attention数据分类预测
    Linux下搭建nginx服务器
    数据结构——图(图的存储及基本操作)
    YOLOV5识别成语点选验证码
    vscode推送gitee方法
  • 原文地址:https://blog.csdn.net/dengfengling999/article/details/126550337