menu.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  1. <template>
  2. <div class="menu">
  3. <div class="menu-head">
  4. <a-input placeholder="名称" style="width: 300px"></a-input>
  5. <a-button type="primary">查询</a-button>
  6. <a-button type="primary" style="background: green" @click="addMenu"
  7. >新增</a-button
  8. >
  9. </div>
  10. <a-spin :spinning="loading">
  11. <a-table
  12. :columns="columns"
  13. :dataSource="tableList"
  14. :pagination="false"
  15. style="background: #fff"
  16. :customRow="customRow"
  17. rowKey="id"
  18. >
  19. <div class="operation-list" slot="operation" slot-scope="text, record">
  20. <a-button type="danger" @click="delMenu({ text, record })"
  21. >删除
  22. </a-button>
  23. <a-button type="primary" @click="editMenu({ text, record })"
  24. >编辑</a-button
  25. >
  26. </div>
  27. </a-table>
  28. </a-spin>
  29. <a-modal
  30. v-model="visible"
  31. :title="title"
  32. @ok="handleOk"
  33. layout="inline"
  34. width="50%"
  35. :confirm-loading="confirmLoading"
  36. >
  37. <a-form :layout="formLayout" :form="form" :rules="rules">
  38. <a-form-item
  39. label="菜单类型"
  40. v-bind="formItemLayout"
  41. v-show="!authType"
  42. >
  43. <a-radio-group :default-value="'目录'" v-model="dataForm.type">
  44. <a-radio
  45. v-for="(item, index) in menuTypeList"
  46. :key="index"
  47. :value="index"
  48. >
  49. {{ item }}
  50. </a-radio>
  51. </a-radio-group>
  52. </a-form-item>
  53. <a-form-item
  54. :label="menuTypeList[dataForm.type] + '名称'"
  55. v-bind="formItemLayout"
  56. v-show="!authType"
  57. >
  58. <a-input
  59. :placeholder="menuTypeList[dataForm.type] + '名称'"
  60. v-decorator="[
  61. 'name',
  62. {
  63. rules: [
  64. {
  65. required: true,
  66. message: '请输入' + menuTypeList[dataForm.type] + '名称',
  67. },
  68. ],
  69. },
  70. ]"
  71. />
  72. </a-form-item>
  73. <a-form-item
  74. label="上级菜单"
  75. v-bind="formItemLayout"
  76. v-show="!authType"
  77. >
  78. <a-popover placement="rightTop">
  79. <a-input
  80. placeholder="请选择上级菜单"
  81. :readonly="true"
  82. v-model="dataForm.parentName"
  83. />
  84. <template slot="content">
  85. <a-tree
  86. :tree-data="tableList"
  87. :title="'11'"
  88. :replaceFields="replaceFields"
  89. @select="onSelect"
  90. >
  91. <template slot="custom" slot-scope="item">
  92. <span>{{ item }}</span>
  93. <!-- <span style="color: #f50">({{ item.num }})</span> -->
  94. </template>
  95. </a-tree>
  96. </template>
  97. </a-popover>
  98. </a-form-item>
  99. <a-form-item
  100. label="授权标识"
  101. v-bind="formItemLayout"
  102. v-show="dataForm.type == 1 && !authType"
  103. >
  104. <a-input placeholder="请输入授权标识" v-model="dataForm.perms" />
  105. </a-form-item>
  106. <a-form-item
  107. label="菜单路由"
  108. v-bind="formItemLayout"
  109. v-show="dataForm.type != 2 && !authType"
  110. >
  111. <a-input
  112. placeholder="请输入菜单路由"
  113. v-decorator="[
  114. 'url',
  115. {
  116. rules: [
  117. {
  118. required: true,
  119. message: '请输入菜单名称',
  120. },
  121. ],
  122. },
  123. ]"
  124. />
  125. </a-form-item>
  126. <a-form-item
  127. label="排序编号"
  128. v-bind="formItemLayout"
  129. v-show="!authType"
  130. >
  131. <a-input-number
  132. id="请输入排序编号"
  133. v-model="dataForm.orderNum"
  134. :min="0"
  135. />
  136. </a-form-item>
  137. <a-form-item
  138. label="菜单图标"
  139. v-bind="formItemLayout"
  140. v-show="!authType"
  141. >
  142. <a-input
  143. placeholder="菜单图标名称(如:fa fa-home fa-lg)"
  144. v-model="dataForm.icon"
  145. />
  146. </a-form-item>
  147. <!-- 此处是数据权限 -->
  148. <a-form-item label="接口地址" v-bind="formItemLayout" v-show="authType">
  149. <a-input placeholder="接口地址" v-model="authPermissions.url" />
  150. </a-form-item>
  151. <a-form-item
  152. label="是否自定义脚本"
  153. v-bind="formItemLayout"
  154. v-show="authType"
  155. >
  156. <a-switch
  157. checked-children="是"
  158. un-checked-children="否"
  159. v-model="authPermissions.customScriptFlag"
  160. ></a-switch>
  161. <!-- {{ authPermissions.customScriptFlag }} -->
  162. </a-form-item>
  163. <a-form-item
  164. label="数据权限分类"
  165. v-bind="formItemLayout"
  166. v-show="authType && !authPermissions.customScriptFlag"
  167. >
  168. <a-select v-model="authPermissions.dataPermissionId">
  169. <a-select-option
  170. v-for="item in authList"
  171. :key="item.id"
  172. :value="item.id"
  173. >{{ item.label }}</a-select-option
  174. >
  175. </a-select>
  176. </a-form-item>
  177. <a-form-item
  178. label="脚本"
  179. v-bind="formItemLayout"
  180. v-show="authType && authPermissions.customScriptFlag"
  181. >
  182. <a-input
  183. placeholder="脚本内容"
  184. v-model="dataForm.icon"
  185. type="textarea"
  186. />
  187. </a-form-item>
  188. </a-form>
  189. </a-modal>
  190. </div>
  191. </template>
  192. <script>
  193. const columns = [
  194. {
  195. title: "ID",
  196. dataIndex: "id",
  197. },
  198. {
  199. title: "名称",
  200. dataIndex: "name",
  201. },
  202. {
  203. title: "图标",
  204. dataIndex: "icon",
  205. },
  206. {
  207. title: "类型",
  208. dataIndex: "type",
  209. scopedSlots: { customRender: "type" },
  210. },
  211. {
  212. title: "上级菜单",
  213. dataIndex: "parentName",
  214. scopedSlots: { customRender: "parentName" },
  215. },
  216. {
  217. title: "授权标识",
  218. dataIndex: "perms",
  219. },
  220. {
  221. title: "排序",
  222. dataIndex: "orderNum",
  223. },
  224. {
  225. title: "操作",
  226. key: "operation",
  227. scopedSlots: { customRender: "operation" },
  228. },
  229. ];
  230. export default {
  231. components: {},
  232. data() {
  233. return {
  234. visible: false,
  235. confirmLoading: false,
  236. title: "",
  237. formLayout: "horizontal",
  238. menuTypeList: ["目录", "菜单", "按钮"],
  239. replaceFields: {
  240. children: "children",
  241. title: "name",
  242. key: "id",
  243. },
  244. form: this.$form.createForm(this, { name: "dynamic_rule" }),
  245. rules: {
  246. requiredField: [
  247. { required: true, message: "请输入必填项", trigger: "blur" },
  248. ],
  249. },
  250. dataForm: {
  251. id: 0,
  252. type: 1,
  253. name: "",
  254. parentId: 0,
  255. parentName: "",
  256. url: "",
  257. perms: "",
  258. orderNum: 0,
  259. icon: "",
  260. },
  261. formItemLayout: {
  262. labelCol: {
  263. xs: { span: 5 },
  264. sm: { span: 5 },
  265. },
  266. wrapperCol: {
  267. xs: { span: 24 },
  268. sm: { span: 16 },
  269. },
  270. },
  271. menuList: [],
  272. columns,
  273. tableList: [],
  274. loading: false,
  275. resetForm: {},
  276. authType: false,
  277. authList: [],
  278. authPermissions: {
  279. customScriptFlag: 0,
  280. dataPermissionId: "",
  281. id: undefined,
  282. menuId: 0,
  283. scriptContent: "",
  284. url: "",
  285. },
  286. };
  287. },
  288. created() {
  289. this.getList();
  290. this.resetForm = { ...this.dataForm };
  291. this.getAuthList();
  292. },
  293. // watch: {
  294. // dataForm(val) {
  295. // console.log(val);
  296. // this.form.updateFields({
  297. // name: this.$form.createFormField({
  298. // ...this.username,
  299. // value: this.username.value,
  300. // }),
  301. // });
  302. // },
  303. // },
  304. mounted() {},
  305. methods: {
  306. customRow(record, index) {
  307. console.log(record, index);
  308. return {
  309. style: {
  310. cursor: "move",
  311. },
  312. // 鼠标移入
  313. onMouseenter: (event) => {
  314. // 兼容IE
  315. var ev = event || window.event;
  316. ev.target.draggable = true;
  317. },
  318. // 开始拖拽
  319. onDragstart: (event) => {
  320. console.log(event);
  321. // 兼容IE
  322. var ev = event || window.event;
  323. // 阻止冒泡
  324. ev.stopPropagation();
  325. // 得到源目标数据
  326. this.sourceObj = record;
  327. },
  328. // 拖动元素经过的元素
  329. onDragover: (event) => {
  330. // 兼容 IE
  331. var ev = event || window.event;
  332. // 阻止默认行为
  333. ev.preventDefault();
  334. },
  335. // 鼠标松开
  336. onDrop: (event) => {
  337. // 兼容IE
  338. var ev = event || window.event;
  339. // 阻止冒泡
  340. ev.stopPropagation();
  341. // 得到目标数据
  342. this.targetObj = record;
  343. console.log(this.sourceObj, this.targetObj);
  344. const tempDta = this.data;
  345. tempDta[this.targetObj.weight] = this.sourceObj;
  346. tempDta[this.sourceObj.weight] = this.targetObj;
  347. let weightList = [];
  348. tempDta.forEach((item, index) => {
  349. item.weight = index;
  350. weightList.push({
  351. id: item.id,
  352. weight: index,
  353. });
  354. });
  355. // this.handleWeightModify(weightList); // 更改顺序接口
  356. },
  357. };
  358. },
  359. getAuthList() {
  360. this.$API.sysManage.getAuthModule("sjqx").then((res) => {
  361. if (res.data.code === 200) {
  362. this.authList = [...res.data.data];
  363. }
  364. });
  365. },
  366. delMenu(item, type) {
  367. this.dataForm = { ...item.record };
  368. let that = this;
  369. this.$confirm({
  370. title: "确认删除吗?",
  371. onOk() {
  372. if (type) {
  373. that.$API.sysManage
  374. .removeMenuAuth({ menuId: item.record.id })
  375. .then((res) => {
  376. if (res.data.code === 200) {
  377. that.$message.success("操作成功");
  378. that.loading = false;
  379. that.getList();
  380. }
  381. });
  382. } else
  383. that.$API.sysManage
  384. .delMenuItem([{ id: item.record.id }])
  385. .then((res) => {
  386. if (res.data.code === 200) {
  387. that.$message.success("操作成功");
  388. that.loading = false;
  389. that.getList();
  390. }
  391. });
  392. },
  393. });
  394. // this.$API.sysManage.delMenuItem([{ id: item.record.id }]).then((res) => {
  395. // if (res.data.code === 200) {
  396. // this.getList();
  397. // }
  398. // });
  399. },
  400. editMenu(item, type) {
  401. this.title = "编辑";
  402. this.visible = true;
  403. this.$nextTick(() => {
  404. this.dataForm = { ...item.record };
  405. this.form.setFieldsValue({ ["name"]: item.record.name });
  406. this.form.setFieldsValue({ ["url"]: item.record.url });
  407. });
  408. if (type) {
  409. this.authType = true;
  410. this.authPermissions.menuId = item.record.id;
  411. this.$API.sysManage
  412. .getMenuAuthItem({ menuId: item.record.id })
  413. .then((res) => {
  414. if (res.data.code === 200) {
  415. this.authPermissions = { ...res.data.data };
  416. }
  417. });
  418. } else {
  419. this.authType = false;
  420. }
  421. },
  422. onSelect(val, { node }) {
  423. this.dataForm.parentId = val[0];
  424. this.dataForm.parentName = node.title;
  425. },
  426. getList() {
  427. this.loading = true;
  428. this.$API.sysManage.getMenuList({}).then((res) => {
  429. if (res.data.code === 200) {
  430. this.loading = false;
  431. this.tableList = [...res.data.data];
  432. } else {
  433. this.loading = false;
  434. this.$message.error(res.data.msg);
  435. }
  436. });
  437. },
  438. addMenu() {
  439. this.title = "新增";
  440. this.visible = true;
  441. this.dataForm = { ...this.resetForm };
  442. this.form.setFieldsValue({ ["name"]: "" });
  443. this.form.setFieldsValue({ ["url"]: "" });
  444. },
  445. handleOk() {
  446. this.form.validateFields((err, values) => {
  447. if (!err) {
  448. // console.log(values, this.dataForm);
  449. if (this.authType) {
  450. this.$API.sysManage
  451. .setMenuAuth({
  452. customScriptFlag: this.authPermissions.customScriptFlag ? 1 : 0,
  453. dataPermissionId:
  454. this.authPermissions.customScriptFlag == 0
  455. ? this.authPermissions.dataPermissionId
  456. : undefined,
  457. id: this.authPermissions.id,
  458. menuId: this.authPermissions.menuId,
  459. scriptContent: this.authPermissions.customScriptFlag
  460. ? this.authPermissions.scriptContent
  461. : undefined,
  462. url: this.authPermissions.url,
  463. })
  464. .then((res) => {
  465. if (res.data.code === 200) {
  466. this.$message.success("操作成功");
  467. this.confirmLoading = false;
  468. this.visible = false;
  469. this.loading = false;
  470. this.getList();
  471. }
  472. });
  473. } else
  474. this.$API.sysManage
  475. .setMenuItem({
  476. ...this.dataForm,
  477. name: values.name,
  478. url: values.url,
  479. })
  480. .then((res) => {
  481. if (res.data.code === 200) {
  482. this.$message.success("操作成功");
  483. this.confirmLoading = false;
  484. this.visible = false;
  485. this.loading = false;
  486. this.getList();
  487. }
  488. });
  489. }
  490. });
  491. },
  492. },
  493. };
  494. </script>
  495. <style lang='less' scoped>
  496. .menu {
  497. display: flex;
  498. flex-direction: column;
  499. background: #fff;
  500. padding: 15px;
  501. box-sizing: border-box;
  502. .menu-head {
  503. display: flex;
  504. button {
  505. margin-left: 15px;
  506. }
  507. }
  508. /deep/ .ant-form .ant-form-item {
  509. display: flex !important;
  510. }
  511. .operation-list {
  512. button {
  513. margin-right: 10px;
  514. }
  515. }
  516. }
  517. </style>