menu-list.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. <template>
  2. <div>
  3. <el-breadcrumb separator=">">
  4. <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
  5. <el-breadcrumb-item>
  6. <a href="#">系统管理</a>
  7. </el-breadcrumb-item>
  8. <el-breadcrumb-item>
  9. <a href="/sys/menu">菜单管理</a>
  10. </el-breadcrumb-item>
  11. </el-breadcrumb>
  12. <el-divider></el-divider>
  13. <!--
  14. 要resetFields起作用,必须配置:model和prop
  15. -->
  16. <el-form ref="queryForm" :model="queryModel" inline class="demo-form-inline">
  17. <el-form-item label="菜单名称" prop="menuName">
  18. <el-input type="text" size="mini" v-model="queryModel.menuName"></el-input>
  19. </el-form-item>
  20. <el-form-item label="菜单类型" prop="menuType">
  21. <el-select v-model="queryModel.menuType" size="mini">
  22. <el-option label="后端接口" value="1"></el-option>
  23. <el-option label="前端页面" value="2"></el-option>
  24. </el-select>
  25. </el-form-item>
  26. <el-form-item label="上级菜单" prop="parentId">
  27. <el-select
  28. size="mini"
  29. v-model="queryModel.parentId"
  30. filterable
  31. remote
  32. placeholder="请输入关键词"
  33. :remote-method="queryMenu"
  34. >
  35. <el-option
  36. v-for="menu in queryMenuResult"
  37. :key="menu.id"
  38. :label="menu.menuName"
  39. :value="menu.id"
  40. ></el-option>
  41. </el-select>
  42. </el-form-item>
  43. <el-form-item>
  44. <el-button
  45. type="primary"
  46. size="mini"
  47. icon="ios-search"
  48. @click="changePage(1)"
  49. :loading="loading"
  50. >查询</el-button>&nbsp;
  51. <el-button
  52. type="info"
  53. size="mini"
  54. style="margin-left: 8px"
  55. @click="handleReset('queryForm')"
  56. >重置</el-button>&nbsp;
  57. </el-form-item>
  58. </el-form>
  59. <el-divider></el-divider>
  60. <el-row class="button-group">
  61. <el-button type="primary" size="small" plain icon="el-icon-circle-plus" @click="handleAdd">新增</el-button>
  62. <el-button
  63. type="primary"
  64. size="small"
  65. plain
  66. icon="el-icon-remove"
  67. :disabled="multipleSelection.length==0"
  68. @click="handleBatchDelete"
  69. >删除选中项</el-button>
  70. </el-row>
  71. <div style="min-height:400px;">
  72. <el-table
  73. :data="tableData"
  74. v-loading="loading"
  75. stripe
  76. border
  77. @selection-change="handleSelectionChange"
  78. >
  79. <el-table-column type="selection" width="55"></el-table-column>
  80. <el-table-column
  81. prop="menuName"
  82. sort-by="menu_name"
  83. label="菜单名称"
  84. width="180"
  85. >
  86. <template slot-scope="{row}">
  87. <i :class="row.icon"></i><span v-html="row.menuName"></span>
  88. </template>
  89. </el-table-column>
  90. <el-table-column
  91. prop="parentName"
  92. sort-by="parent_id"
  93. label="上级菜单"
  94. width="180"
  95. ></el-table-column>
  96. <el-table-column prop="sortNo" label="排序号" :sortable="true" width="180"></el-table-column>
  97. <el-table-column prop="menuType" label="菜单类型" :sortable="true" width="180">
  98. <template slot-scope="{row}">{{row.menuType == 1 ? "后端接口" : "前端页面"}}</template>
  99. </el-table-column>
  100. <el-table-column prop="menuUrl" label="菜单地址" :sortable="true" width="180"></el-table-column>
  101. <el-table-column prop="createTime" label="创建时间" :sortable="true" width="180"></el-table-column>
  102. <el-table-column prop="updateTime" label="更新时间" :sortable="true" width="180"></el-table-column>
  103. <el-table-column label="操作" width="250" fixed="right">
  104. <template slot-scope="{row}">
  105. <el-row>
  106. <el-col :span="12">
  107. <el-button size="mini" type="text" @click="showSubmenu(row)">下级菜单</el-button>
  108. </el-col>
  109. <el-col :span="12">
  110. <el-button size="mini" type="text" @click="addSubmenu(row)">新增子菜单</el-button>
  111. </el-col>
  112. </el-row>
  113. <el-row>
  114. <el-col :span="12">
  115. <el-button size="mini" type="text" @click="handleEdit(row)">编辑</el-button>
  116. </el-col>
  117. <el-col :span="12">
  118. <el-button size="mini" type="text" @click="handleDelete(row)">删除</el-button>
  119. </el-col>
  120. </el-row>
  121. </template>
  122. </el-table-column>
  123. </el-table>
  124. </div>
  125. <el-pagination
  126. :current-page.sync="pageIndex"
  127. :total="totalElements"
  128. :page-sizes="pageSizeList"
  129. @current-change="changePage"
  130. @size-change="pageSizeChange"
  131. layout="total, sizes, prev, pager, next, jumper"
  132. ></el-pagination>
  133. <menu-detail
  134. v-if="showDetailModal"
  135. @close="onDetailModalClose"
  136. :menuId="menuId"
  137. :modalTitle="modalTitle"
  138. :parentMenu="parentMenu"
  139. ></menu-detail>
  140. </div>
  141. </template>
  142. <script>
  143. import Constant from "@/constant";
  144. import MenuDetail from "./menu-detail";
  145. import menuApi from "@/api/sys/menu";
  146. import NProgress from "nprogress"; // progress bar
  147. import "nprogress/nprogress.css"; // progress bar style
  148. export default {
  149. data() {
  150. var self = this;
  151. return {
  152. queryModel: {
  153. menuName: "",
  154. menuType: "",
  155. parentId: ""
  156. },
  157. mLoading: false,
  158. modalTitle: "",
  159. loading: false,
  160. tableData: [],
  161. pageIndex: 1,
  162. pageSize: 10,
  163. totalPages: 0,
  164. totalElements: 0,
  165. field: "",
  166. direction: "",
  167. pageSizeList: [10, 20, 30],
  168. multipleSelection: [],
  169. showDetailModal: false,
  170. menuId: "",
  171. queryMenuResult: [],
  172. parentMenu: {}
  173. };
  174. },
  175. methods: {
  176. changePage(pageIndex) {
  177. var self = this;
  178. self.loading = true;
  179. self.pageIndex = pageIndex;
  180. var formData = new FormData();
  181. formData.append("pageIndex", self.pageIndex);
  182. formData.append("pageSize", self.pageSize);
  183. formData.append("parentId", self.queryModel.parentId);
  184. formData.append("menuName", self.queryModel.menuName);
  185. formData.append("menuType", self.queryModel.menuType);
  186. if (this.field != null) {
  187. formData.append("field", this.field);
  188. }
  189. if (this.direction != null) {
  190. formData.append("direction", this.direction);
  191. }
  192. menuApi
  193. .pageList(formData)
  194. .then(function(response) {
  195. self.loading = false;
  196. var jsonData = response.data;
  197. if(jsonData.result){
  198. var pageInfo = jsonData.data;
  199. self.tableData = pageInfo.data;
  200. self.totalPages = pageInfo.totalPages;
  201. self.totalElements = pageInfo.recordsTotal;
  202. }
  203. else {
  204. self.$message({
  205. message: jsonData.message + "",
  206. type: "warning"
  207. });
  208. }
  209. })
  210. .catch(error => {
  211. self.loading = false;
  212. // self.$message.error(error + "");
  213. });
  214. },
  215. pageSizeChange(pageSize) {
  216. this.pageSize = pageSize;
  217. this.$nextTick(()=>{
  218. this.changePage(this.pageIndex);
  219. });
  220. },
  221. sortChange(data) {
  222. this.field = data.column.field;
  223. this.direction = data.order;
  224. this.changePage(this.pageIndex);
  225. },
  226. handleSelectionChange(val) {
  227. this.multipleSelection = val;
  228. },
  229. handleReset(name) {
  230. this.$refs[name].resetFields();
  231. this.queryMenu();
  232. },
  233. handleAdd() {
  234. var self = this;
  235. self.modalTitle = "新增";
  236. self.menuId = "";
  237. self.parentMenu = {};
  238. self.showDetailModal = true;
  239. },
  240. handleEdit(record) {
  241. var self = this;
  242. self.modalTitle = "编辑";
  243. self.menuId = record.id;
  244. self.parentMenu = {};
  245. self.showDetailModal = true;
  246. },
  247. handleDelete(record) {
  248. var self = this;
  249. self
  250. .$confirm("是否确认删除?", "提示", {
  251. confirmButtonText: "确定",
  252. cancelButtonText: "取消",
  253. type: "warning"
  254. })
  255. .then(() => {
  256. menuApi.remove(record.id).then(function(response) {
  257. var jsonData = response.data;
  258. if (jsonData.result) {
  259. // var index = self.tableData.indexOf(record);
  260. // self.tableData.splice(index, 1);
  261. self.changePage(self.pageIndex);
  262. self.$message({
  263. type: "success",
  264. message: "删除成功!"
  265. });
  266. }
  267. });
  268. });
  269. },
  270. handleBatchDelete() {
  271. var self = this;
  272. var idList = this.multipleSelection.map(record => {
  273. return record.id;
  274. });
  275. this.$confirm("是否确认删除选中项?", "提示", {
  276. confirmButtonText: "确定",
  277. cancelButtonText: "取消",
  278. type: "warning"
  279. }).then(() => {
  280. menuApi.batchRemove(idList).then(function(response) {
  281. var jsonData = response.data;
  282. if (jsonData.result) {
  283. self.changePage(self.pageIndex);
  284. self.$message({
  285. type: "success",
  286. message: "删除成功!"
  287. });
  288. }
  289. });
  290. });
  291. },
  292. onDetailModalClose(refreshed){
  293. this.showDetailModal = false;
  294. if(refreshed){
  295. this.changePage(this.pageIndex);
  296. }
  297. },
  298. queryMenu(keywords) {
  299. var formData = new FormData();
  300. formData.append("keywords",keywords);
  301. formData.append("limit",10);
  302. return menuApi.query(formData).then(response=>{
  303. var jsonData = response.data;
  304. if(jsonData.result){
  305. this.queryMenuResult = jsonData.data;
  306. }
  307. else{
  308. this.$message.error(jsonData.message + "");
  309. }
  310. });
  311. },
  312. showSubmenu(row){
  313. this.queryMenuResult.length=0; //清空
  314. this.queryMenuResult.push(row);
  315. this.queryModel.menuName = "";
  316. this.queryModel.parentId = row.id;
  317. this.changePage(1);
  318. },
  319. addSubmenu(row){
  320. var self = this;
  321. self.modalTitle = "新增";
  322. self.menuId = "";
  323. self.parentMenu = row;
  324. self.showDetailModal = true;
  325. }
  326. },
  327. mounted: function() {
  328. this.changePage(1);
  329. this.queryMenu();
  330. },
  331. components: {
  332. "menu-detail": MenuDetail
  333. }
  334. };
  335. </script>
  336. <style lang="scss" scoped>
  337. .el-breadcrumb {
  338. margin: 10px;
  339. line-height: 20px;
  340. }
  341. .el-divider {
  342. margin: 5px 0;
  343. }
  344. .demo-form-inline {
  345. margin-left: 10px;
  346. text-align: left;
  347. }
  348. .button-group {
  349. padding: 10px;
  350. text-align: left;
  351. }
  352. </style>