index.vue 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. <template>
  2. <div class="pa-3 white">
  3. <m-table
  4. v-loading="loading"
  5. row-key="id"
  6. :items="items"
  7. :headers="headers"
  8. :page-size="total"
  9. :page-current="1"
  10. :total="total"
  11. :default-sort="{ prop: 'sort', order: 'ascending' }"
  12. >
  13. <template #actions-header>
  14. 操作
  15. <m-button class="ml-3" type="orange" icon="el-icon-plus" size="small" @click="onAdd">
  16. 新增
  17. </m-button>
  18. </template>
  19. <template v-slot:hidden="{ row }">
  20. <el-tag
  21. size="small"
  22. :type="row.hidden ? 'success' : 'danger'"
  23. text-color="white"
  24. >
  25. {{ row.hidden ? '已开启' : '已关闭' }}
  26. </el-tag>
  27. </template>
  28. <template #icon="scope">
  29. <i class="mdi" :class="scope.row.icon"></i>
  30. </template>
  31. <template #actions="scope">
  32. <m-button type="primary" class="pa-0" text @click="onEdit(scope.row)">编辑</m-button>
  33. <m-button type="primary" class="pa-0" text @click="onCopy(scope.row)">复制</m-button>
  34. <m-button type="danger" class="pa-0" text @click="onDelete(scope.row)">删除</m-button>
  35. </template>
  36. </m-table>
  37. <menuEdit ref="menuEdit" :title="title" @refresh="initPage"></menuEdit>
  38. </div>
  39. </template>
  40. <script>
  41. import menuEdit from './menuEdit.vue'
  42. import { getRouters, getRoutersDetail } from '@/api/menu'
  43. export default {
  44. name: 'route-manage',
  45. components: { menuEdit },
  46. data () {
  47. return {
  48. headers: [
  49. { label: '菜单名称', prop: 'label', width: 300 },
  50. { label: '图标', prop: 'icon', width: 50 },
  51. { label: '排序', prop: 'sort', width: 50 },
  52. { label: '状态', prop: 'hidden', width: 100, align: 'center' },
  53. { label: '组件路径', prop: 'component', width: 300 },
  54. { label: '权限标识', prop: 'code', width: 300 },
  55. { label: '备注', prop: 'remark' },
  56. { label: '操作', prop: 'actions', width: 200, fixed: 'right' }
  57. ],
  58. items: [],
  59. showParents: false,
  60. show: false,
  61. title: '',
  62. header: [],
  63. total: 0,
  64. orders: [],
  65. loading: true,
  66. itemData: {},
  67. uploadLoading: false,
  68. downloadLoading: false
  69. }
  70. },
  71. created () {
  72. this.initPage()
  73. },
  74. methods: {
  75. async initPage () {
  76. this.loading = true
  77. try {
  78. const { data } = await getRouters({})
  79. this.items = data
  80. this.total = data.length
  81. this.loading = false
  82. } catch (error) {
  83. this.$message.error(error)
  84. }
  85. },
  86. onAdd () {
  87. this.title = '添加菜单'
  88. this.itemData = {}
  89. this.$refs.menuEdit.open({
  90. parentId: 0,
  91. label: null,
  92. type: 0,
  93. path: null,
  94. component: null,
  95. name: null,
  96. code: null,
  97. sort: 0,
  98. hidden: 1,
  99. keepAlive: true,
  100. panorama: false
  101. }, this.items, null)
  102. },
  103. async onEdit ({ id }) {
  104. try {
  105. const { data } = await getRoutersDetail({ id })
  106. this.title = '编辑菜单'
  107. this.itemData = data
  108. const meta = JSON.parse(data.metastr)
  109. this.$refs.menuEdit.open({
  110. parentId: data.parentId,
  111. label: data.label,
  112. type: data.type,
  113. path: data.path,
  114. component: data.component,
  115. name: data.name,
  116. icon: data.icon,
  117. code: data.code,
  118. sort: data.sort,
  119. hidden: data.hidden,
  120. window: meta?.window ?? false,
  121. keepAlive: meta?.keepAlive ?? false,
  122. panorama: meta?.panorama ?? false
  123. }, this.items, data.id)
  124. } catch (error) {
  125. this.$message.error(error)
  126. }
  127. },
  128. async onCopy ({ id }) {
  129. try {
  130. const { data } = await getRoutersDetail({ id })
  131. this.title = '添加菜单'
  132. this.itemData = data
  133. const meta = JSON.parse(data.metastr)
  134. this.$refs.menuEdit.open({
  135. parentId: data.parentId,
  136. label: data.label,
  137. type: data.type,
  138. path: data.path,
  139. component: data.component,
  140. name: data.name,
  141. icon: data.icon,
  142. code: data.code,
  143. sort: data.sort,
  144. hidden: data.hidden,
  145. window: meta?.window ?? false,
  146. keepAlive: meta?.keepAlive ?? false
  147. }, this.items, null)
  148. } catch (error) {
  149. this.$message.error(error)
  150. }
  151. },
  152. onDelete (item) {
  153. this.$confirm(`是否确定删除该选项 ${item.label} 包括所以子项`, '提示')
  154. .then(async () => {
  155. try {
  156. await this.$store.dispatch('menu/deleteMenu', { id: item.id })
  157. this.$message.success('删除成功')
  158. this.initPage()
  159. } catch (error) {
  160. this.$message.error(error)
  161. }
  162. })
  163. .catch(_ => {})
  164. },
  165. async handleCopy ({ id }) {
  166. try {
  167. const { data } = await getRoutersDetail({ id })
  168. const { id: _id, ...obj } = data
  169. this.title = '复制'
  170. this.show = true
  171. this.itemData = obj
  172. } catch (error) {
  173. this.$message.error(error)
  174. }
  175. }
  176. // 导出菜单 数据有问题
  177. // async exportMenu () {
  178. // const date = new Date()
  179. // const time = date.toLocaleString()
  180. // try {
  181. // this.downloadLoading = true
  182. // const { data } = await exportMenu()
  183. // const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' })
  184. // FileSaver.saveAs(blob, `菜单${time}`)
  185. // } catch (error) {
  186. // this.$message.error(error)
  187. // } finally {
  188. // this.downloadLoading = false
  189. // }
  190. // },
  191. // // 导入菜单
  192. // async importMenu (file) {
  193. // // console.log(file)
  194. // const formData = new FormData()
  195. // formData.append('file', file)
  196. // this.uploadLoading = true
  197. // try {
  198. // await importMenu(formData)
  199. // this.$message.success('导入成功')
  200. // } catch (error) {
  201. // this.$message.error(error)
  202. // } finally {
  203. // this.uploadLoading = false
  204. // }
  205. // }
  206. }
  207. }
  208. </script>
  209. <style lang="scss" scoped>
  210. .mdi {
  211. font-size: 1.5em;
  212. }
  213. </style>