menu.vue 7.2 KB

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