index.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. <template>
  2. <div>
  3. <x-crud @load="onLoad">
  4. <template #table-column-icon="{scope}">
  5. <icon-svg :name="scope.row.icon" size="20px"></icon-svg>
  6. </template>
  7. <template #table-column-perms="{scope}">
  8. <el-tag
  9. size="medium"
  10. v-for="(item, index) in scope.row.permList"
  11. :key="index"
  12. style="margin: 2px"
  13. >{{ item }}</el-tag
  14. >
  15. </template>
  16. <template #table-column-router="{scope}">
  17. <el-link type="primary" :href="scope.row.router" v-if="scope.row.type == 1">{{
  18. scope.row.router
  19. }}</el-link>
  20. <span v-else>{{ scope.row.router }}</span>
  21. </template>
  22. <template #table-column-keepAlive="{scope}">
  23. <template v-if="scope.row.type == 1">
  24. <i class="el-icon-check" v-if="scope.row.keepAlive"></i>
  25. <i class="el-icon-close" v-else></i>
  26. </template>
  27. </template>
  28. <template #slot-column-op="{scope}">
  29. <el-button
  30. type="text"
  31. size="mini"
  32. @click="upsertAppend(scope.row)"
  33. v-if="scope.row.type != 2"
  34. >新增</el-button
  35. >
  36. </template>
  37. </x-crud>
  38. <cl-context-menu ref="context-menu"></cl-context-menu>
  39. </div>
  40. </template>
  41. <script>
  42. import { deepTree } from '@/cool/utils/index';
  43. export default {
  44. data() {
  45. return {
  46. crud: null
  47. };
  48. },
  49. methods: {
  50. onLoad({ ctx, app }) {
  51. this.crud = app;
  52. ctx.service(this.$service.system.menu)
  53. .set('dict', { api: { page: 'list' } })
  54. .set('table', {
  55. columns: [
  56. {
  57. prop: 'name',
  58. label: '名称',
  59. width: 200
  60. },
  61. {
  62. prop: 'icon',
  63. label: '图标',
  64. align: 'center',
  65. width: 80
  66. },
  67. {
  68. prop: 'type',
  69. label: '类型',
  70. align: 'center',
  71. width: 100,
  72. dict: [
  73. {
  74. label: '目录',
  75. value: 0
  76. },
  77. {
  78. label: '菜单',
  79. value: 1
  80. },
  81. {
  82. label: '权限',
  83. value: 2
  84. }
  85. ]
  86. },
  87. {
  88. prop: 'router',
  89. label: '节点路由',
  90. align: 'center',
  91. 'min-width': 160
  92. },
  93. {
  94. prop: 'keepAlive',
  95. label: '路由缓存',
  96. align: 'center',
  97. width: 100
  98. },
  99. {
  100. prop: 'viewPath',
  101. label: '文件路径',
  102. align: 'center',
  103. 'min-width': 200,
  104. 'show-overflow-tooltip': true
  105. },
  106. {
  107. prop: 'perms',
  108. label: '权限',
  109. 'header-align': 'center',
  110. 'min-width': 300
  111. },
  112. {
  113. prop: 'orderNum',
  114. label: '排序号',
  115. align: 'center',
  116. width: 100
  117. },
  118. {
  119. prop: 'updateTime',
  120. label: '更新时间',
  121. align: 'center',
  122. sortable: true,
  123. width: 180
  124. }
  125. ],
  126. props: {
  127. 'row-key': 'id'
  128. },
  129. on: {
  130. 'row-click': (row, column) => {
  131. if (column.property && row.children) {
  132. app.refs('table').toggleRowExpansion(row);
  133. }
  134. },
  135. 'row-contextmenu': (row, column, event) => {
  136. let list = [
  137. {
  138. label: '编辑',
  139. callback: (e, close) => {
  140. app.edit(row);
  141. close();
  142. }
  143. },
  144. {
  145. label: '删除',
  146. callback: (e, close) => {
  147. app.delete(row);
  148. close();
  149. }
  150. }
  151. ];
  152. if (row.type != 2) {
  153. list.unshift({
  154. label: '新增',
  155. callback: (e, close) => {
  156. this.upsertAppend(row);
  157. close();
  158. }
  159. });
  160. }
  161. if (row.type == 1) {
  162. list.push({
  163. label: '权限',
  164. callback: (e, close) => {
  165. this.setPermission(row);
  166. close();
  167. }
  168. });
  169. }
  170. this.$refs['context-menu'].open(event, {
  171. list
  172. });
  173. event.preventDefault();
  174. }
  175. },
  176. op: {
  177. props: {
  178. width: '200'
  179. },
  180. layout: ['slot-column-op', 'edit', 'delete']
  181. }
  182. })
  183. .set('upsert', {
  184. props: {
  185. width: '600px'
  186. },
  187. items: [
  188. {
  189. prop: 'type',
  190. value: 0,
  191. label: '节点类型',
  192. span: 24,
  193. component: {
  194. name: 'el-radio-group',
  195. options: [
  196. {
  197. label: '目录',
  198. value: 0
  199. },
  200. {
  201. label: '菜单',
  202. value: 1
  203. },
  204. {
  205. label: '权限',
  206. value: 2
  207. }
  208. ],
  209. on: {
  210. change: index => {
  211. this.changeType(index);
  212. }
  213. }
  214. }
  215. },
  216. {
  217. prop: 'name',
  218. label: '节点名称',
  219. span: 24,
  220. component: {
  221. name: 'el-input',
  222. attrs: {
  223. placeholder: '请输入节点名称'
  224. }
  225. },
  226. rules: {
  227. required: true,
  228. message: '名称不能为空'
  229. }
  230. },
  231. {
  232. prop: 'parentId',
  233. label: '上级节点',
  234. span: 24,
  235. component: {
  236. name: 'cl-menu-tree'
  237. }
  238. },
  239. {
  240. prop: 'router',
  241. label: '节点路由',
  242. span: 24,
  243. hidden: true,
  244. component: {
  245. name: 'el-input',
  246. attrs: {
  247. placeholder: '请输入节点路由'
  248. }
  249. }
  250. },
  251. {
  252. prop: 'keepAlive',
  253. value: true,
  254. label: '路由缓存',
  255. span: 24,
  256. component: {
  257. name: 'el-radio-group',
  258. options: [
  259. {
  260. label: '开启',
  261. value: true
  262. },
  263. {
  264. label: '关闭',
  265. value: false
  266. }
  267. ]
  268. }
  269. },
  270. {
  271. prop: 'viewPath',
  272. label: '文件路径',
  273. span: 24,
  274. hidden: true,
  275. component: {
  276. name: 'cl-menu-file-path'
  277. }
  278. },
  279. {
  280. prop: 'icon',
  281. label: '节点图标',
  282. span: 24,
  283. component: {
  284. name: 'cl-menu-icons'
  285. }
  286. },
  287. {
  288. prop: 'orderNum',
  289. label: '排序号',
  290. span: 24,
  291. component: {
  292. name: 'el-input-number',
  293. props: {
  294. placeholder: '请填写排序号',
  295. min: 0,
  296. max: 99,
  297. 'controls-position': 'right'
  298. }
  299. }
  300. },
  301. {
  302. prop: 'perms',
  303. label: '权限',
  304. span: 24,
  305. hidden: true,
  306. component: {
  307. name: 'cl-menu-perms'
  308. }
  309. }
  310. ]
  311. })
  312. .set('layout', [['refresh-btn', 'add-btn'], ['data-table']])
  313. .on('refresh', (params, { render }) => {
  314. this.$service.system.menu.list().then(list => {
  315. list.map(e => {
  316. e.permList = e.perms ? e.perms.split(',') : [];
  317. });
  318. render(deepTree(list));
  319. this.$store.dispatch('permMenu');
  320. });
  321. })
  322. .on('open', (status, data) => {
  323. this.changeType(data ? data.type : 0);
  324. })
  325. .done();
  326. app.refresh();
  327. },
  328. changeType(index) {
  329. this.crud.setData('upsert.items[prop:router].hidden', index != 1);
  330. this.crud.setData('upsert.items[prop:icon].hidden', index == 2);
  331. this.crud.setData('upsert.items[prop:viewPath].hidden', index != 1);
  332. this.crud.setData('upsert.items[prop:keepAlive].hidden', index != 1);
  333. this.crud.setData('upsert.items[prop:perms].hidden', index != 2);
  334. },
  335. upsertAppend({ type, id }) {
  336. this.crud.append({
  337. parentId: id,
  338. type: type + 1
  339. });
  340. },
  341. setPermission({ id }) {
  342. this.crud.append({
  343. parentId: id,
  344. type: 2
  345. });
  346. },
  347. toUrl(url) {
  348. this.$router.push(url);
  349. }
  350. }
  351. };
  352. </script>