menuEdit.vue 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. <template>
  2. <MDialog ref="editDialog" v-bind="$attrs" @sure="handleSaveEdit">
  3. <MForm ref="editForm" :items="editForm" v-model="editValues">
  4. <template #parentId>
  5. <el-popover
  6. placement="bottom"
  7. width="600"
  8. trigger="click">
  9. <div class="popover-tree">
  10. <el-tree
  11. :data="itemsParents"
  12. node-key="id"
  13. ref="tree"
  14. highlight-current
  15. auto-expand-parent
  16. :expand-on-click-node="false"
  17. :default-expanded-keys="[0]"
  18. @node-click="nodeClick"
  19. :props="{
  20. children: 'children',
  21. label: 'label'
  22. }">
  23. </el-tree>
  24. </div>
  25. <el-input
  26. slot="reference"
  27. v-model="currentNodeName"
  28. placeholder="请选择根菜单"
  29. readonly
  30. ></el-input>
  31. </el-popover>
  32. </template>
  33. </MForm>
  34. </MDialog>
  35. </template>
  36. <script>
  37. import { MENU_TYPE } from '@/utils/dict'
  38. export default {
  39. name: 'menu-edit',
  40. data () {
  41. return {
  42. itemsParents: [],
  43. editValues: {},
  44. currentNodeName: null,
  45. isEdit: null
  46. }
  47. },
  48. computed: {
  49. editForm () {
  50. const type = this.editValues.type
  51. return [
  52. {
  53. label: '上级菜单',
  54. prop: 'parentId',
  55. rules: [{ required: true, message: '请选择上级菜单', trigger: 'change' }]
  56. },
  57. {
  58. label: '菜单名称',
  59. prop: 'label',
  60. type: 'input',
  61. options: { placeholder: '请输入菜单名称' },
  62. rules: [{ required: true, message: '请输入菜单名称', trigger: 'change' }]
  63. },
  64. {
  65. label: '菜单类型',
  66. prop: 'type',
  67. type: 'radioGroup',
  68. button: true,
  69. options: {
  70. size: 'small',
  71. items: [
  72. { text: '目录', label: MENU_TYPE.DIRECTORY },
  73. { text: '菜单', label: MENU_TYPE.MENU },
  74. { text: '按钮', label: MENU_TYPE.BUTTON },
  75. { text: '组件', label: MENU_TYPE.COMPONENT }
  76. ]
  77. }
  78. },
  79. {
  80. label: '菜单图标',
  81. prop: 'icon',
  82. hidden: [MENU_TYPE.BUTTON].includes(type),
  83. type: 'input',
  84. options: { placeholder: '请输入菜单图标' }
  85. },
  86. {
  87. label: '路由地址',
  88. prop: 'path',
  89. hidden: [MENU_TYPE.BUTTON, MENU_TYPE.COMPONENT].includes(type),
  90. type: 'input',
  91. options: { placeholder: '请输入路由地址' },
  92. rules: [{ required: true, message: '请输入路由地址', trigger: 'change' }]
  93. },
  94. {
  95. label: '组件地址',
  96. prop: 'component',
  97. hidden: [MENU_TYPE.BUTTON].includes(type),
  98. type: 'input',
  99. options: { placeholder: '请输入组件地址' },
  100. rules: [{ required: type !== 0, message: '请输入组件地址', trigger: 'change' }]
  101. },
  102. {
  103. label: '组件名称',
  104. prop: 'name',
  105. hidden: [MENU_TYPE.BUTTON].includes(type),
  106. type: 'input',
  107. options: { placeholder: '请输入组件名称' },
  108. rules: [{ required: true, message: '请输入组件名称', trigger: 'change' }]
  109. },
  110. {
  111. label: '权限标识',
  112. prop: 'code',
  113. hidden: [MENU_TYPE.DIRECTORY, MENU_TYPE.MENU, MENU_TYPE.COMPONENT].includes(type),
  114. type: 'input',
  115. options: { placeholder: '请输入权限标识' },
  116. rules: [{ required: true, message: '请输入权限标识', trigger: 'change' }]
  117. },
  118. {
  119. label: '显示排序',
  120. prop: 'sort',
  121. type: 'number',
  122. options: { placeholder: '显示排序' },
  123. rules: [{ required: true, message: '请输入排序序号', trigger: 'change' }]
  124. },
  125. {
  126. label: '显示状态',
  127. prop: 'hidden',
  128. type: 'radioGroup',
  129. options: {
  130. items: [
  131. { text: '显示', label: 1 },
  132. { text: '隐藏', label: 0 }
  133. ]
  134. }
  135. },
  136. {
  137. label: '缓存状态',
  138. prop: 'keepAlive',
  139. type: 'radioGroup',
  140. hidden: [MENU_TYPE.DIRECTORY, MENU_TYPE.BUTTON, MENU_TYPE.COMPONENT].includes(type),
  141. options: {
  142. items: [
  143. { text: '缓存', label: true },
  144. { text: '不缓存', label: false }
  145. ]
  146. }
  147. },
  148. {
  149. label: '开启新窗口',
  150. prop: 'window',
  151. type: 'radioGroup',
  152. hidden: [MENU_TYPE.DIRECTORY, MENU_TYPE.BUTTON, MENU_TYPE.COMPONENT].includes(type),
  153. options: {
  154. items: [
  155. { text: '开启', label: true },
  156. { text: '关闭', label: false }
  157. ]
  158. }
  159. },
  160. {
  161. label: '全景视图',
  162. prop: 'panorama',
  163. type: 'radioGroup',
  164. hidden: [MENU_TYPE.BUTTON].includes(type),
  165. options: {
  166. items: [
  167. { text: '加入', label: true },
  168. { text: '不加入', label: false }
  169. ]
  170. }
  171. }
  172. ]
  173. }
  174. },
  175. methods: {
  176. open (val, items, isEdit) {
  177. this.isEdit = isEdit
  178. this.editValues = val
  179. this.itemsParents = [{ label: '根菜单', id: 0, children: items }]
  180. this.$refs.editDialog.open()
  181. this.$nextTick(() => {
  182. this.$refs.tree.setChecked(val.parentId, true)
  183. const data = this.$refs.tree.getNode(val.parentId)
  184. this.currentNodeName = data.label
  185. this.$refs.editForm.clearValidate()
  186. })
  187. },
  188. handleSaveEdit () {
  189. this.$refs.editForm.validate(async (valid) => {
  190. if (!valid) {
  191. return
  192. }
  193. const metaProp = ['keepAlive', 'window', 'panorama']
  194. const obj = this.editForm.reduce((res, item) => {
  195. if (item.hidden) {
  196. return res
  197. }
  198. if (metaProp.includes(item.prop)) {
  199. res.meta = res.meta || {}
  200. res.meta[item.prop] = this.editValues[item.prop]
  201. return res
  202. }
  203. res[item.prop] = this.editValues[item.prop]
  204. return res
  205. }, { id: this.isEdit ? this.isEdit : undefined })
  206. try {
  207. await this.$store.dispatch('menu/saveMenu', obj)
  208. this.$refs.editDialog.close()
  209. this.$emit('refresh')
  210. } catch (error) {
  211. this.$message.error(error.message)
  212. }
  213. })
  214. },
  215. nodeClick (v) {
  216. this.currentNodeName = v.label
  217. this.editValues.parentId = v.id
  218. }
  219. }
  220. }
  221. </script>
  222. <style lang="scss" scoped>
  223. .popover-tree {
  224. max-height: 500px;
  225. overflow: auto;
  226. }
  227. </style>