menu-operation.tsx 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. import {
  2. NForm,
  3. NFormItem,
  4. NInput,
  5. NSelect,
  6. NSpace,
  7. NButton,
  8. NTreeSelect,
  9. useMessage,
  10. NRadioGroup,
  11. NRadio,
  12. NCascader,
  13. NGrid,
  14. NFormItemGi,
  15. NInputNumber,
  16. useDialog
  17. } from 'naive-ui'
  18. import { defineComponent, onMounted, PropType, reactive, ref } from 'vue'
  19. import { sysMenuSave, sysMenuUpdate } from './api'
  20. export default defineComponent({
  21. name: 'city-operation',
  22. props: {
  23. type: {
  24. type: String,
  25. default: 'add'
  26. },
  27. menuList: {
  28. type: Array,
  29. default: () => []
  30. },
  31. applyList: {
  32. type: Array as PropType<any>,
  33. default: () => []
  34. },
  35. data: {
  36. type: Object as PropType<any>,
  37. default: () => {}
  38. }
  39. },
  40. emits: ['close', 'getList'],
  41. setup(props, { emit }) {
  42. // parentId 上级菜单
  43. // path 路径
  44. // name 名称
  45. // component 组件名
  46. // icon 图标
  47. // type 菜单 | 按钮
  48. // permission 权限
  49. // parentPermission 高亮路径
  50. // sort 菜单排序
  51. // hidden 是否隐藏
  52. // linkPath 外链地址
  53. const forms = reactive({
  54. appId: null,
  55. parentId: null,
  56. type: 0,
  57. name: null,
  58. path: null,
  59. icon: null,
  60. component: null,
  61. permission: null,
  62. parentPermission: null,
  63. linkPath: null,
  64. sort: 0,
  65. hidden: 0
  66. })
  67. const menuList = ref<any[]>([{ id: '0', name: '根结点', isLeaf: true }, ...props.menuList])
  68. const btnLoading = ref(false)
  69. const formsRef = ref()
  70. const message = useMessage()
  71. const onSubmit = async () => {
  72. formsRef.value.validate(async (error: any) => {
  73. if (error) return false
  74. try {
  75. btnLoading.value = true
  76. if (props.type === 'add') {
  77. await sysMenuSave({
  78. ...forms
  79. })
  80. message.success('添加成功')
  81. } else if (props.type === 'edit') {
  82. await sysMenuUpdate({ ...forms, id: props.data.id })
  83. message.success('修改成功')
  84. }
  85. emit('close')
  86. emit('getList')
  87. } catch {}
  88. btnLoading.value = false
  89. })
  90. }
  91. onMounted(async () => {
  92. if (props.type === 'edit') {
  93. const data = props.data
  94. forms.appId = data.appId
  95. forms.parentId = data.parentId
  96. forms.type = Number(data.type)
  97. forms.name = data.name
  98. forms.path = data.path
  99. forms.icon = data.icon
  100. forms.component = data.component
  101. forms.permission = data.permission
  102. forms.parentPermission = data.parentPermission
  103. forms.linkPath = data.linkPath
  104. forms.sort = data.sort
  105. forms.hidden = data.hidden
  106. }
  107. })
  108. return () => (
  109. <div style="background: #fff; padding-top: 12px">
  110. <NForm model={forms} ref={formsRef} label-placement="left" label-width="100">
  111. <NGrid cols={2}>
  112. <NFormItemGi
  113. label="应用分类"
  114. path="appId"
  115. rule={[
  116. {
  117. required: true,
  118. message: '请选择应用分类'
  119. }
  120. ]}
  121. >
  122. <NCascader
  123. v-model:value={forms.appId}
  124. options={props.applyList}
  125. showPath={true}
  126. allowCheckingNotLoaded={false}
  127. checkStrategy="child"
  128. valueField="id"
  129. labelField="appName"
  130. childrenField="bizApps"
  131. placeholder="请选择应用分类"
  132. expandTrigger="hover"
  133. clearable
  134. ></NCascader>
  135. </NFormItemGi>
  136. <NFormItemGi
  137. label="上级菜单"
  138. path="parentId"
  139. rule={[
  140. {
  141. required: true,
  142. message: '请选择上级菜单'
  143. }
  144. ]}
  145. >
  146. <NTreeSelect
  147. v-model:value={forms.parentId}
  148. placeholder="请选择上级菜单"
  149. checkStrategy="parent"
  150. options={menuList.value}
  151. showPath={false}
  152. keyField="id"
  153. labelField="name"
  154. virtualScroll
  155. />
  156. </NFormItemGi>
  157. <NFormItemGi
  158. label="菜单类型"
  159. path="type"
  160. rule={[{ required: true, message: '请选择上级菜单' }]}
  161. >
  162. <NRadioGroup v-model:value={forms.type}>
  163. <NSpace>
  164. <NRadio value={true}>菜单</NRadio>
  165. <NRadio value={false}>按钮</NRadio>
  166. </NSpace>
  167. </NRadioGroup>
  168. </NFormItemGi>
  169. <NFormItemGi
  170. label="菜单名称"
  171. path="name"
  172. rule={[
  173. {
  174. required: true,
  175. message: '请输入菜单名称',
  176. trigger: ['blur', 'input']
  177. }
  178. ]}
  179. >
  180. <NInput
  181. v-model:value={forms.name}
  182. placeholder="请输入菜单名称"
  183. clearable
  184. maxlength={100}
  185. ></NInput>
  186. </NFormItemGi>
  187. {forms.type === 0 && (
  188. <>
  189. <NFormItemGi
  190. label="路由路径"
  191. path="path"
  192. rule={[
  193. {
  194. required: true,
  195. message: '请输入路由路径',
  196. trigger: ['blur', 'input']
  197. }
  198. ]}
  199. >
  200. <NInput
  201. v-model:value={forms.path}
  202. placeholder="请输入路由路径"
  203. clearable
  204. maxlength={100}
  205. ></NInput>
  206. </NFormItemGi>
  207. <NFormItemGi label="菜单图标" path="icon">
  208. <NInput
  209. v-model:value={forms.icon}
  210. placeholder="请输入菜单图标"
  211. clearable
  212. maxlength={100}
  213. ></NInput>
  214. </NFormItemGi>
  215. <NFormItemGi
  216. label="组件名称"
  217. path="component"
  218. rule={[
  219. {
  220. required: true,
  221. message: '请输入组件名称',
  222. trigger: ['blur', 'input']
  223. }
  224. ]}
  225. >
  226. <NInput
  227. v-model:value={forms.component}
  228. placeholder="请输入组件名称"
  229. clearable
  230. maxlength={100}
  231. ></NInput>
  232. </NFormItemGi>
  233. <NFormItemGi label="链接地址" path="linkPath">
  234. <NInput
  235. v-model:value={forms.linkPath}
  236. placeholder="外链/内嵌时链接地址(http://www.colexiu.com)"
  237. clearable
  238. maxlength={100}
  239. ></NInput>
  240. </NFormItemGi>
  241. <NFormItemGi label="高亮路径" path="parentPermission">
  242. <NInput
  243. v-model:value={forms.parentPermission}
  244. placeholder="子页面高亮路径"
  245. clearable
  246. maxlength={100}
  247. ></NInput>
  248. </NFormItemGi>
  249. </>
  250. )}
  251. <NFormItemGi
  252. label="权限标识"
  253. path="permission"
  254. rule={[
  255. {
  256. required: true,
  257. message: '请输入权限标识',
  258. trigger: ['blur', 'input']
  259. }
  260. ]}
  261. >
  262. <NInput
  263. v-model:value={forms.permission}
  264. placeholder="请输入权限标识"
  265. clearable
  266. maxlength={100}
  267. ></NInput>
  268. </NFormItemGi>
  269. <NFormItemGi label="菜单排序" path="sort">
  270. <NInputNumber
  271. v-model:value={forms.sort}
  272. placeholder="请输入菜单排序"
  273. clearable
  274. ></NInputNumber>
  275. </NFormItemGi>
  276. {forms.type === 0 && (
  277. <NFormItemGi label="是否隐藏" path="hidden">
  278. <NRadioGroup v-model:value={forms.hidden}>
  279. <NSpace>
  280. <NRadio value={1}>是</NRadio>
  281. <NRadio value={0}>否</NRadio>
  282. </NSpace>
  283. </NRadioGroup>
  284. </NFormItemGi>
  285. )}
  286. </NGrid>
  287. </NForm>
  288. <NSpace justify="end">
  289. <NButton type="default" onClick={() => emit('close')}>
  290. 取消
  291. </NButton>
  292. <NButton type="primary" onClick={() => onSubmit()} loading={btnLoading.value}>
  293. 保存
  294. </NButton>
  295. </NSpace>
  296. </div>
  297. )
  298. }
  299. })