editForm.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. /* eslint-disable */
  2. <template>
  3. <a-modal
  4. title="编辑菜单"
  5. :width="1000"
  6. :visible="visible"
  7. :confirmLoading="confirmLoading"
  8. @ok="handleSubmit"
  9. @cancel="handleCancel"
  10. :destroyOnClose=true
  11. >
  12. <a-spin :spinning="formLoading">
  13. <a-form :form="form" >
  14. <a-form-item v-show=false >
  15. <a-input v-decorator="['id']" />
  16. </a-form-item>
  17. <a-row :gutter="24">
  18. <a-col :md="12" :sm="24">
  19. <a-form-item
  20. label="菜单名称"
  21. :labelCol="labelCol"
  22. :wrapperCol="wrapperCol"
  23. hasFeedback
  24. >
  25. <a-input placeholder="请输入菜单名称" v-decorator="['name',{rules: [{required: true, min: 1, message: '请输入菜单名称!'}]}]" />
  26. </a-form-item>
  27. </a-col>
  28. <a-col :md="12" :sm="24">
  29. <a-form-item
  30. style="width: 100%"
  31. :labelCol="labelCol"
  32. :wrapperCol="wrapperCol"
  33. label="菜单编号"
  34. hasFeedback
  35. >
  36. <a-input placeholder="请输入菜单编号" v-decorator="['code', {rules: [{required: true, min: 1, message: '请输入菜单编号!'}]}]" />
  37. </a-form-item>
  38. </a-col>
  39. </a-row>
  40. <a-row :gutter="24">
  41. <a-col :md="12" :sm="24">
  42. <a-form-item
  43. :labelCol="labelCol"
  44. :wrapperCol="wrapperCol"
  45. label="所属应用"
  46. has-feedback
  47. >
  48. <a-select style="width: 100%" placeholder="请选择应用分类" v-decorator="['application', {rules: [{ required: true, message: '请选择应用分类!' }]}]" >
  49. <a-select-option v-for='(item,index) in appData' :key="index" :value="item.code" @click="changeApplication(item.code)">{{item.name}}</a-select-option>
  50. </a-select>
  51. </a-form-item>
  52. </a-col>
  53. <a-col :md="12" :sm="24">
  54. <a-form-item
  55. :labelCol="labelCol"
  56. :wrapperCol="wrapperCol"
  57. label="菜单层级"
  58. >
  59. <a-radio-group v-decorator="['type',{rules: [{ required: true, message: '请选择菜单层级!' }]}]" >
  60. <a-radio v-for='(item,index) in typeData' :key="index" :value="item.code" @click="meneTypeFunc(item.code)">{{item.value}}</a-radio>
  61. </a-radio-group>
  62. </a-form-item>
  63. </a-col>
  64. </a-row>
  65. <a-row :gutter="24">
  66. <a-col :md="12" :sm="24">
  67. <div v-show="pidShow">
  68. <a-form-item
  69. :labelCol="labelCol"
  70. :wrapperCol="wrapperCol"
  71. label="父级菜单"
  72. has-feedback
  73. >
  74. <a-tree-select
  75. v-decorator="['pid', {rules: [{ required: true, message: '请选择父级菜单!' }]}]"
  76. style="width: 100%"
  77. :dropdownStyle="{ maxHeight: '300px', overflow: 'auto' }"
  78. :treeData="menuTreeData"
  79. placeholder="请选择父级菜单"
  80. treeDefaultExpandAll
  81. >
  82. <span slot="title" slot-scope="{ id }">{{ id }}
  83. </span>
  84. </a-tree-select>
  85. </a-form-item>
  86. </div>
  87. <div v-show="redirectShow">
  88. <a-form-item
  89. :labelCol="labelCol"
  90. :wrapperCol="wrapperCol"
  91. >
  92. <span slot="label">
  93. <a-tooltip title="如需打开首页加载此目录下菜单,请填写加载菜单路由,设为首页后其他设置的主页将被替代">
  94. <a-icon type="question-circle-o" />
  95. </a-tooltip>&nbsp;
  96. 重定向
  97. </span>
  98. <a-input prop="redirect" placeholder="请输入重定向地址" v-decorator="['redirect']" />
  99. </a-form-item>
  100. </div>
  101. </a-col>
  102. <a-col :md="12" :sm="24">
  103. <a-form-item
  104. :labelCol="labelCol"
  105. :wrapperCol="wrapperCol"
  106. >
  107. <span slot="label">
  108. <a-tooltip title="按钮:无,菜单:内链、外链、组件">
  109. <a-icon type="question-circle-o" />
  110. </a-tooltip>&nbsp;
  111. 打开方式
  112. </span>
  113. <a-radio-group :disabled="openTypeDisabled" v-decorator="['openType',{rules: [{ required: true, message: '请选择打开方式!' }]}]">
  114. <a-radio v-for='(item,index) in openTypeData' :key="index" :value="item.code" @click="meneOpenTypeFunc(item.code)">{{item.value}}</a-radio>
  115. </a-radio-group>
  116. </a-form-item>
  117. </a-col>
  118. </a-row>
  119. <a-divider />
  120. <a-row :gutter="24" >
  121. <a-col :md="12" :sm="24">
  122. <div v-show="componentShow">
  123. <a-form-item
  124. :labelCol="labelCol"
  125. :wrapperCol="wrapperCol"
  126. hasFeedback
  127. >
  128. <span slot="label">
  129. <a-tooltip title="前端vue组件 views文件夹下路径,例:system/menu/index。注:目录级填写:RouteView(不带面包屑),PageView(带面包屑),菜单级内链打开http链接填写:Iframe">
  130. <a-icon type="question-circle-o" />
  131. </a-tooltip>&nbsp;
  132. 前端组件
  133. </span>
  134. <a-input placeholder="请输入前端组件" :disabled="componentDisabled" prop="component" v-decorator="['component',{rules: [{required: componentRequired, message: '请输入前端组件'}]}]"/>
  135. </a-form-item>
  136. </div>
  137. </a-col>
  138. <a-col :md="12" :sm="24">
  139. <div v-show="routerShow">
  140. <a-form-item
  141. :labelCol="labelCol"
  142. :wrapperCol="wrapperCol"
  143. hasFeedback
  144. >
  145. <span slot="label">
  146. <a-tooltip title="浏览器显示的URL,例:/menu,对应打开页面为菜单页面">
  147. <a-icon type="question-circle-o" />
  148. </a-tooltip>&nbsp;
  149. 路由地址
  150. </span>
  151. <a-input placeholder="请输入路由" v-decorator="['router', {rules: [{required: routerRequired, message: '请输入路由!'}]}]" />
  152. </a-form-item>
  153. </div>
  154. <div v-show="permissionShow">
  155. <a-form-item
  156. :labelCol="labelCol"
  157. :wrapperCol="wrapperCol"
  158. label="权限标识"
  159. hasFeedback
  160. >
  161. <a-input placeholder="请输入权限标识" v-decorator="['permission', {rules: [{required: permissionRequired, message: '请输入权限标识!'}]}]" />
  162. </a-form-item>
  163. </div>
  164. </a-col>
  165. </a-row>
  166. <a-row :gutter="24">
  167. <a-col :md="12" :sm="24">
  168. <div v-show="linkShow" >
  169. <a-form-item
  170. :labelCol="labelCol"
  171. :wrapperCol="wrapperCol"
  172. hasFeedback
  173. >
  174. <span slot="label">
  175. <a-tooltip title="当选择了需要内链或外链打开的选项,此处输入要打开的链接地址,例:https://www.stylefeng.cn">
  176. <a-icon type="question-circle-o" />
  177. </a-tooltip>&nbsp;
  178. 内外链地址
  179. </span>
  180. <a-input placeholder="请输入内链打开地址" :disabled="linkDisabled" v-decorator="['link', {rules: [{required: linkRequired, message: '请输入权限标识!'}]}]" />
  181. </a-form-item>
  182. </div>
  183. </a-col>
  184. <a-col :md="12" :sm="24">
  185. <div v-show="iconShow" >
  186. <a-form-item
  187. :labelCol="labelCol"
  188. :wrapperCol="wrapperCol"
  189. label="图标"
  190. >
  191. <a-input placeholder="请选择图标" disabled="disabled" v-decorator="['icon']" >
  192. <a-icon slot="addonAfter" @click="openIconSele()" type="setting" />
  193. </a-input>
  194. </a-form-item>
  195. </div>
  196. </a-col>
  197. </a-row>
  198. <a-row :gutter="24">
  199. <a-col :md="12" :sm="24">
  200. <a-form-item
  201. :labelCol="labelCol"
  202. :wrapperCol="wrapperCol"
  203. >
  204. <span slot="label">
  205. <a-tooltip title="系统权重:菜单可分配给任何角色,业务权重:菜单对超级管理员不可见">
  206. <a-icon type="question-circle-o" />
  207. </a-tooltip>&nbsp;
  208. 权重
  209. </span>
  210. <a-radio-group v-decorator="['weight']">
  211. <a-radio v-for='(item,index) in weightData' :key="index" :value="item.code" >{{item.value}}</a-radio>
  212. </a-radio-group>
  213. </a-form-item>
  214. </a-col>
  215. <a-col :md="12" :sm="24">
  216. <a-form-item
  217. :labelCol="labelCol"
  218. :wrapperCol="wrapperCol"
  219. label="是否可见"
  220. >
  221. <a-switch id="visible" checkedChildren="是" unCheckedChildren="否" v-decorator="['visible', { valuePropName: 'checked' }]"/>
  222. </a-form-item>
  223. </a-col>
  224. </a-row>
  225. <a-row :gutter="24">
  226. <a-col :md="12" :sm="24">
  227. <a-form-item
  228. :labelCol="labelCol"
  229. :wrapperCol="wrapperCol"
  230. label="排序"
  231. >
  232. <a-input-number style="width: 100%" v-decorator="['sort', { initialValue: 100 }]" :min="1" :max="1000" />
  233. </a-form-item>
  234. </a-col>
  235. <a-col :md="12" :sm="24">
  236. <a-form-item
  237. :labelCol="labelCol"
  238. :wrapperCol="wrapperCol"
  239. label="备注"
  240. hasFeedback
  241. >
  242. <a-input placeholder="请输入备注" v-decorator="['remark']"></a-input>
  243. </a-form-item>
  244. </a-col>
  245. </a-row>
  246. </a-form>
  247. </a-spin>
  248. <a-modal
  249. :width="850"
  250. :visible="visibleIcon"
  251. @cancel="handleCancelIcon"
  252. footer=""
  253. :mask=false
  254. :closable=false
  255. :destroyOnClose=true
  256. >
  257. <icon-selector v-model="currentSelectedIcon" @change="handleIconChange"/>
  258. </a-modal>
  259. </a-modal>
  260. </template>
  261. <script>
  262. import { getAppList } from '@/api/modular/system/appManage'
  263. import { getMenuTree ,sysMenuEdit} from '@/api/modular/system/menuManage'
  264. import IconSelector from '@/components/IconSelector'
  265. import { sysDictTypeDropDown } from '@/api/modular/system/dictManage'
  266. export default {
  267. name:'menu_edit',
  268. components: {IconSelector},
  269. data () {
  270. return {
  271. labelCol: {
  272. xs: { span: 24 },
  273. sm: { span: 6 }
  274. },
  275. wrapperCol: {
  276. xs: { span: 24 },
  277. sm: { span: 16 }
  278. },
  279. visibleIcon:false,
  280. visible: false,
  281. confirmLoading: false,
  282. appData:[],
  283. menuTreeData:[],
  284. redirectShow:true,
  285. componentShow:true,
  286. componentDisabled:false,
  287. componentRequired:true,
  288. routerRequired:true,
  289. routerShow:true,
  290. iconShow:true,
  291. openTypeShow:true,
  292. pidShow:true,
  293. permissionShow:true,
  294. permissionRequired:true,
  295. //图标组件
  296. currentSelectedIcon: 'pause-circle',
  297. typeData:[],
  298. openTypeData:[],
  299. weightData:[],
  300. formLoading:true,
  301. linkShow:true,
  302. openTypeDisabled:false,
  303. openTypeDefault:[],
  304. openType:'',
  305. linkRequired:true,
  306. linkDisabled:false,
  307. type:'',
  308. form: this.$form.createForm(this),
  309. }
  310. },
  311. methods: {
  312. //打开页面初始化
  313. edit (record) {
  314. this.visible = true
  315. //获取系统应用列表
  316. this.getSysApplist();
  317. this.sysDictTypeDropDown()
  318. //图标
  319. this.currentSelectedIcon = record.icon
  320. //默认选中菜单项,并初始化
  321. this.form.getFieldDecorator('type',{valuePropName:'checked',initialValue:record.type.toString()})
  322. this.meneTypeFunc(record.type.toString(),record.openType.toString())
  323. //默认选中的单选框
  324. const visibleDef=false
  325. if(record.visible=='Y'){
  326. this.visibleDef=true
  327. }
  328. this.form.getFieldDecorator('weight',{valuePropName:'checked',initialValue:record.weight.toString()})
  329. this.form.getFieldDecorator('visible',{valuePropName:'checked',initialValue:this.visibleDef})
  330. this.form.getFieldDecorator('icon',{initialValue:record.icon})
  331. setTimeout(()=>{
  332. this.setMenuItem(record)
  333. this.changeApplication(record.application)
  334. },100)
  335. },
  336. setMenuItem(record){
  337. this.form.setFieldsValue(
  338. {
  339. id:record.id,
  340. name:record.name,
  341. code:record.code,
  342. application:record.application,
  343. redirect:record.redirect,
  344. component:record.component,
  345. permission:record.permission,
  346. link:record.link,
  347. router:record.router,
  348. sort:record.sort,
  349. remark:record.remark,
  350. }
  351. );
  352. this.form.getFieldDecorator('pid',{initialValue:record.pid})
  353. },
  354. /**
  355. * 获取字典数据
  356. */
  357. sysDictTypeDropDown(){
  358. this.formLoading=true
  359. //菜单类型
  360. sysDictTypeDropDown({code:'menu_type'}).then((res)=>{
  361. this.typeData=res.data
  362. })
  363. //权重
  364. sysDictTypeDropDown({code:'menu_weight'}).then((res)=>{
  365. this.weightData=res.data
  366. })
  367. //内外链
  368. sysDictTypeDropDown({code:'open_type'}).then((res)=>{
  369. this.openTypeData=res.data
  370. this.formLoading=false
  371. })
  372. },
  373. getSysApplist() {
  374. return getAppList().then((res) => {
  375. if (res.success) {
  376. this.appData=res.data
  377. } else {
  378. this.$message.warning(res.message)
  379. }
  380. })
  381. },
  382. changeApplication(value){
  383. getMenuTree({'application':value}).then((res) => {
  384. if (res.success) {
  385. this.form.resetFields(`pid`,[]);
  386. this.menuTreeData=[{
  387. "id": "-1",
  388. "parentId": "0",
  389. "title": "顶级",
  390. "value": "0",
  391. "pid": "0",
  392. "children":res.data
  393. }]
  394. } else {
  395. this.$message.warning(res.message)
  396. }
  397. })
  398. },
  399. /**
  400. * 选择菜单类型执行初始化表单变量
  401. */
  402. meneTypeFunc(type,openType){
  403. this.type = type
  404. if(type=='0' || type=='1'){
  405. //内外链地址显示,给空值
  406. this.linkShow=true
  407. this.form.resetFields(`link`,[]);
  408. //图标选择显示
  409. this.iconShow=true
  410. //路由必填,设置空值,并显示
  411. this.routerRequired=true
  412. this.form.getFieldDecorator('router',{initialValue:''})
  413. this.routerShow=true
  414. //权限标识框隐藏,选填,给空值
  415. this.permissionShow=false
  416. this.permissionRequired =false
  417. this.form.getFieldDecorator('permission',{initialValue:''})
  418. //打开方式设置为组件 ,禁用选择方式
  419. this.openType = openType
  420. this.form.getFieldDecorator('openType',{initialValue:this.openType})
  421. this.openTypeDisabled = false
  422. }
  423. if(type=='0'){
  424. //重定向展示,并给空
  425. this.redirectShow=true
  426. this.form.resetFields(`redirect`,[]);
  427. //组件默认为显示,设置可输入,给默认组件 PageView,验证必填
  428. this.componentShow=true
  429. this.componentDisabled=false
  430. this.form.getFieldDecorator('component',{initialValue:'PageView'})
  431. this.componentRequired=true
  432. //父级初始化顶级,并将其隐藏
  433. this.form.getFieldDecorator('pid',{initialValue:'0'})
  434. this.pidShow=false
  435. }else{
  436. if(type=='1'){
  437. //组件可以手输,取消值
  438. this.componentDisabled=false
  439. this.form.getFieldDecorator('component',{initialValue:''})
  440. }
  441. //重定向输入隐藏,并给空值
  442. this.redirectShow=false
  443. this.form.getFieldDecorator('redirect',{initialValue:''})
  444. //父级选择放开
  445. this.pidShow=true
  446. }
  447. if(type=='2'){
  448. //组件设置不填,不可输入,并给空(手输的跟设置的)
  449. this.componentRequired = false
  450. this.componentDisabled=true
  451. this.form.resetFields(`component`,[]);
  452. this.form.getFieldDecorator('component',{initialValue:''})
  453. //路由选填,设置空值,并隐藏
  454. this.routerRequired=true
  455. this.form.getFieldDecorator('router',{initialValue:''})
  456. this.routerShow=false
  457. //内外链地址隐藏,给空值
  458. this.linkShow=false
  459. this.form.getFieldDecorator('link',{initialValue:''})
  460. //权限标识框显示,必填,给空值
  461. this.permissionShow=true
  462. this.permissionRequired =true
  463. this.form.getFieldDecorator('permission',{initialValue:''})
  464. //图标选择隐藏,并给空
  465. this.iconShow=false
  466. this.form.getFieldDecorator('icon',{initialValue:''})
  467. //打开方式设置为无 ,禁用选择方式
  468. this.openType = '0'
  469. this.form.getFieldDecorator('openType',{initialValue:this.openType})
  470. this.openTypeDisabled = true
  471. //取消icon
  472. this.form.getFieldDecorator('icon',{initialValue:''})
  473. }
  474. this.meneOpenTypeFunc(this.openType)
  475. },
  476. /**
  477. * 选择打开方式执行方法
  478. */
  479. meneOpenTypeFunc(openType){
  480. this.form.resetFields(`openType`,openType);
  481. if(openType == '2' || openType == '3'){
  482. //点击内外链的时候保留原值,其他清空
  483. if(this.linkDisabled = false){
  484. this.form.resetFields(`link`,[]);
  485. }
  486. //设置内外链可手输,加验证
  487. this.linkDisabled = false
  488. this.linkRequired = true
  489. }else{
  490. //设置内外链不可手输,取消值,取消验证
  491. this.linkDisabled = true
  492. this.form.resetFields(`link`,[]);
  493. this.linkRequired = false
  494. }
  495. //另起一个分支
  496. if(openType == '3'){
  497. this.componentRequired = false
  498. this.componentDisabled=true
  499. this.form.resetFields(`component`,[]);
  500. this.form.getFieldDecorator('component',{initialValue:''})
  501. }else{
  502. this.componentRequired = true
  503. if(this.type == '1' || this.type == '2'){
  504. this.form.getFieldDecorator('component',{initialValue:''})
  505. }else{
  506. this.form.resetFields(`component`,[]);
  507. this.form.getFieldDecorator('component',{initialValue:'PageView'})
  508. }
  509. if(openType == '2'){
  510. //组件设置为 iframe
  511. this.form.resetFields(`component`,[]);
  512. this.form.getFieldDecorator('component',{initialValue:'Iframe'})
  513. }
  514. }
  515. if(this.type == '2'){
  516. if(openType == '0'){
  517. this.componentRequired = false
  518. this.routerRequired = false
  519. }
  520. }
  521. },
  522. openIconSele(){
  523. this.visibleIcon=true
  524. },
  525. handleIconChange(icon){
  526. //console.log('新图标:'+icon)
  527. this.form.getFieldDecorator('icon',{initialValue:icon})
  528. //this.form.resetFields(`icon`,icon);
  529. this.visibleIcon=false
  530. },
  531. handleCancelIcon(){
  532. this.visibleIcon=false
  533. },
  534. handleSubmit () {
  535. const { form: { validateFields } } = this
  536. this.confirmLoading = true
  537. validateFields((errors, values) => {
  538. if (!errors) {
  539. if(values.visible){
  540. values.visible='Y'
  541. }else{
  542. values.visible='N'
  543. }
  544. sysMenuEdit(values).then((res) => {
  545. this.confirmLoading = false
  546. if(res.success){
  547. this.$message.success('编辑成功')
  548. this.$emit('ok', values)
  549. this.handleCancel ()
  550. }else{
  551. this.$message.error('编辑失败:'+res.message)
  552. }
  553. }).finally((res) =>{
  554. this.confirmLoading = false
  555. })
  556. } else {
  557. this.confirmLoading = false
  558. }
  559. })
  560. },
  561. handleCancel () {
  562. this.form.resetFields();
  563. this.confirmLoading = false
  564. this.visible = false
  565. }
  566. },
  567. }
  568. </script>