topmenu.vue 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. <template>
  2. <basic-container>
  3. <avue-crud :option="option"
  4. :table-loading="loading"
  5. :data="data"
  6. :page.sync="page"
  7. :permission="permissionList"
  8. :before-open="beforeOpen"
  9. v-model="form"
  10. ref="crud"
  11. @row-update="rowUpdate"
  12. @row-save="rowSave"
  13. @row-del="rowDel"
  14. @search-change="searchChange"
  15. @search-reset="searchReset"
  16. @selection-change="selectionChange"
  17. @current-change="currentChange"
  18. @size-change="sizeChange"
  19. @refresh-change="refreshChange"
  20. @on-load="onLoad">
  21. <template slot="menuLeft">
  22. <el-button type="danger"
  23. size="small"
  24. icon="el-icon-delete"
  25. plain
  26. v-if="permission.topmenu_delete"
  27. @click="handleDelete">删 除
  28. </el-button>
  29. <el-button size="small"
  30. icon="el-icon-delete"
  31. @click="handleMenuSetting"
  32. v-if="permission.topmenu_setting"
  33. plain>菜单配置
  34. </el-button>
  35. </template>
  36. <template slot-scope="{row}" slot="source">
  37. <div style="text-align:center">
  38. <i :class="row.source"></i>
  39. </div>
  40. </template>
  41. <template slot="sort" slot-scope="{row}" >
  42. <el-input-number v-model="row.sort" @change="sortChange(row)" :min="1" :max="100"></el-input-number>
  43. </template>
  44. </avue-crud>
  45. <el-dialog title="下级菜单配置"
  46. append-to-body
  47. :visible.sync="box"
  48. width="345px">
  49. <el-tree :data="menuGrantList"
  50. show-checkbox
  51. node-key="id"
  52. ref="treeMenu"
  53. :default-checked-keys="menuTreeObj"
  54. :props="props">
  55. </el-tree>
  56. <span slot="footer"
  57. class="dialog-footer">
  58. <el-button @click="box = false">取 消</el-button>
  59. <el-button type="primary"
  60. @click="submit">确 定</el-button>
  61. </span>
  62. </el-dialog>
  63. </basic-container>
  64. </template>
  65. <script>
  66. import {getList, getDetail, add, update, remove, grant, grantTree, getTopTree} from "@/api/system/topmenu";
  67. import {mapGetters} from "vuex";
  68. import iconList from "@/config/iconList";
  69. export default {
  70. data() {
  71. return {
  72. form: {},
  73. box: false,
  74. query: {},
  75. loading: true,
  76. props: {
  77. label: "title",
  78. value: "key"
  79. },
  80. page: {
  81. pageSize: 10,
  82. currentPage: 1,
  83. total: 0
  84. },
  85. selectionList: [],
  86. menuGrantList: [],
  87. menuTreeObj: [],
  88. option: {
  89. height: 'auto',
  90. calcHeight: 30,
  91. tip: false,
  92. searchShow: true,
  93. searchMenuSpan: 6,
  94. border: true,
  95. index: true,
  96. viewBtn: true,
  97. selection: true,
  98. dialogWidth: 900,
  99. dialogClickModal: false,
  100. column: [
  101. {
  102. label: "菜单名",
  103. prop: "name",
  104. search: true,
  105. rules: [{
  106. required: true,
  107. message: "请输入菜单名",
  108. trigger: "blur"
  109. }]
  110. },
  111. {
  112. label: "菜单图标",
  113. prop: "source",
  114. type: "icon",
  115. slot: true,
  116. iconList: iconList,
  117. rules: [
  118. {
  119. required: true,
  120. message: "请输入菜单图标",
  121. trigger: "click"
  122. }
  123. ]
  124. },
  125. {
  126. label: "菜单编号",
  127. prop: "code",
  128. search: true,
  129. rules: [{
  130. required: true,
  131. message: "请输入菜单编号",
  132. trigger: "blur"
  133. }]
  134. },
  135. {
  136. label: "菜单排序",
  137. prop: "sort",
  138. type: "number",
  139. slot: true,
  140. rules: [{
  141. required: true,
  142. message: "请输入菜单排序",
  143. trigger: "blur"
  144. }]
  145. },
  146. ]
  147. },
  148. data: []
  149. };
  150. },
  151. computed: {
  152. ...mapGetters(["permission"]),
  153. permissionList() {
  154. return {
  155. addBtn: this.vaildData(this.permission.topmenu_add, false),
  156. viewBtn: this.vaildData(this.permission.topmenu_view, false),
  157. delBtn: this.vaildData(this.permission.topmenu_delete, false),
  158. editBtn: this.vaildData(this.permission.topmenu_edit, false)
  159. };
  160. },
  161. ids() {
  162. let ids = [];
  163. this.selectionList.forEach(ele => {
  164. ids.push(ele.id);
  165. });
  166. return ids.join(",");
  167. },
  168. idsArray() {
  169. let ids = [];
  170. this.selectionList.forEach(ele => {
  171. ids.push(ele.id);
  172. });
  173. return ids;
  174. }
  175. },
  176. methods: {
  177. submit() {
  178. const menuList = this.$refs.treeMenu.getCheckedKeys();
  179. grant(this.idsArray, menuList).then(() => {
  180. this.box = false;
  181. this.$message({
  182. type: "success",
  183. message: "操作成功!"
  184. });
  185. this.onLoad(this.page);
  186. });
  187. },
  188. rowSave(row, done, loading) {
  189. add(row).then(() => {
  190. this.onLoad(this.page);
  191. this.$message({
  192. type: "success",
  193. message: "操作成功!"
  194. });
  195. done();
  196. }, error => {
  197. window.console.log(error);
  198. loading();
  199. });
  200. },
  201. rowUpdate(row, index, done, loading) {
  202. update(row).then(() => {
  203. this.onLoad(this.page);
  204. this.$message({
  205. type: "success",
  206. message: "操作成功!"
  207. });
  208. done();
  209. }, error => {
  210. window.console.log(error);
  211. loading();
  212. });
  213. },
  214. rowDel(row) {
  215. this.$confirm("确定将选择数据删除?", {
  216. confirmButtonText: "确定",
  217. cancelButtonText: "取消",
  218. type: "warning"
  219. })
  220. .then(() => {
  221. return remove(row.id);
  222. })
  223. .then(() => {
  224. this.onLoad(this.page);
  225. this.$message({
  226. type: "success",
  227. message: "操作成功!"
  228. });
  229. });
  230. },
  231. handleDelete() {
  232. if (this.selectionList.length === 0) {
  233. this.$message.warning("请选择至少一条数据");
  234. return;
  235. }
  236. this.$confirm("确定将选择数据删除?", {
  237. confirmButtonText: "确定",
  238. cancelButtonText: "取消",
  239. type: "warning"
  240. })
  241. .then(() => {
  242. return remove(this.ids);
  243. })
  244. .then(() => {
  245. this.onLoad(this.page);
  246. this.$message({
  247. type: "success",
  248. message: "操作成功!"
  249. });
  250. this.$refs.crud.toggleSelection();
  251. });
  252. },
  253. handleMenuSetting() {
  254. if (this.selectionList.length !== 1) {
  255. this.$message.warning("只能选择一条数据");
  256. return;
  257. }
  258. this.menuTreeObj = [];
  259. grantTree()
  260. .then(res => {
  261. this.menuGrantList = res.data.data.menu;
  262. getTopTree(this.ids).then(res => {
  263. this.menuTreeObj = res.data.data.menu;
  264. this.box = true;
  265. });
  266. });
  267. },
  268. beforeOpen(done, type) {
  269. if (["edit", "view"].includes(type)) {
  270. getDetail(this.form.id).then(res => {
  271. this.form = res.data.data;
  272. });
  273. }
  274. done();
  275. },
  276. sortChange(row) {
  277. update(row).then(() => {
  278. this.onLoad(this.page);
  279. }, error => {
  280. window.console.log(error);
  281. });
  282. },
  283. searchReset() {
  284. this.query = {};
  285. this.onLoad(this.page);
  286. },
  287. searchChange(params, done) {
  288. this.query = params;
  289. this.page.currentPage = 1;
  290. this.onLoad(this.page, params);
  291. done();
  292. },
  293. selectionChange(list) {
  294. this.selectionList = list;
  295. },
  296. selectionClear() {
  297. this.selectionList = [];
  298. this.$refs.crud.toggleSelection();
  299. },
  300. currentChange(currentPage) {
  301. this.page.currentPage = currentPage;
  302. },
  303. sizeChange(pageSize) {
  304. this.page.pageSize = pageSize;
  305. },
  306. refreshChange() {
  307. this.onLoad(this.page, this.query);
  308. },
  309. onLoad(page, params = {}) {
  310. this.loading = true;
  311. getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
  312. const data = res.data.data;
  313. this.page.total = data.total;
  314. this.data = data.records;
  315. this.loading = false;
  316. this.selectionClear();
  317. });
  318. }
  319. }
  320. };
  321. </script>
  322. <style>
  323. .none-border {
  324. border: 0;
  325. background-color: transparent !important;
  326. }
  327. </style>